12 ms·
As a heavy user of Python, and someone who grew up with the "curly braces" languages, I have a question for y'all. Is this really readable? (setv result (-
by IgorPartola 9y ago
As a heavy user of Python, and someone who grew up with the "curly braces" languages, I have a question for y'all. Is this really readable?
(setv result (- (/ (+ 1 3 88) 2) 8))
Or rather is it more readable than
result = ((1 + 3 + 88) / 2) - 8
I just... Do you just get used to this, or is it something that you have to keep struggling with? Especially given that the latter is how we do math the rest of the time?
- evilduck 9y agoIt's just training. Buy and use a RPN calculator and lisp suddenly seems normal. (To answer your question directly, yes it's readable. You learn to look past the syntax in lisp the same as you stop reading semi-colons and curly braces in other languages)
- deleted 9y ago[deleted]
- gkya 9y agoM-x calc!
- xelxebar 9y agoOr if you're a fan of cli tools, check out dc!
- unkown-unknowns 9y agoI use dc every now and then but I wish it'd do decimal math by default. 9 35 5 12 *+/p Furthermore I think it's strange that the order of the operands of the division operator is divisor as top-most value on the stack and dividend as second top-most value and not the other way around. For example, to me it'd feel more natural if 3 5 /p was equivalent to 5 / 3 in infix notation, not 3 / 5 Because when I think of a fraction I think of it as "dividend over divisor". Edit: Actually I Googled and it makes sense now. I've been focusing on what's on the stack but if we look at what is provided as input instead then it becomes "calculate dividend, calculate divisor, divide". Longer example which shows this: Algebraic expression (4 + 2 * 5) / (1 + 3 * 2) RPN 4 2 5 * + 1 3 2 * + /
- boomlinde 9y agoSome distributions use a ".dcrc" or some such that will be executed on startup. Dump "3k" in there to set the precision. The order of the operands of non-commutative operators reflects popular RPN calculators and Forth. You can swap the topmost elements of the stack with "r", for example "3 5r/p"
- vram22 9y agoFor people who prefer infix, bc was/is a more user-friendly wrapper over dc. See: $ man bc and https://en.wikipedia.org/wiki/Bc_(programming_language) https://en.wikipedia.org/wiki/Bc_(programming_language) I normally invoke it with: $ bc -l to get more digits of precision after the decimal point (see Wikipedia page). Excerpt: [ bc first appeared in Version 6 Unix in 1975 and was written by Robert Morris and Lorinda Cherry of Bell Labs. bc was preceded by dc, an earlier arbitrary-precision calculator written by the same authors. dc could do arbitrary-precision calculations, but its reverse Polish notation (RPN) syntax was inconvenient for users, and therefore bc was written as a front-end to dc. bc was a very simple compiler (a single yacc source file with a few hundred lines), which converted the new, C-like, bc syntax into dc's postfix notation and piped the results through dc. ] Note that GNU bc is no longer a front-end to dc: [ In 1991, POSIX rigorously defined and standardized bc. Two implementations of this standard survive today: The first is the traditional Unix implementation, a front-end to dc, which survives in Unix and Plan 9 systems. The second is the free software GNU bc, first released in 1991 by Philip A. Nelson. The GNU implementation has numerous extensions beyond the POSIX standard and is no longer a front-end to dc (it is a bytecode interpreter). ] Also, you can pipe the standard output of any other (filter) command into bc, and likewise, pipe bc's output to any other filter.
- chx 9y agoNormal? It's upside down! I am a die hard RPN fan, started with a HP 32S when I was 14 years old almost three decades ago, upgraded to a HP 48G a few years old (well, kind of a 48G - 48GX hybrid, a friend of mine and I hacked it to 512K SRAM, gosh, hand soldering those little TSOP legs, brrr, we just stacked them chips and ran the data legs together, those were the days). But this is alien and hard to read, RPN should be _reverse_ polish notation, you know? And + 1 2 3 is weird because it makes + a three argument operation, or I guess in this case, variable number of arguments. 1 2 3 + + is easy to read and understand :)
- jwr 9y agoFrom a long-time Lisper (Common Lisp, and now Clojure): not, this is not comfortably readable. That said, I very rarely write code like this. I tend to split operations over multiple lines, so that you don't spend so much time digging into and out of nesting levels. Prefix notation is not ideal for reading math. People have been writing infix math notation libraries for CL for exactly this reason. It's not a showstopper, though. Also, I do find that sometimes having + and < to be of arbitrary arity is really convenient and makes for nicer code.
- kazinator 9y ago> People have been writing infix math notation libraries for CL for exactly this reason. People have writing these notation libraries, but then not actually using them. Infix libraries for CL mostly exist to end arguments; "we have infix; Lispers choose not to use it, and you will understand why soon enough".
- a-saleh 9y agoI actually used them quite often when i.e. dealing with math. I just realized I don't use math that ofthen when programming :)
- mthomas 9y agoI find that both are equally (un)readable. However, for expressions that are that long, I'm inclined to write: (setv result (-> (+ 1 3 88) (/ 2) (- 8)))
- deleted 9y ago[deleted]
- jamescostian 9y agoI am not a lisper, but that looks pretty cool. The non-lisp ways of writing that would either require adding parens like GP or writing things like "result /= 2", but that means repeating "result" or whatever variable many times.
- cle 9y agoThis is even better than in-fix notation.
- lliamander 9y agoIndeed, I like that better than either typical prefix or infix nested expressions. What do you advise in the case the expression tree is a little bit more complex? For example: (setv result (- (/ (+ 1 3 88) 2) (* 8 (+ 3 2)))
- mthomas 9y agoI don't see any clever way to make that more readable. I would have to break it into two subexpressions and then take the difference. i.e. (setv e0 (-> (+ 1 3 88) (/ 2))) (setv e1 (-> (+ 3 2) (* 8))) (setv result (- e0 e1))
- kazinator 9y agoBTW doesn't setv support multiple pairs? (setv e0 (-> (+ 1 3 88) (/ 2))) e1 (-> (+ 3 2) (* 8)) result (- e0 e1)) like setq and setf in CL.
- 9y ago
- swiley 9y agoI'd imagine it's like FORTH: If you read enough of it (it only takes a few days of reading) it becomes clear.
- throwaway135634 9y agoIn my experience, the hardest part about reading Forth is recognizing when a word doesn't use RPN because of metaprogramming
- ifelsehow 9y agoAs @jwr says, there are different paradigms in Lisp, such that you would never really write code like this.
- 6581 9y agoI have been using RPN calculators for all my life (except when I was forced to use infix calculators in school). Your first example is at least as readable to me as the second one. Just read it from inside to outside instead of from left to right.
- dunham 9y agoIn school, RPN occasionally caused trouble for me as I could work through an entire problem (leaving values on the stack) without writing down any intermediate steps.
- deathanatos 9y agoThis is the main reason Lisp has just never grown on me. I'm certain — and other responses demonstrate — that the readability can certainly be improved here. Yes, a programming language needs nothing more than parens. But dedicating a tastefully chosen set of sigils seems to make a lot of difference, in my opinion.
- kbp 9y agoI understand this point of view if most of your programs are just doing arithmetic, but once you start using functions and procedures the differences are pretty minimal.
- kazinator 9y agoIn the dialect called TXR Lisp, I have introduced precisely that: some tastefully chosen syntactic sugars which do not disturb the structure of the surrounding Lisp. I believe I made a wise choice by not targetting arithmetic. My syntactic inventions target areas like working with arrays, string processing, OOP and higher order functions. Small taste: 1> (let ((x "abc") (y "def")) (swap [x 0..2] [y 2..:]) (list x y)) ("fc" "deab") 2> (mapcar (ret `@1-@2`) "abc" "def") ("a-d" "b-e" "c-f") 3> '#"lorem ipsum dolor sit" ("lorem" "ipsum" "dolor" "sit") 4> (let ((a "dolor")) ^#`lorem ipsum @,a sit`) #`lorem ipsum dolor sit` 5> (eval *4) ("lorem" "ipsum" "dolor" "sit") 7> (defstruct (point x y) nil (x 0) (y 0)) #<struct-type point> 8> (new point) #S(point x 0 y 0) 9> (new (point 1 2)) #S(point x 1 y 2) 10> (new point x 2 y 3) #S(point x 2 y 3) 11> (let ((a (new (point 10 20)))) ^(,a.x ,a.y)) (10 20) 12> (let ((a (new (point 10 20)))) `<@{a.x}, @{a.y}>`) "<10, 20>" 13> (defmeth point distance (p) (sqrt (+ (* p.x p.x) (* p.y p.y)))) (meth point distance) 14> (new (point 3 4)).(distance) 5.0 15> (defmeth point distance-to (p q) (let ((r (new (point (- q.x p.x) (- q.y p.y))))) r.(distance))) (meth point distance-to) 16> (new (point 3 4)).(distance-to (new (point 20 30))) 31.0644491340181 19> (let ((pts (build (dotimes (i 10) (add (new (point (rand 10) (rand 10)))))))) pts) (#S(point x 5 y 6) #S(point x 1 y 1) #S(point x 1 y 3) #S(point x 5 y 7) #S(point x 2 y 8) #S(point x 7 y 3) #S(point x 1 y 1) #S(point x 2 y 4) #S(point x 5 y 6) #S(point x 5 y 3)) 20> (mapcar .(distance) *19) (7.81024967590665 1.4142135623731 3.16227766016838 8.60232526704263 8.24621125123532 7.61577310586391 1.4142135623731 4.47213595499958 7.81024967590665 5.8309518948453) 21> (mapcar (ret @1.(distance-to @2)) *19 (cdr *19)) (6.40312423743285 2.0 5.65685424949238 3.16227766016838 7.07106781186548 6.32455532033676 3.16227766016838 3.60555127546399 3.0)
- cutler 9y agoIt's not merely a matter of syntax or taste. Lisp's code-as-data and advanced macros are made possible by its s-expressions.
- jonahx 9y ago> Do you just get used to this Short answer: yes, and in far less time than you'd think. The difference between the examples you cite, specifically, is trivial, and if it's a sticking point for you I'd suggest (and I'm not trying to be catty at all) that you broaden your experience with different languages. I mean, languages like J can become readable with enough experience -- stuff like the above is just a blip on the syntactical radar screen. Optimizing syntax for readability is a worthy goal, but experience (both with the language in question and languages in general) is an almost insurmountable confound here, and ultimately your goal should be to effortlessly "see past" surface differences so you can concentrate on the deeper facilities the language provides for expression.
- IgorPartola 9y agoHeh. I am pulling this example straight from Hy's tutorial. They are the ones claiming that this syntax is superior to Python's. I do have a hard time with parsing it in my brain. Long ago, I internalized what I believe to be true about programming languages: they should be optimized for the humans using them, not for the machines that run the programs or the compiler authors who create them. This leads to less bugs. Maybe your goal is to see past syntax to understand language semantics. My goal is to get code shipped with as few bugs as possible as quickly as possible. Python and ES let me do that pretty well. Also don't meant to be catty, to each their own interests.
- didibus 9y agoI think what was meant was that the semantics should be optimized to human. Those semantics matter more then the syntax, since you can quickly get used to syntax. So think of it as learning to recognize and pronounce an alphabet used to form words, over understanding the meaning of sentences in a given language. Having said that, once you get used to the lisp syntax, as I did, I find it is better suited to humans. But to believe it you need to try out structural editing.
- IgorPartola 9y agoHmm, that seems to imply that you can't optimize for semantics and syntax at the same time.
- dustingetz 9y agoIn clojure you write it like this, so the parens indicate scope. No need to mutate an environment here. dunno about hy (let [result (- (/ (+ 1 3 88) 2) 8)] ; result defined inside the expression only )
- cannonpr 9y agoI used to be mostly a Python guy, fell in love with Clojures syntax, you get used to it surprisingly fast, and it's caused me less headaches than 'interesting' pythonic syntax. That having been said, I still love Python too.
- erikpukinskis 9y agoI would never use a variable name like result, it's meaningless. And the inner values should be labeled too, with their own variable names. Any compiler worth its salt will optimize the names away.
- kazinator 9y agoThere are advantages: Long Lisp expressions break into multiple indented lines according to a couple of very easy rules: (- (/ (+ 1 3 ;; sideways tree [-] --- [/] --- [+] -- 1 3 8 8) ;; | | `- 8 8 2) ;; | ` 2 8) ;; `- 8 by contrast, there is any satisfactory, canonical way to break up infix into multiple lines (with excellent support from editors like Emacs and Vim). Thus, Lisp expressions can be longer while remaining understandable. (Which is important because entire function definitions, for instance, are really one big expression.) There is no ambiguity in Lisp expressions. The parentheses are not optional grouping punctuators, but operators denoting operator application (analogous to the parentheses in f(x, y)). You never, ever have to grapple with "what is the precedence/associativity of this?" or "I know the precedence/associativity of this, but did the person who wrote this intend it that way?" Sufficiently long expressions are hard to read in any notation. Just like in any language, Lisp programs break down complex calculations with intermediate variables: (let ((bytes (+ 1 3 8 8)) ;; what is this term? Oh, bytes (words (/ bytes 2)) ;; why divide it by two? Ah 16 bit words (size (- words 8))) ;; Why subtract? Account for some header or special offset. ...) > Do you just get used to this What happens is that you have to get used to working with big, nested prefix expressions: because that's what functions are. A 200 line function in Lisp is a 200 line nested expression. You find that this it is perfectly manageable and you even like it. You get used to structuring code that way, and then that all applies to arithmetic expressions also, which are just more of the same thing. Given that you're able to cope with big functions made up of that sort of syntax, you are then not fazed by some five node arithmetic subexpression.
- breck 9y agoI'm a Lisper (and Pythoner) and strongly agree, the first one is not readable. I would say it's gross. It boggles my mind that Lispers haven't taken that problem seriously. I have taken it very seriously and have been working on it for years. I just started publishing my results. http://breckyunits.com/the-flaw-in-lisp.html http://breckyunits.com/the-flaw-in-lisp.html What I've discovered is that the parentheses are completely unnecessary in Lisp, and in fact cause much harm by making Lisp harder to read and maintain in the long run. Drop the parentheses in Lisp by switching to whitespace/geometry for syntactic structure and you suddenly have the dream language. Your example above would be something like: setv result - / + 1 3 88 2 8 You might think that looks a little strange too at first, but the neat thing about that code is you can write it on a piece of graph paper, draw lines around each word, connect the indented nodes, and you'd have a tree visualization of your syntax code without doing a single transformation of the source.
- anaphor 9y agoThe problem is that it requires all of your functions to have a fixed arity I think, or at least a lower bound on the arity, or you use newlines as part of the syntax. Check out this https://shriram.github.io/p4p/ https://shriram.github.io/p4p/
- breck 9y agoVery interesting link, thanks for sharing. I'm always eager to see developments in the Racket world. > The problem is that it requires all of your functions to have a fixed arity I think, or at least a lower bound on the arity, or you use newlines as part of the syntax. This was my initial thought as well. However, in my latest batch of ETNs (the name I give to these types of lisps), I've found that a simple convention of putting any variadic argument last seems to work well. An example may help. Here would be a language blueprint that defines 2 node types: =+2 description Adds two numbers pattern resultIdentifier number number =+ description A variadic adder of unknown arity pattern resultIdentifier number+ Here's a sample program in the language we partially defined above: =+2 sum 2 5 print sum # prints 7 =+ sum 1 2 4 print sum # prints 7
- 9y ago
- zeveb 9y agoI'd say that they're about equally (un)readable. What do you think of: (setf result (make-instance 'foo :bar (baz quux))) vice: result = new Foo(bar=baz(quux)) The first is simple to write a parser for, but the second is … evil.
- dragonwriter 9y agoPrefix notation is something you get used to; it's not as easy as infix for operations that use the same infix operators with the same meaning and priority in the domain (e.g., math) but real programming languages often use operators that aren't standard math operators and have precedence and/or associativity quirks with the operators they use which increase overhead. Prefix notation is basically everything-is-a-function, which I think is ultimately less overhead overall, though still more for simple math, than infix. Indentation can help, too.
- jrs95 9y agoI find it difficult to read if I just try and read it left to right, but if I simply go directly to the innermost operation its not really much more difficult for me. And I’m not a lisp user, either.
- brudgers 9y agoNeither is readable because both are filled with magic numbers. With experience the Lisp becomes more readable when formatted conventionally: (setv result (- (/ (+ 1 3 88) 2) 8)) Line breaking the Python is possible but unconventional and requires additional symbols. As expressions become more complex, languages with infix operators are faced with the choice between some form of operator precedence and strict left to right (or right to left) application. It is hard to look at: 6 * 89 & 57 >> 2**2 - 1 and see the implicit parenthesis. And maybe not having to figure out where the implicit parentheses go in complex cases is part of the attraction of Lisp syntax. Lisp code does not require going to the rule book as often.
- mythrwy 9y agoOnce you are in the parentheses line breaks in python are just fine, no additional symbols needed. result = ((( 1 + 3 + 8) / 2) * 6) works. Also works as a way to deal with long strings without the \. long_string = ('hello' 'really' ' really' ' long' ' line' )
- brudgers 9y agoLine breaks in Python are generally unconventional. For what it is worth, the PEP 8 recommendation is for the operator to begin the line (Knuth style), i.e. result = ((( 1 + 3 + 8) / 2) * 6) How much that looks like Lisp is a matter of opinion I suppose.
- cgag 9y agoI find it pretty readable.
- gkya 9y agoMaths in lisp is like learning a language with a different alphabet, it's confusing at first, then becomes natural. I myself prefer lisp's syntax especially for maths and parenthesise heavily in other languages because in you can never know how tightly they follow mathematical association rules, and that can be a source for really annoying bugs. Generally the total absence of syntactical ambiguity in lisp is really relieving (tho lots of complexity is shifted into macro expansion, which is less intriguing for me as macroes allow easy inspection whereas core language constructs not so much).
- benji-york 9y ago> you can never know how tightly they follow mathematical association rules You might be interested in the way Pony (https://www.ponylang.org/ https://www.ponylang.org/) handles mathematical order of operation rules: it doesn't. Runs of like-operator are allowed, but any complex expression has to have all the operations grouped by parentheses so as to remove any ambiguity.
- gnaritas 9y agoSmalltalk and Lisp work that way as well; operator precedence is an illogical hangover from the blackboard and chalk era; it's a needless complication that greatly simplifies both the language and understanding when removed.
- klibertp 9y agoYes! Now try telling this to some more mathematically oriented people. The opposition is so violent that I stopped trying long ago :(
- gnaritas 9y ago> mathematically oriented i.e. the blackboard indoctrinated. It's much harder to unlearn something than to learn something, you have to show them what they think is "natural" isn't, it's just what they were taught and it's based on laziness not intelligence and implicit hidden rules are bad and lead to ambiguity. Operator precedence is simply stupid. In Lisp and Smalltalk, operators are just ordinary functions and the lack of precedence makes everything simpler across the board.
- such_a_casual 9y agoPrefix notation is a problem because nothing beats the familiarity of: x = 10 But prefix notation is superior. You don't have to invent an order of operations out of thin air. All your functions take several arguments, not just 2. So + is now sum, - is difference, / quotient, > greater than order, etc. They aren't special. they're just like everything else. It'll never be as familiar, but it's smarter and makes writing code easier. For example "hello " + name + ", welcome to the " + place +"." + "hello " name ", welcome to the " place "." The reality is you want functions that work on many things, not just 2, even when you're doing math. 1 + height + x + floor-height + 1 height x floor-height infix notation does nothing to make code clearer
- kazinator 9y agoAnyway, you want string interpolation for the former example anyway: 1> (let ((name "Alice") (place "The Palace")) `Hello @name, welcome to @place!`) "Hello Alice, welcome to The Palace!" string interpolation is compatible with Lisp designs; it is self-contained and so doesn't "disturb" the surrounding syntax with issues of precedence and associativity. The above example is from TXR Lisp which has this built in. For Common Lisp, there is the cl-interpol and other packages, and other dialects have their own solutions.
- such_a_casual 9y agoAnd it's pretty trivial to roll your own.
- jlarocco 9y agoIt takes some getting used to, but eventually the Lisp style is just as readable as the non-Lisp style. For actual coding (in an editor vs reading in a browser) it's even easier with things like matching parenthesis highlight, jump to matching brace, and rainbow parenthesis mode.
- ohyes 9y agoI was never any good at math in the first place, order of operations always screwed me up, still does. Order of operations actually makes no sense at all (if you really think about it). So yeah, lisp is easier for me.
- ohyes 9y agoCompare to: 1 + 3 + 88 / 2 - 2 Or (1 + 3 + 88) / 2 - 2 Or (1 + 3 + 88) / (2 - 2) If it comes down to it, I'm going to fully parenthesize the stupid thing anything else is difficult to parse. If I'm using all the parens, prefix is fine.
- IgorPartola 9y agoSince I can't edit, I'll reply to my own comment. This is not my example, but one I pulled straight from Hy's tutorial at https://hy.readthedocs.io/en/stable/tutorial.html#basic-intro-to-lisp-for-pythonistas https://hy.readthedocs.io/en/stable/tutorial.html#basic-intr.... I don't think I could have dreamt up code like this.
- didibus 9y agoI got used to it, now I almost have the reverse problem. Having said that, sometime for math, infix operators for complex equations are easier, and its easy to write a macro in Lisp to let you do that too: (setv result (infix ((1 + 3 + 88) / 2) - 8))
- endgame 9y agoI've only written a small amount of elisp but I've found that while you don't actually do all that much arithmetic manipulation, the ease of manipulating S-Expressions outweighs the price of entry.
- asimjalis 9y agoHere is how I would write that expression in Hy. (-> 1 (+ 3) (+ 88) (/ 2) (- 8)) Here is how I would write the assignment, using my definition of def2. (defmacro def2 [value variable] `(def ~variable ~value)) (-> 1 (+ 3) (+ 88) (/ 2) (- 8) (def2 result))
- dmoney 9y agoAs a Python-lover who previously played with Common Lisp and Clojure, lispy syntax took less getting used to than having no end tags, but I'm still not used to prefix math.
- torrent-of-ions 9y agoYes, it is. I can't say anything about being "more readable" but English is presumably "more readable" than isiXhosa for you. Reading is a skill that has to be learnt and practised. You were not born with the ability to read English or infix notation, you just got used to them.
- klibertp 9y agoI have a blog post about this: http://klibert.eu/posts/tools_for_lisp_syntax.html http://klibert.eu/posts/tools_for_lisp_syntax.html (with pictures: http://klibert.eu/statics/images/lisp-editor-features1.png http://klibert.eu/statics/images/lisp-editor-features1.png). Basically, in my opinion, what makes a difference in readability is the tooling a certain kind of syntax enables. As you can see on my "Languages" page I have been trying out new languages for quite a while now, and so I've seen all levels of syntactic helpers. The syntax itself is actually a secondary concern: it's really not that important if your editor can easily generate it, manipulate it, and display while hiding parts of it for you. However, how easy it is to write such tooling for a language depends on the kind of syntax it uses. Languages with more complex grammars are generally harder to support properly in the editor. Of course, how good the tools are, depends also on a level of effort invested in making them so - so relatively complex, but popular, languages may still have better editor support. Anyway, back on topic of Lisp: yes, you get used to the prefix notation to the point that - after a long while, mind you - you're able to open a Lisp file in Notepad and still easily read it. No one does it, though, unless forced for some reason - things like: - blink the matching paren, display parens as rainbow colored - jump to matching paren - jump to inside next expression - reliably select current block of code - fix indentation automatically when copy&pasting code - split ( (..|..) -> (..)|(..) ), join, transpose, extend the current expression - convolute, which means making the nested (inner) expression the outside one all of this makes Lisp readable, and probably more readable than some other languages with much more complex grammars. Lisp is not the only language with such a "feature" - recently I found Idris to be very good in this regard, both Erlang and (even more so) Elixir are similar, some (popular) brace languages too. Then there's a thing about macros and trivial AST manipulation in Lisp, arguably enabled by the syntax being as it is. You can have pattern-based macros in any language, actually (see Nim, or Dylan), but the raw AST being identical to the code makes certain kinds of imperative macros much easier to write. Again, take a look at Nim: is has imperative macro facility, but for every piece of syntax you want to introduce you need to call a special constructor.
- a-saleh 9y agoWell, when using clojure and needed to deal with lot of math I usually used some sort of infix macro, i.e. [1]. Otherwise, I wasn't really bothered by the brackets. And most of the time I would be using some sort of threading macro anyway [2], such as -> mthomas suggested in one of the responses. [1] https://github.com/rm-hull/infix https://github.com/rm-hull/infix [2] https://clojure.org/guides/threading_macros https://clojure.org/guides/threading_macros
- pvdebbe 9y agoThe thing is that usually basic algebra like this occurs somewhat seldomly in code. The rest of the function calls are readable, this is the (only) outlier to readability.
- flavio81 9y ago> Do you just get used to this, or is it something that you have to keep struggling with? You get easily used to parenthesis and you start loving them, since the auto-indenting (on any good Lisp editor) can make you have very readable code. In fact, Common Lisp, having so much versatility in control flow operators (and, in general, a ton of handy helper functions), lets you write really readable code, and often that is the case. So highly readable, that the downside is that the common Common lisper (pun intended) feels no need to add comments in the code... As for your formula (setv result (- (/ (+ 1 3 88) 2) 8)) It can be written in a more readable way. As user "brudgers" wrote above: (- (/ (+ 1 3 88) 2) 8) ... and it gets more evident. As for "result", usually in Lisp you don't need to have such a variable since the last expression returned by a function automatically becomes the return value of the function.
- platform 9y agoprefix notation mimics of how we call functions setv result (my_function arg1, arg2) to me this is as readeable as set result= my_function( arg1, arg2) I realize that specifically arithmetic expressions in prefix notation look foreign, however I think most of the code are function calls -- and that's very normal. If I would to think of an example where LISP notation is un natural -- it would be the if-statements.
- eggy 9y agoI am a polyglot, so no, I don't find it unreadable. I would probably structure it differently. I always wonder why Lisp never ceases to get singled out for parentheses when each language uses parentheses, braces, semicolons, colons, pipes, etc... I program in C, Forth\Factor, Lisp/Scheme, Python, J, APL, F#, C#, Asm, Basic, Clojure and others. Each has their syntax and differences, and it just takes getting used to them. I like Hy, but as the documentation says it is not Lisp or Clojure, but Homoiconic Python with that guiding and constraining its implementation. A lot of fun, really. I only get as much pleasure from J for play.
- kazinator 9y ago> I always wonder why Lisp never ceases to get singled out for parentheses POSIX shell: FOO=$(basename $(dirname $(cat file))) Make: OBJS=$(foreach x,$(WHATEVER),\ $(addprefix $(call BLAH,arg),....))
- rthomas6 9y agoAs a Python user who read about 60% of SICP, yes it really is readable. The trick is to realize that in lisps open-parenthesis denotes something more than a grouping. ( means "function call", and a change in scope. So if it really was written in Python, it would look something like this: setv(result, sub(div(add(1, 2, 88), 2), 8)) Really, this is clearer what's happening under the hood than infix notation. + is a function, and so is =. Why is it called the way that it is, other than convention? It's just syntactic sugar. Doing it with prefix notation makes every function have the same syntax, which makes nesting functions easier to look at and reason about.