fact
fact

Reputation: 557

Arithmetic with Chars in Julia

Julia REPL tells me that the output of

'c'+2

is 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase) but that the output of

'c'+2-'a'

is 4.

I'm fine with the fact that Chars are identified as numbers via their ASCII code. But I'm confused about the type inference here: why is the first output a char and the second an integer?

Upvotes: 8

Views: 155

Answers (2)

StefanKarpinski
StefanKarpinski

Reputation: 33249

Regarding the motivation for conventions, it’s similar to time stamps and intervals. The difference between time stamps is an interval and accordingly you can add an interval to a time stamp to get another time stamp. You cannot, however, add two time stamps because that doesn’t make sense—what is the sum of two points in time supposed to be? The difference between two chars is their distance in code point space (an integer); accordingly you can add an integer to a char to get another char that’s offset by that many code points. You can’t add two chars because adding two code points is not a meaningful operation.

Why allow comparisons of chars and differences in the first place? Because it’s common to use that kind of arithmetic and comparison to implement parsing code, eg for parsing numbers in various bases and formats.

Upvotes: 8

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69829

The reason is:

julia> @which 'a' - 1
-(x::T, y::Integer) where T<:AbstractChar in Base at char.jl:227

julia> @which 'a' - 'b'
-(x::AbstractChar, y::AbstractChar) in Base at char.jl:226

Subtraction of Char and integer is Char. This is e.g. 'a' - 1.

However, subtraction of two Char is integer. This is e.g. 'a' - 'b'.

Note that for Char and integer both addition and subtraction are defined, but for two Char only subtraction works:

julia> 'a' + 'a'
ERROR: MethodError: no method matching +(::Char, ::Char)

This indeed can lead to tricky cases at times that rely of order of operations, as in this example:

julia> 'a' + ('a' - 'a')
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> 'a' + 'a' - 'a'
ERROR: MethodError: no method matching +(::Char, ::Char)

Also note that when working with Char and integer you cannot subtract Char from integer:

julia> 2 - 'a'
ERROR: MethodError: no method matching -(::Int64, ::Char)

Motivation:

  • subtraction of two char - this is sometimes useful if you want to get a relative position of a char with reference to other char, e.g. c - '0' to convert char to its decimal representation if you know char is a digit;
  • adding or subtracting an integer and char - the same but in reverse e.g. you want to convert digit to char and write '0' + d.

I have been using Julia for years now, and I used this feature maybe once or twice, so I would not say it is super commonly needed.

Upvotes: 6

Related Questions