@p so after an exhausting week of problem solving I needed a way to fall asleep and apparently tonight that has been making a language and shell that is a faithful superset of POSIX sh. So it's elixir, but with processes, pipes and signals instead of actors, mailboxes, and monitors.
I even added a `supervise` builtin because go gives me the things unix doesn't
@p I've wanted to do this for a while, I've kept putting it off but I've thought through a lot of it, so 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.
You know, fun.
So technically there is a bit of syntactical whitespace. I treat `VAR=value` exactly how POSIX handles assignment, but I treat `pattern = expr` (note the spaces around = ) for elixir-style matching and binding. I have both | and |>. I have the literals #{ and %{ which were so much fun to solve for. Technically, -- is a token because --build was breaking in the shell for a while. 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.
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.
Thank you for listening btw, I always get so self-conscious when I want to talk about these things but no one gets me. I start just shitposting threateningly.
@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:
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):
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.
@p I'm about to pass out in my chair but I deeply appreciated you sharing those sexps, they brought back a lot of memories. And
> ; 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)
:ameliayes: this is hilarious, and not just because of haskell but also because of clojure
> I think I get you and I am jazzed.
Thank you for your gettingness, I hope to share this code with you soon.
> I was a tcsh user for many years for no real reason
Default on Solaris; I didn't switch to bournealike until I started running Linux at home and I was a teenager and everyone said how terrible and stupid csh was.
> maybe someday we can be turbodrunk and calling eachother niggers over our $SH preferences.
> I'm about to pass out in my chair but I deeply appreciated you sharing those sexps, they brought back a lot of memories.
I don't have a :mccarthysmug:!
> this is hilarious, and not just because of haskell but also because of clojure
This might actually predate Clojure but I remember seeing their "Here's how we got fewer parens in the language" and being thoroughly unimpressed and then wanting to vomit when I saw what they did with brackets. On the other hand, people besides Rich Hickey use his language. Anyway, I don't know whether Clojure has a thing for that but I ended up using `(= name (\ ... -> ...))` more often than `(def name (...) ...)`.
(Oh, also `...` was a builtin: it was the void function, stolen from...unlambda! `(... x)` would yield `...` for any `x`, and it was named `...` since pattern-matching was a recursive process and you could use it for ignored arguments because it would return non-false/non-nil. So you could get the last element of a list with `(apply (lambda (*... e) e) some-list)`, though of course pattern-matching was slower than just indexing. It was a very fun language but I lost my fascination with Lisp. The language itself was kind of a fever-dream version of CSP-Ruby-Lisp.)
At any rate, does Clojure have some sort of syntax like that?
> Thank you for your gettingness, I hope to share this code with you soon.
@p@fsebugoutzone.org@DemonSixOne@poa.st@vii@dsmc.space csh was default for root on *bsd until quite recently. I used tcsh on my sysv shell account in college. And that carried over into my personal nonsense. I eventually lost it, but ricing out prompts was a fun time.
@miscbrains@DemonSixOne@vii I was on bash when I started to get real about scripting, just in time for people to start yelling at me for bashisms and UUOC.
There was some hilarious copypasta that I wish I could find, the guy was like "Shut the fuck up about me using cat and using backslashes to escape instead of quoting because I live in the moment under the cursor" or something like that.
UUOC is actually a symptom of cognition, same reason postfix calculators were always popular: your mind thinks "object, object, relation". So "I want this file" then "I want this transformation on the file" is a natural way to think. I refuse to stop cat'ing files into awk.
@DemonSixOne@vii Ha, I was envious of the guys that were allowed to touch the Solaris boxes; I was stuck telnetting into them from the Windows 95 machine like a fucking pleb. (Was very pleased to use pine to check my email.)
@p@fsebugoutzone.org@DemonSixOne@poa.st@vii@dsmc.space There's definitely some group think consensus going that took over. csh and co were definitely scriptable as well, or i wouldn't have had tomes dedicated to them back in the day.
Whatever the case, they lost out. I still use those shells locally: because I don't give a fuck, familiarity, and the scripting i'm generally doing is pretty low key.
ctrl d as an autocomplete still haunts me whenever i use another shell.