Parenthesis Inference

111 views
Skip to first unread message

Martin Coxall

unread,
Dec 18, 2009, 2:07:43 PM12/18/09
to clo...@googlegroups.com
I had this thought at work, when I should have been working, so please bear with me if it's nonsense.

One of the things that always puts people off of Lisp, as we all know, are the parentheses. Now, many ways have been suggested of doing this in other Lisps, but have never taken off, mainly due to inertia and a fear of sacrificing homoiconicity.

However, I love Clojure, and want to see it really take off. And so I want to see all barriers to that removed. Also, I think the language is young enough that seemingly-but-not-really radical proposals can still be sneaked in.

Let's take this example, since I note that Rich Hickey weighed in in the comments:

http://www.innoq.com/blog/st/2009/12/clojurelisp_readability.html

(apply merge-with +
(pmap count-lines
(partition-all *batch-size*
(line-seq (reader filename)))))

This little snippet has ten parentheses. And is potentially very unnerving to a non-lisper. Ten parentheses in four lines seems a lot to most programmers.

Rich, in the comments, suggests a pipelined style to make the code more readable:

(->> (line-seq (reader filename))
(partition-all *batch-size*)
(pmap count-lines)
(apply merge-with +))


I accept that this is more readable because it has less nesting. But it now has *12* parentheses, more than the original, potentially just as alarming to the Lispophobes.

My question is this: why can't we introduce a simple and importantly, optional 'off-side rule' (much simpler than Haskell's) that allows the reader to infer many of the parentheses?

A very simple offside rule could turn the original into:

apply merge-with +
pmap count-lines
partition-all *batch-size*
line-seq (reader filename)


With a startling two parentheses and Rich's corrected version into:

->>
line-seq (reader filename)
partition-all *batch-size*
pmap count-lines
apply merge-with +


Also with two. That last example in particular looks splendidly readable. Almost... monadic.

The parenthesis inference here is very simple, and could be stated in two sentences:

For each line that is not within a vector, and does not have an opening parenthesis, infer an opening parenthesis at the start of the line. Remember the level of indentation, and infer a closing parenthesis at the end of the line *before* the next line whose indentation is the same as or less than the remembered one.

My question is: why would such a scheme work/not work, and why would/would not it be desirable?

Martin

Mark Engelberg

unread,
Dec 18, 2009, 7:29:46 PM12/18/09
to clo...@googlegroups.com
The main downside of such an approach is that if you copy and paste
your code to a new context in which it has a different level of
indenting, it's very easy to screw things up. You then have no way to
re-indent the code without fully analyzing and understanding the
*semantics* of the code, because the only syntactic cues (the
whitespace) is now invalid and can't be trusted.

Lispers tend to like the fact that the parentheses can be used by the
computer to auto-format and auto-indent your code, and parens help
ensure that everything is grouped correctly (e.g., when you put your
cursor over a paren, it shows you the other paren that goes with it)
-- then once it is formatted, they use the indenting levels to
understand their code and ignore the parentheses. But it's comforting
to know the parentheses are there should the code ever get moved
around or edited.

Sean Devlin

unread,
Dec 18, 2009, 7:53:19 PM12/18/09
to Clojure
What you're looking for is called "Python".

The parens are your friend. Learn to love them. They are there to
remind you that you're building a data structure, not just writing
code.

Sean

CuppoJava

unread,
Dec 18, 2009, 8:35:50 PM12/18/09
to Clojure
In my personal experience, the fastest way to get accustomed to the
parenthesis is to learn how to read the indentation. That was the
biggest hurdle for me coming from reading C/Java code. Lisp
indentation is quite expressive and a little more subtle (unlike the
indent-two-spaces-for-a-loop scheme in C/Java). I think this point is
maybe not stressed enough. No one can actually read lisp code by
counting parentheses in their head.
-Patrick

Vagif Verdi

unread,
Dec 18, 2009, 8:58:32 PM12/18/09
to Clojure
Welcome to the big club of people who in last 50 years came up with a
"brilliant" idea to "fix" lisp.

As for Ten parentheses, i do not see a single one. Noone notices
starting parens because they are markers saying "this is a function".
And of course noone notices ending parens because they are for your
IDE, not for the human.

Martin Coxall

unread,
Dec 18, 2009, 7:38:25 PM12/18/09
to clo...@googlegroups.com

On 19 Dec 2009, at 00:29, Mark Engelberg wrote:

> The main downside of such an approach is that if you copy and paste
> your code to a new context in which it has a different level of
> indenting, it's very easy to screw things up. You then have no way to
> re-indent the code without fully analyzing and understanding the
> *semantics* of the code, because the only syntactic cues (the
> whitespace) is now invalid and can't be trusted.

My general feeling is that it's bad form to make sensitive whitespace the *only* option (I'm looking at you, Python).

What I'm wondering is whether there's any harm in making it available as an option, and whether it makes sense as a default. Haskell answered yes to both these questions, and what it gains Haskell in readability is well worth the tradeoff.

However, I agree that fully-parenthesized syntax should always be available to those that want it. But I assume that it's Rich's plan that Clojure should be more accessible than to just Lisp-heads, and a less parenthesized syntax might go a long way to easing their jitters.

Martin

Mike Meyer

unread,
Dec 18, 2009, 7:48:17 PM12/18/09
to clo...@googlegroups.com, pseud...@me.com
On Fri, 18 Dec 2009 19:07:43 +0000
Martin Coxall <pseud...@me.com> wrote:

> For each line that is not within a vector, and does not have an opening parenthesis, infer an opening parenthesis at the start of the line. Remember the level of indentation, and infer a closing parenthesis at the end of the line *before* the next line whose indentation is the same as or less than the remembered one.
>
> My question is: why would such a scheme work/not work, and why would/would not it be desirable?

Congratulations, you've just (re-invented) ABC & Python.

It can work. It's very comfortable to write, as it cuts down on a lot
of the syntactic noise in a program.

Downsides:

- Breaking the formatting of code beaks the meaning.
- Cutting and pasting inside a program becomes more interesting. It
can be done - emacs can rigidly indent a region that's been pasted
to the right place - but you can't really fix it "by hand" later.
- The size of tabs suddenly *matters*.

And the biggie:

- A lot of people find this significant whitespace as off-putting as
the parenthesis in LISP. Not as many, but still a significant
number.

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Martin Coxall

unread,
Dec 18, 2009, 7:59:47 PM12/18/09
to clo...@googlegroups.com

On 19 Dec 2009, at 00:53, Sean Devlin wrote:

> What you're looking for is called "Python".
>
> The parens are your friend. Learn to love them. They are there to
> remind you that you're building a data structure, not just writing
> code.
>
> Sean
>

As it happens, I agree with you: I learned to stop noticing the parens a long time ago, and think that Clojure's rather pragmatic approach to parens-reduction (lambda/vector literals) and other syntactic conveniences (object invocation syntax, comma whitespace) strikes a good balance.

But I'm trying to think of it from the point of view of Joe Q. Coder, who will take one look at our beloved elegant, expressive Clojure, see all the parens and run screaming.

Many people find would Clojure's comparative lack of syntax very human-hostile. Who is the intended audience of Clojure? Is it other Lispers? Or other Java programmers?

Martin

Vagif Verdi

