9 ms·
This is maybe the best introductions to Lisp i have seen, especially for a js dev like me it could hardly get more approachable and convincing. I could not hel
by jFriedensreich 6y ago
This is maybe the best introductions to Lisp i have seen, especially for a js dev like me it could hardly get more approachable and convincing.
I could not help but thinking at the end, this is really awesome but s-expressions are kind of hard to read and reason about for my brain, it would be cool if we could generate them from more readable syntax, maybe something like javascript :D . Unfortunately the standard js AST seems to be not a great fit but i found a S-Expression encoder for js AST https://github.com/anko/eslisp https://github.com/anko/eslisp
This way instead of having to write s-expressions manually we took a whole circle and are back at js but with macros, not relying on eval and having a code is data representation...
- TeMPOraL 6y ago> This is maybe the best introductions to Lisp i have seen, especially for a js dev like me it could hardly get more approachable and convincing. The classical one is "The Nature of Lisp"[0], which introduces data-as-code through XML and Java build tools. Same idea, just with examples more relevant at the time of writing. Still worth a read for non-webdev programmers. Having learned Lisp, it's half funny, half disheartening to watch the industry repeatedly tries to rediscover "code as data", as people's configuration or data files in markup language du jour grow in complexity and eventually start directly encoding executable code... and then stop shy of embracing the code/data duality. -- [0] - https://www.defmacro.org/ramblings/lisp.html https://www.defmacro.org/ramblings/lisp.html
- maximilianroos 6y agoGreenspun's tenth rule [0]: "Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp." Also: > Hacker Robert Morris later declared a corollary, which clarifies the set of "sufficiently complicated" programs to which the rule applies "...including Common Lisp." [0] - https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule
- drran 6y agoJavaScript (which is based on Scheme dialect of Lisp) is formally specified, well-developed, and fast, so quote above is outdated.
- TeMPOraL 6y agoJavaScript isn't based on Scheme, it's what would have been Scheme if deadlines and marketing needs didn't make Netscape use a hacky toy language instead. The place where JavaScript contains "an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp" is Babel.
- flavio81 6y ago>Hacker Robert Morris later declared a corollary, which clarifies the set of "sufficiently complicated" programs to which the rule applies "...including Common Lisp." This is referring to CL implementations that depend heavily on C. Many CL implementations now are almost 100% Lisp code.
- konjin 6y agoIf you take anything away from that: brackets are the most compact way to serialize a tree, for some reason they are called s-expressions. The parse tree for lisp is the syntax tree, you just rename each bracket node to whatever the first atom in the bracket happens to be. One thing that XML could have done that s-expressions can't is a way to serialize a dag if proper nesting of tags wasn't required. I'm playing around with a language based on that, the mental load of having no clear way to delineate blocks visually makes it hard to reason about, unfortunately.
- Perseids 6y agoI think that should be the marketing of Lisp: A necessary evil ;) But seriously speaking, for me Lisp would be much more appealing if it had been introduced to me as a specialized niche language, though for an important niche nonetheless, instead of as the be-all-and-all language for your superpowered startup [1]. (For those that don't already have a goto list of counterarguments to "Lisp all the things": My main contra-point to Lisp is that with all the meta programming powers you get, you write yourself into your own little corner where no-one but you and your friends live. You want advanced syntax highlighting, linting, automatic refactoring for your special features? Write it yourself! You want outsiders to participate (think: new employees)? Write all documentation yourself, too!) [1] http://www.paulgraham.com/avg.html http://www.paulgraham.com/avg.html
- TeMPOraL 6y agoHaving worked in a Common Lisp startup, I'll only agree with half of your counterarguments :). > You want advanced syntax highlighting, linting, automatic refactoring for your special features? Write it yourself! That's true to an extent. Simple things are simpler in Lisps, because the syntax is trivial. So highlighting and structured editing are easy. The rest, is near impossible, at least for a full-featured Lisp like Common Lisp. That's a consequence of being an extremely dynamic language, that ships a compiler and intertwines parsing, compiling and execution. The flip side of being able to run arbitrary computation at compile time is that, in general, you can't know what the program will do until you run it. The dominant free CL IDE, SLIME, does just that: it queries your running Lisp image for its current state, to provide you with formatting and autocomplete and other hints. That said, "near impossible" is a function of community size. Had CL anywhere near as much popularity as Java or Python does, I'm sure folks at IDEA would make automatic refactoring work for CL as well :). > You want outsiders to participate (think: new employees)? Write all documentation yourself, too! That I strongly object to. Code generation and compile-time execution aren't magic, or even particularly hard concept. They're just another flavor of code. You manage it the same way as regular code - you package it into modules with well-defined interfaces, and document them. I've worked with CL in a team settings, and I've worked on legacy CL code that's as old as I am; it's not harder than "regular" legacy code. And you always have to write your documentation yourself, there's no escape from that, no matter what language you use.
- simongray 6y ago> I could not help but thinking at the end, this is really awesome but s-expressions are kind of hard to read and reason about for my brain, it would be cool if we could generate them from more readable syntax, maybe something like javascript :D . So many people start out thinking like this when they learn Clojure or some other Lisp and then after like 2-4 weeks of reading Lisp code, any C-like code starts to look comparatively irregular and Lisp feels much easier to read.
- jFriedensreich 6y agoI heard that before but i wonder how much is survivorship bias :D it reads just so awkward to me as a programming language, even though i 100% dig the beauty and everything that it allows.
- simongray 6y agoIt's just a different paradigm than what most developers are familiar with so there is a learning bump, same as functional programming if all you've done is object-oriented stuff. The awkwardness is only temporary. If you can already see the beauty of Lisp code, then you just need to build a little project in it to make the awkwardness fade away. I recommend Clojure/ClojureScript. It's quite practical for web development and also an excellent gateway into functional programming.
- arethuza 6y agoI used Common Lisp as my main language for about 6 years (long time ago now) - yes for the first few days the syntax is a bit jarring but I've found that any new language is fundamentally different in approach to what you are used to has that effect (pretty much the same happened the first time I saw C, Lisp, PostScript etc.)
- wavegeek 6y ago> i wonder how much is survivorship bias Here is one anecdata. When my daughter was 14 I taught her a Lisp and then a traditional programming language. She found the random syntax of the trad formatted language bizarre.
- chriswarbo 6y ago> it would be cool if we could generate them from more readable syntax There are a few options out there; maybe take a look at Sweet Expressions? Some Lisp implementations have native support for different syntax, but the nice thing about these formats (which are essentially just serialisations of concrete syntax trees) is that we can convert them into the expected format automatically, e.g. using a pre-processor. I have a go-to page on my blog for discussions involving s-expressions, including links to various alternative syntaxen: http://chriswarbo.net/blog/2017-08-29-s_expressions.html http://chriswarbo.net/blog/2017-08-29-s_expressions.html
- hobby-coder-guy 6y agoSyntaxen?
- agumonkey 6y agonow you can go read norvig lisp in python very similar, build out of python []
- wavegeek 6y ago> s-expressions are kind of hard to read and reason about for my brain I think it's likely this is just a matter of familiarity. Like the way that people think the Windows (/ whatever) GUI is intuitive - but when you test this by putting someone who has never used it in front of a screen, it actually isn't. "What do you mean if I write something and don't also 'save' it, whatever that is, it will disappear? This is supposed to be better than paper...". The text editor handles indenting and matching. After a while it is completely transparent.
- username90 6y agoThat becomes a no true Scotsman fallacy though. People argue "Either you like lisp syntax or you haven't used it enough to have a valid opinion". That is a bullshit argument.
- ACow_Adonis 6y agoIt is and it isn't :) Obviously opinions on the language shouldn't be given too much weight if a person hasn't spent too much time investigating/ using it. As a non-JavaScript person, all the JavaScript examples looks like gobbledygook unless I sit down and consciously think about what the examples are showing, and it kinda hurts my head a bit, but I can slowly force myself through it. But as someone with a few years of lisp under my belt, even the closure examples (and I've never used clojure) parse pretty close the speed of thought. It really is hard to explain to someone who hasn't used lisp for 6-12 months, but there really is a lisp "enlightenment" experience, which is totally unlike anything I've experienced with any of my other languages. I'm not saying this makes it better or worse than other languages, but I am saying it's real, and that lisp code is not only parsable, but exceptionally so to an experienced lisp programmer. One day you're sitting there thinking there's a whole lot of brackets, balancing and indentation in this godforsaken language, and then something just clicks over in your brain and you don't even see the brackets any more and it's all just data structure, and you see the shape of it, and you say to yourself "well that was pretty fucking cool" and from that day on you don't really see the brackets any more, it's all just names, indentation and data structures. edit: and it should also be recognised that an editor implementing parentheses balancing, indentation options, and keyword lookup/ completion also becomes a relatively trivial exercise when your code consists of variable names and structured data.
- coldtea 6y ago>I could not help but thinking at the end, this is really awesome but s-expressions are kind of hard to read and reason about for my brain is (map foo '(1 2 3)) that more difficult than: [1, 2, 3].map(foo) ? Or: (let ((array #(1 2 3 4 5))) (vector-set! array 0 3) (vector-ref array 0)) that more difficult than: let array = [1, 2, 3, 4, 5]; array[0]=3 array[0]
- Joker_vD 6y agoYes. It's all personal, of course, but I find that the typographical variety of "traditional" languages with syntax makes it way easier to me to read/parse them than LISP. Parens, parens, everywhere, nor a drop of structure. And when it comes to macros and (pseudo)-quoting, the LISP is hands down more obnoxious (again, for me) than, say, Python's f"{}".
- wtetzner 6y ago> It's all personal, of course, but I find that the typographical variety of "traditional" languages with syntax makes it way easier to me to read/parse them than LISP. I wonder how much of that has to do with your familiarity with "traditional" language syntax. For example, when I started writing Lisp, I had a similar opinion. But I write Clojure professionally for a while, and that disappeared. Now I haven't written Lisp in probably 7 years, but I still have no problem reading it. > Parens, parens, everywhere, nor a drop of structure. On the other hand, in some sense it's all structure. There are certainly advantages to having everything be delimited.
- capableweb 6y ago> Clojure professionally for a while, and that disappeared. Now I haven't written Lisp in probably 7 years, but I still have no problem reading it. Slightly off-topic but interesting none-the-less. After starting to program with Clojure both as an hobby and professionally, how do you go back something that is not lisp/repl driven? I've tried time and time again to go back to JavaScript, as I used to be OK with it, but I just cannot justify the hassles I have to fight with everyday, compared to if my co-workers just picked up Clojure instead.
- miki123211 6y agoThis is exactly what Elixir is doing! It has nice, readable, ruby-like syntax, but it's a Lisp at the core. Really powerful macros (see Ecto), and a syntax that isn't off-putting to the majority of programmers. Most things in Elixir, including constructions like if and def, operators and even module accesses (`Module.function`) are compiled to a simple AST based on function calls. Because that AST isn't usually written by humans, besides the function and the arguments, each node might contain additional context information, like the file and line number the call appeared in. That lets you do some really cool stuff, like distinguishing x (a variable you define) from x (defined by a macro), which is a frequent source of bugs in other languages that support macros. 99% of Elixir is syntax sugar over function/macro calls, and its true AST is smaller than Clojures. You can read more here: https://hexdocs.pm/elixir/syntax-reference.html#the-elixir-ast https://hexdocs.pm/elixir/syntax-reference.html#the-elixir-a...
- pgt 6y agoLisp has only one rule called the Operational Form: (operator arg1 arg2 arg3 ...) The Operational Form is just a list denoted by parentheses. The operation or 'function' comes first, followed by its arguments or operands, e.g. (+ 1 2 3) => 6 The + symbol resolves to the plus function and is passed in the arguments 1, 2 and 3. Nested forms are evaluated inside-out: (+ 5 (- 10 6)) => 9 Traditionally, Lisp only has one data literal: `(linked lists)`, but Clojure adds `[square brackets for vectors]` and `{:curly brackets}` for hash maps. The colon denotes a keyword, which is a symbol which only ever resolves to itself and is commonly used for labeling things, e.g. keys in a map. Notice how the operational form is just a list with some symbols and data literals. In Lisp, the syntax for writing data structures and the syntax for writing code is the same syntax. And since a function operates on data and produces new data, what if a function could operate on code and produce new code, since code is just data? We call such a function a macro (and I don't mean Excel macros). Macros run at "compile-time" (technically 'read time') and the code output is executed at "run-time" (or during 'evaluation'). The benefit of macros is that if your language is missing a feature, you can add it. You can see this in practice by looking at the source code for the `and` and `or` logic functions in Clojure, which are typically built-ins, but in Clojure they are just macros bootstrapped on top of the special forms `if` and `let`: https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8dce5fb6d16b87845c8b9d/src/clj/clojure/core.clj#L842-L852 https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8d... Clojure only has 13 special forms: [fn let let loop do while . if def recur try catch throw quote var monitor-enter monitor-exit] Everything else is built on top of that. When I started learning Clojure, I found the ClojureScript Koans to be very helpful in getting a feel for the semantics and to become familiar with the argument placement: http://clojurescriptkoans.com/ http://clojurescriptkoans.com/ If you come from a traditional OO-background, my condolensces and I recommend starting with Rich Hickey's 2-hour talk, "Clojure for Java Programmers": https://www.youtube.com/watch?v=P76Vbsk_3J0 https://www.youtube.com/watch?v=P76Vbsk_3J0
- kyberias 6y ago> If you come from a traditional OO-background, my condolensces Is this condescending attitude really necessary or useful?
- masukomi 6y agoThere's a curly-brackets based infix formatting you could use if you'd prefer. https://srfi.schemers.org/srfi-105/ https://srfi.schemers.org/srfi-105/ Or, you could use T-Expressions if Python style whitespace indentations to represent code nesting is easier on your brain. https://srfi.schemers.org/srfi-110/srfi-110.html https://srfi.schemers.org/srfi-110/srfi-110.html Scheme and Lisp are VERRRRY Flexible.
- athenot 6y agoThank you! I'm in the camp of "Curious about Lisp but never jumped into it" and was wondering if indentation could reduce some of the bracket-noise. This is VERY elegant!
- fao_ 6y ago> I could not help but thinking at the end, this is really awesome but s-expressions are kind of hard to read and reason about for my brain, it would be cool if we could generate them from more readable syntax, maybe something like javascript :D Little known fact: The people who came up with lisp wanted to do this, too. https://www.wikiwand.com/en/M_expressions https://www.wikiwand.com/en/M_expressions
- minerjoe 6y agoI think the story continues to where, in the beginning, they thought a change would be good, but after seeing the benefits that s-expressions gave, changed their minds.