NUMEXPR, STREXPR, #+, $+

Compiler edit 890: add new operators and casting functions to eliminate the ambiguity in the + operator, which functions as addition or concatenation, depending on the context.

NUMEXPR(expr)

NUMEXPR(expr) is the mirror image of STREXPR$(expr). It tells the compiler to expect and treat the argument expression as a numeric expression. This may seem similar to the VAL(x) function but differs in important ways.

VAL() is designed to convert a string value (variable or expression) to a number. If given an expression for an argument, it expects the expression to be a string expression, which means that it will intepret any + operator as concatenation, and will convert any numeric operands to string. Only after the expression argument is fully evaluated (as a string) does it get converted to a numeric value.

NUMEXPR(expr) expects the argument to be a numeric expression, which means that it will interpret any + operator as addition, and will convert any string operands to numbers. Since the resulting expression will be a numeric value, there is no need for a final conversion. Examples:

map1 x,f,6

map1 y,b,2

map1 z,f,6

map1 a$,s,10

map1 b$,s,10

 

x = y + z                ! addition

x = numexpr(y + z)       ! same; numexpr() has no effect here

a$ = y + z               ! concatenation (due to string target)

a$ = numexpr(y + z)      ! addition

x = a$ + b$              ! addition; same as val(a$) + val(b$)

x = numexpr(a$ + b$)     ! addition; same as above

x = val(a$ + b$)         ! concatenation; (val expects a string argument)

x = str$(a$ + b$)        ! addition(!); same as val(a$) + val(b$)

fn'foo(a$ + b$)          ! concatenation; (a$ sets string mode here)

fn'foo(numexpr(a$ + b$)) ! addition

 

 

NUMEXPR(expr) is particularly useful when working with DYNSTRUCT members, since they are always treated by the compiler as strings, possibly causing intended addition operations to be compiled as concatenation. In fact, the compiler will now treat any expression involving a dynstruct.member and the + operator as an error, unless one of the casting functions NUMEXPR(expr) or STREXPR$(expr) is used.

Also See

•   $+ and #+ operators

•   The Overloaded Plus Operator

•   STREXPR$() (below)

STREXPR$(expr)

STREXPR$(expr) is the mirror image of NUMEXPR(expr). It tells the tells the compiler to expect and treat the expression argument as a string expression. This may seem similar to the STR$(x) function but differs in important ways.

STR$(x) is designed to convert a numeric value (variable or expression) to a string. If given an expression for an argument, it expects the expression to be a numeric expression, which means that it will intepret any + operator as addition, and will convert any string operands to numeric. Only after the expression argument is fully evaluated (as a number) does it get converted to a string value.

STREXPR$(expr) expects the argument to be a string expression, which means that it will interpret any + operator as concatenation, and will convert any numeric operands to strings. Since the resulting expression will be a string value, there is no need for a final conversion. Examples:

map1 x,f,6

map1 y,b,2

map1 z,f,6

map1 a$,s,10

map1 b$,s,10

 

x = y + z                ! addition

x = strexpr$(y + z)      ! concatenation; same as str$(y) + str$(z) (sum then converted to string)

a$ = y + z               ! concatenation (due to string target)

a$ = strexpr$(y + z)     ! same; strexpr$() here has no effect

x = a$ + b$              ! addition; same as val(a$) + val(b$)

x = strexpr(a$ + b$)     ! concatenation; result then converted to string

x = val(a$ + b$)         ! concatenation; (val expects a string argument)

x = str$(a$ + b$)        ! addition(!); same as val(a$) + val(b$)

fn'foo(x + y)            ! concatenation; (a$ sets string mode here)

fn'foo(strexpr$(x + y))  ! concatenation

 

STREXPR$(expr) is particularly useful when working with DYNSTRUCT members where the compiler is unable to determine at compile time the ultimate type of the member when it is bound at run time. Use of the casting functions eliminates the possible confusion and resulting logical errors of mistaking addition for concatenation or vice versa.

Also See

•   $+ and #+ operators

•   The Overloaded Plus Operator

•   NUMEXPR()

The #+ and $+

The #+ and $+ operators may be used as unambiguous alternatives to the + operator, eliminating any doubt as to whether the operation will be addition (#+) or concatenation ($+). This is particularly useful in the context of DYNSTRUCTs, since the compiler is unable to know at compile time the types that the members will be bound to at run time, which could easily lead to confusion in a statement like:

foo.bar = a + b         ! addition or concatenation?

If foo is a DYNSTRUCT, then the compiler will treat foo.bar as a string (without knowing its eventual bound type). So that would cause it to compile the + in the above statement as concatenation.

To avoid such confusion (and logical errors), use the unambiguous operators, e.g.:

foo.bar = a #+ b        ! addition

foo.bar = a $+ b        ! concatenation

 

Note that since "$" could be a suffix on a variable, the $+ operator must be preceded by a delimiter (preferably a space for clarity), else the compiler may try to associate it with the prior variable name, i.e.

a = b$+c                ! compiler reads as b$ + c

a = b $+ c              ! compiler reads as b $+ c

a = b$$+c               ! compiler reads as b$ $+ c

 

Note that these unambiguous operators achieve the same objective as the casting functions NUMEXPR(expr) and STREXPR$(expr). You can freely mix and/or combine them for clarity, but generally only one method of resolving ambiguity is necessary.