4 ms·
Thank your for commenting! > This immediately makes me want to read said postcard. Is there something to this effect? [Couldn't find it.] I actually did not d
by rusini 7y ago
Thank your for commenting!
> This immediately makes me want to read said postcard. Is there something to this effect? [Couldn't find it.]
I actually did not do such exercise, sorry :-) BUT: 1) almost all syntactic features are demonstrated in the first two examples/lessons in the wiki (and could be compressed further); 2) the formal context-free grammar can be found in the large PDF (caution: crude, work in progress!): https://github.com/rusini/manool/releases/download/v0.2-beta/MANOOL.pdf https://github.com/rusini/manool/releases/download/v0.2-beta... It has only 25 rules. That's comparable with Smalltalk. Besides, Smalltalk was a source of inspiration for the syntax, since it is culturally a cousin of LISP, does not use S-expressions, but its syntax does allow for a kind of DSLs (think ... ifTrue: ...). MANOOL is similar in that respect, but its syntax is closer to S-expressions (allows you to express name bindings).
>I didn't see the advantage...
S-expressions have syntactic sugar to express lists: (A B C) -> (A . (B . (C . ()))) MANOOL has that and slightly more: infix/postfix operators (and one prefix), etc.: A[B; C] -> {A B C}, A + B -> {(+) A B}, {A: B C} -> {A {B C}}, A.B[C] -> {B A C}, etc... (it does not have dotted pair notation, but I hope the idea is clear).
That syntactic sugar is abstract and independent of what actually A[B; C] and A + B mean. The intention, for example, is that the syntax (at the context-free grammar level - surface syntax) does not need to change no matter what features we need in the future. It is said that context-free grammars are not modular: as the language evolves it is easy to introduce ambiguities (think C++). MANOOL approach does not suffer from that; features (like keywords if, while...) can even be made available selectively in a limited scope, if needed. I call it "universal grammar".
On the other hand, I strongly suspect that the resulting syntax is better than S-expressions "psychologically" (sorry LISP'ers :-). It is not a matter of our familiarity with infix notations (from mid school), but our brain has very limited "stack". Anyway, the point of MANOOL is not its syntax or homoiconicity; it was originally just a nice implementation strategy. The point lies deeper in some semantic features...
BTW that's not the first time that someone comes and suggests something to replace S-expressions and... fails. BUT one successful example is Smalltalk (albeit the result is not quite "homoiconic"), so that inspired me too.
As to why {} instead of ()... the main reason is that () had to be reserved for explicit grouping of subexpressions (just like in mid school or Smalltalk): (1 + 2) * 3. BTW that's why I had to use [] for "applications" and that might look ugly to people (but think about failed M-expressions).
As to optional ";", that was precisely one of those "design compromises" I am talking about. Personally, I am not a fan of "semicolon omissions" :-)
- karmakaze 7y agoGreat explanation. I do see the advantage of universally supported expression equivalence vs case-by-case macros. The semicolons are fine as there are few, it's all the brace blocks and following colon-prefixed lines that I would prefer worked like Python. Indenting is human readable vs { : } being more machine readable. There could be a 1:1 rule for converting between formats.
- rusini 7y agoI agree with you in that aesthetically and psychologically, the syntax of MANOOL is not the prettiest thing. But as I already commented, it is a result of trade-offs, and the syntax aesthetics is simply not the main point of the language. Any language whose syntax is more semantic-tailored would almost always look better. However, in turn, we gain homoiconicity and syntactic macros, which is not simply a nice-to-have feature but a huge expressiveness boost, as they are already used to introduce useful constructs without clobbering the core implementation written in C++. Now: whether one can afford the advantage and pay the price on syntactic level is up to once's use case. Of course, we could still support homoiconicity given almost any grammar (think about Dylan or any language that formally has syntactic macro features... Julia? Rust?), but then there is another trade-off: the mapping "plain text -> AST" and the language itself would be much more complex (and the implementation simplicity is the ultimate goal of the MANOOL project that sometimes even goes in parallel with other appealing goals). As I have commented, personally, I had to struggle with myself once I devised the context-free grammar for MANOOL after a lot of experiments and realized that actually there were no much room for improvement given the constraints. However, surprisingly, I accustomed myself quite quickly (which I would not say it is always the case for authentic S-expression-based languages as LISP advocates suggest). After all, MANOOL is an intermediate point between S-expression-based languages and "normal" languages. Compare: Scheme: (define Fact (lambda (N) (if (= N 0) 1 (* N (Fact (- N 1))))) ; a lot of closing parentheses here ; use Fact Python: def Fact(N): if N == 0: return 1 else: return N * Fact(N - 1) # use Fact MANOOL: { let rec { Fact = { proc { N } as : if N == 0 then 1 else N * Fact[N - 1] } } in -- use Fact } Note that in the past, personally, I would prefer rather an "absolutely beautiful" Ada/VHDL/PL-SQL syntax: if ... then ... else ... end if; -- "very" explicit terminator and: while ... loop ... end loop; -- ditto Note that also, personally, I do not like the Python/Nim/Occam approach to code indentation, but that's a whole new (orthogonal) story, and if you like, I could expose my rationale separately... But here we are gradually approaching the story of ":". Note that ":" is a punctuation sign that does not has the usual meaning, as e.g., in Python, or even natural languages. Once upon a time, someone suggested me that if you have an "if" with two branches, one short and another much longer, the shorter branch should appear visually first. In practice, that worked well for me. It apparently has to do with a "stack" in our brain. Another observation I had is that the Ada syntax, however "elegant" as it may seem with short examples, may quickly become ugly as the code complexity raises. And the problem is the excess of indentation (well, to mitigate that, some would suggest creating abstractions and name things, but personally, I would prefer to avoid naming things as long as I can, without going into extremes of combinatory logic-based programming ;-). So, I though, maybe the authors of Algol-60 (and Pascal) were right, maybe I could write better, say: for I := 0 to 99 do if A[I] = Value then {note the lack of indentation} Found := I; ... and that is the point of those colons in MANOOL: instead of writing: { for ... do { if ... then ... else ... } } one can write: { for ... do : if ... then ... else -- note that ":" is aligned with the braces since their syntactic roles are very similar ... -- but anyway MANOOL is a free-form language } Note that those colons are actually a means to get some "right-associative" syntax rules in the language (which are useful in the cases mentioned above).