Cave when doing without Str()!

Everything else that doesn't fall into one of the other PB categories.
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Cave when doing without Str()!

Post by Little John »

Hi,

I just stumbled across a nasty issue, of which we really should be aware when concatenating strings and numeric values without using Str() (or StrD() etc.).

Code: Select all

; "classic" way:
x = 7
res$ = "Result: " + Str(x + 2)
Debug res$                      ; -> 9

; new option since PB 5.10:
x = 7
res$ = "Result: " + x + 2
Debug res$                      ; -> 72
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: Cave when doing without Str()!

Post by c4s »

Yes, yesterday I came across this issue as well. In that case I would normally try to put in parentheses, like this:

Code: Select all

x = 7
res$ = "Result: " + (x + 2)
Debug res$
...but unfortunately this doesn't work (yet).
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Cave when doing without Str()!

Post by Danilo »

Maybe the following should be allowed now, it currently gives an error:

Code: Select all

; new option since PB 5.10:
x = 7
res$ = "Result: " + (x + 2)
Debug res$                      ; -> 9
Feature Request?
Thade
Enthusiast
Enthusiast
Posts: 266
Joined: Sun Aug 03, 2003 12:06 am
Location: Austria

Re: Cave when doing without Str()!

Post by Thade »

Well Guys ... you're lucky ... there's rumor that PB 6.00 will have a clearvoyance module ...

You will never have to define yourself anything on your own anymore ... you just write one letter and the compiler knows exactly what you wanted to do ...

Know what I mean? :twisted:

LOL
.
--------------
Yes, its an Irish Wolfhound.
Height: 107 cm; Weight: 88 kg
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Cave when doing without Str()!

Post by Danilo »

Thade wrote:Know what I mean? :twisted:
No. Can you explain, please?

Works as expected in other languages.

JAVA:

Code: Select all

package app;

public class Main {
    public static void main(String[] args) {
        int i = 7;
        System.out.println( "Result: " + i + 2 ); // Result: 72
        System.out.println( "Result: " + (i+2) ); // Result: 9
    }
}
C#:

Code: Select all

using System;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            int i = 7;
            Console.Out.WriteLine( "Result: " + i + 2 ); // Result: 72
            Console.Out.WriteLine( "Result: " + (i+2) ); // Result: 9
        }
    }
}
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Cave when doing without Str()!

Post by Little John »

Danilo,

thanks for your additional information regarding other languages.
Danilo wrote:Feature Request?
Done. :-)
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Cave when doing without Str()!

Post by freak »

Danilo wrote:Works as expected in other languages.

JAVA:

Code: Select all

package app;

public class Main {
    public static void main(String[] args) {
        int i = 7;
        System.out.println( "Result: " + i + 2 ); // Result: 72
        System.out.println( "Result: " + (i+2) ); // Result: 9
    }
}
Beware though that the results are different if you change the order:

Code: Select all

        System.out.println( i + 2 + " Result" ); // 9 Result
        System.out.println( (i+2) + " Result" ); // 9 Result
That is because "a + b + c" is interpreted as "(a + b) + c" and thus the evaluation kicks in in both cases.

Imho it is clearer to just concatenate all operands if strings and numbers are mixed and not try to be smart and evaluate some of the expressions before. You can always use Str() if that is actually the result you want and you have full control.
quidquid Latine dictum sit altum videtur
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Cave when doing without Str()!

Post by Danilo »

freak wrote:Beware though that the results are different if you change the order:

Code: Select all

        System.out.println( i + 2 + " Result" ); // 9 Result
        System.out.println( (i+2) + " Result" ); // 9 Result
That is because "a + b + c" is interpreted as "(a + b) + c" and thus the evaluation kicks in in both cases.

Imho it is clearer to just concatenate all operands if strings and numbers are mixed and not try to be smart and evaluate some of the expressions before. You can always use Str() if that is actually the result you want and you have full control.
Please allow me to add a multiplication to the examples in Java and C# (to be more clear what we are talking about).

Java:

Code: Select all

package app;

public class Main {
    public static void main(String[] args) {
        int i = 7;
        System.out.println( "Result: " + i + 2 );           // Result: 72
        System.out.println( "Result: " + (i+2) );           // Result: 9

        System.out.println( "Result: " + i + 2 * 6 );       // Result: 712
        System.out.println( "Result: " + (i+2) * 6 );       // Result: 54
        System.out.println( "Result: " + (i+ 2 * 6));       // Result: 19

        System.out.println( i + 2 + " is the result" );     // 9 is the result
        System.out.println( (i+2) + " is the result" );     // 9 is the result

        System.out.println( i + 2 * 6 + " is the result" ); // 19 is the result
        System.out.println( (i+2) * 6 + " is the result" ); // 54 is the result
    }
}
C#:

Code: Select all

