I'm not even criticizing, most of these are hobby projects and you can code how you like. I just think it's funny how hard Lisp clings onto the parenthesis thing while claiming the parenthesis thing doesn't matter.
I'm not even criticizing, most of these are hobby projects and you can code how you like. I just think it's funny how hard Lisp clings onto the parenthesis thing while claiming the parenthesis thing doesn't matter.
This enables a bunch of stuff: code can be relatively easily treated as data. It allows easy code generation, transformations (-> macros), traversal (-> interpreters/compilers) or editing.
The parentheses are just a part of the s-expression textual syntax. The s-expressions then are used by basic operations like READ, MACROEXPAND, PRINT and EVAL. Additionally many of the primitive data functions can be used to manipulate code: first/rest, list, append, reverse, map, ...
S-expressions in memory are a really really good idea and chronically underused in modern programming languages.
The parentheses are irrelevant to the core ideas of lisp. You can make a lisp using C-like braces and infix notation - what makes a lisp is the representation of the program in memory as a tree and the operations you can perform on that representation.
All the interesting macro expansion in lisp is performed after parsing, unlike in the C preprocessor, so you can write your programs using Egyptian hieroglyphics for all lisp cares.
That was thought around 1960. Lisp had m-expressions in books. The actual Lisp system used s-expressions. The next few decades were often spend trying to get rid of s-expressions on the surface. Most of these attempts failed. If they succeeded they were something different. Like ML. One can think of the early ML as a kind of typed Lisp with a different syntax.
What Lisp made attractive was the similarity between internal and external representation. The Lisp system was internally manipulating programs as s-expressions - that was easier to understand when the external representation is similar.
> The parentheses are irrelevant to the core ideas of lisp.
S-expressions are an actual core idea of Lisp, while you focus on a minor aspect of s-expressions-> that s-expressions use parentheses to denote cons cells and lists.
Since the Lisp uses a certain data representation internally, it is much easier to use a simple textual format for that data externally too - one which makes the mental transformation easy. Using a complex and unrelated syntax does not make that easier, it makes it actually harder.
> All the interesting macro expansion in lisp is performed after parsing, unlike in the C preprocessor, so you can write your programs using Egyptian hieroglyphics for all lisp cares.
Actually that's not true: that's one of the ideas of Lisp and large programming system have been built around this. A Lisp system will expose its inner working to the programmer. Live and interactive systems are not an exception, they are the default.
If you are a JS programmer or God-forbid a C++ programmer, you are already living in a world where the transformation from lexical syntax to AST is dozens or hundreds of pages with weird edge cases (e.g. JS semicolon insertion or C++ most vexing parse). If that can be reduced to 1 or 2 pages it's still a massive improvement from their perspective even if it looks like a downgrade to a hardcore lisper who eats parentheses for breakfast, lunch and dinner.
Lisp programmers's don't 'like parentheses' - parentheses is not what makes Lisp.
Lisp was designed to do programming with s-expressions (aka nested lists). That's its core original purpose. Lisp even means 'List Processor'. It was then early detected that this can be applied to Lisp itself, for example by interpreting s-expressions as Lisp programs.
'Parentheses' are just a part of the notation. If you take away the feature of s-expressions on the surface and thus also the notation, you are no longer programming on the surface in classic Lisp. You can always use alternative notations, but that will take away the seamless symbolic programming.
> failure in the sense that they have prevented lisp's cool semantics from reaching a broader audience
'parentheses' did not prevent that.
Over decades lots of original Lisp stuff was moved to other languages (garbage collection, image-based programming, functional programming, macros, etc.).
There are lots of languages which are somewhat re-invented or re-designed Lisps: Logo, Dylan, Julia, Ruby, ... One can already use those.
Lisp should drop s-expression-based syntax, so that C++ or JavaScript become different internally? This makes no sense.
> If you are a JS programmer or God-forbid a C++ programmer, you are already living in a world where the transformation from lexical syntax to AST is dozens or hundreds of pages with weird edge cases (e.g. JS semicolon insertion or C++ most vexing parse). If that can be reduced to 1 or 2 pages it's still a massive improvement from their perspective even if it looks like a downgrade to a hardcore lisper who eats parentheses for breakfast, lunch and dinner.
Complain to those. Not to a Lisp programmer.
All the beautiful aspects of lisp make it decidedly unwieldy in production software. There’s a tendency of projects written in lisps to be unwritten in lisps as they mature.
In a Lisp system, the code is always there and not just in textual forms.
> All the beautiful aspects of lisp make it decidedly unwieldy in production software. There’s a tendency of projects written in lisps to be unwritten in lisps as they mature.
There are two main factors which lead to Lisp software being rewritten:
1) deployment. In the early days it was the lack of resources (memory, speed, ...), but there are other factors like having a robust runtime or the ability to integrate in larger software around it.
2) familiarity. There are not many people available to maintain Lisp software. Not because the syntax is strange, but because the whole language is strange. There are no major other programming languages which work like Lisp, so few people can productively program in it. There are exceptions to it, like the simple Lisp used in AutoCAD and related software. These have millions of installations and the complexity on the Lisp side is not that huge - there it's mostly used as a simple interactive programming language.
What makes Lisp actually difficult for programmers is not the syntax, but the pervasive use of code as data, code transformations, various ways of meta-programming, etc. It's the features it was developed for: computing with symbolic expressions - here even applied to itself.
The language Lisp was built to compute with symbolic expressions, then the idea that a Lisp program is itself a symbolic expression is tempting... this then leads to center programming activities around this idea.
If a piece of code is read more often than it's interpreted, written, and compiled, it's probably example code.
There's quite a lot of big systems written in Lisp. Unfortunately they rarely ever were opensourced, and we get to have blinders made out of our own limited experiences and common generational knowledge loss in IT.
Of course it matters; it just doesn't matter in the sense of not being a problem.
Your argumentation is rooted in drifting across different semantics of the phrase "doesn't matter".
And it's very different from other Lisps in the sense it's trying hard to be an ecosystem for language-oriented programming, which is probably taking the idea of macros to a new level.
I've used Common Lisp and Clojure for many years, but Racket looks more and more appealing to me.
this is actually a problem in my eyes and will prevent it from gaining industrial traction. for example, this keeps the main developers as a revolving door of graduate students writing code and the core maintainers as full professors who have priorities different from industrial users. secondly, the culture of racket is as a research language. they just replaced the runtime (loads of risks for industrial users), and now they are replacing the syntax. this does not create an environment enticing to industrial users. the racket team feels these changes will increase its user base, but i believe if that ever happens, these changes are deferring such an increase well into the future.
The lack of syntax matters in the sense that once you don't have any you realise that it just gets in the way. Having lots of parentheses is a small price to pay for powerful tools so that's why "it doesn't matter". Non-lispers generally don't understand how lisp is different from their language of choice and therefore don't understand why the lack of syntax is an advantage.
of s-expressions. Lisp has an additional layer of syntax on top of s-expressions.
For example the DEFINE-CONDITION operator has this syntax:
define-condition name (parent-type*) ({slot-spec}*) option* => name
slot-spec::= slot-name | (slot-name slot-option)
slot-option::= [[{:reader symbol}* |
{:writer function-name}* |
{:accessor symbol}* |
{:allocation allocation-type} |
{:initarg symbol}* |
{:initform form} |
{:type type-specifier} ]]
option::= [[(:default-initargs . initarg-list) |
(:documentation string) |
(:report report-name) ]]
function-name::= {symbol | (setf symbol)}
allocation-type::= :instance | :class
report-name::= string | symbol | lambda expression
with even more syntax for things like lambda expressions and type specifiers.I just feel that when someone says that Lisp does not have syntax or that syntax is not important, it's plain wrong...
I completely agree. I just feel that not every programming language needs to have the same approach to syntax. Lisp is different from most languages in its way to have a data syntax in which programs are written. Thus the data syntax is textual (s-expressions) and the program syntax is structural (based on data structures like lists, symbols, numbers, ..).
Every function and macro description in the HyperSpec has a "Syntax:" synopsis right at the top.
Section 2 of the standard is "Syntax".
I think an interesting synthesis is Haskell, where function calls are simply juxtaposition. Parenthesis are just grouping like most languages, but it ends up feeling quite Lispy.
You might want to rethink that hurried statement just a tad:
// C
for ((i = 0; i < MAX; i++)) {...}
printf(("hello, %", name));
#if defined ((__GNUC__))
# Shell
var=$((cat /etc/motd))
# Pascal
type color_type = ((Red, Green, Blue));But if you want to be technical, most of your examples would not be considered expressions in the given language.
int j = i = 0; i < MAX; i++; /* ? I think not. */
But sure, many languages also use parenthesis for things besides general expressions. Ultimately this argument is anti-productive nitpicking.So that's a piece of cognitive load that you have to carry to know when the parentheses are on an expression, and do not change the meaning if compounded, versus when they are around something else where they may not be removed or compounded.
In Lisp, everything is an expression, and no there is no willy-nilly removal of nesting or compounding of nesting. That's less to remember.
Even fragments of forms are expressions, according to ANSI CL glossary terminology. If we have (let ((a b)) ...) then a, b, (a b), ((a b)) and let are all expressions. With the exception of b, what they are not is forms: expressions presented for evaluation.
> Ultimately this argument is anti-productive nitpicking.
Who started it?
WTH? You, by nitpicking a general statement meant to connect two perspectives and maybe allow some synthesis between two starkly divided worlds.
I've had the Lisp kool-aid. I agree it makes for a great time. I can do without the proselytizing blast.
FWIW "in Lisp [parenthesis] also mean another level of application" is also technically incorrect (nesting is not always application), but I think it gets the actual point across better than being more abstract.
The advantage of the regularity isn't its human readability, but its ability to macro, no?
What I'd like to see is better tools for reading and editing such a regular syntax. Probably I should just learn emacs, but I'm thinking someone could make a more intuitive structured editor for LISP syntax. No need to mush around blobs of text when everything is nested lists.
This.
You can write macros for less regular languages, but there's always additional friction involved. At some point, it comes down to whether you think LISP is a "programmable programming language."
If you do, macros are a core part of the paradigm, and s-exprs make macros easy to work with.
No ambiguity; no brain cycles required to work out what element is a child or sibling of what element. Great editing ergonomics.
> If you already love s-expressions then lisp-flavored languages will make it nicer when you need to build on existing platforms. In case the target language does not support advanced features like macros and REPL-driven development, these can often be easily added by using the s-expressions layer.
To the comment about "parenthesis-laden syntax", I find that, if I actually count the characters, my Java code tends to have just as many parens as my Clojure code. I suspect that there's just a tendency, if all you've ever known is algol-style syntax, to hyper-fixate on lparens that appear to the left of the function name. I think maybe the only programmers who get to criticize others for overuse of parenthesis are Forth, ML, and Haskell programmers.
))))))))))
that ends some lispy code. }
})
]}
}])
}
}
}
}> Syntax, interestingly, complects meaning and order often in a very unidirectional way. Professor Sussman made the great point about data versus syntax, and it's super true. I don't care how many you really love the syntax of your favorite language. It's inferior to data in every way.
Rich Hickey