top | item 43616728

(no title)

jmercouris | 10 months ago

Javascript is Lisp in C's clothes? On what basis? Also what does Lua have to do with Lisp? It has no Lisp syntax whatsoever.

discuss

order

0x3444ac53|10 months ago

Fennel has actually convinced me that Lua and lisp have more in common than one might think. I don't know what the above comment was referencing, but I've always found beauty in lisp languages for having a primary datastructure that all others can be abstracted to. Lisp, classically, has list, clojure has sequences, and Lua/fennel has tables.

https://fennel-lang.org/

creata|10 months ago

And Tcl has strings.

Fennel is more popular than I expected! It's in the official repositories of Arch, Fedora and Debian.

cmdrk|10 months ago

as a Lisp-curious person, Fennel was a gateway drug for me

Barrin92|10 months ago

> Javascript is Lisp in C's clothes? On what basis?

On a lot of bases. Javascript has real lambdas, a sort of homoiconicity of code and data (hence JSON as a data format), also has the same dynamic take as lisps on "types belong to data". Rather than variables types belong to values. Brendan Eich's original idea was literally to "put scheme in the browser" and you can in fact pretty easily convert the Little Schemer to JS.

Saying two languages don't have much in common because they don't have the same syntax is a bit like saying we don't have much in common because we don't have the same hair color.

alex-robbins|10 months ago

> a sort of homoiconicity of code and data (hence JSON as a data format)

I get that "sort of" was an attempt to hedge, but really, this isn't even close. Homoiconicity here would be if all javascript source files were valid JSON documents. A weaker version would be if it were common to use JSON to represent an arbitrary javascript program, but I've never heard of that, either. (For a good explanation of this weaker sense of homoiconicity, this stackoverflow page [1] is pretty good.)

[1]: https://stackoverflow.com/questions/31733766/in-what-sense-a...

To use Clojure as an example of a language that is homoiconic, you can take any Clojure source file, send it to an EDN parser (EDN being Clojure's equivalent of JSON), and not only will parsing succeed, but the result will be a complete representation of the program (you could execute it if you wanted to). In contrast, if you try to send JS to a JSON parser, you'll get an error as soon as it hits a function definition, or a for loop, or an operator, or whatever.

kazinator|10 months ago

But MacCarthy's original LISP 1 and LISP 1.5 do not have real lambdas. The lambda feature parametrizes a piece of code as a function literal, but doesn't capture anything.

What they have is code parsed to a data structure, which is then susceptible to manipulation by the program before being executed. JS has some dumb textual eval, like the Bourne shell.

They also have the concept of a symbol.

And only one value that is false.

galaxyLogic|10 months ago

JavaScript is not Lisp but it is more like Lisp than like C, even though syntactically it much resembles C.

ES6 JS has nice syntax for calculating with lists:

   let [car, ...cdr] = [1,2,3]
After the above 'car' has value 1 and 'cdr' has value [2,3].

behnamoh|10 months ago

in that case Python is also a Lisp because it has:

    car, *cdr = [1, 2, 3, 4]

tcfhgj|10 months ago

hmm Rust as well:

    let [car, cdr @ ..] = [1,2,3];

nateglims|10 months ago

Javascript hotloading development setups are about the closest you can get to the REPL development loop outside of lisp. I'd imagine lua is similar if the embedding is set up for it.

soapdog|10 months ago

I hate to be that guy but a ton of languages have REPLs. The whole collection of smalltalks out there are basically an interactive environment. All of them forth languages do it too. Factor, Racket, LiveCode, there are so many. And for most of them, watching files and hotreloading is not how they do it.

johnisgood|10 months ago

Pretty sure they are just filesystem watchers. Correct me if I am wrong. Filesystem watching is NOT hot loading.

gavmor|10 months ago

Have you used `bun --hot`?

xonre|10 months ago

Lua is C in Lisp's clothing.

Lisp killer features were GC, good data representation, first class functions. Lua has all that and more. But its being a "thin" library over the C runtime shows through the clothes.

flavio81|10 months ago

>Lisp killer features were GC, good data representation, first class functions.

Lisp's killer feature is procedural macros that are extremely easy to write and debug.

Lua doesn't have such a thing, that's why Fennel was created.

Erlang also doesn't have such a thing, that's why LFE was created.

0x3444ac53|10 months ago

Also, I do want to point out that despite very recognizable syntax, that's not the only thing that makes lisp lisp. Primary example of lisp-y syntax on a non-lisp would be Janet [0]

https://janet-lang.org/

cy_hauser|10 months ago

It looks like fennel and janet are from the same dev.

behnamoh|10 months ago

Not having cons lists makes Janet non-lispy?

gavmor|10 months ago

I have an intuition that the comment you're responding to has a lot of truth to it, but I am going to have to educate myself to give you an answer.

One thing I do know is that JS and Lisp both treat functions as first-class citizens, allow some degree of meta-programming, and rely heavily on hierarchical (e.g., nested objects in JavaScript vs. s-expressions in Lisp).

Passing functions by reference enables both LISP and JS to compose higher-order functions and, as suggested in another commented, both Lisp and JavaScript's "dynamic stack frames" somehow live updates to running code without requiring a complete restart of the application. The only clear example of this I can find, however, is Bun's --hot mode, which performs a "soft reload," updating its internal module cache and re-evaluates the changed code while preserving global state.

I have some vague notion that this is a favorite feature of Lisp, but it's not clear to me that it's unique to these language families.

---

Edit: Lexical scoping, closures, some tail-call optimization...

---

Edit 2:

> Programming language “paradigms” are a moribund and tedious legacy of a bygone age. (Dave Herman)[0]

---

Edit 3:

> The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."

> Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.

> On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.

-- Anton van Straaten 6/4/2003 [1]

0. https://cs.brown.edu/~sk/Publications/Papers/Published/sk-te...

1. https://people.csail.mit.edu/gregs/ll1-discuss-archive-html/...

timewizard|10 months ago

LISP is an assembly language with a interpreter stashed inside of it.

Dynamic dispatch and the Object System are bolted onto the side and are still unparalleled by any language that I'm aware of.