using System;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            int i = 7;
            Console.Out.WriteLine( "Result: " + i + 2 );           // Result: 72
            Console.Out.WriteLine( "Result: " + (i+2) );           // Result: 9

            Console.Out.WriteLine("Result: " +  i + 2  * 6 );      // Result: 712
            Console.Out.WriteLine("Result: " + (i + 2) * 6 );      // Result: 54
            Console.Out.WriteLine("Result: " + (i + 2  * 6));      // Result: 19

            Console.Out.WriteLine( i + 2 + " is the result" );     // 9 is the result
            Console.Out.WriteLine( (i+2) + " is the result" );     // 9 is the result

            Console.Out.WriteLine( i + 2 * 6 + " is the result" ); // 19 is the result
            Console.Out.WriteLine((i + 2) * 6 + " is the result"); // 54 is the result
        }
    }
}
Both languages give the same and correct results. It is the opposite of magic,
it is just following the operator precedence rules.
What we call operator precedence as programmers is what we begin to learn
in kindergarten (1+2 = 3) and we add new stuff later in school:
1 + 2 * 3 = 7
(1+2) * 3 = 9

We learned that parenthesis have higher priority than plus, minus, multiplication, division.
We also learned that operators of the same priority are evaluated from left to right.

(Side note 1: Parenthesis are missing from the operator precedence table in the PB manual)
(Side note 2: Parenthesis are called "Brackets" in PB manual, whereas "Brackets" is used for [] most of the time)

PB reference manual -> Variables, Types and Operators:
() Brackets. You can use sets of brackets to force part of an expression to be evaluated first, or in a certain order.

Example:
a = (5 + 6) * 3 ; Result will be 33 since the 5+6 is evaluated first
b = 4 * (2 - (3 - 4)) ; Result will be 12 since the 3-4 is evaluated first, then the 2-result, then the multiplication
PB supports this common rule generally, but not in:

Code: Select all

x = 7
res$ = "Result: " + (x + 2)
It is the same rule. Expressions in Parenthesis/Brackets are evaluated first, then the result is added to the string.

It may be confusing at first, even for some of the experienced PB programmers, because it is a new PB feature.
You learn about operator precedence in every beginner's programming course, and you always learn it in the same way,
used world wide in every-days life, in mathematics and used by every programming language.

If you remember what you learned at school, you understand why the results in Java and C# are like they are:

Code: Select all

int i = 7;
System.out.println( i + 2 + " Result" ); // 9 Result
With the simple string concatenation system freak suggests, the PureBasic result would be:

Code: Select all

i = 7
PrintN( i + 2 + " Result" ) ; 72 Result
It is wrong, even every non-programmer should understand that. It is against all common sense
and against everything we learned.
Operators of same precedence are evaluated from left to right. 7 + 2 = 9.

Going a non-standard way for PureBasic in this case could be even more confusing... in my opinion.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Cave when doing without Str()!

Post by freak »

The difference is that the + has two different meanings here. The operator is overloaded as both +(addition) and +(string concatenation).

The current rule is quite simple: If you mix strings and numbers, the + becomes the +(string concatenation) for all operands.
In the Java example, whether the + is addition or string concatenation depends on the position of the operand in the expression. Yes, there is a logical explanationfor it, but it is not very intuitive.

In my eyes it is more intuitive that if you start with:

Code: Select all

"foo" +(concatenation) 7 +(concatenation) 2
And you simply reorder the operands, you end up with:

Code: Select all

7 +(concatenation) 2 +(concatenation) "foo"
Rather than:

Code: Select all

7 +(addition) 2 +(concatenation) "foo"
Btw, you school examples don't really help here because in math, operations with the same precedence can be reordered as desired without changing the result. I.e. a+b+c=(a+b)+c=a+(b+c). It is only computer languages that make things different here because The + does not have the same meaning depending on context.

Programming is the process of constantly reordering and rewriting code. The more intuitive it is to make such changes, the easier it is to adapt a piece of code as needed. The rules in the other languages may be logical, but they are not intuitive and therefore don't help writing better programs, but rather introduce a new source of bugs.
quidquid Latine dictum sit altum videtur
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Cave when doing without Str()!

Post by skywalk »

I repeat. The omission of 'Str(somenumber)' is only marginally helpful to most coders.
And, due to conflicting operator precedence, it is becoming super confusing.
If the parser can eventually differentiate string precedence vs numeric, then I want operator overloading for my functions too :!:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Cave when doing without Str()!

Post by Danilo »

@freak:
OK, can't change it anyway.

Maybe you can at least re-think the original request:

Code: Select all

x = 7
res$ = "Result: " + (x + 2) ; Expressions within Parenthesis are evaluated first.
It is a syntax error now.
It is intuitive to many programmers.
It is readable.
It is correct according to the PB manual ( Expressions within Parenthesis are evaluated first )

If not changed, we just use Str() as we did before. Thanks for taking your time to discuss it.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Cave when doing without Str()!

Post by eddy »

Danilo wrote:Maybe you can at least re-think the original request:

Code: Select all

x = 7
res$ = "Result: " + (x + 2) ; Expressions within Parenthesis are evaluated first.
+1
It could be a good solution
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Cave when doing without Str()!

Post by blueznl »

eddy wrote:
Danilo wrote:Maybe you can at least re-think the original request:

Code: Select all

x = 7
res$ = "Result: " + (x + 2) ; Expressions within Parenthesis are evaluated first.
+1
It could be a good solution
Nope, utterly bad solution. First part is a string, and you're trying to add a numeric variable to it. This should always throw an error.

(And languages that don't should die a long and painful death :-))
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply