People who "get" Lisp get over any aversion to the syntax, and usually even come to appreciate it. People who can't get over the syntax never actually get Lisp.
[0] For large values of nobody
People who "get" Lisp get over any aversion to the syntax, and usually even come to appreciate it. People who can't get over the syntax never actually get Lisp.
[0] For large values of nobody
There is zero Lisper on this planet that think about "Ubiquitous parentheses" as the best possible syntax. Not even the seemingly fanatics of Lisp's "regular syntax". Proof: no one in her right mind (not even you) would prefer (quote X), or even (' x) over 'x. 'x is an irregularity that makes the whole thing terser, while using up less cognitive power. In other words, it's better.
Now why stop there? You could try and remove more parentheses by using a tab syntax, or introduce a few other irregularities, or both. There's a good chance that we could come up with something better than the currently widely accepted surface syntax.
Conclusion: it's perfectly possible to get Lisp and not surrender to it's standard syntax, because it may just not be the best. Besides, I'd think twice before suggesting that David A. Wheeler don't deeply understand Lisp.
Now, knowing that the standard syntax is the only widely used one, one of course have to get over it to have a chance of understanding lisp. But if you only meant that, You hardly said anything at all¹.
[0] When you wrote "syntax", I assumed you talked about surface syntax.
[1] http://lesswrong.com/lw/jb/applause_lights/
Edit (addendum): By the way, I'm surprised this issue isn't settled yet by structure editing. With a structure editor, programmers could choose the surface syntax they like independently of the underlying S-expression tree. (Incidentally, this could apply to any language, though with more difficulties.)
In the article, Wheeler says the goal is to "provide a better notation that others can read". To quote pg: "Historically, languages designed for other people to use have been bad"[0]. I've found that to be true with most alternate syntax proposals I've read, including this one. I do not find it as readable as the original Scheme, nor is it as readable as Python.
The constraint is that the grammar of the resulting syntax has to be capable of expressing everything expressable by S-expressions, has to be unambiguous, and it has to be pretty-printable back into a canonical form. The last point itself is pretty hard to do, but if you actually look at the grammars of a lot of programming languages, very few of them aren't ambiguous!
Some quotes from a different page on the OP's site [2] suggest that even some experienced lispers can see value in conventional syntax:
> I've used Lisp my whole programming life and I still don't find prefix math expressions natural. - Paul Graham
> After 13 years of doing Lisp and 3 or 4 years of Python, I agree: I prefer writing Lisp, but Python is easier to read. - John Wiseman
Personally, I hold no aversion to the parentheses. But I can see some advantages/uses for a more conventional syntax. Also, it's a fun problem. :)
---
I've been meaning to go through it in detail, but to be honest I really like s-expressions, really really. I'd even say the regularity of syntax is one of lisp's greatest features (even Clojure's [] and {} literals are going too far for my taste...)
In my company, I came up with one myself (http://code.google.com/p/muvee-symbolic-expressions/wiki/Tab...) when some aesthetic objections arose to the use of (paren (laden (scheme))) as a scripting language for our product. It is quite telling that we ended up not using the tab syntax in the end, though it is still available in the product :D
tab-syntax version: https://gist.github.com/716416 scheme-syntax version: https://gist.github.com/716417
Other than that there have been many conventional syntaxes derived from Lisp: Logo, ML, Dylan, ...
What most of these don't have is the code as data as code as data ... support or at least it gets more difficult.
If the representation via s-expressions is not needed, other syntaxes are not that difficult to implement...
Languages, just like any other computer software, have a User Experience: the experience of programming in them. For example, the usual justification people give for why they like Ruby is that it has a good UX. There's no theoretical purity there, they just say it's "fun to code in."
Lisp, meanwhile, does not obey any of the principles of HCI that have been discovered in the last 30 years (how could it? It was invented before them!) There's a large gulf of evaluation stopping a programmer new to a Lisp codebase from understanding what their changes will do to it. UI design is about human psychology, not theoretical purity; solving this problem might seem like "papering over" the purity of the language from a theoretical perspective, but when doing actual comparative usability studies[1], it would be clear that the "papered-over" version would have something going for it that the theoretically-pure version does not.
[1] A comparative usability study on a language is very simple to perform: you basically print out some code samples, let people with no experience in the language (but general programming experience) read them for a set time period, and then evaluate their comprehension.
There is a fairly prominent Lisper who argues the exact opposite; that Lisp is the ideal language for coding before knowing what you really want to code. I'd suggest reading Paul Graham's essays on the subject as a basis for discussing this particular point before going any further.
For example, the usual justification people give for why they like Ruby is that it has a good UX. There's no theoretical purity there, they just say it's "fun to code in."
Ruby's usability is pretty nice, but it has some seriously cool theoretical ideas, too. It's a few steps beyond just putting a prettier interface on i.e. Java. It may not be the most original language, but it's popularizing a lot of things most "working programmers" haven't encountered.
A comparative usability study on a language is very simple to perform: you basically print out some code samples, let people with no experience in the language (but general programming experience) read them for a set time period, and then evaluate their comprehension.
That seems like a questionable metric for the quality of a programming language.
I don't know if you're assuming here that I don't actually use Lisp; I do, and have, for at least six years, after reading those very essays. I still find it to be write-only, but I don't think I'm communicating what I mean by that clearly.
When I say "write-only", my meaning is "requires extensive amounts of external mental state for interpretation." An unfinished painting is write-only: while you're painting, you can experiment, yes, but that's because the "random-access" bit that you're experimenting upon is not what's on the canvas, but rather what's been loaded up into your mind. If you leave off a painting for some months and then return to it, or if someone else tries to finish your painting—well, they will need to spend days staring at it to dissect the original goal of the work, the original style and methodology, before they can proceed. It is the same with Lisp: the text of a Lisp program is the canvas, while the "effective rules" of the program end up reflected mostly in the programmer's mind. To resume a Lisp program after some months is no easy task, any more so than rebuilding a filesystem index purely from its on-disk data records.
> Ruby's usability is pretty nice, but it has some seriously cool theoretical ideas, too. It's a few steps beyond just putting a prettier interface on i.e. Java. It may not be the most original language, but it's popularizing a lot of things most "working programmers" haven't encountered.
There's a large difference between "theoretical ideas" and "theoretical purity." A theoretically-pure language can be held in the mind all at once, because it only has a few key concepts. Lisp, Smalltalk, Forth, Lua or io, etc. are theoretically-pure, while, say, Perl, while containing many amazing and useful theories, is theoretically a leftover surprise. Theoretical purity is good for the usability of a language: three tools in your toolbox are better than three-dozen, if they each solve all the same problems just as efficiently. However, it seems like, the more theoretically-pure a language becomes, the less concerned its practitioners become with actually evaluating or developing the UX of the language. This is, I think, why Go is being mostly rejected by working programmers, for example: C, as much as it doesn't seem like it, is a theoretically-pure language (as in assembler, it's all just memory addresses which either hold values or other memory addresses), and Go is purely a UX enhancement over it—but the systems programmers are so used to C-like syntax for their systems programming that they won't stop to consider alternatives that enhance long-term usability (such as, say, slices.)
> That seems like a questionable metric for the quality of a programming language.
Well, I did say "basically." :) Think of the sort of "reading comprehension" test you might have had to do in elementary school. To be scientific, you have to control for the subjects' exposure to different linguistic paradigms, the content of each code-snippet, etc. In fact, it would likely be easiest to test with two entirely made-up languages, each of which differ by only one syntactic element X, and see how comprehension varies on X. But I digress: it was just an example off the top of my head, because there are currently no metrics for programming language quality whatsoever, and any metric, no matter how bad, is better than none. If you have a better idea, then we should use that better idea, but what we shouldn't do is pretend the usefulness of a programming language[1] is completely subjective, and that they can't be compared.
[1] I do not use "programming language" to mean "platform" or "standard library" here; merely the mapping from syntax to semantics. LISP-style Lisp is the degenerate-case of a programming language, with a one-to-one mapping from its syntax to the compiler's AST structure.
It appears to me that you do not have very much practical experience writing code in lisp. You are understanding the 'code is data' statement in completely the wrong way.
I store and treat my 'data' in exactly the same way that anyone would in perl or python or ruby. I don't think I've ever had a problem distinguishing code from data, when I had the desire. (I keep it in config files, or data files, or in variables).
Code is data, to me, means that I can take some data, and transform it into code. Code is a description of how the world is, at some level, and so is data.
(For example, I could take a description of the hierarchy of a website's rest service, and write a function to transform it into a series of functions that do the proper requests, in the proper formats, with the proper parsers).
How can you argue that lisp does not obey any principles of HCI simply because HCI wasn't invented when Lisp was? It doesn't make sense as an argument. If I don't have a name for something, does it not exist? Gravity didn't exist until Newton described it?
What HCI principles does lisp violate? (I find the idea of HCI principles dubious. Isn't good HCI 'whatever scores well in usability tests').
Lisp is not theoretically pure. It is theoretically empty. It makes no assumptions about what the 'proper use' of it is. The whole point of abstraction, to a programmer, is to 'paper over' the actual language and make the program a description of itself. Lisp is amazing at abstraction. (By amazing I mean the unqualified very best).
----
As an addendum. Your comparative usability study[1] is horribly flawed, because you assume programming experience. You should assume no programming experience. The majority of programmers have experience in an Algol derived language. This introduces a huge bias into any study that you would decide to do. Anything that looks and acts like Algol will be easily deciphered, anything else will not be.
That is just one axis of usability, optimizing for comprehension by someone unfamiliar with the language. Usability is also optimizing for the experienced programmer. Some designs do a good job for both, some work well for one at the expense of the other.
Hef Raskin had some interesting things to say about this:
(Btw, it's Jef Raskin.)
Intuitiveness is indeed highly correlated to previous human experience. But aside from pre-existing interfaces, an interface designer has available the whole of an average person's real world experience - the mouse is intuitive because it mimics a person's experience of moving a physical object - it doesn't mimic exactly but closely enough that a person can use their existing experience to extrapolate. And an interface designer who wanted to improve a standard interface may be able to find a different facet of human experience analogous to the task at hand and thus (contrary to the link) it is possible to create interfaces which are new and intuitive (but I'll admit it's damn hard and you should have a reason).
Most computer languages leverage human experience with natural language - not exactly, but partly. That's why Ruby's "return 5 if done" syntax seems really nice. Thus I'd argue you can make a reasonable study of what constitutes an intuitive interface.
So I claim the intuitiveness of Lisp's parentheses is a valid question for debate.
I like Lisp because it is wholly unambiguous in visual syntax. That is not something I find in languages such as Perl, Python, Ruby, C++, Haskell, or C. I do find unambiguity in assembly as well.
I've also found that the general idea of "build your own Lisp" as a reason for lack of comprehension is specious when stacked up against the Java or .NET frameworks. You have to know the framework calls to understand what's going on. The same applies for C++ template metaprogramming.
I don't consider that a criticism; I consider that an acknowledgement of the ability of programming languages to provide abstraction.
I am a working programmer, and I like Lisp.
That's just stupid. If the programmer doesn't understand English and the program is written with English identifiers, does that fail the test? What about APL and Perl?
"Because the people who "get" Lisp are almost always theoreticians who know what they want to code before they code it."
And you seem to be a theoretician who has never had to maintain any Lisp code.
It's called a comparative usability study. The same person looks at the same code sample written in two different languages, A and B (in random order), given time T to absorb each one (where T is much less than the time it would actually take to fully absorb the code), and then the references are removed and they are given tests on the properties of sample_A and sample_B (again in random order.) The score is not a measure of either A or B individually, but rather the ratio A:B, derived by the ratio of correct questions in sample_A:sample_B. A:B is then handed to a Bayesian neural network as a confidence score.
Thus, if the test-taker doesn't know English, they get the same (low) score on both tests—to the BNN, that is the same as "no new evidence."
Also, you wouldn't be comparing, say, Java to APL. You'd be comparing Java to Java + "an unless statement", or APL to APL + "enforced whitespace." You want to see the relative worth of language features, not the relative worth of our current languages, which have mostly been slapped together with no concern for UX. The result of such a study would be a set of UX suggestions, of language features that comparatively increase, or comparatively decrease comprehension.
> And you seem to be a theoretician who has never had to maintain any Lisp code.
For the last eight months, I've been writing Clojure for a living. I've written quite a bit of CL before that. I still find it harder to come back to any Lisp project after a month or two than to come back to code in any other language.
This is still meaningless if you're testing it on someone who doesn't know APL. Having an "unless" statement in your example is exactly like testing for English comprehension. This technique would make sense if you're testing proposed design choices for changes to APL on APL programmers (here's 60 seconds to read this program; what do you think it means?), it would make sense if you have equivalent programs in different languages being tested on users of those languages ("users of Perl understood program X 10% better than users of APL given 60 seconds to examine it"), but it is meaningless in the context you provide.
> Thus, if the test-taker doesn't know English, they get the same (low) score on both tests—to the BNN, that is the same as "no new evidence."
So, of course, you wouldn't test APL vs. APL+whitespace on someone who doesn't know APL, because your test results would always, predictably, be 1:1. But you wouldn't be testing APL vs. anything—because APL is a set of design choices that have already been made, and anyone who knows APL would already have taken the time to absorb those design choices. It would be most scientifically rigorous, as I said, to start with a made-up programming language (a random combination of language features that has no overarching design principle which users could recognize to reduce cognitive load), teach it to the users, and then do the tests on that language, vs. that language w/ modifications.
Compare J, Q, and Dyalog. Three modern APL dialects, very different in feel.
You might protest that J or Q aren't APLs (they only use ASCII! Q has ragged arrays!), but that's like arguing Scheme isn't a Lisp.
Thank you for walking right into my trap.
The reason I like to use APL in arguments about programming language syntax/semantics is that it's "unusual" compared to Algol-derived languages in more than just the syntax.
Matlab/Octave are also array programming languages that in fact are very similar to APL despite having a C-like syntax. It does not make it any easier for people to figure out what Matlab programs do if they don't understand array programming. (And if you don't know linear algebra, then in practice you can't understand most typical Matlab programs at all).
You're implicitly assuming that all programming languages have similar imperative/algorithmic interpretations and differ by syntax. This is a result of a very fundamental epistemological error.
There is no such thing as "programming" that people understand. All programming languages are related to (derived from, or applied to) other domains of knowledge.
If you ignore this fact all the conclusions that you will come to will either apply only to your implicitly assumed domain (which may not fit any problems that people actually want to solve) or will be incoherent.
Your assertion is false that it's easy to perform a usability test on a subject familiar with programming concepts but not exposed to syntax. It is not easy to learn programming without exposure to any language, so finding subjects for such a test would be difficult.
Most languages that have syntactic structures descended from Algol do all look the same so of course they are easier for someone with experience of one language in the family to understand than something else from a completely different heritage.
I did a lot of programming in Common Lisp, so Scheme looks fairly sensible. Similarly I did a fair bit in PostScript - so I can sort of work out what is going on with Forth and other RPN languages.
As for understanding large codebases in Lisp written by other people - a good Common Lisp environment (we used LispWorks) is about the best tool to dig around in other peoples code (largely because of the excellent REPL).
To the people downvoting, that is not what downvoting is for.
I've been a "working programmer" who happens to write Common Lisp for a few years. Common Lisp is a programming language like any other: people who write good code in other languages can write good code in Common Lisp, and people who write bad code can make everyone's life just as miserable. Most time spent figuring out a new code base isn't the style or set of features used, it's figuring out the domain-specific logic. Macros aren't abused to any greater extent than C++'s operator<<, monkeypatching, or preprocessors.
I am of the opinion that anyone who calls Common Lisp a "theoretically-pure" language has not done anything but a simple recursion exercise: features like loop's inability to detect sequence type, the difference between progn and prog1 in terms of multiple values, having functions like rplaca or caar, and mixing &optional with &key are not what I think of when I think elegant or "theoretically-pure". They're there because the designers were sometimes wrong and sometimes doing the best with what they had.
We're not talking about the extremes, here, though; we're talking about completely average code, written by completely average programmers, and the comparative number of extra milliseconds it takes these programmers to comprehend, or recall, the correct syntax in one language vs. another.
Milliseconds matter; when Google shaves milliseconds off their page load times, they earn millions of dollars. This isn't because every user is slightly better off, but because some discrete number of users switched from "eh, this is taking too long, I'm outta here" to "alright, I'll put up with that." People get fed up with programming languages all the time, but no one bothers to find a formal reason for it. Has anyone ever done an eye-tracking study on people programming?
> I am of the opinion that anyone who calls Common Lisp a "theoretically-pure" language
No one's doing that. "Lisp" as a general term does not mean "Common Lisp"; it refers to the feature intersection of all popularly-implemented Lisps—the "Lisp" that Greenspun's rule refers to getting implemented everywhere. That "Lisp" is very pure.
So tired of hearing this from Lisp zealots. There are actually many intelligent people that understand lisp but don't think the plusses of the syntax outweigh the minuses.
I think there probably is not. As you point out, there are many solid language choices that do not have Lispy syntax and a lot of very smart people being very productive with them. If the syntax bothers a person enough, this alternate syntax probably won't help.
As someone with an interest in programming languages I do feel I have reasonable grasp on Lisp's s-expressions, but I dislike the parentheses syntax. However I don't think an alternate syntax would help me, most Lisp would still be parenthesis Lisp...
I think most of people like me instead flock to functional languages like Haskell. As I mentioned in an earlier Haskell discussion I think Lisp's macros are probably more powerful (in the sense that they can express more then Haskell code), but like a lot of Haskell coders I just don't agree with the Lispers that this (slight?) increase in expressibility is worth the loss of readable Haskell syntax.
I think the uniformity of Lisp syntax makes it hard to scan and find the various parts I'm interested in. Especially the quote operators can be nefariously easy to gloss over...
With regard to Haskell the original post eloquently sum up most of my problems with it (and then so more).
edit: Haha, I thought this thread was attached to the "Lisk" topic (Lisp syntax for Haskell) that's what I meant with "original post" above.
Or, for those who cannot draw the correlation: "Well, all true Lispers like parentheses."
Never mind that pure functional programming is an ideal that even Lisp does not live up to. Think I'm throwing B.S. around? Try doing I/O in Lisp without side-effects.
Now that we've established that Lisp is not at the top of the blub-curve, maybe we can get on with: 1. Writing functional languages people actually use. 2. Advancing the state-of-the-art in programming languages from being mired in a single-threaded monolithic server past.
With respect to my second point, much progress has been made; but it is still underpinned by single-threaded programming language design. What we need is someone who truly groks multiprocessor, multi-threaded, heterogeneous run-time environments; and from that knowledge can write a language to take advantage of such an environment.
It certainly isn't!
nor am I convinced that side-effects are an ideal to attain
I assume you mean avoiding side-effects? I tend to agree. The style I favor is pretty free-wheeling with side-effects in small scopes (within a function or something smaller) and gets progressively more disciplined as the composed pieces get larger and larger. I find programming this way strikes a nice balance between the two styles (imperative and functional). It lets one write most algorithms in a straightforward, efficient way while providing much of the advantages of strictness. To sum up: side-effects within black boxes, side-effect-freeness outside them, and a lot of small, atomic, composable black boxes. This is a natural way to use Common Lisp. (Especially if you avoid CLOS like I do.)
I tend to make sure that side-effects are limited to some "block" of code (function/class/module/whatever).
I just don't see the problem with syntax much anymore - Python syntax bugs me - a language's usability for the practitioner of the language works around the axis of semantics and maintainability far more than syntax. Obviously J, APL, and egregarious abuses of Perl are examples of syntactical issues, but, as was once said, one can write COBOL in any language....
I'd rather go with the powerful semantics and boring syntax of Lisp. I like this image- http://img264.imageshack.us/img264/1397/lispnd7.png.
Please Google: Starlisp, Paralations, NESL, Multilisp, Qlisp, Actors (ACT 1, ABCL), Termite, Kali
There have been only two (tuplespaces and STM) parallel programming paradigms that have not been pioneered by people who can be considered "Lispers."