unread,
Dec 18, 2009, 9:27:40 PM12/18/09
to Clojure
On Dec 18, 4:59 pm, Martin Coxall <pseudo.m...@me.com> wrote:
> But I'm trying to think of it from the point of view of Joe Q. Coder, who will take one look at our beloved elegant, expressive Clojure, see all the parens and run screaming.

Let James Gosling worry about Joe Q. Coder. He does a very good job at
that. Do you think HP worries that soccer moms will not use their
Engineering Calculators ?

> Who is the intended audience of Clojure? Is it other Lispers? Or other Java programmers?

The intended audience are Software Engineers. Not the people who hide
behind "this-is-not-intuitive" their lack of willing to learn the most
effective way to spend their professional life.

Sean Devlin

unread,
Dec 18, 2009, 9:28:57 PM12/18/09
to Clojure
Look, Clojure does a lot to make life easier. But if Joe Q. Coder
isn't willing to *try* to work with parens, he won't have a chance
picking up Clojure.

It is proudly a Lisp for people that want to get things done. Any
Java/.NET/Python/Brainfuck/Ruby/Basic/C/C++ (No Perlmongers :)) that
want to get better are welcome. However, there is a way things are
done in the language, driven by the underlying problems reality
imposes on developers. A prospective Clojure developer must accept
that the language does this to help you, not hurt you, and they need
to be open to the ideas.

That is the intended audience.

Sean

Anniepoo

unread,
Dec 18, 2009, 9:37:45 PM12/18/09
to Clojure
I read this and think of Roedy Green's essay on source code in
database, http://mindprod.com/project/scid.html and on Knuth's
'literate programming' - the idea that source code is inherently not
it's representation (it's the reader output that's homoiconic, not the
file representation on disk) and that there might be several
representations.
Reading Roedy Green's essay I think of how obsolete it sounds after
refactoring IDE's came around. Let me suggest that this is a great
idea, but one that should be part of some clojure-centric IDE, not a
part of the language.

It seems barking up the wrong tree to think that clojure will find
more acceptance if we find some method of reducing the number of
parens involved.
What's hostile to most programmers is that Clojure demands a lot more
thinking per line of code. I remember when OO came in, and then when
design patterns came in - each decreased the amount of thinking about
code and increased the amount of typing.
After all, the same java programmers who are frightened by Clojure are
happily reading nested structures in XML all the time.

Alex Osborne

unread,
Dec 18, 2009, 9:50:06 PM12/18/09
to clo...@googlegroups.com
Martin Coxall <pseud...@me.com> writes:

