If Syntax - Spicery/Nutmeg GitHub Wiki
if is the first word of a conditional expression and must be matched by a corresponding end or endif. For example:
if tough(steak) then
fry(steak)
else
grill(steak)
endif
When this code is executed, the Nutmeg runner first executes the
condition (i.e. tough(steak)). If this evaluates to false then
grill(steak) is executed, otherwise fry(steak) is executed. The full
syntax of allowable conditional commands is quite complex. An if
statement has the form:
if CONDITION then
CONSEQUENT
elseif CONDITION then
CONSEQUENT
...
[any number of additional elseif ... then ... clauses]
...
else
CONSEQUENT
endif
The else CONSEQUENT can be omitted if desired. The
elseif CONDITION then CONSEQUENT can be either omitted or repeated as many
times as required. A CONDITION is any expression, and a CONSEQUENT
is any sequence of Nutmeg statements.
The condition should, when executed, produce a result. If the result is
false, then the corresponding consequent is ignored, and the program
moves on to the next elseif, or if there isn't one, to the else
clause. If there is no elseif or else, then the program moves on to
the code following the endif.
If the result of executing a condition is anything other than true or
false, then an error is raised.
if statements can be nested inside one another, i.e. a CONDITION or a
CONSEQUENT of an if statement may itself contain if statements.
For example:
if isnumber(n) then
if n > 0 then
'positive'
else
'less than or equal to zero'
endif
endif
It is permissible, but unusual, for a CONSEQUENT to contain no code at
all, but this must be flagged with an explicit pass or ()
def prlist( list );
if list.isEmpty then
pass
else
println( head(list) )
prlist( tail(list) )
endif
enddef
Sometimes it is more natural to reorder the if-statement so the false condition is dealt with first. Nutmeg provides the ifnot variant, which is equivalent to negating the whole condition with not. The syntax is identical to that of a normal if except that it starts with the ifnot keyword and finishes with end or endifnot.
ifnot tough(steak) then grill else fry endifnot( steak )
And that's equivalent to:
if not(tough(steak)) then grill else fry endif( steak )
Why provide this version, given that it's not even any shorter? The primary motivation is making the language self-consistent. Everywhere in the language where there is a condition, Nutmeg always provides both positive and negative versions e.g. while/whilenot, return if/ifnot. And this consistency makes the language easier to remember. Another, lesser motivation is to reduce the number of parentheses.
As a good example of this, there is also an alternative form of elseifnot, which is equivalent to elseif with the whole condition negated.
IfExpression ::=
'if' IfCore ('endif'|'end') |
'ifnot' IfCore ('endifnot'|'end')
IfCore ::=
Expression ('then'|':') Statements
( ('elseif'|'elseifnot') Expression ('then'|':') Statements )* ('else' ':'? Statements)?
An if statement is essentially a sequence of condition-action pairs together with an optional default action. The conditions are evaluated in order and must evaluate to true or false. As soon as a condition evaluates to true the matching action is evaluated and then the statement finishes. If no conditions match then the default action, if provided, is evaluated and the statement finishes.
The Statements of an if-statement introduce their own lexical scopes that enclose the statement and no more. This ensures that variables introduced by the statements are only in scope where their definition is guaranteed to be executed.