Yeah, having automated insertion of brackets/parenthesis is necessary to adopt, otherwise you find yourself annoyed very quickly. Once you've adopted to automatic insertion of that, it's hard to go back to language where you don't have that...
Yeah, having automated insertion of brackets/parenthesis is necessary to adopt, otherwise you find yourself annoyed very quickly. Once you've adopted to automatic insertion of that, it's hard to go back to language where you don't have that...
The following are all a single key combination in most editors that support Paredit or equivalents:
- Kill an entire loop or data structure to the right of the cursor
- Swap two deeply nested expressions to the left and right of the cursor
- Absorb ("slurp") or expel ("barf") expressions to either side of your current expression, into that expression
- Delete the entirety of the expression enclosing where your cursor is, leaving everything to the right intact but raised to the enclosing level (this one is amazingly common but you would never think to use it until someone shows it to you, after which you use it every day)
It takes a couple of days to get these and many other shortcuts into your fingers, after which it's hard to live without them. http://emacsrocks.com/e14.html is a good introduction.
Structural editing is the first thing I miss going back to Python, Ruby, JavaScript, etc. That, and, of course, instant REPL evaluation of the expression under my cursor.
that said paredit should have a statue on the moon or something
Like just the very simple test assertion in this article is not particularly easy to parse. Obviously I realize that it calls a function and asserts the return value is equal to the expected value because that’s how tests work, but it’s so much less readable than what I’m used to.
Most of us are too familiar with the infix notation. It is deeply ingrained on the subconscious level of our assumptions about programming languages. It is indeed tricky to quickly parse a snippet written in a Lips with an untrained eye.
Many software developers with prior experience in programming, at their very first encounter with a Lisp dialect, instinctively try to reject it. It looks unnatural and doesn't feel right.
In comparison - most people who never wrote a single line of code ever before, usually don't struggle with Clojure or Racket.
However, if one ignores the instinct, persists, and gives it some more time, they may find an incredible world of possibilities.
There is a way to speed up the process of adapting to reading and writing Lisp code. The trick of learning to read Lisp code efficiently, is simply refactoring code on the go. Don't try to learn a Lisp dialect by merely staring at code - in books, on web pages, etc.
Pick up an IDE or editor that supports Structural Editing. Structural Editing is a way to navigate and refactor your code without breaking parenthesis or other characters that define the structure of your code. Learn basic structural editing commands - slurp, barf, raise, transpose. And modify the code, pick up functions, and try to dissect them. With a connected REPL, Lisp allows you to evaluate any expression without any prior ceremony (a feature that most other languages don't have). You can try every single piece, break up functions into smaller ones, or compose multiple small functions into a bigger one. It doesn't take too long until you see the benefits of this approach. Sadly, for some people going back to normal life, after discovering powers of Lisp becomes like going back to drugs after detoxification.
Almost every discussion oh HN about Lisp-dialect results in at least one comment of someone claiming that they've tried writing Lisp for many years but never have "discovered" its powers or even after years it still feels "unreadable" to them. Most of the time, those comments are disingenuous. Lisp does not require anyone to have a "differently wired brain." Nobody comes into this world with the innate ability to read and understand Mandarin better than English or with the ability to be able to learn Python and Javascript but not Clojure.
Most people don't realize that very often, path to simplicity lies through the thorns of breaking existing habits. They choose an "easy" way. The "way of familiarity." And without even realizing, they usually create more work for themselves.
If everyone says you have to use a plugin to auto-insert parentheses, that means computers know where they go. So why are we writing them??
Having the parens has advantages, like everything being explicitly delimited, which makes it really unlikely that you'll insert some code that you thought was part of a block, but really wasn't (think one-armed if without braces in C-like languages). It also makes it easy to have your editor help you navigate your code. Being able to jump around expressions conveniently can really speed things up.
At least none of the solutions I've found been 100% perfect. So I much rather have the computer do as much as it can, then I correct if it gets it wrong. Collaboration with the machine is better in this case.
You write the parentheses because they have meaning. I can understand your frustration but I don't think you gave lisp a fair chance if you are asking "why parens".
> '(this is a list)
> this is a list
These don't have the same meaning. The computer can't know what meaning you want to give to the code beforehand.I'm sure once one spends enough time with it, one starts to think in Lisp, and the desire to solve the "problem" disappears. :)
There are plenty of non-paren functional and OO languages (f#, haskell, python, java) to replace functional and OO lisps depending on the itch you want to scratch. JavaScript has babel / babylon to generate a full AST to rewrite source code, though you need to either fork babylon or use sweet.js if you want your own macros.
SRFI-49[0] describes I-expressions, which can be mixed with S-expressions. I've tried it while learning Scheme, because parens didn't look good at first. My experience was that parens are an issue only until you get used to them, afterwards they're a boon.
https://srfi.schemers.org/srfi-110/srfi-110.html
They've been implemented for (at least) Racket:
I don't say this to be demeaning! I would say there are far more chances you really enjoy the language than not. Give it a try and stop worrying about the parenthesis and start thinking in terms of an AST.
(let ((x 0)) (+ x 1))
If you want Python that's fine but there is definitely no problem with parens in Lisp/Scheme :)As others have said, the best way to check it out is to get a REPL running in a decent IDE and play with the language. There’s something quite intuitive in its workflow: knowing that you want to do something, though you’re not quite sure what it is yet, and typing a single ( gives you all the power and space you need to figure it out no matter how deep inside a code block you are.
> we expect future generations of Lisp programmers to continue to reinvent Algol-style syntax for Lisp, over and over and over again, and we are equally confident that they will continue, after an initial period of infatuation, to reject it. (Perhaps this process should be regarded as a rite of passage for Lisp hackers.)
Programmers in languages like Ruby (optional parens for method calls) and Tcl (no parens for proc calls) might agree with you! Why does virtually every language require parens, when they're not needed? At least with Lisp, they serve a necessary purpose.
Another one: almost every language uses commas to separate items in a list, including function arguments. In the vast majority of cases, the commas are useless. Lisp doesn't use commas to separate elements (though Clojure allows them if that's your druthers). Why can't I say f(x y) or [3 4 5] in, say, Python? There's nothing else it could possibly mean.