> My question is this: why can't we introduce a simple and importantly,
> optional 'off-side rule' (much simpler than Haskell's) that allows the
> reader to infer many of the parentheses?

If you haven't seen them before, check out sweet expressions. This guy
has put a lot of thought and experimentation into it.

http://www.dwheeler.com/readable/sweet-expressions.html

Coming from a background in Python and Ruby, I found S-expressions
initially very hard to read and would probably have loved something like
this. However I pretty soon got used to the Lisp syntax and now I
actually prefer it. If I did use something like sweet-expressions as
"training wheels", I'd probably have stuck with them and then never have
learned to read other people's code and never discovered the joy of
paredit and SLIME.

It's possible to use paredit with other languages, but it
doesn't seem to work as well due to the lack of consistency.
Similarly, I have tried a couple of SLIME-like things for Ruby and
Python but they never worked quite as well as you have to resort to
manually selecting everything you want to eval, instead of just being
able to say "eval last expression". I guess in theory it should be
possible to make this work with an infix/whitespace-sensitive syntax but
the amount of extra effort involved must discourage implementation
efforts.

I agree with Anniepoo, if you really want to do something like this it's
probably better done in the editor rather than the language itsel. By
putting it in the editor, you're retaining the simplicity in the actual
source-code, plus any file you open will be in your preferred syntax and
when you give your code to other people it will be in their preferred
syntax.

In fact it looks like there's already an Emacs mode for doing it on a
read-only basis:

http://www.emacswiki.org/emacs-zh/UnParenMode

I have at some point seen a mode that makes them invisible for editing
as well and uses whitespace and highlighting to indicate nesting, but I
can't find it now.

Sean Devlin

unread,
Dec 18, 2009, 9:50:48 PM12/18/09
to Clojure
Look, your IDE won't be a good clojure environment, because it will
encourage sloppy thinking. Write some more macros, and learn to
appreciate that you are building data structures. Really.

Grrrr....

On Dec 18, 9:37 pm, Anniepoo <annie6...@yahoo.com> wrote:
>   I read this and think of Roedy Green's essay on source code in

> database,http://mindprod.com/project/scid.htmland on Knuth's

Seth

unread,
Dec 18, 2009, 9:59:02 PM12/18/09
to Clojure
Many/most of the best programmers I know have allergic reactions to
parens. I think this is a normal reaction based on the amount of
successful time they have spent with ; terminated languages. FWIW, I
certainly flinch when I see Objective-C code with [ ] in strange
places, although these other programmers do not.

I'd like to think that forgetting about operator precedence and
enabling things like (< 1 2 3 4) are the first step to appreciating
list oriented mental parsing.

I don't hope Clojure ever becomes a lowest common denominator
language. There will always be a stream of competitors for that title,
like VB and Java. But I do hope that Clojure becomes widely known
enough to build a reputation for terse, fast, concurrency-friendly
code with a fair amount of punctuation. Remember, the punctuation
threshold for "hello, world" in Java is {([]){();}}

Alex Osborne

unread,
Dec 18, 2009, 10:17:18 PM12/18/09
to clo...@googlegroups.com
Anniepoo <anni...@yahoo.com> writes:

> What's hostile to most programmers is that Clojure demands a lot more
> thinking per line of code. I remember when OO came in, and then when
> design patterns came in - each decreased the amount of thinking about
> code and increased the amount of typing.

*shudder* Yes, this is a seriously disturbing trend in some languages.
While each line is doing less there's an awful lot more of them. I
guess this is another good example of "apparent simplicity" with "real
complexity".

ajay gopalakrishnan

unread,
Dec 18, 2009, 10:51:55 PM12/18/09
to clo...@googlegroups.com
Hi,

I've a different take on the entire thing. Based on my experience I have realized the following:
  1. A lot of software engineers do not have a CS background. Out of them, many joined this field for the fun of coding and are willing to learn new things. I know many like that. However, I feel a large majority of them are those for whom Java is probably what Software development basically is. (This has been a boon and bane of Computer Science. It reduces the barrier to entry, but also prevents them from appreciating the true beauty. Many can code a web application, thanks to Rails, Hibernate and the like without even having an idea of what B-tree is) Everything begins and ends with Java. They don't even know anything about C/C++.
    And I think it would be foolish to assume that Clojure acceptance will reach critical mass unless it is accepted by this group of people. 
  2. Second issue is Bosses (higher-ups) and convincing them is hard. Language features and the beauty of Lisp is not going to convince them. The biggest problem is I think when they realize that they will have to loose all the Imperative programming skills they have acquired all over these years and now they will be on equal footing with the rest when it comes to Functional programming experience.
  3. Sad as it is, most of the work gets done by Copy-paste work and unless there is a online cookbook type thing, people will find it hard.
Unless Clojure (not just Clojure, any functional programming language) reduces this barrier to entry for both the non-core developers and the Bosses, I think any FP language will find it hard.
Now, if we want Clojure to get accepted fast, I think we must be eager to reduce this barrier to entry. Just saying that "If you can program in LISP" then you can code Clojure is not a very smart answer. Similarly saying "get used to parenthesis" is not a smart answer either.

It's really wrong to think that if they do not accept Clojure they are doomed. The users have a higher hand and if not Clojure, new languages will keep on being built until some language gets accepted by all.

I think what needs to be done is the following:
  1. In LISP like languages, Parenthesis is a non-issue as long as code is properly indented. And hence strictly following indenting rules while defining functions/Macros etc. is really really crucial. Hence my next point.
  2. Excellent IDE indenting support for code Indentation. I have tried Enclojure and it is good. But what I find is difficult for the LISP newbie is deciding when to put code on the new line for function arguments and all that. I know that there are rules for that (most Scheme like), but frankly speaking, people have become very lazy and wouldn't waste time reading the indenting rules, especially when the other Haskell,F#, Scala camp boasts to address the same issues and say that we do it all without a lot of parenthesis. So in short, Can we do something in the IDE to make Clojure code indentation a totally no-brainer?
    Perhaps Enclojure must show some placeholders properly indented based on whether it is defmacro, defn or fn etc and the developer just fills it up. This would be an excellent aid in promoting LISP indenting standards.
    Overtime, once Clojure is widespread people will automatically start doing it correctly.
  3. A nice and good article written by Clojure folks that highlights how to transition from the OOPS thinking to Functional thinking.
    1. Just saying "Practice coding recursively" does not help at all. Even core CS people do not use recursion for every thing these days. Students have OS labs, Networking Labs and projects but everyone knows that it does not involve much of recursion and all - just a plain sequence of operations, that's all. At most 2-3 courses on Algorithms is where they use Recursion heavily.
    2. I think the keyword "let" and the pipeline is very understated. "let" is the single most important thing that makes this transition easy.
  4. Have an article that has some decent functions in it and each should have an explanation of how an experienced Clojurian/LISPian would read this code mentally. Just write it as a transcript. Or may be a Screen cast.
  5. Have a cookbook like article for all common tasks.
  6. Explain how idiomatic code looks like in Clojure. I feel experienced Lispers can help in this. It feels very scary when an experienced OOPS developer knowing all idiomatic code in OOPS does not know anything in LISP. I'm afraid to say that this feeling of shame must be prevented. After all, writing idiomatic LISP code is not rocket science. It is just lack of experience
I personally feel that Clojure has enough of nice features. All that is left to do is to make the transition easier. Although it may seem less technical and less interesting to the geeks, it is important to realize that all coders are not geeks and not everybody behaves rationally. Looks, presentation and ability to lure people also matters. After all, looks and ease in every way is an integral part of a Programming Language.

Finally, comments like "doing XYZ will encourage them to write sloppy code" is not good. Nobody likes to write sloppy code. They do it because writing good code is very hard in the language or the IDE does not support it.

A language need not be very good to be a success. A lot depends on the IDE support. It is known to everybody that most of the Java code is written in IDE like Eclipse only. And Eclipse goes a long way in reducing the boilerplate code, thus reducing a flaw in the Java language. Similarly Enclojure and Counterclockwise support be just splendid. Just saying "use Slime/Vimclojure" does not help again.

My 5 cents. it is too long for 2 cents.

Thanks,
Ajay G



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Avital Oliver

unread,
Dec 19, 2009, 3:50:22 AM12/19/09
to clo...@googlegroups.com

It seems that noone has brought up the amazing paredit mode for emacs which gives you keyboard commands for s-expression structure manipulation. It also makes sure you never get your close parenthesis wrong. I use it and can't imagine writing any medium+-complexity code without it.

On Fri, Dec 18, 2009 at 9:28 PM, Sean Devlin <francoi...@gmail.com> wrote: > > Look, Clojure...

Laurent PETIT

unread,
Dec 19, 2009, 8:25:14 AM12/19/09
to clo...@googlegroups.com
It's certainly something I would like to add to counterclockwise.

If only paredit's code was written in clojure, it could have been more easily reused by enclojure, La Clojure and counterclockwise ! :-(



2009/12/19 Avital Oliver <avi...@thewe.net>
--

Stefan Kamphausen

unread,
Dec 19, 2009, 8:50:59 AM12/19/09
to Clojure
Hi,

On 18 Dez., 20:07, Martin Coxall <pseudo.m...@me.com> wrote:
> One of the things that always puts people off of Lisp, as we all know, are the parentheses.

one of the things that always put Lispers off is this same question.

I have three arguments to make. Love, reason and trust.

* Love. Parentheses are an advantage, you will learn to love them if
you start some serious hacking.
* Reason. They could have been taken away in more than 50 years of
history. Guess what, they are still there. If I came to lisp as a
newbie, I would think that there must be some reason.
* Trust. Just trust all the people telling you over and over again for
ages, just trust all the fine software engineers who kept them in
place for a very long time.


Stefan

Daniel Werner

unread,
Dec 19, 2009, 9:10:19 AM12/19/09
to Clojure

Whitespace-sensitive S-exprs have indeed already been implemented for
Clojure. The author's github account seems to have been renamed/
deleted, however:

http://209.85.129.132/search?q=cache:-f3Sb3BYidoJ:github.com/onyin/pleajure

For my own toy programs, I have seen little use for significant
whitespace in Clojure so far. Even though I work with Python
professionally and like it's lack of syntactical noise, Clojure's
parentheses (and vector brackets, and map braces) tend to communicate
the programmer's intent more clearly, especially when code becomes as
dense as is possible using Lisps/FP. All of this once the initial
hurdle is overcome, of course. Clojure just looks and feels different
compared to most mainstream languages, different even compared to the
more traditional Lisps.

I guess it's mostly a matter of judging a language by its long-term
merits instead of initial appearance -- just like with so many other
things in life.

Erik Price

unread,
Dec 19, 2009, 10:30:01 AM12/19/09
to clo...@googlegroups.com
Personally, I don't think the problem for non-Lispers is with the
number of parentheses so much as with the *depth* of parens-nesting
and having to invert the reading order, starting from the deepest
s-expr and reading your way back out.

I'm still very new to Clojure (basically I have only been paying close
attention to it for a few weeks, and have not written any substantial
Clojure code yet), and I come from ten years of programming the usual
non-Lisp Python/Java/JavaScript/C-style languages. But I can honestly
say that reading Clojure code comes very naturally for me now, as long
as I'm familiar with all the functions in an expression, and I assure
you that it's certainly not that I'm special or particularly bright.

Interested programmers are willing to learn different syntaxes -
judging from the number of apps, there are probably at least fifty
thousand programmers who were willing to look past all the square
brackets in Objective-C so that they could write iPhone apps. What I
think makes it difficult to approach an S-expression isn't the
parentheses, but the fact that you often have to read it in an inverse
order, or maintain a mental stack of functions that have been applied
so far. For me, this is especially the case when function calls are
nested very deeply.

I'm not familiar with it, but from your example it appears that the
->> macro lets the code be written in an order which is not inverted.
Furthermore, the first example "looks" like it has more parens than
the ->> example, even though it actually has fewer, because of its
deeper nesting - so it's easier to read through what's happening in
the ->> example, without having to maintain a mental stack of what
functions have are being applied to the expression. For interested
programmers new to Clojure, I would think this is way more useful than
reducing the number parentheses.

e

PS: I use the term "interested programmers" above because I don't
think Clojure will ever appeal to a programmer who isn't interested in
learning something new. The syntax is the easy part. The hard part is
learning a different approach to designing and structuring programs.

