Embed Notice
HTML Code
Corresponding Notice
- Embed this notice@vii I ain't talked language design in what feels like *forever*! Thank ye, vi-i.
> most of what I've been doing is just disambiguating the few places where backwards-compat with POSIX sh requires me to make choices, or just where adding one thing makes the whole parser go a little bit stupid and I have to rearrange things
:tomduff: Duff has a smug remark about being able to do BNF for his shell, which Bourne could not; on the other hand, `if not {` is a terrible thing. (Rog Peppe's shell is the nicest shell I have ever used in my life and I will fight Bourne and Korn and Duff and EVEN ROG PEPPE IF HE DISAGREES.)
But I feel you: parser is the hardest part of sh and "superset with clean structural things" is bound to be even harder, especially the type-matching stuff you've done.
> I treat `VAR=value` exactly how POSIX handles assignment, but I treat `pattern = expr` (note the spaces around = ) for elixir-style matching and binding.
That is interesting! When I was doing Cha I actually made function calls syntactic sugar for pattern-matched assignment and then cdr'ing down the body of the function and eval'ing each item in the body. Basically, bindings were callable, so you do `(= b (bind (a 0)))` then `(b 'a)` would return 0, and a lambda was just [binding, arglist, *body] so you could deconstruct lambdas and call them manually:
(bind ((args (arglist-of f))
(body (body-of f))
(b ((binding-from f) '(bind))))
(= b (b 'lpm args l))
(last (map b body))))
This was also how the object system worked: it was a prototype-based system where you'd do message-passing by evaling a symbol in a binding. You can probably guess how macros worked: they were just lambdas that had no binding attached so they'd use the caller's binding. I haven't crawled that codebase in a minute, I was evidently mad with power because some of the comments were...here is an excerpt:
; ah ha ha ha...AHAHAHAHAHA
(= to-bool (compose ! !))
And it meant lambdas/bindings were actually mutable so there was a function for doing a hyperstatic-ish thing (though it only stopped *rebinding*, because `dup` was shallow):
(def seal! b/l
(shadow 'b)
(= b (if (binding? b/l) b/l (binding-from b/l)))
(b '(map shadow (all-syms)))
b/l)
(= seal (compose seal! dup))
And while I'm on this tangent, if you'll permit me to indulge a little, there was a file "haskell.cha" that was essentially "fuck haskell lol" that was full of weird macros and one of them I moved into "core.cha" that exploited the pattern-matching on args:
; So, this was sort of a joke, and it was in haskell.cha, but actually I like it:
(= \ (macro (*args '-> *body) (list 'lambda args body)))
; You can do this: (\ x y -> + x y)
Anyway, now that I've got my old-man reminiscing out of the way, this is a detour around saying that I like what you're doing with pattern-matching.
> I support both `if cond; then ... fi` and `if expr do ... end`. I support atoms, but the POSIX : builtin must be followed by a space.
Fun shit.
> There's a chance I'm not going to be able to run, say, gentoo scripts through it. I haven't tried yet. But I think my coverage is good enough, and now I have my own shell.
Slick shit.
> I want to talk about these things but no one gets me.
I think I get you and I am jazzed.
> I start just shitposting threateningly.
I see no problem.