4 ms·
> Thanks for your simple concrete examples and explanations! I'm glad someone liked it :-) > I love his description of Forth as "a weird backwards lisp with n
by xscott 2y ago
> Thanks for your simple concrete examples and explanations!
I'm glad someone liked it :-)
> I love his description of Forth as "a weird backwards lisp with no parentheses"
I've been interested in that duality between Forth and Lisp before, but my progression always seems to following this path:
- Since Forth is just Lisp done backwards and without parens, and since it's not hard to write an sexpr parser, I might as well do Lisp to check the arity on function calls.
- But in addition to arity errors, I'd really like the compiler to catch my type errors too.
- And since I've never seen an attractive syntax for Lisp with types, I might as well have a real grammar...
And then I've talked myself out of Forth and Lisp! Oh well.
- DonHopkins 2y agoPostScript is kind of like a cross between Forth and Lisp, but a lot more like Lisp actually. And its data structures, which also represent its code, are essentially s-expressions or JSON (polymorphic dicts, arrays, numbers, booleans, nulls, strings, names (interned strings), operators (internal primitives), etc.) https://donhopkins.medium.com/the-shape-of-psiber-space-october-1989-19e2dfa4d91e https://donhopkins.medium.com/the-shape-of-psiber-space-octo... Not coincidentally, James Gosling designed the NeWS window system and implemented its PostScript interpreter, years before designing and implementing Java. And before that he designed and implemented "MockLisp" in his Unix version of Emacs, which he self effacingly described like: "The primary (some would say only) resemblance between Mock Lisp and any real Lisp is the general syntax of a program, which many feel is Lisp's weakest point." https://news.ycombinator.com/item?id=29954778 https://news.ycombinator.com/item?id=29954778 James Gosling's Emacs Mocklisp was like FEXPRs on PCP, with support for prompting the user to supply omitted arguments. https://news.ycombinator.com/item?id=14312249 https://news.ycombinator.com/item?id=14312249 DonHopkins on May 10, 2017 | parent | context | favorite | on: Emacs is sexy Hey at least Elisp wasn't ever as bad as Mock Lisp, the extension language in Gosling (aka UniPress aka Evil Software Hoarder) Emacs. It had ultra-dynamic lazy scoping: It would defer evaluating the function parameters until they were actually needed by the callee (((or a function it called))), at which time it would evaluate the parameters in the CALLEE's scope. James Gosling honestly copped to how terrible a language MockLisp was in the 1981 Unix Emacs release notes: https://archive.org/stream/bitsavers_cmuGosling_4195808/Gosl https://archive.org/stream/bitsavers_cmuGosling_4195808/Gosl 12.2. MLisp - Mock Lisp Unix Emacs contains an interpreter for a language that in many respects resembles Lisp. The primary (some would say only) resemblance between Mock Lisp and any real Lisp is the general syntax of a program, which many feel is Lisp's weakest point. The differences include such things as the lack of a cons function and a rather peculiar method of passing parameters. "Rather peculiar" is an understatement. More info, links and code examples: https://news.ycombinator.com/item?id=8727085 https://news.ycombinator.com/item?id=8727085 Comparison of PostScript with Forth and Lisp: https://news.ycombinator.com/item?id=22456471 https://news.ycombinator.com/item?id=22456471 [...] PostScript is much higher level than Forth, and a lot more like Lisp than Forth, and has much better data structures than Forth, like polymorphic arrays (that can be used as code), dictionaries (that can be used as objects), strings, floating point numbers, and NeWS "magic dictionaries" that can represent built-in objects like canvases, processes, events, fonts, etc. Yet Forth doesn't even have dynamically allocated memory, although in a few pages of code you can implement it, but it's not standard and very few Forth libraries use it, and instead use the linear Forth dictionary memory (which is terribly limited and can't be freed without FORGETting everything defined after you allocated it): https://donhopkins.com/home/archive/forth/alloc.f https://donhopkins.com/home/archive/forth/alloc.f PostScript is homoiconic. Like Lisp, PostScript code IS first class PostScript data, and you can pass functions around as first class objects and call them later. https://en.wikipedia.org/wiki/Homoiconicity https://en.wikipedia.org/wiki/Homoiconicity [...]
- xscott 2y agoYeah, I've never used Postscript except as a document format created by LaTeX :-) There was a language called "V" a while back, different than a more recent language called V. It was basically a Forth where quoting was done with square brackets. This replaced the colon-semi notation for defining words, and it was also nice for nested data structures. This language seems to have fallen off the web though. You mentioned FExprs. I never looked at Mock Lisp, and it sounds like Gosling doesn't think I should! However, I'm sure you're aware of Kernel. I think of Scheme as the "prettiest programming language I don't want to use", and I think the vau stuff in Kernel makes it even prettier. (But I still don't want to use it.) For homoiconicity, I've also considered something like Tcl or Rebol/Red. The latter two blur the lines between lexer and parser in a way that I'd like to learn more about. But really, I always come back to wanting static typing. Both for compile time error checking, and to give the compiler a leg up in runtime performance. Instead of using separate declarations like you see in Typed Racket and some others, I wonder if a Lisp with the addition of one "colon operator" to build typed-pairs would do it. Just one step down the slippery slope of infix syntax sugar. In the context of WebAssembly, something like this: (import (foo a:i32 b:f64):()) (export (bar x:i64 y:f32):(i32 i32) (code goes here) ) Using colons to specify the types of the parameters and return result(s). It'd also be nice to have colon pairs like this for key:value in hash tables, or as cond:code in switch/conditional constructs.