Martin Coxall

unread,
Dec 19, 2009, 9:18:43 AM12/19/09
to clo...@googlegroups.com
>
>
> It is proudly a Lisp for people that want to get things done. Any
> Java/.NET/Python/Brainfuck/Ruby/Basic/C/C++ (No Perlmongers :)) that
> want to get better are welcome. However, there is a way things are
> done in the language, driven by the underlying problems reality
> imposes on developers. A prospective Clojure developer must accept
> that the language does this to help you, not hurt you, and they need
> to be open to the ideas.
>
> That is the intended audience.

Clojure may be a new Lisp, but it seems the die hard holier-than-thou attitude of old-school Lipsers is alive and well.

Look, there's a reason nobody uses Lisp. And the attitude of "we know best and if you can't see that you're an idiot" is certainly part of it.

A prospective Clojure developer "must" not do anything. They will probably take one look at Clojure's seemingly user-hostile syntax, read how unless they immediately embrace parens that they are *not welcome*, click their browser back button and never give another thought to Clojure again.

Martin

Martin Coxall

unread,
Dec 19, 2009, 9:22:22 AM12/19/09
to clo...@googlegroups.com

On 19 Dec 2009, at 13:50, Stefan Kamphausen wrote:

> Hi,
>
> On 18 Dez., 20:07, Martin Coxall <pseudo.m...@me.com> wrote:
>> One of the things that always puts people off of Lisp, as we all know, are the parentheses.
>
> one of the things that always put Lispers off is this same question.
>
> I have three arguments to make. Love, reason and trust.
>
> * Love. Parentheses are an advantage, you will learn to love them if
> you start some serious hacking.

I've seriously hacked in many languages, and have come to rely on the presence of Syntax. If Clojure wants me to seriously believe that syntax is overrated, it had better had a bloody go argument.

> * Reason. They could have been taken away in more than 50 years of
> history. Guess what, they are still there.

Guess what? NOBODY uses Lisp. Because of those parens.

> If I came to lisp as a
> newbie, I would think that there must be some reason.
> * Trust. Just trust all the people telling you over and over again for
> ages, just trust all the fine software engineers who kept them in
> place for a very long time.

I trust the many, many more people that have rejected Lisp for its hostile syntax and delusions of importance than the statistically insignificant minority who have actually stuck with it.

Martin

Martin Coxall

unread,
Dec 19, 2009, 9:25:36 AM12/19/09
to clo...@googlegroups.com
>
> I guess it's mostly a matter of judging a language by its long-term
> merits instead of initial appearance -- just like with so many other
> things in life.
>

That - right there - is a tacit admission that the Clojure community will find it actively desirable that it remain a minority language, so we can all feel smug that we understand something those poor average programmers were too simple to see.

You know there's nothing wrong with allowing Clojure to display its elegance upfront, rather than making programmers work for it like it's some Presbytarian admission exam.

Martin

David Nolen

unread,
Dec 19, 2009, 12:21:11 PM12/19/09
to clo...@googlegroups.com
On Sat, Dec 19, 2009 at 8:25 AM, Martin Coxall <pseud...@me.com> wrote:
>
> I guess it's mostly a matter of judging a language by its long-term
> merits instead of initial appearance -- just like with so many other
> things in life.
>

That - right there - is a tacit admission that the Clojure community will find it actively desirable that it remain a minority language, so we can all feel smug that we understand something those poor average programmers were too simple to see.

I don't think anybody in the Clojure community wants to Clojure to be a fringe language. Considering the ML now has about 3K subscribers (up 2500 from 14 months ago) I think Rich Hickey and the community have done a fair job touting it's advantages.

However, there are somethings about every language that you just have to accept. Lisp's parentheses are one of those things. For example, it's really not worth complaining about Python's enforcement of significant whitespace. Sure people sing it praises now, but to this day there still fruitless discussions about the matter mostly initiated by people with only a passing familiarity of the language.
 
You know there's nothing wrong with allowing Clojure to display its elegance upfront, rather than making programmers work for it like it's some Presbytarian admission exam.

You are not the first to bring up the concern about parentheses and you will certainly not be the last. My advice would be to let the matter drop. People who aren't going to learn Lisp just because it has parentheses aren't going to be converted. But from the variety of programmers on this list, parens are not a significant deterrant for programmers coming from the background of Java, Scala, JavaScript, C, C++, Objective-C, OCaml, Haskell, Prolog, Erlang, PHP, Perl, Python, Ruby, etc.

Sean Devlin

unread,
Dec 19, 2009, 12:52:08 PM12/19/09
to Clojure
Martin,

I was short with you yesterday. I'm sorry about that. Please let me
try again.

I'm all for providing better documentation, eliminating bad design,
and holding hands as people get up to speed. As a community, we
constantly need to do more work to make it accessible. That's the
point of the IRC channel & this list. I believe you browse the
archives you'll see that mutual assistance is the prevailing attitude
here.

Clojure's clean design does make it easy to learn. The sequence
abstraction makes the core library small. The persistent data
structures make it easier to write multithreaded stuff than in any
other language (I invite you to provide a counter example). The macro
system is hygienic, and as powerful as any other.

I'm going to use a point from Paul Grahams' crtique of Java:

http://www.paulgraham.com/javacover.html

The main point I want to echo is that tools "designed for other
people" always seem to be inferior to tools "designed for myself".
Clojure was originally written by Rich for Rich. I check that any
feature I suggest really improves my own code before I post to the
list. After that, the idea has to survive critique from lots of other
Clojure experts, making sure that the feature is "designed for
myself". A lot of proposals don't get past this step, because it is
already solved or it doesn't fit into the Clojure way.

Removing parens is one of those changes that simultaneously is
"designed for other people" and makes the expert's job more difficult
(By making macro writing & argument resolution harder). It's a
complete and total loss from my perspective, and that is what evokes
the emotional response. I've suffered enough at the hands of
languages "designed for other poeple". This is Clojure, and I want to
keep it a language "designed for myself".

Sean

Joseph Smith

unread,
Dec 19, 2009, 1:04:46 PM12/19/09
to clo...@googlegroups.com
Very abstract java example (as concise as possible):

List<Object> processList(List<Object> oldObjects)
{
   List<Object> newObjects = ArrayList<Object>;
   for(Object object : oldObjects) 
   {
      newObjects.add(manipulate(object));
   }
   return newObjects;
}

Clojure equivalent:

   (defn processList [#^Object list] 
     (for [object list] (manipulate object)))

I realize this is a very pedestrian example, but a couple things to note (and I'm sure mentioned previously):
 - Lisps are much more expressive, in general
 - Compared to most languages there is significantly less syntactic noise- There is "just enough" syntax to delimit the code.
 - The code is a data-structure (homoiconicity), and it is very easy to see where the expression begins and ends (this is good for readability, code formatters, etc)
 - Lisps are very consistent- no special code formatting rules to remember. Despite what seems like a large number of parentheses there are far less 'control' characters. 
I.e. instead of : . ; ( ) { }  you have ( ), and usually fewer of them.
 - Most programmers rely on their IDE/Editor or indentation to make sure they are matching curly-braces correctly, 
   which is made harder by blocks of code that frequently extend beyond the height of your screen. 
   IDEs/editors can match parentheses as well. :) 
 - The parentheses make the code sleek and aerodynamic

Joseph Smith

unread,
Dec 19, 2009, 1:15:33 PM12/19/09
to clo...@googlegroups.com
Oops.. left two parentheses out in my Java code. Guess that just furthers my point. :)

 List<Object> newObjects = ArrayList<Object>();

