Language Modernization ideas for discussion - Idea 4 - Richer operators

Started by Eric B., January 25, 2021, 11:42:21 PM

Previous topic - Next topic

Eric B.

Next idea:  Richer set of operators.  Adds support for the following operators: +=, -=, *=, /=, and IN.

For instance:
Code (genero) Select
LET x = x + 1
is the same as
Code (genero) Select
LET x += 1
This could be used with any of the normal math operators (+=, -=, *=, etc.).

IN is a shortened form of OR:
Code (genero) Select
IF x IN ('Y','y') THEN...
is the same as
Code (genero) Select
IF (x = 'Y' OR x = 'y') THEN...

Reuben B.

IN has also been discussed previously, https://4js.com/support/issue/?id=FGL-4238

I have never really understood why we have not implemented an IN(), after all it is SQL syntax that most 4gl developers are familiar with.  I would place BETWEEN, MIN, MAX in the same category as being available in SQL but not 4gl.  Over time we have added syntax from SQL such as nvl() and iif(), and who used to code sin(x) as SELECT SIN(x) FROM systables WHERE tabid = 1 before util.Math was added.  I am sure there are 4gl developers that have coded something they would code in SQL statement into a 4gl statement and been caught out.

A number of customers will have their own library functions that implement a list (many possible implementations such as delimited string, XML, JSON, DICTIONARY, ARRAY) and then have functions to create a list and to search within it.  For example

Code (genero) Select
IF cust_state = "NY" OR cust_state = "CA" OR cust_state = "WA"

I would have coded as
Code (genero) Select
IF in(cust_state, list3("NY","CA","WA"))

... the only downside being I was limited to however many listN functions I coded to construct a list with N elements unless I built my list one element at a time.


What is missing is a compelling argument to get IN over the line.

Your example is probably not the best ...

Code (genero) Select
IF x IN ('Y','y')

could be written as
Code (genero) Select
IF x.toUpperCase() = "Y" THEN
or
Code (genero) Select
IF x MATCHES "[Yy]" THEN



A better example is to say

Code (genero) Select
IF expr() IN (val1(), val2(), val3(), ...)


as to code it like ...
Code (genero) Select
IF expr() = val1() OR expr() = val2() OR expr() = val3()

... sees expr() evaluated multiple times and val1(), val2() and val3() always evaluated (unless OPTIONS SHORT CIRCUIT is turned on)

To code it so each expression is only evaluated once is something like ...

Code (genero) Select
CASE expr()
   WHEN val1() LET l_in = TRUE
   WHEN val2() LET l_in = TRUE
   WHEN val3() LET l_in = TRUE
   OTHERWISE LET l_in = FALSE
END CASE
IF l_in ...


and being able to code

Code (genero) Select
IF expr() IN (val1(), val2(), val3(), ...)

and
Code (genero) Select
CASE expr()
   WHEN IN(val1(), val2(), val3()) ...

is preferable

So if you have a better example, that will help the cause.

Reuben






Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero

Rene S.

Implementing operators like += should not be a big deal. Those operators are very common.

The operator IN is another story.
Yes, this operator could be helpful, the operator exists in SQL for good reasons.

But. See Reuben's example using the operator IN in a CASE statement:

Code (genero) Select

CASE expr()
   WHEN IN(val1(), val2(), val3()


This this the simplified grammar of the CASE statement:
Code (genero) Select

CASE expr { WHEN expr [statement ...] } ... [OTHERWISE [statement ...]] END CASE


When parsing
Code (genero) Select

WHEN IN(val1(), val2(), val3()

Then the compiler would not see the operator IN, the compiler would seen the function name IN.

Compare this with
Code (genero) Select

CASE some_value
    WHEN "foo" -- acts as some_value == "foo"
    WHEN "bar1" OR "BAR2" -- acts as some_value = ("bar1" OR "BAR2"), this is legal nonsense
    WHEN func1() -- acts as some_value = func1()
    WHEN IN(val1, val2) -- acts as some_value = IN(val1, val2) -- IN is a function name
    WHEN MATCHES "pattern" -- syntax error
    WHEN < "zzzz" -- syntax error


All I want to say is: the operator IN does not solve the request for enhancing the CASE statement to support more than one value per WHEN.

(Edited to transpose CASE and WHEN which had been typed the wrong way around)