unseemly
unseemly copied to clipboard
Core syntax reform
The current Unseemly syntax is ad-hoc, and it's a mess. But maybe the syntax for syntax operations, while weird, is okay. I think the thing I keep on tripping over is everything else. Proposal: Make everything that's not types or syntax related a carbon-copy of Scheme syntax. (So, lambdas, case statements, etc., ... and modify build_a_language.unseemly to match). Type syntax should probably be made normal, too. Maybe steal from Rust to the extent possible?
IMHO yes, this could help readability :wink:
So… I’m really not sure how to deal with the fact that Scheme syntax and typical type syntax are so different. Here’s an idea I need to write down to see how it looks: just use angle brackets as if they were parens.
(define (foo bar : <forall x <seq x>> baz : <maybe int>)
(match bar
((some x) (plus x (len bar)))
((none) eightythree))))
The fact that forall looks like just another parameterized type bugs me. And the equivalent issue in Scheme’s expression syntax as also always kinda bothered me. So we could imagine capitalizing names that are “reserved words”, like so:
(Define (foo bar : <Forall x <seq x>> baz : <maybe int>)
(Match bar
((some x) (plus x (len bar)))
((none) eightythree))))
It reminds me how, from an aesthetic perspective, I really like lower-case code.
Another option, which operates on a totally different axis, is to syntactically mark name introductions. A cute idea I had from long ago puns on a convention in written English:
(define ('foo' 'bar' : <forall 'x' <seq x>> 'baz' : <maybe int>)
(match bar
((some 'x') (plus x (len bar)))
((none) eightythree))))
Eh? Eh? Yeah, it's not a good idea, I just had to write it down.
More seriously, both "is a 'reserved word'" and "is an Atom" are things that we can pretty plausibly hand off to the syntax highlighter. So maybe the all-lowercase no-syntax option would be fine!
Let's see how this looks, integrated with... uh "syntax-for-syntax" (i.e., special punctuation-y forms for things that have specifically to do with syntax):
(extend-syntax expr
(macro (t)
((lit default-token "for")
(name elt-pat <pat t>)
(lit default-token "in")
(name body (bind <expr unit> (as elt-pat t))))
'[expr | (foldl
(lambda (unit-value : unit arg : ,[(prefab-type t)],)
(let ((,[elt-pat], arg)) ,[body],))
(tuple) ,[seq],)]'))
extend-syntaxdoes a single::=also; have a separate form to do wholesale replacement of multiple NTs,{ },for "recur into this NT" is probably unnecessary, so drop it.- Lowercase letters look weird for type parameters. And types without
<>(or sometimes even:) are ... hard to see. But the syntax-highlighter could help. - At first losing
:=seemed inconceivable, but I think this is better? - Binding annotations are still gibberish, but you can put
bindandasinto a search engine; you can't do that with<--and: - Looks like I still want to keep the highly heterodox two-spaces-between-colon-separated-things idea. Welp. Unless... does
(unit-value: unit arg: ,[(prefab-type t)],)look okay?
I'm... maybe sold?
Just for kicks, here's what happens in irritate-Mitch mode:
[extend-syntax expr
[macro [t]
[[lit default-token "for"]
[name elt-pat <pat t>]
[lit default-token "in"]
[name body [bind <expr unit> [as elt-pat t]]]]
'[expr | (foldl
[lambda [unit-value : unit arg : ,[[prefab-type t]],]
[let [[,[elt-pat], arg]] ,[body],]]
(tuple) ,[seq],)]']]
There were ... two functions in the whole thing. Honestly, tons of square brackets look worse than tons of parentheses. The thing that tempts me a little bit is that you don't have to hold down shift to type them. I think that, at one point, I had swapped (/) and [/] on my keyboard.
What would Unseemly look like with the "most normal" syntax (Scheme expressions plus Rust types)?
(extend-syntax Expr
(macro (T)
((lit default-token "for")
(name elt-pat Pat<T>)
(lit default-token "in")
(name body (bind Expr<Unit> (as elt-pat T))))
'[Expr | (foldl
(lambda (unit-value: Unit arg: ,[(prefab-type T)],)
(let ((,[elt-pat], arg)) ,[body],))
(tuple) ,[seq],)]'))
This is probably the right thing to do. I'm kind of resistant to it -- I want to start with some kind of grand unified theory of syntax, or at least not use the shift key so much. But Unseemly is weird enough already. And I have to admit that it's pretty readable this way.