Julia doesn't seem to use a string to perform interpolation

The official docs indicate:

Both concatenation and string() interpolation of a string() call to convert objects to string form

However, the following minimal working example seems to show otherwise:

 type MyType x::Int end import Base.string Base.string(m::MyType) = "world" m = MyType(4) println("hello $m") println("hello " * string(m)) 

The second last line evaluates to hello MyType(4) in the REPL, and the last line evaluates (as expected) the value of hello world .

So what am I doing wrong?

(I'm still on v0.4, but the official versions of the document indicate that this should not make any difference.)

+5
source share
1 answer

The documentation is absolutely correct:

 julia> expand(:(println("hello $m"))) :(println((Base.string)("hello ",m))) 

That is, println("hello $m") equivalent to println(string("hello", m)) . By the time the code is compiled or interpreted, it is one and the same.

However your overload

 Base.string(m::MyType) = "world" 

is not the correct way to overload string . This method covers only one argument of type MyType . (That's why, by the way, your code seemed to work for concatenation: this particular example involved calling string with one argument. The results would be the same if you wrote "$m" .) The right way to overload it is

 Base.show(io::IO, m::MyType) = print(io, "world") 

which may seem strange at first. The reason this should be overloaded is because string delegates to print , which delegates to show .

After updating the minimum working example to

 type MyType x::Int end Base.show(io::IO, m::MyType) = print(io, "world") m = MyType(4) println("hello $m") println("hello " * string(m)) 

The result will be as expected.


As a side note, note that your example can be more efficiently written as

 println("hello ", m) 

This avoids the creation of intermediate lines. This illustrates why the system is configured so that string calls print , which calls show : the input / output method is more general and can print to various forms of input / output directly, whereas if it were the other way around, they should convert things to strings (requiring time allocation and therefore poor performance) before sending to IO.

+9
source

Source: https://habr.com/ru/post/1258275/


All Articles