ajay gopalakrishnan

unread,
Dec 19, 2009, 12:16:03 PM12/19/09
to clo...@googlegroups.com
The intended audience are Software Engineers. Not the people who hide
behind "this-is-not-intuitive" their lack of willing to learn the most
effective way to spend their professional life.

Why is it that you believe them to be mutually exclusive events? You portray Software engineers as if they are Gods and the most brilliant minds on the planet. A lot are just average. And ofcourse, if Clojure does not try to make them feel at home, it is just going to be another Hobby language. That's all.

Mark Engelberg

unread,
Dec 19, 2009, 2:35:41 PM12/19/09
to clo...@googlegroups.com
On Sat, Dec 19, 2009 at 9:21 AM, David Nolen <dnolen...@gmail.com> wrote:
> I don't think anybody in the Clojure community wants to Clojure to be a
> fringe language.

Actually, I don't mind if Clojure retains a certain degree of "fringe" status.

To clarify, I think the ideal size for a language community is
somewhere in between the two extremes. You certainly want enough
people who love working with a language that the language keeps moving
forward and cool libraries and tools are continually being developed.

On the other hand, there's something very nice about knowing a
language that is a bit of a "secret weapon". Sometimes companies
advertise that they are looking for a certain language, not because
they really need that language, but because they know that any
developer who knows that language is likely to be of a certain high
caliber. They use the language as a way to weed out run-of-the-mill
software engineers. Languages like Haskell, Scheme, and ML are often
used for this purpose (not Java, of course, it's too mainstream).
Such job posts also send a signal to talented developers that their
company is a special place to work, because they know the value of
"secret weapon" languages. I would actively like to see Clojure
remain obscure enough to fall into this category.

I sympathize with the original poster's point, however. I have been
using Lisp dialects for 20 years, and I still find Lisp code harder to
read than its mainstream counterparts. The parentheses provide a
visual sameness to the code that forces you to think very hard to
understand it. Python, on the other hand, is the most readable
language I've encountered. So, despite all the claims that you'll
"learn to love parentheses", I'll say that it's not necessarily true.
I have no love for the hyper-consistent prefix syntax for functions,
macros, and keywords, and all the deeply-nested parentheses that
result. Still, I'm flexible enough that I have no problem
*tolerating* Lisp's syntax. And if other people can't see past the
parentheses and understand the value of the language, I have a hard
time getting worked up about that (see above point).

Stuart Sierra

unread,
Dec 19, 2009, 3:37:43 PM12/19/09
to Clojure
On Dec 18, 9:28 pm, Sean Devlin <francoisdev...@gmail.com> wrote:
> It is proudly a Lisp for people that want to get things done.  Any
> Java/.NET/Python/Brainfuck/Ruby/Basic/C/C++ (No Perlmongers :))

I was a Perlmonger back in the day. :)

-SS

Sean Devlin

unread,
Dec 19, 2009, 3:47:54 PM12/19/09
to Clojure
Well, good thing you repented of your evil ways!!!!

Joost

unread,
Dec 19, 2009, 5:34:21 PM12/19/09
to Clojure

Most programming languages aren't judged on their syntactical
elegance, otherwise nobody would use Erlang, for example. Now I like
Erlang, but I still think it just looks horrible and it has way too
many syntactical niggles that are hard to get familiar with.

Lisp languages are completely simple in that regard. The worst
question you generally run into is whether to add 1 or 2 pairs of
parentheses at some point. Clojure makes this a bit simpler in the
generally-used cases and a bit harder overall (since it uses 4+
different kinds of delimiters)

Now that does not mean it doesn't look "alien". It does. Deal with it
or do something else. But don't pretend that doing what clojure *does*
is much easier to write or read in any kind of "familiar" syntax,
unless you're got a really serious contender. It's been tried many
times - McCarthy himself did not think s-expressions were the final
syntax for the language - but nobody has been able to come up with a
syntax that actually works better for Lisp.

Once everything is an expression - and especially when you place a
large emphasis on side-effect free code - all you can really do to
improve the "parenthesis problem" is to compact typical constructs.
We've already got macros and decent reader syntax.

Alex Osborne

unread,
Dec 19, 2009, 6:23:58 PM12/19/09
to clo...@googlegroups.com
Martin Coxall <pseud...@me.com> writes:

> I trust the many, many more people that have rejected Lisp for its
> hostile syntax and delusions of importance than the statistically
> insignificant minority who have actually stuck with it.

Sometimes people are just looking for excuse to criticize. Before it
was considered mainstream, there was just as much noise about Python and
whitespace-sensitivity and the explicit "self" in method arguments as
there is about Clojure and parens.

> But I'm trying to think of it from the point of view of Joe Q. Coder,
> who will take one look at our beloved elegant, expressive Clojure, see
> all the parens and run screaming.

Take away the parens and that same Joe Q. Coder is likely to pick
something else to take one look at and run away screaming. Perhaps the
JVM, perhaps immutability, perhaps the whitespace-sensitive syntax.

I'm not telling you not to try it. If you can pull off a preprocessor
or much better an editor, that makes Clojure code _significantly_ easier to
read while retaining its expressiveness, simplicity of macro writing and
tool support then I will join you in using and championing it. But this
is the same "great idea" that everyone who's ever used a lisp since the
dawn of programming has come up with and despite numerous attempts, to
my knowledge not a single one of them has ever taken off. That doesn't
mean it's not possible, just that it's not going to be as simple as just
allowing "others" to write whitespace-sensitive Clojure.

The reaction you are seeing from the old-school lispers (of which I am
not one, unless 4 months is "old") is understandable. It's the same
sort of reaction you would get from an old-school Python programmer if
you jumped on the Python mailing list and declared that you've solved
the significant-whitespace problem: allow newcomers to write Python code
with lisp-like parens. ;-)

Phil Hagelberg

unread,
Dec 19, 2009, 8:45:27 PM12/19/09
to clo...@googlegroups.com
"Alex Osborne" <a...@meshy.org> writes:

>> But I'm trying to think of it from the point of view of Joe Q. Coder,
>> who will take one look at our beloved elegant, expressive Clojure, see
>> all the parens and run screaming.

> But this is the same "great idea" that everyone who's ever used a lisp


> since the dawn of programming has come up with and despite numerous
> attempts, to my knowledge not a single one of them has ever taken off.

You're forgetting about Dylan!

...

(peals of explosive laughter here)

-Phil

Charras

unread,
Dec 19, 2009, 10:28:53 PM12/19/09
to Clojure
can't believe, you guys, WAIST! your time discussing about
parentheses. There are far more interesting things to discuss. Please
don't waist time (time is life, is all we have) in that, and
specially, this is a public group, where knowledge should be share,
not nonsense discussions.

If somebody likes parentheses, good, if not, don't program in anything
lispy. No body is forcing that person to program in lisp.

Guido

ajay gopalakrishnan

unread,
Dec 19, 2009, 3:08:12 PM12/19/09
to clo...@googlegroups.com
I think this discussion is getting too long, but anyway ..

