Is this normal behavior for ToString

Var i As Integer = 1
Var col As String = (i + 2).ToString

Compiler says:

Type mismatch error. Expected String, but got Integer.

Xojo 2026r1.2
macOS Sequoia

Str(i + 2) works fine.

This works as expected:

Var i As Integer = 1
Var col As String = Integer(i + 2).ToString

Sure looks like a bug to me. What if you switch the expression to “2+i"?

This is, unfortunately, expected behavior. Xojo can’t use syntax like that. Casting is necessary, as demonstrated.

2 Likes

Can you give a general description of what’s not permitted?

I’ve tried about four ways to write it up accurately, but I’m not a compiler engineer, so my explanations are not technically accurate and I know it. But essentially code inside parenthesis does not create a function, so there’s no return type, so you can’t apply extension methods to something with no type. That’s why CType(1 + 2, Integer).ToString or Integer(1 + 2).ToString will work - both have a known type of integer.

You might ask “well of course (1 + 2) would produce an integer, why can’t it figure that out?” And that would be a very good question. I believe it should, but it can’t. There are much more complicated examples where the return type is less obvious, but it just doesn’t matter, the compiler can’t handle it.

4 Likes

I believe it’s more that an expression can’t have an attached method.

The same way you can’t say 1.ToString, you can’t say 1+1.ToString, and expect the compiler to figure it out. You cast it into a temporary variable whose type has methods.

Edit: Actually after re-reading your comment we’re saying the same thing! Cheers!

1 Like

THe problem also lies in the lack of documentation.

When I falled in that kind of traps in the past, I changed my code to:

Var i As Integer = 1
Var myVal As Integer
Var col As String

myVal = (i + 2)
col = myVal.ToString

NB: I do not really like the " = 1" in

Var i As Integer = 1

But with time and mimetism…

Thanks to Martin, today I learned

Integer(i + 2).ToString

is the replacement for str(i+2)

Thanks :smiley:

It’s a shame Xojo can’t auto-convert primitive data types on casting.

It would be much easier to write the above as: String(i+2)

And yet you can do this:

If (A and B) then

So it’s a little more subtle than just never working at all. The compiler does have other limitations concerning numeric values, perhaps that is relevant here.

You can certainly do
Str(i+2)
It’s only extension methods that can’t handle expressions.

1 Like

Yes, you can. But you need (1+1) instead 1+1 due to some disambiguations, and it adds more complexity to the expression analyzer and Xojo probably avoided it to favor “other things”.

Here is Ruby deciding the type at expression evaluation time:

First (1+1.1) becomes Double(2.1) internally
Then Double(2.1).to_s becomes String(“2.1”)
Then "Here: "+“2.1” becomes String(“Here: 2.1”)

In Ruby, yes, you can indeed do exactly 1+1.to_s but it first converts 1.to_s to a string and then tries to add it to the integer 1, which will compile but will give you a type error at runtime.

In c# you can also do var x = 1+1.ToString(); and x would end up being the string “11”.

Obviously a compiler engineer can choose to parse whichever way they want their language to behave, but the ambiguity created by allowing this type of syntax is bad design imo. I’m glad Xojo doesn’t allow it.

3 Likes

Interestingly, I thought that Str had been deprecated in favour of the ToString methods. However, on re-checking the documentation it’s not listed as such so guess it’s just too useful to get rid of :sweat_smile:

1 Like

This is Rust, the most admired, modern, full featured and heavily designed by a huge number of computer scientists, system language. I guess they don’t agree with “bad design”.

(1+1).ToString is NOT the same as 1+1.ToString(). The parentheses disambiguate the order of operations. The latter would be bad design.

1 Like

Well, I said that above, even with an example, and you criticized it and called it “bad design”? Now you adhered the design? Ok.

I think we’re in agreement - I provided some additional examples in other languages but my original statement was, and consistently has been that without the parentheses it’s bad design and I’m glad Xojo doesn’t support it (even WITH the parentheses Xojo doesn’t support it, but that’s not what I’ve been talking about).

Well, my argument was considering the OP question. His point was (expression).method(). And I will support (expression).method() and literal.method() constructs in the future.

Have a nice week.. :wink: