Next idea: Richer set of operators. Adds support for the following operators: +=, -=, *=, /=, and IN.
For instance:
LET x = x + 1
is the same as
LET x += 1
This could be used with any of the normal math operators (+=, -=, *=, etc.).
IN is a shortened form of OR:
IF x IN ('Y','y') THEN...
is the same as
IF (x = 'Y' OR x = 'y') THEN...
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
IF cust_state = "NY" OR cust_state = "CA" OR cust_state = "WA"
I would have coded as
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 ...
IF x IN ('Y','y')
could be written as
IF x.toUpperCase() = "Y" THEN
or
IF x MATCHES "[Yy]" THEN
A better example is to say
IF expr() IN (val1(), val2(), val3(), ...)
as to code it like ...
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 ...
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
IF expr() IN (val1(), val2(), val3(), ...)
and
CASE expr()
WHEN IN(val1(), val2(), val3()) ...
is preferable
So if you have a better example, that will help the cause.
Reuben
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:
CASE expr()
WHEN IN(val1(), val2(), val3()
This this the simplified grammar of the CASE statement:
CASE expr { WHEN expr [statement ...] } ... [OTHERWISE [statement ...]] END CASE
When parsing
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
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)