Coming from an imperative background, especially Java which is a lot bloated, when I tried to read Lisp code, I start to get the feeling that I am staring at the same place for a long time. In an imperative setting, it definitely means that I am unable to understand the code. However, in the case of Lisp, since it is more condensed than Java, even though I am looking at the same place for a longer time, I am actually assimilating at almost the same rate!

I believe that for Lisp beginners coming from Imperative style, the Brain is being fooled into believing that it is dumb! Actually it is doing perfectly fine as long as it understand the different functions/API.

Parenthesis, prefix notations were never a big issue for me. In fact, the parenthesis are mostly invisible in properly syntax highlighted and properly indented code. However proper indentation is the key. In other languages you can figure out things based on syntax symbols like [] { } => and so on. Since Lisp does not have any of these, the only support the Programmer has is Indentation!

I should not say this ... but just to get a feel I stared at some Scala code for a while and said to myself - "What the hell is this! Why am I feeling it painful to move my eyes so much and there is so much of syntactic noise".

It is just a matter of getting used to. Granted not everybody will feel comfortable in the same time and so there will be resistance to Lisp style syntax for a while.


--

Mike Meyer

unread,
Dec 19, 2009, 4:37:29 PM12/19/09
to clo...@googlegroups.com, pseud...@me.com
On Sat, 19 Dec 2009 14:22:22 +0000
Martin Coxall <pseud...@me.com> wrote:

> On 19 Dec 2009, at 13:50, Stefan Kamphausen wrote:
> > * Reason. They could have been taken away in more than 50 years of
> > history. Guess what, they are still there.
> Guess what? NOBODY uses Lisp. Because of those parens.

You've overstated the case. Both times.

I encounter about one company a year that uses LISP commercially -
mostly doing the heavy lifting on the back end server in what we call
"cloud" applications these days. Anyone serious about either emacs or
Autocad works with lisp. XlispStat seems to still be alive and
well. Sure, even all put together, they're a really small fringe group
- but the difference between "nothing" and "almost nothing" can be
*very* significant (just ask the guy who though that the Tacoma
narrows wind resonance was nothing).

Second, I've encountered both people and companies that have dropped
LISP, and the reason is almost never "those parens." It usually
because of one of a number of reasons that can be summarized as "LISP
doesn't play well with others":

1. Lack of access to system libraries and frameworks.
2. The pain of sharing data with system utilities and applications.
3. The difficulty of moving programs to other platforms, *especially* if
the LISP has solved 1 & 2!

This is why the people doing LISP commercially tend to use it on
servers - they duck issue #3 for getting the solution to their
customers, and thus only have to find an implementation that solves #1
and 2 on their server platform.

Note that Clojure solves all three problems by running on the JVM with
Java integration.

Of course, the question is - how much have you overstated the case?
Because that will determine how true this is:

On Sat, 19 Dec 2009 12:16:03 -0500
ajay gopalakrishnan <ajgo...@gmail.com> wrote:
> Why is it that you believe them to be mutually exclusive events? You portray
> Software engineers as if they are Gods and the most brilliant minds on the
> planet. A lot are just average. And ofcourse, if Clojure does not try to
> make them feel at home, it is just going to be another Hobby language.
> That's all.

Possibly. But what do you mean by "Hobby language"? Something like Oz,
which only a few people have heard of, and is pretty much only used
academically? I suspect we're already past that stage. Or something
like Python, which has a fair share of the LAMP market, in spite of
having syntax issues that drive about as much discussion as the parens
in LISP do, but almost no presence as an "enterprise language"?

If the latter, I'm perfectly happy with that. I've made pretty good
living writing Python the past decade or so. If I were willing to use
Django or one of the other web templating systems built in Python, I
could have done even better.

The question here is, how much are you willing to give up in order to
make Clojure "an enterprise language"? In the python community - and
I've already seen a bit of it here - complaints about the lack of
static type checking are about as common as complaints about the lack
block delimiters. Are we going to add type declarations to Clojure to
make those people "feel at home"? The end result of this path is that
Clojure just becomes another Java, and won't be as productive or as
much fun as it is today.

One of the best things about Python is that the community wants the
language to actually improve, even if it means not growing the
community. Features aren't normally added to the language just because
a lot of people want them; they're added because they actually answer
a real need, and don't encourage people to write ugly code.

Part of this is because they realize that adding a feature has a cost
even for people who don't use it. If nobody uses it, why add it? If
somebody uses it, then at some point you'll encounter code that does -
so you'll have to know about it. If it encourages the creation of ugly
code, so much the worse. The net result of these attitudes is that,
even after nearly 20 years of change and community growth, python
remains both powerful and a joy to write and read.

So, does it really do you any good to add features to Clojure that
attract more programmers if the end result is a language that you
don't enjoy programming in, and that doesn't give you the productivity
that drew you to the language in the first place?

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Brandon Mason

unread,
Dec 19, 2009, 7:55:37 PM12/19/09
to Clojure
Is it possible that people are confusing their inability to comprehend
deeply nested function calls (no offense intended by that - I hit this
often myself) with the strangeness of the perens? I think what others
have said about having to think more about each line of Clojure is
true. It is more expressive and information-dense. The remedy to
this though is not to eliminate the perens syntax, but to use
intermediate defs and defns to break up the logic into manageable
chunks. These defs would also make the code more self documenting, by
associating names with information.

As someone who's never learned a lisp before, I find myself warming up
quickly to the perens syntax. I think that it's appropriate that a
language which takes a completely different approach should also have
a different syntax than what I'm used to. I don't think that "it
might offend some people" is a valid argument for stripping out a core
element of the language syntax. If they're not willing to come out of
their comfort zones on such a minor detail then they probably aren't
very receptive to functional programming in the first place.

And that's my $0.02. :-)

-Brandon

On Dec 19, 10:21 am, David Nolen <dnolen.li...@gmail.com> wrote:

> > clojure+u...@googlegroups.com<clojure%2Bunsu...@googlegroups.com>

Alex Osborne

unread,
Dec 20, 2009, 12:07:56 AM12/20/09
to clo...@googlegroups.com

Gosh. So I am. It was created by Apple, no less. It even lets you use
semicolons. Semicolons and Apple! That's got to be a recipe for
success with the superficial masses.

Seriously though, there's plenty of examples that show that popularity
does not strongly depend on readable syntax (look at HTML, Ant, heck
Perl). But from either side, an argument based on an appeal to
popularity is sort of missing the point. I share the opinion of Mark
Engelberg and others. I don't mind Lisp syntax because it has benefits,
but it's definitely not as readable. The sweet expressions guy (David
Wheeler) covers this pretty well:

http://www.dwheeler.com/readable/retort-lisp-can-be-readable.html

I'm not sure if sweet expressions are the answer. Or even if there is
an answer. But for me editor support is key. I've overheard this
conversation countlessly, about so many languages:

"Oh, what's that you're coding in?"
"Foobar. It's pretty awesome."
"Yeah, it looks pretty nice."
"See how you don't need to specify the blahs? The compiler just
figures it out."
"Nice! I might try it out. Does it work with Eclipse?"
"Well, sort of, but ..."
"Oh. Are there any other nice editors that work better with it?
Netbeans maybe?"
"Not really. There's an Emacs mode but ..."
"Oh. Well. Nevermind then. Some other time, maybe."

I know David Wheeler's retort to the suggestion of tools is:

If you have to use tools to make parens less of a problem, perhaps
you should use a better notation that removes extraneous characters
in the first place.

