5 ms·
History of Lisp Parentheses (2019)
- brudgers 4y ago"Elegant weapons for a more civilized age" https://xkcd.com/297/ https://xkcd.com/297/
- gumby 4y agoI never liked the ] in Interlisp (so never used it myself) nor alternative syntax systems like LOOP (also avoided it). I don’t understand the obsession some people have with the parentheses. They basically fade into the background and when you do look at them it’s because they are informative. They are no more cognitively burdensome than the space bar.
- bmitc 4y agoI like Racket's way of handling them, to a degree. Each of {}, [], and () are interchangeable, and the use of [] is mostly down to convention. For example, it is often used in let bindings: (define x (let ([a 1] [b 2]) (+ a b))) By to a degree, I would actually prefer if the convention was enforced.
- gsinclair 4y agoThe convention is enforced in Clojure. [] for bindings, {} for maps.
- deleted 4y ago[deleted]
- funcDropShadow 4y agoIt is not a convention in Clojure. (), [], {}, #{} represent different data structures.
- Sakos 4y agoIt's really just syntactic sugar, so I would agree with the statement that the convention is being enforced.
- funcDropShadow 4y agoYou get different data structures. I.e. printing #{ 1 1 2 2 } prints #{ 1 2 } whereas [ 1 1 2 2 ] prints [ 1 1 2 2].
- tmtvl 4y agoNot exactly, it uses square brackets for vectors sometimes and curly brackets for maps sometimes, yet other times it uses square brackets for maps: (let [a 1 b 2] (+ a b)) Instead of: (let {a 1 b 2} (+ a b)) (I think my map notation may be wrong, I always just bounce off Clojure so I'm bound to make mistakes).
- shaunsingh0207 4y agoI quite like how fennel handles it as well, {} for standard lua tables and [] for arrays, but [] stands to define variables in a let binding. Of course this comes from Lua's quirks, but its a nice, sane way to handle it.
- lispm 4y agoThis is an old feature of some Scheme implementations. There are also books where the Scheme code is written this way, IIRC.
- wellpast 4y agoExactly. Totally baffled by the supposed popular reaction to parens. (However I use IDEs that match and color parens so maybe then didn't have such in the olden days referenced here.) Not having S-expressions is weird. Not being able to drop my cursor anywhere and with a few keystrokes to expand my selection "grab" a referentially transparent value expression and just relocate it or move it or evaluate in the REPL. What are all these other PLs and programmers even doing?
- gumby 4y agoA lot of languages pointlessly make a distinction between a statement and an expression. I can’t imagine why anyone would want that.
- sph 4y agoIt's one of the things I love the most in Rust, and was previously just seen in functional languages. Even scripting languages like Python feel clunkier than Rust due to the unnecessary statement/expression distinction.
- slaymaker1907 4y agoScribble (Racket documentation language) uses a very interesting @-syntax that is very similar to m-expressions. '@func[x y]{some text}\ -> '(func x y "some text")'.
- lispm 4y agoWhich is basically the syntax of Scribe, an early markup language from CMU's Brian Reid. https://en.wikipedia.org/wiki/Scribe_(markup_language) https://en.wikipedia.org/wiki/Scribe_(markup_language) There is a user's manual from 1978: http://bitsavers.informatik.uni-stuttgart.de/pdf/cmu/scribe/Scribe_Introductory_Users_Manual_Jul78.pdf http://bitsavers.informatik.uni-stuttgart.de/pdf/cmu/scribe/...
- xenadu02 4y ago> Although LISP is one of the most powerful tools available ... the format of the input language (S-expression) is awkward to use -- so awkward that many errors in programming LISP stem directly from the fact that S-expressions are the only allowable form of input. The inherent difficulty of producing correctly working S-expressions is tacitly recognized by anyone who uses M-expressions in place of them, when not communicating directly with the computer. Extremely accurate and written in 1964.
- bmitc 4y agoEditors have come a long way in those 60 years. Having written some Racket and Scheme, I notice no increase in the amount of syntax errors compared to other languages. Other languages have all sorts of syntactical gotchas because of all the syntax features they have.
- aidenn0 4y agoEditor support is missing adjust-parens[1], which I've been using for about a decade. 1: https://elpa.gnu.org/packages/adjust-parens.html https://elpa.gnu.org/packages/adjust-parens.html
- sph 4y agoDo you use this as an alternative to paredit?
- aidenn0 4y agoYes. Lisp code is only a small fraction of the code I edit, and trying to get my fingers to switch between paredit and not-paredit mode is not something I've been successful at. Adjust-parens lets me use line-oriented editing commands to structurally manipulate the lisp code, so it's much easier to context switch between lisp and not-lisp code.
- ravi-delia 4y agoI think we just have to accept that some people like s-exprs and some people don't. What people have against parentheses is beyond me, but I also can't explain why I find languages without them so ugly. Either way, the discussion is pointless if you assume LISPers tolerate the parentheses but would prefer something "better", or if you assume everyone is only opposed to the parentheses because of FUD. People literally just have different tastes!
- shaunsingh0207 4y agoFor me it's the one-way-ness of it, can't find a nice work to describe it. Most programs in languages will go outward and then inward, lisps just go outward. I quite like the "look" of python as well, except that its missing the colorful parenthesis and the expressiveness that makes lisp so powerful
- Jach 4y agoI dunno, my Lisp code comes back in pretty frequently, but I'm defining new functions, using CLOS, making use of let* or other nifty macros (uiop:nest is occasionally useful), and refactoring when a function gets too large. But compared to horrors I've frequently seen in JavaLand (especially in older code when the more modern practice of extract method/function refactoring was less common, more laborious, and not really automated), tons of Lisp code I come across from others has been pretty sane as far as indentation and spacing goes. It seems like a problem mostly handled by style: just because you can easily represent the whole expanded AST in one function definition, and only use simple cons/list/array/map data structures, doesn't necessarily mean you should. And sure there are plenty of (in my opinion) not so great examples out there, like it's rather unfortunate that this is the first example for the cl-sdl2 project: https://github.com/lispgames/cl-sdl2/blob/main/examples/basic.lisp https://github.com/lispgames/cl-sdl2/blob/main/examples/basi... (Though on another metric, the longest line is only 96 characters; most of my lines happen to be under 80 but I don't hold myself to that limit, my screen and editor windows support wide lines by default, like >200 characters wide.) The huge nest of with-macros further impedes runtime redefinition and modification, because now sure you can change code and redefine the function, but your game loop isn't going to see any of that on further iterations. At least the other renderer.lisp example is moving in a better direction splitting the game loop up into several draw functions, and you see those have a normal pattern of going out and then back in. Urbit docs for its language Hoon once called the phenomenon something like "attacking the right margin". I recalled this fosdem paper describing it more https://archive.fosdem.org/2018/schedule/event/urbit/attachments/paper/1887/export/events/attachments/urbit/paper/1887/whitepaper.pdf https://archive.fosdem.org/2018/schedule/event/urbit/attachm... especially in 6.3.2: > There are two common syntactic problems in functional languages: closing terminator piles (eg, right parens in Lisp) and indentation creep. A complex function will have a deep AST; if every child node in that AST is indented past its parent, any interesting code tends to creep toward the right margin. > To solve terminator piles, there are two forms of every Hoon twig: “tall” and “flat”, ie, multiline and single-line. Tall twigs can contain flat twigs, but not vice versa, mimicking the look of “statements” and “expressions” in an imperative language. Flat form is enclosed by parentheses and separated by a single space; tall form is separated by multiple spaces or a newline, and (in most cases) not enclosed at all. ... > Right-margin creep is prevented by backstep indentation; where a classical language might write ?: test then else > Hoon writes ?: test then else > Ideally the most complex twig is the else; if not, there’s an alternate form, ?., which reverses q and r. Hoon code is rather interesting to look at (random file: https://github.com/urbit/urbit/blob/master/pkg/arvo/lib/aqua-azimuth.hoon https://github.com/urbit/urbit/blob/master/pkg/arvo/lib/aqua...) especially with its rune vs keyword syntax choice, but I don't think it's worth the effort.
- lisper 4y ago> A more conventional notation was planned but never happened: This is evidence that S-expressions are objectively superior to other serializations. They are objectively simpler (this is why they were chosen in the first place -- writing a parser for sexprs is vastly easier than writing a parser for just about anything else), and the fact that humans who become accustomed to them early on generally prefer not to move away from them is evidence that other representations offer no advantages, and considerable disadvantages in the form of added complexity for no objective benefit. In other words, the main reason people don't like S-expressions is that they are indoctrinated from an early age (like grade school) into objectively inferior serializations, which trace their roots literally into antiquity. Lisp should be taught in elementary school. Children should be taught to think not in terms of of "two times three" and "two plus three" but rather "the sum of two and three" and "the product of two and three". It would make the world a better place in the long run.
- shadowofneptune 4y agoThe more 'objectively' is used here, the less meaning it seems to have. If people have trouble using the notation, it's a subjective issue that cuts into the utility of the language. Even after getting used to it myself, I sometimes get tied up translating infix formulas to RPN or PN. There doesn't need to be one notation/language to handle everything.
- qsort 4y agoThe point is why people have more trouble parsing (+ 2 3) than they have parsing (2 + 3). I agree with you (contra GP) that path dependency is a fine reason to prefer infix. Continuing with what we're used to is very often the preferable choice where the costs of switching are high and the benefits unclear. I actually think that infix notation has some advantages, especially for associative operations {e.g. if (G, +) is a group and a, b, c \in G, it's much more natural to write a + b + c than to choose between the equivalent (+ (+ a b) c) and (+ a (+ b c))}. But undeniably S-expressions are superior from a teaching point of view as they don't hide the "true" structure. Even though I don't dislike infix at all, it's hard to argue the reason most people prefer it isn't that they're just used to it.
- ktpsns 4y agoInterestingly, the author mentioned both M-expressions ("never implemented") and Mathematica (with a number of interesting links). Mathematics expressions are quite close to https://en.wikipedia.org/wiki/M-expression https://en.wikipedia.org/wiki/M-expression . Function application is not (f x y) or f[x; y] but f[x, y]. In contrasts, lists in Mathematica are {1,2,3} and thus pretty close to [1;2;3]. This curly bracket list notation is already syntactic sugar, as Lists are actually List[1,2,3] and thus very transparent to how you can represent them in LISP. Mathematica introduces a number of handy abbreviations such as f@x for f[x] or {x,y,z}/.f == Map[f,{x,y,z}] == {f[x],f[y],f[z]}. It even "overloads" the double semicolon symbol ;; basically acting as as in/pre/post-fix "operator", cf. https://reference.wolfram.com/language/ref/Span.html https://reference.wolfram.com/language/ref/Span.html -- the same is true with virtually any symbol such as "==" (Equals) or "+" (Plus). The Mathematica/Wolfram language could really be a game changer if it was open source.
- Y_Y 4y agoEven F[1,2,3] is sugar for and sexp. If you treat it like (F 1 2 3) it will work. You can take the head, or "quote" it with Hold. Or you can forget that an imagine that the language indexes from 1.
- lispm 4y ago> M-expressions ("never implemented") There were a bunch of approaches and even implemented languages. https://github.com/shaunlebron/history-of-lisp-parens/blob/master/alt-syntax.md https://github.com/shaunlebron/history-of-lisp-parens/blob/m...
- hackrnusr 4y agoIt already is: https://mathics.org/ https://mathics.org/