Lisp has too many parentheses...
symbo1ics.com
symbo1ics.com
Also, you don't need to invent backcronyms for CAR/CDR, they're now called first/rest.
Having said that, I really like the presentation of your blog, nice typography. And after skimming your book[1] in progress, and noting your obvious theoretical bent and taste for rigor, I can only anticipate to read more of your future posts (latch on to something "obscure" like ACL2 and make something fun with it.)
[1] http://symbo1ics.com/blog/?page_id=77
[Edit:
The book has code samples in 4 different languages; LISP (the ancient cap-cased "one"), ML, C, and what looks like Pascal. If you want to learn about the axiomatic specification of computer programs, specially for "structured" programming, then look into the works of Gries and others, specially in the silver "Texts and Monographs In Computer Science" books (the entire series is a feast of delight that should be devoured, and washed down with heirloom, stolen wine):
The Science of Programming, Gries.
The Design of Well-Structured and Correct Programs, Alagic and Arbib.
The selection Programming Methodology edited by Gries has various approaches to the structured method, with contributions from Dijkstra, Hoare, Wirth, Reynolds and other rock-stars of axiomatic semantics and verification.]
I, too, am looking forward to more posts; it's worth checking out the posts that are up already. Definitely my kind of thing (see my http://copperthoughts.com/p/set-theory-and-lisp/).
This is where I'll refer people who know nothing about Lisp when they complain about it; not too self-righteous, pleasantly informative, and theoretically interesting.
Actually, now that I think about it, "fire" is much cooler sounding than "cadr". But not as cool sounding as cadadr.
(def coll [[1 2 3]
[4 5 6]
[7 8 9]])
(second (second coll)) ; => 5
And often when I'm digging deep inside a nested data structure, I don't need just one piece of data, so destructuring comes in handy: (let [[[top-left]
[_ middle]
[_ _ bottom-right]] coll]
[top-left middle bottom-right]) ; => [1 5 9](I prefer pattern matching / destructuring-bind, though.)
In Clojure it's usually more idiomatic to use destructuring, which I think is much more understandable since the form follows the structure that is being accessed.
Or you can use get-in, which takes a sequence of keys to dig into a deep associative data structure. It doesn't work with sequences, but building highly nested seqs is rather uncommon in Clojure.
http://groups.google.com/group/clojure/browse_frm/thread/11a...
http://img264.imageshack.us/img264/1397/lispnd7.png
In practice, I don't find it has many more parens or angle-brackets than, say, C++ or Java. Considering (), {}, and <> in those two languages, I'd bet Lisp wins.
BTW, while Halstead metric predict various things about imperative languages like Algol/PL/1/C/C++/Java quite well, it fails when applied to Haskell: http://www.cs.stir.ac.uk/~kjt/techreps/pdf/TR141.pdf
And fail spectacularly - they have to introduce special "invisible apply" operator to make Haskell to be closer to imperative languages, just to do not look like they are cheating.
This is attributed to juxtaposition as application (as it reduces number of lexems) and to definition of functions by pattern matching. I think other languages with those two features would have same effect over predictive force of Halstead metric.
It hides the parentheses, and emacs by default will indent your lisp correctly. Just like the real thing (except you can't edit while in UnParenMode...minor issue).
I do enjoy the irony in commenting with "can we get rid of the paretheses" on a post explaining why the parentheses are not important. When you truly understand lisp, you will no longer see the parentheses. They aren't real.
In my experience, that's easily 2/3 of the web and half of all email and IM clients. It was so bad that I was surprised when it didn't fail somehow.
Pastebin is just the kind of workaround I would hate to be consigned to. Reading offline or printing becomes a huge headache because important details are constantly missing.
Mandating whitespace complicates the situation, and for what benifit? You're the one proposing a dramatic change, show some dramatic evidence to back up your proposition.
What did you not understand by "let's not do this?"
> We can get rid of (or make optional) a lot of parentheses by making indentation significant. That's how programmers read code anyway: when indentation says one thing and delimiters say another, we go by the indentation. Treating indentation as significant would eliminate this common source of bugs as well as making programs shorter.
Because the Lisps have such a canonical way to indent them, in practise it feels very similar to significant whitespace with a funny input method.
You and Understanding are not exactly on speaking terms, are you?
You can play around with significant whitespace all you like, but you have lost the simple representation of a list. How many hideous grammar hacks will you add to get this back?
I think it's a terrible idea, but there you go.
"Dorsal" means "top", like where the dorsal fin on a fish is.
http://www.google.com/search?sourceid=chrome&ie=UTF-8...e.g. "of, pertaining to, or situated at the back, or dorsum."
Seems fish are the oddball, in a way. Their top is basically their back.
Wikipedia has a wall of text by way of explanation:
http://en.wikipedia.org/wiki/Anatomical_terms_of_location#Wh...
I'm pretty near sighted, so I always have to squint to figure out if something is a brace or a paren. I think it is one of the main reasons I like lisp...
There are no braces, and all I have to do is make sure that emacs indents everything properly (ctrl+alt+q at top of form... in my head I call it 'regrinding') so I know that the forms I've written have the closing parens in the proper places.
I know people complain about the parens, but I spend literally no time fudging with the formatting of my lisp code.. emacs just does it. Java and C code, however I always end up fiddling with (even with an 'advanced' IDE like eclipse).
Argument: "Lisp has too many parentheses. It's unreadable."
Response: "It's conceptually elegant that everything is parentheses."
This doesn't address the real point -- you can't read it well. You do get advantages for macros and symbolic processing. But the cost in readability is still there.
Here's a DSL I'm working on for CouchDB:
(defmapping post
:pre-commit timestamp
:fields {:author-id :string
:title :string
:created :date-time
:modified :date-time
:body :string
:tags [:string]
:meta {:copyright :string
:href :string}})
I wish my work in other languages had this kind of structural clarity all the time!In constrast my favorite Python lib for CouchDB work looks like this:
creators = ListField(DictField(Mapping.build(
name = DictField(Mapping.build(
name_authority = TextField(),
name_authority_id = IntegerField(),
display_string = TextField()
)),
user_id = IntegerField(),
roles = ListField(TextField()),
attrs = ListField(TextField()),
xts = ListField(TextField()),
)))
Just look at all those parens!I mean, all you're doing in your list example is creating dictionary and list examples of the mapping you want. There is literally nothing stopping you from doing that in Python.
creators = [{"name" :{"name_authority" :TextField,
"name_authority_id" :IntegerField,
"display_string" :TextField},
"user_id" :IntegerField,
"roles" :[TextField],
"attrs" :[TextField],
"xts" :[TextField]}]
Yes you could do something like this. But the lack of keywords does reintroduces some noise via the quotes around strings. Moving the colons around like this to give visual alignment would probably be frowned upon. So my sense is that this would be considered "un-Pythonic" but I could be wrong. creators = [
{
"name": {
"name_authority": TextField,
"name_authority_id": IntegerField,
"display_string": TextField
},
"user_id" :IntegerField,
"roles": [TextField],
"attrs": [TextField],
"xts": [TextField]
}
]
anywayLisp (the concept) isn't a language at all, as far as we use the term to describe something that humans can use to communicate information serially. Lisp is actually a model for representing a transformation of an AST as an AST—no more, and no less. To communicate a Lisp transformation model, we must encode it as a stream of characters—and that stream, if we don't do anything to make it readable, becomes the "degenerate case" of programming languages: pure S-expression syntax.
However, there's no need for Lisp and S-expressions to go hand-in-hand. For decades we've known that programming languages have UX considerations every bit as important as those of the programs made with them. Lisp precedes that realization, but even when Lisp was first invented, S-expressions were never intended to be its primary encoding (search "M-expressions".) It just turned out that Lisp was such a powerful model that it was immediately put to use before a nicer syntax could be wrapped around it. (Also, its core user-base were mathematicians, who already had the isomorphic Lambda-calculus notation to think in terms of, so the learning curve wasn't evident to them.)
The point I'm getting at, here, is that any programming language syntax can have Lisp-transformation-model semantics. As long as `read` and `eval` are separate functions of your compiler+runtime, and the AST that normally travels between the two can be manipulated by your own code, you have a Lisp.
That's what people mean when they say that "the parentheses don't matter."
By "you", don't you mean you?
Seriously, the average nesting depth of a C program is maybe 3-4 (function, conditional, loop, etc), and C programs are simple. More complex languages like Java and C++ will easily have 4-7 levels of nesting on average. Clojure and Arc code are probably right on par with that.
http://stackoverflow.com/questions/105852/conditional-loggin...
Indeed, I suspect that the cyclomatic complexity of an average lisp function will be less than that of, say, the average Python function. It'd be the same with any functional language; they encourage you to only have one or two conditionals per function.
It took me a long time to get used to this in functional programming, and I got annoyed with how deeply nested my code got. Then I learned that it was just the language telling me to decompose my functions! :-)
> For simplicity, let’s use the notation
Yes, let's! Except in lisp, you can't. ;)
(Yes, feeling snarky.)
defun diff(expr, x){
if(expr == x) 1
else if(car(expr) == 'plus') ['plus', diff(cadr(expr), x), caddr(expr), x]
else if(car(expr) == 'times')[
'plus',
['times', cadr(expr), diff(caddr(expr), x)],
['times', diff(cadr(expr), x), caddr(expr)]
]else 0
}But would your example code still be considered lisp?
*Except also that Haskell is typed and does not include code quoting/eval. But that's what Template Haskell is for :)
http://groups.google.com/group/comp.lang.lisp/msg/7700fb02a2...