But I'm not sure I agree with him. I find code (in any syntax) harder
to read without syntax highlighting. I also find it frustrating to
write without at least basic auto-indentation. We're going to want
tools anyway and Lisp's simple syntax and homoiconicity make it so much
easier to write them.

Funnily enough, I know people who claim Python and Ruby are horrifying.
What do they prefer? XSLT. Yes, that XSLT. Yes, the W3C one. Really.

Why? Better editor support. Structural editing, on the fly validation,
online previewing, XPath generation, backmapping, extensive
auto-completion, profilers, debuggers, graph and table visualizations,
WYSIWYG XSL-FO report generators, the list goes on and on. The language
and syntax are quite frankly awful, but boy do they have some nice
tools.

The more I use paredit's structural editing the more I find I can't live
without it either. The one annoyance I have with it is when I
accidentally manage to insert a stray bracket and it gets confused. But
maybe here there's something to be learned from the XSLT folks, even if
their serialization format leaves a lot to be desired. Maybe paredit
should be taken to its logical conclusion: just edit data structures
directly, don't worry about the text.

Let your editor display and edit infix math. Heck, let it show you
complex math expressions with LaTeX formatting for the ultimate in
readability. Let it show nesting just with indentation.

When you save the file, what does your hypothetical editor do? It
writes things out, properly indented, in that good-old relatively easy
to parse (for both man and machine) syntax from time immemorial.

Can we have our cake and eat it too?

Sean Devlin

unread,
Dec 20, 2009, 12:40:53 AM12/20/09
to Clojure
Give it a shot. Hack up a prototype. Let's see what happens.

On Dec 20, 12:07 am, "Alex Osborne" <a...@meshy.org> wrote:

ajay gopalakrishnan

unread,
Dec 19, 2009, 10:57:22 PM12/19/09
to clo...@googlegroups.com

Is it possible that people are confusing their inability to comprehend
deeply nested function calls (no offense intended by that - I hit this
often myself) with the strangeness of the perens?  I think what others
have said about having to think more about each line of Clojure is
true.  It is more expressive and information-dense.  The remedy to
this though is not to eliminate the perens syntax, but to use
intermediate defs and defns to break up the logic into manageable
chunks.  These defs would also make the code more self documenting, by
associating names with information.


Yes. Even I feel the same. The problem is not the Parens, but Remembering the deep stack of function calls. This brings me to my next question:
  • Is it LESS idiomatic to use "lets" to bind the output of a few functions.
  • Do you derive ANY benefit by deeply nesting functions? I would assume the opposite. The only loss is conciseness and I would be willing to sacrifice it a bit for readability.
 If not, then the use of Let should be highly encouraged. And that will fix the problem provided code is indented correctly.

ajay gopalakrishnan

unread,
Dec 20, 2009, 1:51:24 AM12/20/09
to clo...@googlegroups.com
Yes, Martin, please give it a try. Only then can we know if the parenthesis is real issue or not. There is no point arguing about it. The only disadvantage is that, over time, people will forget that it is actually a list. But, hey, if it does not prevent us from writing efficient and correct code then why not forget it and leave the compiler to worry about that.
If possible, I would also want to see a macro that allows me to write (x < y) instead of  (< x y).

(+ x y) can be read literally as "add x to y"
(square x) can be read literally as "squares x"
(< x y) how do you read this literally left-to-right?

Relational operators being so common in code, I think it abuse of notation is valid here.

Thanks
Ajay G.

Richard Newman

unread,
Dec 20, 2009, 2:12:16 AM12/20/09
to clo...@googlegroups.com
> (< x y) how do you read this literally left-to-right?

I've been writing Common Lisp and Clojure for about 6 years now, and I
read that "less-than x y" without any confusion.

I have almost no problems with prefix notation; even arithmetic (which
I was taught in infix for years) rarely trips me up when writing.
Reading prefix-notation arithmetic is, of course, a joy when compared
to infix (no trying to remember precedence, building intermediate tree
nodes in my head, etc.).

Alex Osborne

unread,
Dec 20, 2009, 2:25:57 AM12/20/09
to clo...@googlegroups.com
ajay gopalakrishnan <ajgo...@gmail.com> writes:

> If possible, I would also want to see a macro that allows me to write (x < y)
> instead of  (< x y).

Here's Chouser's infix function, which he apparently has never used
since writing it:

http://paste.lisp.org/display/75230

> (+ x y) can be read literally as "add x to y"
> (square x) can be read literally as "squares x"
> (< x y) how do you read this literally left-to-right?

Ah yeah, that's one that still trips me up. Some people kind of read
(< x y z) as (ascending? x y z) and you could think of the < symbol as a
ramp going up so the z is above the y is above the x. Even knowing that
I still confuse myself occasionally though. I don't have any problems
with arithmetic or function calls, I just really expect the larger
quantity to be on the "wide" side of the < wedge.

ajay gopalakrishnan

unread,
Dec 20, 2009, 2:27:45 AM12/20/09
to clo...@googlegroups.com
Precedence is an overrated thing. You dont run into that issue every day. When we do we have the support of (). So, a developer must have the option to disambiguate it when necessary, but otherwise should not have to type the otherwise redundant () all the time. (All this talk is about arithmetic expressions, so the whole () problem in LISP in general)
Arithmetic expressions are rarely complicated enough to need full bracketing. And hence, it is better to have a preprocessor that fills in the required brackets when they are just redundant.

For e.g.

(+ (* 1 3)  (/ 1 5))

It would be better if I could write it as:

+ (* 1 3) (/ 15)

and the preprocessor should be able to convert it to (+ (* 1 3) (/ 1 5))
After all, the additional () is what the compiler needs. Not me. Above simplified version is mathematically unambiguous.  

This is much less noise.


--

Piyush Ranjan

unread,
Dec 20, 2009, 5:02:02 AM12/20/09
to clo...@googlegroups.com
I may be way off here and if I am feel free to flame!

isn't it true that lisp being an AST transfers the overhead of parsing to humans ? 
Let me restate that: lisp manages to skip a step that other languages do, i.e. parsing the language to AST ?
I understand that it gives you great power but at the same time it comes with its overhead(?). So in essence
ruby or python like languages which have very lisp"y" constructs are actually lisp + parsing ? 

Martin Coxall

unread,
Dec 20, 2009, 5:36:53 AM12/20/09
to clo...@googlegroups.com

>
>
>
> As for Ten parentheses, i do not see a single one. Noone notices
> starting parens because they are markers saying "this is a function".
> And of course noone notices ending parens because they are for your
> IDE, not for the human.


This is I like, I'd never thought about S-exprs this way before. Even though I am accustomed to them now, I wish I'd had somebody explain them like this to me before.

Martin

Martin Coxall

unread,
Dec 20, 2009, 5:45:23 AM12/20/09
to clo...@googlegroups.com

On 20 Dec 2009, at 07:27, ajay gopalakrishnan wrote:

> Precedence is an overrated thing. You dont run into that issue every day.

Yeah, only every time you write a simple mathematical expression. And how often does that happen when you're programming?!

Martin

Martin Coxall

unread,
Dec 20, 2009, 5:58:25 AM12/20/09
to clo...@googlegroups.com

On 20 Dec 2009, at 06:51, ajay gopalakrishnan wrote:

> Yes, Martin, please give it a try. Only then can we know if the parenthesis is real issue or not. There is no point arguing about it. The only disadvantage is that, over time, people will forget that it is actually a list. But, hey, if it does not prevent us from writing efficient and correct code then why not forget it and leave the compiler to worry about that.
> If possible, I would also want to see a macro that allows me to write (x < y) instead of (< x y).

