You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the syntax, values are generally more tautly contained, like numbers or record literals, where you can't possibly think of ripping the value up into smaller pieces. Expressions, however, usually consist of other expressions that could be "ripped up"; for example, 3 + 3 in some contexts (like next to a multiplication * operator) can be rebracketed if no parentheses are used. Expressions can be used as a value by putting them in parentheses, which in effect keeps the expression contained.
As a rule of thumb, you need parentheses if you want to use an expression in multiplication, but you don't for a value:
letprod1=3*"wow"// No parentheses needed around a string; it's a value!letprod1=3*1+1// `1 + 1` isn't a proper grouping here because multiplication binds tighter (per PEMDAS); it's an expression!
For reference, here are the expressions and values in the Python and JS implementations:
(Function expressions are listed as pipeRhs in the JS impl. at the same level as booleanExpression, so it and if expressions are effectively expressions)
There's notable differences between the implementations so we'll have to write tests documenting the correct behaviour and then fix each implementation accordingly. (The Python branch is no longer the de facto implementation per #117 and might be incorrect.) That's a separate issue though!
Anyways, it would be nice if we could use function expressions, if/else expressions, and match expressions without parentheses. After all, they look fairly self-contained.
letwow=3*iftrue{9}else{6}
That can't be rebracketed as 3 * if because (3 * if) true { 9 } else { 6 } isn't valid syntax.
Parentheses are quite annoying, so it would be nice to not have to use them.
This should be a fairly simple change, just moving those expressions from expression to value. Assuming the tests are complete, they shouldn't fail more than they did before with this change.
For function expressions, ignoring type errors, 3 * [] -> () {} * 3 isn't syntactically ambiguous, even if the [] could be an empty list and the {} could be an empty record. -> is only used in function expressions and type annotations (and I guess match expressions?), and type annotations are fairly isolated from expressions. Thus, the -> is fairly indicative of a function expression, so there's no way to ambiguously reanalyse un-parenthesised function expressions
For if/else expressions, we don't allow values right next to each other with only spaces in between. For example, wow { a: 1 } sheep { b: 2 } isn't valid syntax. Even with newlines in between, because we have a limited subset of expressions that are allowed as statements, they're still invalid syntax. So, 3 * if condition { a } else { b } * 3 isn't ambiguous. Even if it got rebracketed to 3 * if and { b } * 3 (again, ignoring type errors), the middle condition { a } else is a series of values without anything in between them, so that's invalid syntax. Even with newlines, they aren't valid statements on their own:
// Not ambiguousletwow=3*ifcondition{a}else{b}*3
Also, if and else are keywords, so they're quite certainly for an if/else.
Similarly for match expressions, 3 * match(value) { ... } * 3 could be seen as 3 * match(value) and { ... } * 3, but they're next to each other, so that's invalid syntax. Additionally, match is also a keyword
The text was updated successfully, but these errors were encountered:
In the syntax, values are generally more tautly contained, like numbers or record literals, where you can't possibly think of ripping the value up into smaller pieces. Expressions, however, usually consist of other expressions that could be "ripped up"; for example,
3 + 3
in some contexts (like next to a multiplication*
operator) can be rebracketed if no parentheses are used. Expressions can be used as a value by putting them in parentheses, which in effect keeps the expression contained.As a rule of thumb, you need parentheses if you want to use an expression in multiplication, but you don't for a value:
For reference, here are the expressions and values in the Python and JS implementations:
N-lang/python/syntax.lark
Lines 140 to 145 in 61bb3e4
N-lang/python/syntax.lark
Lines 174 to 188 in 61bb3e4
N-lang/js/src/grammar/grammars/expressions.ne
Lines 3 to 6 in fe1457e
N-lang/js/src/grammar/grammars/expressions.ne
Lines 78 to 86 in fe1457e
(Function expressions are listed as
pipeRhs
in the JS impl. at the same level asbooleanExpression
, so it and if expressions are effectively expressions)There's notable differences between the implementations so we'll have to write tests documenting the correct behaviour and then fix each implementation accordingly. (The Python branch is no longer the de facto implementation per #117 and might be incorrect.) That's a separate issue though!
Anyways, it would be nice if we could use function expressions, if/else expressions, and match expressions without parentheses. After all, they look fairly self-contained.
That can't be rebracketed as
3 * if
because(3 * if) true { 9 } else { 6 }
isn't valid syntax.Parentheses are quite annoying, so it would be nice to not have to use them.
This should be a fairly simple change, just moving those expressions from
expression
tovalue
. Assuming the tests are complete, they shouldn't fail more than they did before with this change.For function expressions, ignoring type errors,
3 * [] -> () {} * 3
isn't syntactically ambiguous, even if the[]
could be an empty list and the{}
could be an empty record.->
is only used in function expressions and type annotations (and I guess match expressions?), and type annotations are fairly isolated from expressions. Thus, the->
is fairly indicative of a function expression, so there's no way to ambiguously reanalyse un-parenthesised function expressionsFor if/else expressions, we don't allow values right next to each other with only spaces in between. For example,
wow { a: 1 } sheep { b: 2 }
isn't valid syntax. Even with newlines in between, because we have a limited subset of expressions that are allowed as statements, they're still invalid syntax. So,3 * if condition { a } else { b } * 3
isn't ambiguous. Even if it got rebracketed to3 * if
and{ b } * 3
(again, ignoring type errors), the middlecondition { a } else
is a series of values without anything in between them, so that's invalid syntax. Even with newlines, they aren't valid statements on their own:Also,
if
andelse
are keywords, so they're quite certainly for an if/else.Similarly for match expressions,
3 * match(value) { ... } * 3
could be seen as3 * match(value)
and{ ... } * 3
, but they're next to each other, so that's invalid syntax. Additionally,match
is also a keywordThe text was updated successfully, but these errors were encountered: