27 ms·
We need to talk about parentheses (2020)
- boxed 3y ago> It depends… on operator precedence I think implementing operator precedence in ANY programming language is a mistake. `1 + 1 * 2` should be a syntax error. In C, in Python, in Java.
- tempodox 3y agoI vigorously disagree.
- lionkor 3y agoFor that example, I agree, but how about a | b || c >> d & e * f ? I think its reasonable to say that a language should not allow that
- OJFord 3y agoYou can take any reasonable grammar and come up with unreasonably ugly/illegible code.
- lionkor 3y agoYeah, of course, but grammar can be designed as to not allow as much implicit magic. If you can do it, someone will do it (in prod, in your product).
- tempodox 3y agoThe reason why this expression shouldn't compile has nothing to do with precedences (C has some odd choices here to be sure), but because of mixing incompatible types. Arithmetic integers, bitvector integers, Booleans, and possibly even floats. Conversions to appropriate types should have to be explicit. But C's type system is weak as all hell and this shit actually compiles there. (I'm only mentioning C because your example looks like it.)
- rfl890 3y agoThere‘s no implicit type conversion here. As long as all the vars are the same type it works (albeit unpredictable if you don‘t know operator precedence for the lang).
- bmacho 3y agoHow about *paste Linux source code here*? Should the language C allow it? It's long and complicated, you don't even have enough time to read it, let alone to comprehend it.
- samatman 3y agoThat expression would not pass code review around me, and a linter should flag it for sure. But all the precedence rules you're invoking here are useful in isolation, and I see no reason why they shouldn't parse in combination. A linter can use heuristics to flag cases which should be parenthesized, a parser would need a defensible rule for failing a parse. What would that rule be?
- sokoloff 3y agoThere is value in notational simplicity. For the same reason that math has defined precedence (and even omits multiplication signs entirely in many places), programming languages in some domains will choose to do the same. It’s not a problem if you want to create a language that does not do this, but I think it is a problem if you want to ban others from doing it.
- tsimionescu 3y agoAlgebra only really has defined precedence between multiplication and addition/subtraction. In all other cases, even division, there is either a non-linear textual representation, or parantheses are required. You have fractions, exponents, radical signs, various signs which appear only at the beginning of an expression (sigma, integral, lim) etc. Even multiplication is often distinguished more by the shape of the text than by actual precedence rules, once you leave basic arithmetic - expressions like "1 - 3xy + 2y²" make the order of operations obvious from text layout, which is why they are preferred over "1 - 3 × x × y + 2 × y ^ 2", which no mathematician ever writes.
- sokoloff 3y agoExponentiation also has defined precedence, does it not? (Everyone who has passed algebra agrees that y is squared before being multiplied by 2 in your example.)
- tsimionescu 3y agoYou can view that as precedence, but I think it's more correct to say that exponentiation binds to the single symbol it is attached to. When you write x² + 2, I don't think it's operator precedence that makes it clear this is not equal to x ^ 4. Similarly, in the following expression: x _ + 2 2 I don't think it's precedence that makes it clear you first divide by 2 and then add 2 to the result.
- sokoloff 3y agoAlternatively, perhaps what you're observing is simply the graphical representation of the underlying mathematical precedence rules. (Obviously, over hundreds of years of symbolic math, the notation and precedence has co-evolved, with precedence probably generally, well, preceding notation.) y = x / 3 + 2 y = 2 + x / 3 y = x/3 + 2 We all agree those are the same, despite a lack of an any cues in the first two. That suggests to me that there is a defined precedence for division vs addition in math. (So much so that it doesn't even seem like a controversial statement to make.)
- lifthrasiir 3y agoSome operator precedences are way more reasonable than others, and those between arithmetic operators are good examples. What we actually need is a partial order of operator precedences: you can have `1 * 2 + 3` or `full_name ?? first_name ++ " " ++ last_name` but not necessarily `1 * 2 & 3` because that combination of operators is uncommon and a parenthesis should be preferred instead of an arbitrary total order.
- zarzavat 3y agoShould `x == 1 or y == 3` be a syntax error? Because that’s operator precedence too.
- kragen 3y agothat's certainly a plausible position; in lisp (or = x 1 = y 3) is generally an error; even if it's not an error it doesn't mean what you intend it to. having to write (x == 1) || (y == 3), similar analogous to the code you'd write in lisp, would be only a minor burden in c, x == 1 || y == 3 works fine, but unfortunately the bitwise operators have the wrong precedence; x & 2 == 2 is parsed as x & (2 == 2), which is never what you meant. so even the best software designers have made terrible blunders in precedence design math formulas are a bigger issue; 3*x**2 + x/2 + 1 is a lot better than the fully parenthesized version
- zarzavat 3y agoThere are of course operations with unclear precedence relationships and it’s completely reasonable to want to force parentheses when composing those operations. However, there are also operations with crystal clear precedence relationships, such as logical conjunction and comparison, and in that case it has to be asked what exactly would the parentheses be there for? In lisp the answer is: to enable syntactic homogeneity and to enable macros. But in other languages like Python that don’t have sexpr based syntax, parenthesizing everything would just be pointlessly unreadable.
- kragen 3y agoit isn't crystal clear to everyone, smart guy, it's only clear if you're familiar with it
- ctrw 3y agoThat is type inference actually.
- boxed 3y agoyea it should
- frud 3y agoFor basically forever compilers and languages have been designed with a total ordering on operator precedences. The Yacc compiler generator tool maps operator precedence to integers, as do most handwritten compiler parsers. A total ordering has a definite answer to the question "is x greater than, equal to, or less than y?" for all x and y. A partial ordering will answer "I don't know" for some x and y. It's quite possible to implement operator precedence using a partial ordering. When the parser has to resolve precedence between two operators and their relationship is not defined, throw an "ambiguous precedence" error. You can implement the partial ordering by putting all the operators into a DAG of sets of operators. If two operators are in the same set, they have equal precedence. If there is a path through the DAG from one operator to the other, that defines the precedence relation. Else there is no relation. Say "*" is defined to have a higher precedence than "+", and they both have an undefined precedence relation with "&". Then "1 + 2 * 3" should compile into "1 + (2*3)", but "1 + 2 & 3" should throw an "ambiguous precedence" syntax error.
- adrian_b 3y agoThe lack of operator precedence has no relationship with the mandatory use of parentheses. For example the APL syntax for expressions, which I prefer, is that there is no operator precedence. The operands are associated to operators strictly from the right to the left, regardless which operators or functions are used, which is a much wiser choice than the reverse traditional order of evaluation. No parentheses are used, except when they are needed to modify the default evaluation order.
- samatman 3y agoThat would get really annoying. Not in expressions like 1 + 3 * 6. Personally, I include the parentheses anyway, as a matter of style, and would write 1 + (3 * 6). But in expressions like i + 3 > 4 / n? No thank you, (i + 3) > (4 / n) would drive me up a wall. Ymmv.
- recursivedoubts 3y agopreach king https://hyperscript.org https://hyperscript.org doesn’t allow mixing different infix operators w/o parentheses
- phoe-krk 3y ago> humans can’t immediately parse structure with a glance, and sometimes we have to count parentheses by hand. This is why automatic indentation is important when working with Lisp. This is mentioned later in the article, but I consider it mandatory because of the multitude of problem this approach resolves. For example, upon pasting the below snippet into emacs: (let* ((foo 10) (bar (+ foo 32)) (* foo bar)) The editor 1) notifies me that there is a missing paren somewhere, 2) automatically* reindents this code into: (let* ((foo 10) (bar (+ foo 32)) (* foo bar)) At this moment, it's obvious that we have three variable bindings, one of them malformed, and the programmer can correct this by planting a missing paren in the proper place. I wrote about this topic at length in https://mov.im/blog/phoe%40movim.eu/cd3577f6-fb1d-45f5-b881-7b9a68ee822e https://mov.im/blog/phoe%40movim.eu/cd3577f6-fb1d-45f5-b881-... before. * with aggressive-indent and electric-indent enabled in emacs, as soon as the missing paren is placed at the end
- bloopernova 3y agoAren't there 11 parentheses in both of your code snippets? I must be missing something, sorry could you possibly explain where the missing parenthesis should be?
- taeric 3y agoIt helps to basically vocalize what the code is doing. It is a "let" form, which has a list of variables, and then a body section using them. (It is a "let*", which also means that the variables can refer to variables that come before them, but not too relevant here.) To that end, the first () in a "let" should be of the forms (name value), where value can be a longer form, if needed. To that end, the last (name value) in the list should almost always look like (name value)), as it is closing the first in the list, that is ((name value).
- lelandbatey 3y agoThey're not saying that the second snippet is "fixed", they're saying that the auto-indented second snippet highlights the mistake to the reader. Yes there are 11 parentheses in both the code snippets because both are "incorrect" in that they're both missing a parenthesis. The GP is trying to point out that since Emacs automatically re-indents the first snippet so that it looks like the second snippet, the reader knows immediately that something "isn't quite right".
- tromp 3y ago> Here’s the same code, but with all parentheses in place: (define (fac x) (if (<= x 0) 1 (* x fac (- x 1)))) Still one pair missing. Is it true that in normally formatted LISP code, every line should start with an opening parenthesis? Btw, I prefer Haskell's syntax of fac x = if x <= 0 then 1 else x * fac (x-1)
- mtreis86 3y agoNope, lisp doesn't care about whitespace at all, including line endings. The way lisp is read in is as if there was no whitespace, just objects in lists. (foo bar baz) (foo bar baz) (foo bar baz) All the same thing to lisp
- tsimionescu 3y agoThat's not quite right. Lisps care a lot about the presence of whitespace, just not about their type or number. (foo bar baz) is very very different from (foobarbaz). They are identical in this respect to the C family of languages, in fact (the only difference is that they allow newlines in quoted strings, which C languages normally do not).
- samatman 3y agoThe term of art is whitespace insensitive, meaning that whitespace is only necessary when needed to separate tokens, and any amount will do when it's allowed. While it may be possible to write a language in which whitespace may be inserted or left out literally anywhere, I'm unaware of any actual languages where this is true.
- KingOfCoders 3y agoComing from Java, Scala, Javascript one nice benefit of Go, was no parantheses around if conditions. At first I thought an irrelevant change but now I do think it makes code more readable.
- xmcqdpt2 3y agoProbably one of the best thing about the new "pythonized" Scala 3 syntax is that it doesn't require parentheses around if conditions.
- wlindley 3y ago»> ... "curly braces" ... « Ugh. Braces are "curly" — there are no "square braces" or "round braces." Needlessly redundant and confusion-inducing. Can we please eradicate this circumlocution from programming language?
- _Wintermute 3y agoThis is a regional thing. In the UK they're all brackets. Brackets, square brackets, curly brackets.
- lmm 3y agoEven if that's true (and it wasn't in my experience of the UK), no-one calls any character other than {} braces (even with extra qualifiers), right?
- tsimionescu 3y agoThey are also called curly brackets, so I imagine the confusion comes from there, and from the fact that the words "braces" and "brackets" are relatively similar, making them easy to confuse, especially for non-natives.
- ehecatl42 3y agoParentheses (()), braces({}), brackets([]), and chevrons(<>). I concur.
- teddyh 3y ago<http://www.catb.org/~esr/jargon/html/A/ASCII.html http://www.catb.org/~esr/jargon/html/A/ASCII.html>
- tsimionescu 3y agoOr, in British English, brackets(()), curly brackets({}), square brackets ([]).
- 3y ago
- oakpond 3y agoMaybe the outcome of this syntax experiment is that less is not always more. Maybe in general people prefer more syntactical notations than what Lisps offer out of the box.
- deleted 3y ago[deleted]
- zelphirkalt 3y agoAlso many people, who have actually used Lisps prefer the notation for its ease of editing code.
- bmacho 3y agoI don't think we need to talk about parentheses? I doubt there is anything nontrivial but useful to say about them? Anyone found anything in the article?
- bmacho 3y agoI think I'll take these votes as a no.
- kragen 3y agoprogrammers a choosing a language because of syntax are like house buyers choosing a house because of the color it's painted
- lex-lightning 3y agoBut what if the two houses are otherwise identical? Even a small convenience will tip decisionmaking
- kragen 3y agoin cases similar to that, it would be a reasonable thing to do
- tmtvl 3y agoI'd like to think I'd have a far easier time painting a mauve house ochre than I'd have trying to change Rust to have an S-expression syntax (not in the least because I have the programming chops of a slightly dimwitted housefly).
- kragen 3y agoit's an excellent point: non-programmers choosing a programming language would do well to pick a language whose syntax they like, since they can't change it
- erik_seaberg 3y agoThe wrong paint won’t stop you from adding a garage, but choosing a complex and non-uniform syntax makes it so hard for end users to extend the language that we almost never try. Imagine how much more readable Java would be if Lombok didn’t need to smuggle each option in a prefix @Annotation.
- kragen 3y agoif running your java through m4 before you compiled it is a major advantage, doing it is trivial. compiling from a completely different surface syntax is a little more work but still not life-changing
- Joker_vD 3y agoYALPAAG (Yet Another "LISP's Parentheses Are Actually Great") article. One would think that if they really were that great, there wouldn't have been any need to keep writing such articles after several years, and yet here we are again. > humans can’t immediately parse structure with a glance No, humans absolutely can, as long as those structures are: a) delimited; and b) the delimiters used aren't nauseatingly repeating. LISP's parentheses start failing at the b) condition much sooner than semantic whitespace/indentation starts to.
- nataliste 3y agoYAEAR (Yet Another "Earth's Actually Round") article. One would think that if the earth was really round, there wouldn't have been any need to keep writing such articles after several years, and yet here we are again. > humans can’t immediately see curvature with a glance No, humans absolutely can, as long as those curvatures are: a) intuitive; and b) the curvatures used aren't nauseatingly large. Round Earth start failing at the b) condition much sooner than a flat-earth model. In short, generations are forced to effectively re-learn basic facts about the world they inhabit because new members are in fact ignorant and must be disabused of their intuitive yet incorrect assumptions.
- samatman 3y agoWhat on Earth did you intend to convey with this? I'm mystified. Are you, in fact, comparing a preference for Algolic syntax over s-exprs, to... flat Earth theory? Surely not.
- nataliste 3y agoThe comparison between preferences for Algolic syntax over s-expressions and flat Earth theory is not about equating the legitimacy or scientific validity of the concepts but rather highlights the persistence of debate and the necessity of re-education. It illustrates that regardless of the objective correctness or efficiency of a concept (like the roundness of Earth or the utility of LISP's parentheses), there will always be a need to revisit and reiterate these concepts for new audiences who may not yet understand or accept them. The analogy aims to show how education and clarification are ongoing processes, necessitated by the arrival of individuals unfamiliar with established knowledge or preferences.
- xmcqdpt2 3y ago> And this is, in fact, a made-up example but the thing is, I was a C programmer for the past 5 years, and I was working with low-level code (bare metal actually). And I have never seen the use of explicit scoping of variables. [...] I find this a major problem when dealing with C because I always see about 10 uninitialized variables at the start of each function, where half of those are used only once. Somewhere. And thank god, if there are no global variables. Sure, if you write C like it's 1995, it's not going to be very readable. You don't need to define variable at the beginning of a scope, and you can use {} to scope variables to tighter blocks. And functions can be small. (Sometimes you need to keep variables for longer than you would like for cleanup reason, that's true.)
- ctrw 3y agoSo your solution to having too many () is to have just as many {}. I'm not complaining but...
- PeterisP 3y agoWell, no, the above solution is to have a {} if and only if explicit scoping is desired instead of having just as many {} as there would be (). Sometimes you need explicit scope for a bunch of things and the code would benefit from it. That doesn't justify having explicit scopes for everything all the time.
- zelphirkalt 3y agoIsn't is always safer to have variables scoped only to the relevant part of the code, that is supposed to make use of them? So basically it would result in almost the same number of parens.
- lex-lightning 3y agoThis isn’t always possible, even in lisp. Compare to Rust’s non-lexical lifetimes
- wslh 3y agoIn a simple DSL I am working based on s-expressions I enable things like removing parenthesis in single line expressions. For example, (define a "hello world!") is just define a "hello world!" <EOL> Another example that could work more than RPN/FORTH (or close to the ; operator in smalltalk) is: (* 4 (+ 1 2 3)) equals to: + 1 2 3 . <EOL> * 4 <EOL> The DSL is not LISP based but s-expr to define a DAG like in an spredsheet.
- QuadmasterXLII 3y agoPssst- hey kid! I heard you came to this side of town looking for a lisp with no parentheses. If you're not a narc, I've got the goods. Try a little bit of this julia! end Ok, ok I know your parents warned you about indexing from 1 but they also thought that global variables should be replaced with singleton factories, so what do they know.
- klabb3 3y agoMonster! You’ll have to pry my 0-indexing from my cold dead hands.
- lispm 3y agoWe actually need to talk about lists. The single reason why Lisp uses parentheses is the list notation -> programs are actually lists, not just text. The same code which runs CL-USER 10 > (let* ((foo 10) (bar (+ foo 32))) (* foo bar)) 420 becomes data, when quoted: CL-USER 11 > (quote (let* ((foo 10) (bar (+ foo 32))) (* foo bar))) (LET* ((FOO 10) (BAR (+ FOO 32))) (* FOO BAR)) A typical Lisp function can then substitute all * symbols to + symbols: CL-USER 12 > (subst '+ '* '(LET* ((FOO 10) (BAR (+ FOO 32))) (* FOO BAR))) (LET* ((FOO 10) (BAR (+ FOO 32))) (+ FOO BAR)) EVAL can execute lists: CL-USER 13 > (eval (subst '+ '* '(LET* ((FOO 10) (BAR (+ FOO 32))) (* FOO BAR)))) 52 Thus the single main feature is that Lisp itself is an application of the List Processor. This feature then is user visible in read eval print loops, debuggers, inspectors, code formatters, source interpreters, code generators (-> macros), embedded languages, ... So Lisp developers loved it, because one would not need translators between user facing (infix) syntax and internal data structures (ASTs, ...). Thus early attempts for other syntax variants failed, because this duality between data and code has some kind of elegance. Something which for example impressed Alan Kay (of OOP / Smalltalk / Dynabook / ... fame), when he understood that something like a Lisp evaluator can be written in a few lines of Lisp code, processing lists, which is code. -> https://www.quora.com/What-did-Alan-Kay-mean-by-Lisp-is-the-greatest-single-programming-language-ever-designed/answer/Alan-Kay-11?share=1 https://www.quora.com/What-did-Alan-Kay-mean-by-Lisp-is-the-...
- deleted 3y ago[deleted]
- taeric 3y agoI had fun trying to explain this a few years back. https://taeric.github.io/CodeAsData.html https://taeric.github.io/CodeAsData.html I do have to confess I have rarely taken huge advantage of this fact. But the idea is pretty easy to help look at code.
- kqr 3y agoList is confusing terminology. It's a tree. Sure, any node of a Lisp tree is implemented as a list of branches, but fundamentally we are talking about trees, still.
- danieltanfh95 3y agoThe weird thing about parentheses is that lispers only really get how powerful and how simple it makes programming after prolonged exposure, and thats why every now and then we have articles that try to explain this magical moment to folks. The strength of lisps syntax basically boil down to a few things: 1. Scope is visually clearer than in non-lisps, you dont need to hold the parser in your head while reading code. 2. Code as lists allows consistent and simple macros. 3. No need to reinvent editor tooling.
- melagonster 3y agoThis is a interesting idea! Maybe all programming languages have their sweet points that learners find "magic" and then generate blog articles.
- jwindle47 3y agoI loved this article, this is exactly what programmers in my community complain most about with regard to lisp. The greatest strengths for me are the scoping and how lisp enables interactive development. For one, I don't even see parens anymore when writing code. They've become automatic where I'm able to parse structure at least better than I have in the past. With a REPL, (I specifically use Clojure), development has become fun again. A typical debugging process is attaching to my actual program, and calling functions seeing what happens. I love the flow of defining functions in my code, `def`-ing some test data, and calling those functions. I'll use `cider-inspect` to see if the data structure looks correct and iterate. Everyone should at least try a lisp. Iterative, interactive development is so fun and powerful.
- RodgerTheGreat 3y agoProgramming languages are user interfaces. The syntax of a programming language is part of that user interface. Some choices are poor by virtually any measure (stropped keywords come to mind; as visually hideous as they are unpleasant to type), but most choices represent tradeoffs that favor certain usage patterns over others. Lisp de-prioritizes legibility at a glance and concision in order to give maximum priority to simplicity in metaprogramming. I'm not convinced this is a good tradeoff; I would no sooner choose to drive to work in an amphibious tank that got 0.2 miles per gallon to be able to cut across a single river along the way. Lispers say that I could use specialized tooling to compensate for poor ergonomics, but in many contexts- someone else's computer, a text box or static text on a website, a general-purpose textual diff or search tool, print in a book, a whiteboard- these affordances are not available, and I would still have to contend with the inconvenient reality of Lisp's very real design choices.
- thaumasiotes 3y ago> stropped keywords come to mind; as visually hideous as they are unpleasant to type It's pretty common today for people to voluntarily put SQL keywords in all caps. > Lisp de-prioritizes [...] concision Really?
- RodgerTheGreat 3y agoBy the standards of a K programmer, Lisp is quite verbose and excessively nested.
- trealira 3y ago> Really? Yeah, Lisp can be verbose due to the lack of built-in syntax for things other than lists. Take the Common Lisp syntax/library functions (there's not really built-in syntax) for hash tables: https://cl-cookbook.sourceforge.net/hashes.html https://cl-cookbook.sourceforge.net/hashes.html Compare it with Python dictionary syntax: https://developers.google.com/edu/python/dict-files https://developers.google.com/edu/python/dict-files Almost everything that's built-in to other languages has to be given a name that makes sense in Lisp. It makes it more readable in some ways, but also more verbose.
- mindslight 3y agoI've got this theory that what people actually don't like about Lisp parentheses is not the amount of nesting, nor the opening paren's prefix location, but rather that parentheses always include a hard nesting apply (or really, the syntax layer equivalent of a hard nesting list). In other words - most programmers are used to having an assertion that ((foo)) (foo) and foo are all equivalent, and also assume the basic top-level production is already some kind of list (not a single expression). Lisp breaks these long-loved assumptions. Writing Haskell feels quite Lispy in that the basic syntax is quite generic, but you can nest parentheses all day long without changing the meaning, or even use some generic operators ($, .) to write out a structure in a clearer way. I'd love to see an attempt at a Lisp syntax that felt similarly. (And yes, I know there have been 2^37 attempts at different Lisp syntaxes, but I still haven't found one in line with this idea)
- Beijinger 3y agoThis is why every sane person uses an RPN calculator. :-0
- norir 3y agoThis comes off more as a series of rationalizations than a compelling argument. Lisp is easy for a computer to parse, not great for humans. There other languages with comparably rich metaprogramming that syntactically have a better tradeoff between computer and human legibility.
- worewood 3y agoYeah, it reads like "parentheses are good, here is a 50-page essay on why" - sounds like the author is grasping at straws.
- phoe-krk 3y ago> Lisp is easy for a computer to parse, not great for humans. Which is why "best of both worlds" approaches work best in my opinion, no matter if it's "just" automatic indentation and paren-counting that leaves actual editing to humans, or more intrusive approaches like Parinfer (mentioned in the article) that automatically infer parenthesisation from code indentation and edit the code as appropriate. Properly indented Lisp is easy to read (for me), and badly indented code can be misread even in languages like C++.
- packetlost 3y agoNah, parenthesis are easy to parse with the eye if you spend even a small amount of time working with them. You still have to indent reasonably like you would with every other syntax.
- gary_0 3y agoIf I wanted to I could get used to reading Lisp. I could also get used to reading Klingon. But I never had to get used to reading Python.
- davexunit 3y agoSpeak for yourself, I find the lisp syntax to be among the easiest to read.
- norir 3y ago
- camgunz 3y agoParens are powerful in lisp(s) because it means the syntax is its own AST and can be manipulated by itself (macros). It's one of those exploding head moments that you (including me) can get totally ensorceled by. But--as with all language features--I think pragmatism demands that we ask "what incredible software has this produced", and I can't think of any standouts.
- Turing_Machine 3y agoThis site is written in Lisp, I believe (a dialect called Arc). Not only that, but the site and Y Combinator as a whole likely wouldn't exist without Lisp. https://paulgraham.com/avg.html https://paulgraham.com/avg.html (Wow! Over 20 years ago!)
- iainmerrick 3y agoHas anything else notable been done with Arc? Rather than "Lisp gives you superpowers", maybe the story is actually "there were some very effective developers who happened to use Lisp to build their stuff".
- camgunz 3y agoYeah but I'm skeptical that there's anything about HN's software that's uniquely enabled by being written in Arc. I want someone to point to a feature in a Lisp and say, "you can write X software only in Z because there's Y feature". I'll even accept "significantly more easily" instead of "only" here. For example: "you can write secure kernels only in Rust because it has direct hardware access and memory safety" (let's stipulate this is all true).
- tmtvl 3y agoThere are various problems with 'what incredible software has this produced?'. Various incredible software which has been produced date back from before the Lisp machine went the way of the dodo. An example of this would be Genera. Other incredible software has a very specific type of draw which doesn't work for everyone. Examples would be Guix and Emacs. And yet other software is very niche, leading to it being barely discoverable. As Lisp isn't a hot programming language (like Rust is), these projects don't usually get 'this thing was programmed in Lisp' coverage. Things like NASA's SPIKE, for example (cfr. <https://allegrograph.com/press_room/franzs-allegro-cl-used-for-scheduling-the-hubble-space-telescope-discovery-of-earendel/ https://allegrograph.com/press_room/franzs-allegro-cl-used-f...>).
- 1letterunixname 3y agoAnd if they had just used an RPN CAS like Erable... ;] 10 [ENTER] foo [STO] « foo 32 + » bar [STO] foo bar *
- kleiba 3y ago> This code does exactly the same thing as Rust code Except it doesn't - because after the final parenthesis of the Lisp snippet, the let-binding is finished, i.e., the introduced variables are no longer in scope. That is not the case after the end of the last line in the Rust example. The whole point of parentheses is to mark where something starts and where it ends. Here, it is where the scope of the let-defined variables starts and ends. Without some sort of "parenthesizing", there might be a start, but it's much harder to mark where something ends.
- sgeisenh 3y agoI think it's more subtle than that. Rust has a notion of non-lexical lifetimes (https://rust-lang.github.io/rfcs/2094-nll.html https://rust-lang.github.io/rfcs/2094-nll.html) and the compiler often completely avoids the use of the stack for small, trivially droppable values, regardless of their lexical scope. In some ways, `let` in Rust is a more C-like variant of the `let ... in ... end` construct from OCaml. Not to mention that you can always introduce a new lexical scope with `{ ... }` in Rust code.
- User23 3y agoI believe there are Common Lisp implementations that will happily stack allocate dynamic extent values.
- tmtvl 3y agoI like Lisp syntax because the following works: (if (<= lower-bound position upper-bound) ...) And the following doesn't: if (lower_bound <= position <= upper_bound) ...
- User23 3y agoAlso (+) And (*) Are well defined.
- nyrikki 3y agoMostly this article is about people being exposed to M-expressions in elementary math. As someone whos first programming post BASIC was on a Symbolics machine, coding _conventions_ worked just fine with s-expressions The Polish notation is probably what most people are reacting to unless you used the reverse version with an HP calculator. Whitespace isn't significant in C like the author suggests, it is coding convention. COBOL is a counterexample for whitespace significance not helping with readability. But for lisp the parentheses was a non-issue with just a few emacs macros. But that is the same with most modern languages outside of novelties like bf
- ur-whale 3y agoVery long article to find a justification for a Stockholm syndrome.
- justincredible 3y ago[dead]
- bfung 3y agoLisp code is == to its AST, the programmer is literally writing the AST that runs, hence meta programming is really easy. The trade-off ends up being that metaprogramming becomes harder while syntax gets changed shrug, do it long enough and the parans disappear: Q: How can you tell when you've reached Lisp Enlightenment? A: The parentheses disappear. ~ Anonymous
- chalcolithic 3y agoYet another chance to regret that REBOL has never caught on
- anthk 3y agoAs I use vim/slimv, I don't care, paredit fixes that.
- wduquette 3y agoDo we though? Do we really need to talk about parentheses? I've learned a lot from LISP and its variants over the years, and I understand the value of LISP syntax for meta-programming, but if any of this was truly compelling we'd have all been doing it for years. Every language has its own form of Stockholm Syndrome, I guess.
- valcron1000 3y agoExcept for the structural editing enabled by the usage of parenthesis, all the other features can be achieved without them in ex. Haskell: a = let foo = 10 bar = foo + 32 in foo * bar b = 1 & (+ 2) & (* 9) & (/ 5)
- bakul 3y agoOne can think of s-expr parentheses as structural formatting commands - sort of like markdown. Then you can render an s-expr in a different way so long as the structure is maintained. For example choosing diff background color at each level or for different types of s-expr.
- efilife 3y ago> While I do not find jokes in this comic funny (except maybe C one), the Lisp part is pretty representative of how non-Lispers see Lisps in general, which is unfortunate. Lisp programmers see the exact same thing as non Lisp programmers. This image is funny because Lisp is known for its use of parentheses and no amount of coping will change this.
- stefanovic 3y agoFist post here, and shameless self promotion: I happen to have written a paper on that topic: "Unifying Textual and Visual: A Theoretical Account of the Visual Perception of Programming Languages" https://dl.acm.org/doi/abs/10.1145/2661136.2661138 https://dl.acm.org/doi/abs/10.1145/2661136.2661138 direct pdf link: https://dl.acm.org/doi/pdf/10.1145/2661136.2661138 https://dl.acm.org/doi/pdf/10.1145/2661136.2661138 The paper offers a theoretical account based on the semiology of graphics from Bertin, using Lisp as an example (with very similar examples to Andrey's), but also other languages e.g. Befunge ;-)
- yencabulator 3y agoIt's weird to have a Lisp fanboy gushing about parentheses without seemingly knowing about M-exprs, Dylan, and how the paren-heavy syntax wasn't meant for humans. https://en.wikipedia.org/wiki/Dylan_(programming_language) https://en.wikipedia.org/wiki/Dylan_(programming_language)
- lispm 3y ago> the paren-heavy syntax wasn't meant for humans In Lisp the "paren-heavy syntax" was for humans. It was even a part of M-exprs. It was the syntax for data in the m-expression syntax. But the M-exprs wasn't implemented, the code was translated by humans to full s-expressions and entered that way. Users then found out that it was easier to stay with s-expressions.
- hackburg 3y ago[dead]