First of all thank you for your excellent work on your F interpreter, very appreciated!
I played with it a bit and now I have a few recommendations on how to improve the core language.
Ok so there are two things I dislike about the way semicolons work:
- A semicolon after last statement in file required
- No semicolon after last statement in block allowed
The first bullet-point will be weird once we introduce a REPL. It would be nice if the REPL and file parser would be exactly the same. Otherwise it's not that big of a deal, but please hang on there's a reason I point that out ;)
The no-semicolon-after-last-expression-in-block rule can be a bit weird when dealing with multi-line blocks. Although the last semicolon should be optional because of single-line blocks, some users (me included) might want to put it in there on occasion.
An easy fix for both issues might be to make the semicolon a regular operator just like +
and <-
, so that infix behavior is (a ; b) = b
and postfix behavior is (a;) = a
.
For the sake of consistency it could actually be the (;)
function, so that (a;b) = (;) a b
and (a;) = (;) a
and (;) a b .... c d => d
, but then a := b
would have to be an expression. I kinda like that actually, because then everything in the language would be an expression. Very simple and fun.
On another note, the way ...
is currently hardcoded into the grammar makes it very inflexible.
Some things I want to be able to say are not possible that way.
Perhaps it should be syntactically accepted everywhere and the interpreter should do the work of treating it specially (that is splicing it into the surrounding /(argument )?list/).
All in all these changes hopefully simplify the grammar. All infix syntax will just be regular operators as far as the parser is concerned (except for :=
maybe).
In any case I'd like to be able to say the following things:
list := [|...|
(myList := {...}; myList)
];
list 1 2 3; // => {1, 2, 3}
plus := [|...|
do |x y| ... [
x + y
]
];
plus 2 2; // => 4
printTwice := [|...|
print ... ...;
];
printTwice "hello" // stdout => hello hello