I might try to knock up "optional parens inference for Clojure" and add in some manner of curly infix as an exercise. It doesn't look like it will be too hard. Since {} is taken for literal maps, I'd need something else for curly infix. [|...|], %...%, $...$?

I'm sensing that most people seem to agree that S-exprs *are* fugly and hostile to those new to Lisp, but that the alternative (significant whitespace) is even worse. So we're kind of stuck with them if we want the expressive power of homoiconicity.

It's just that I think there's ample reason to believe S-expressions are the reason most people abandoned Lisp. It doesn't seem to be a great hook to get people to try a new one.

Martin

Alex Osborne

unread,
Dec 20, 2009, 10:05:02 AM12/20/09
to clo...@googlegroups.com
Martin Coxall <pseud...@me.com> writes:

> I might try to knock up "optional parens inference for Clojure" and
> add in some manner of curly infix as an exercise. It doesn't look like
> it will be too hard. Since {} is taken for literal maps, I'd need
> something else for curly infix. [|...|], %...%, $...$?

Let's just try a few example functions from contrib.

(defn subset?
"Is set1 a subset of set2?"
[set1 set2]
(and (<= (count set1) (count set2))
(every? set2 set1)))

Drop the outer parens.

defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and (<= (count set1) (count set2))
(every? set2 set1)

Lets break after "and" so we can drop some more parens.

defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and
<= (count set1) (count set2)
every? set2 set1

Now lets introduce infix with say, |...|.

defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and
|(count set1) <= (count set2)|
every? set2 set1

Maybe they need spaces?

defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and
| (count set1) <= (count set2) |
every? set2 set1

Has that suddenly made things more readable? Maybe. I don't know. It
certainly felt really weird writing it. That "and" by itself does
remind me of Haskell. The code is definitely looking very tree-like
now, maybe that's a good thing? My eyes *are* jumping to the "words"
easier and it's definitely less noisy.

Yet, this no longer obviously looks like a list. Is that bad? I don't
know. Do we need to be constantly reminded our code has a list
representation? Does it make macros harder to think about?

Lets try some more examples. How about arity overloading?

defn reductions
"Returns a lazy seq of the intermediate values of the reduction (as
per reduce) of coll by f, starting with init."
[f coll]
if (seq coll)
rec-seq self (cons (first coll) (map f self (rest coll)))
cons (f) nil
[f init coll]
rec-seq self (cons init (map f self coll))

Or a macro?

defmacro rec-seq
"Similar to lazy-seq but binds the resulting seq to the supplied
binding-name, allowing for recursive expressions."
[binding-name & body]
`let [s# (atom nil)]
reset! s# (lazy-seq (let [~binding-name @s#] ~@body))

It becomes weirdly tempting to insert more line breaks just to get rid
of the rest of the parens.

defmacro rec-seq
"Similar to lazy-seq but binds the resulting seq to the supplied
binding-name, allowing for recursive expressions."
[binding-name & body]
`let [s# (atom nil)]
reset! s#
lazy-seq
let [~binding-name @s#] ~@body

Hmm. Have we solved anything? Will this just make the complaints go

(from (too (many (parens))))

to
too
many
nesting
levels?

ngocdaothanh

unread,
Dec 20, 2009, 10:56:40 AM12/20/09
to Clojure
I have been studying Clojure for 3 months. My experience:
* After knowing about Lisp coding style and indents: parens
disappeared
* After knowing about reading from inside to outside: Clojure code is
more understandable (http://groups.google.com/group/clojure/
browse_thread/thread/144142dcb5586292/a3df3bb6741b1a56)
* The problem is not parens, the problem is *nested* parens. The 2
tips above + adding intermediate meaningful immutables using "let"
help a lot.

Sean Devlin

unread,
Dec 20, 2009, 11:49:21 AM12/20/09
to Clojure
Alex,

I just thought of something. I think we're all forgetting the amount
of hacking done at the REPL.

;This is easy to type
user=>(from (too (many (parens))))

;Uh-oh
user=>to
too
many
nesting
levels?

This might be an area where the parens are a win.

Sean

On Dec 20, 10:05 am, "Alex Osborne" <a...@meshy.org> wrote:

ajay gopalakrishnan

unread,
Dec 20, 2009, 12:35:33 PM12/20/09
to clo...@googlegroups.com
It's better if we can support both. It's never one size fits all.

Richard Newman

unread,
Dec 20, 2009, 12:39:00 PM12/20/09
to clo...@googlegroups.com
> It's better if we can support both. It's never one size fits all.

Who is "we"?

If you're talking about something *you* want, you can go build it…

Martin Coxall

unread,
Dec 20, 2009, 12:41:29 PM12/20/09
to clo...@googlegroups.com
On 20/12/2009 5:39 PM, Richard Newman wrote:
>> It's better if we can support both. It's never one size fits all.
>
> Who is "we"?
>
> If you're talking about something *you* want, you can go build it�
>

I see Clojure is well on the way to building a community at least as
repellingly exclusionary as all the other Lisps nobody uses.

Martin

Richard Newman

unread,
Dec 20, 2009, 1:09:48 PM12/20/09
to clo...@googlegroups.com
Martin,

> I see Clojure is well on the way to building a community at least as
> repellingly exclusionary as all the other Lisps nobody uses.

Thanks for the thinly veiled jab.

I've worked on a bunch of libraries, answered a bunch of questions on
the mailing list, and attended a few meetups. I put in quite a bit of
time to make beginners feel welcome and to help this community grow.

I object to people who are -- to exaggerate somewhat -- saying "hey,
this motorcycle's great, and I think tons more people would ride if
you put two more wheels on. Let me know when you're finished".

Real communities grow around people scratching shared itches, and I'm
not going to spend my time working on somebody else's non-problem for
free. I have plenty of -- paid -- Lisp work to do. (Must be all those
customers that don't exist.)

I think most of the active Clojure community ranges from not caring to
genuinely liking s-expression notation, and many of us have seen (many
times!) folks arrive from other languages, suggest that the Lisp of
the day should switch to using indentation to get rid of all those
parens, and then either move on to Ruby/Python/whatever… or realize
than the parens aren't a problem after all.

The same goes for infix math; lots of beginners start writing an infix
math library, and by the time they're done they've become familiar
with prefix notation and no longer want their new library.

Someone who cares enough to solve a problem should go and solve it.
Saying "we" should go and solve a problem is using weasel words to
coerce others.

Back on the topic: McCarthy originally intended Lisp to have an Algol-
ish syntax (m-expressions), but nobody ever finished the work because
they found s-expressions to be sufficient:

http://en.wikipedia.org/wiki/M-expression

> The project of defining M-expressions precisely and compiling them
> or at least translating them into S-expressions was neither
> finalized nor explicitly abandoned. It just receded into the
> indefinite future, and a new generation of programmers appeared who
> preferred internal notation to any FORTRAN-like or ALGOL-like
> notation that could be devised.
> — John McCarthy[1], History of Lisp

I think a lot of people would benefit from learning the lessons of
history.

I'm done on this topic. It's old enough to drink, I don't think
anything significant will come of it, and I'm happy with Clojure's
current trajectory.

-R

Stefan Kamphausen

unread,
Dec 20, 2009, 1:11:05 PM12/20/09