From: Kenneth Tilton
Subject: Road to Clojure Survey
Date: 
Message-ID: <49912cf7$0$3243$607ed4bc@cv.net>
In 25 words or less, why is Clojure better than Common Lisp?

In 100 words or less, why is Clojure better than Common Lisp?

Have you switched to Clojure? If so, from what?

From: ·············@gmail.com
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <bc840f65-d2aa-4632-bc32-8bfc935a6019@r10g2000prf.googlegroups.com>
On Feb 10, 12:30 am, Kenneth Tilton <·········@gmail.com> wrote:
> In 25 words or less, why is Clojure better than Common Lisp?
>
> In 100 words or less, why is Clojure better than Common Lisp?
>
> Have you switched to Clojure? If so, from what?

I guess I've switched, from Common Lisp, mostly because I changed jobs
last November and I couldn't take my CL code base with me, so I was
able to examine Clojure from a fresh perspective.

I'm exploring Clojure for my simulation work.  The biggest plus for me
in my domain is Clojure's concurrency model: immutable data
structures, agents, STM, and NO USER LOCKS!.  This makes it very easy
to spread model calculations across cores without having to protect
against improper concurrent data sharing either with hard to develop/
debug locks or by "convention".  Even though Clojure has no built-in
distributed support, it'll eventually get one and until then, it
appears that one can use any of the mechanisms available through the
JVM.

The second big thing for me is the Java interoperability, as my domain
needs access to lots of different math and there's lots of math
libraries for Java that are accessible through Clojure's very nice
Java interop facilities.  Additionally, it's very easy to tell Clojure
what the types are of  data items (like various CL declarations,
although easier to use) which speed things up.  CL's numeric tower is
more featureful, but Clojure's is certainly adequate.  There's no
native complex number support, although you can do that in the Java
layer.  I haven't yet needed to use complex numbers in my work so
that's not a big deal for me but I have seen some postings of math
types who miss native complex numbers.  There's no problem with
Clojure functions being the callbacks for Java code, as Clojure
functions implement all the right Java interfaces to make that work.

The HotSpot JVM seems speedy enough for me and it has a JIT so things
that run a while automatically speed up.  For some micro benchmarks in
the areas that I care about, Clojure compares well with SBCL once the
JIT has had a chance to optimize things.  The last time I had done any
serious work in Java was in 1997 so I was very pleasantly surprised at
how far JVM performance has progressed.

I initially thought I was going to miss CLOS because my prior code
base heavily depended on CLOS, especially method combination to help
make a lot of boilerplate disappear (in addition to removing the rest
of the boilerplate with a very high-level abstract model definition
language implemented with macros on steroids), but the way maps
(hashmaps), multi-methods, meta-data, and ad-hoc hierarchies work
together mostly make up for the lack of CLOS.

The big step for me here was getting past "it doesn't have CLOS, how
can I model essentially object-oriented simulation models without
something like CLOS?" to "with what's available in Clojure, what's the
Clojure-idiomatic way of creating the model building abstractions I
need?"  Once I got past that hang-up, I was able to proceed quite
nicely and am happy with the result.  My user-level model building
code will be as nice, concise, and high-level as my CL version was
(this is all work in progress).

The other things I miss in Clojure in addition to the above mentioned
method combination are symbol macros, macrolet, and LOOP (!), but
there are ways around most of these things so their ommision aren't
too painful.  For day-to-day programming, LOOP is probably the thing I
miss the most, as any looping has to be done through recursion.
There's a language construct to make tail-recursive calls efficient on
the TCO-less JVM, but I do miss some of the more powerful features of
LOOP (yes, I'm LOOP-evil).  However, the Clojure community is very
active so I expect that over time these will be filled in with
libraries.

When I was doing my initial investigation last December, what really
cinched it for me was watching Rich's Clojure for Lisp Programmers
videos and the concurrency video.  They are very good and should
answer any questions about whether Clojure is suitable for any
particular task.  The concurrency video is particularly good and goes
into technical depth discussing Clojure's concurrency support, the
design decisions Rich faced and why he made certain choices, and an in-
depth code walkthrough of an ant-colony food gathering simulation
using agents.  Very cool stuff.  Even though the video wasn't
specifically about Java interoperability, he does show building up a
graphical UI to show the ants speeding around in the REPL.  Very, very
cool stuff.

My opinion after watching these videos is that Rich has *very* good
design taste.  Starting with the goals he wanted, in my opinion, he's
made the right decision every time.  It's obvious from the videos that
he has a deep command of programming language theory, which has led
him to choose a lot of semantics and implementation techniques that
fit together well, instead of that "groping in the dark" feeling you
get from say, certain languages.

In summary, I'm not going to say that Clojure is better or worse than
Common Lisp.  For my particular domain, I can do some things easier
than I can do in the Common Lisp implementations I have available to
me (an important qualifier!) so it's useful for me.  Your mileage may
and will vary.

Oh, I should add that I've purchased the beta of Stuart Halloway's
"Programming Clojure" book from Pragmatic Programmer's and it covers
the language nicely.  I was able to breeze through the book in several
hours and came away with a good command of the language.  Keep in mind
that it's more geared towards a non-Lisp reader than a CL expert.

Glenn Ehrlich
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49919573$0$3220$607ed4bc@cv.net>
·············@gmail.com wrote:
> On Feb 10, 12:30 am, Kenneth Tilton <·········@gmail.com> wrote:
>> In 25 words or less, why is Clojure better than Common Lisp?
>>
>> In 100 words or less, why is Clojure better than Common Lisp?
>>
>> Have you switched to Clojure? If so, from what?
> 
> I guess I've switched, from Common Lisp, mostly because I changed jobs
> last November and I couldn't take my CL code base with me, so I was
> able to examine Clojure from a fresh perspective.

<snip great response>

Thx! You gave me ideas for a lot of questions. New survey soon (all of 
which you have already answered).


kt
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <4991fc96$0$90262$14726298@news.sunsite.dk>
 ge> I'm exploring Clojure for my simulation work.  The biggest plus for me
 ge> in my domain is Clojure's concurrency model: immutable data
 ge> structures, agents, STM, and NO USER LOCKS!.
 ge>   This makes it very easy to spread model calculations across cores
 ge> without having to protect

spreading across cores makes sense if it speed ups things, right?
even if there are no apparent locks, STM etc., etc. might have its
overhead. and it might be possible that Clojure running on all 8 cores
works actually slower than SBCL running on single one.

so, all these features are sort of "cool", but totally meaningless
without proper benchmarking data. (if we're speaking about CPU-bound
applications.) 
From: Kaz Kylheku
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <20090216135640.875@gmail.com>
On 2009-02-10, Kenneth Tilton <·········@gmail.com> wrote:
> In 25 words or less, why is Clojure better than Common Lisp?

It has more kinds of parentheses. And symbols have to prove themselves
worthy before they are interned.

> In 100 words or less, why is Clojure better than Common Lisp?

That constraint I can't deal with. I only ``do'' 25 words or less.

And anyway, in this world, by the time your ad execs throw together a monstrous
100 word sound bite, the competition has eaten your lunch.

> Have you switched to Clojure? If so, from what?

NewLisp, mostly. In fact, I switched from NewLisp to Clojure about six times
just today alone!   Well, no four. One of those times I went to Scheme first,
then Clojure, and another time I was actually using Common Lisp and /thought/
it was Clojure, until I misspelled some names. The misspellings scrolled off
the screen, and so I didn't know what to unintern to get back to a clean state.
I ended up rebooting the machine.
From: Pascal J. Bourguignon
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <7cfximzips.fsf@pbourguignon.anevia.com>
Kaz Kylheku <········@gmail.com> writes:

> On 2009-02-10, Kenneth Tilton <·········@gmail.com> wrote:
>> In 25 words or less, why is Clojure better than Common Lisp?
>
> It has more kinds of parentheses. And symbols have to prove themselves
> worthy before they are interned.

This is why it's worse.


>> In 100 words or less, why is Clojure better than Common Lisp?
>
> That constraint I can't deal with. I only ``do'' 25 words or less.

And 25 is not less than 100 anymore?


> And anyway, in this world, by the time your ad execs throw together a monstrous
> 100 word sound bite, the competition has eaten your lunch.


-- 
__Pascal Bourguignon__
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gms806$c5i$1@aioe.org>
On 2009-02-10 05:31:27 -0500, ···@informatimago.com (Pascal J. 
Bourguignon) said:

> Kaz Kylheku <········@gmail.com> writes:
> 
>> On 2009-02-10, Kenneth Tilton <·········@gmail.com> wrote:
>>> In 25 words or less, why is Clojure better than Common Lisp?
>> 
>> It has more kinds of parentheses. And symbols have to prove themselves
>> worthy before they are interned.
> 
> This is why it's worse.
> 
> 
>>> In 100 words or less, why is Clojure better than Common Lisp?
>> 
>> That constraint I can't deal with. I only ``do'' 25 words or less.
> 
> And 25 is not less than 100 anymore?

<http://en.wikipedia.org/wiki/Sarcasm>

-- 
Raffael Cavallaro, Ph.D.
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gmt9fs$53o$1@news.motzarella.org>
Pascal J. Bourguignon schrieb:
> Kaz Kylheku <········@gmail.com> writes:
> 
>> On 2009-02-10, Kenneth Tilton <·········@gmail.com> wrote:
>>> In 25 words or less, why is Clojure better than Common Lisp?
>> It has more kinds of parentheses. And symbols have to prove themselves
>> worthy before they are interned.
> 
> This is why it's worse.

The question at this point could be why this is worse.
Honestly, I see only advantages here.
The [] and {} give some hold to the eye, which I find nice.
One can of course argue that it is less consistent, and that a �real
Lisper� will only want to use (). But let�s not forget that () them-
self are reader macros. And if we want to argue with consistency in
mind, then those people should not make use of other reader macros in
CL as well, such as  '  #'  `  ,  ,@
I however see that a few handselected reader macros are a great thing.
They should exist for the most commonly used tasks.
Lists are mostly used in Clojure to write code :)
Vectors have taken more or less the place of the list.
One can �cons� elements to it (the function really is conj) and traverse
it with the same performance as lists. But random access is done in near
constant time. Also reversing a vector is much faster, though this is
less often needed, as conj adds elements at the end of the vector, not
to the front (as with lists).

Passing around small hashmaps is so simple.
(some-function {:a 10, :b 20}) vs

(let ((temp (make-hash-table)))
   (setf (gethash :a temp) 10
         (gethash :b temp) 20)
   (some-function temp))


And the other thing that Kaz said about interned symbols also makes sense.
For example Hans H�bner writes in his blog:
�Clojure wants to be a Lisp, but it explicitly does not try to be
backwards compatible. This opened a rather large design space to Rich
Hickey, and some of the choices he made really do make sense. He
specifies a reader, yet his reader does not intern symbols. That is a
big win, as it allows the reader to actually work with arbitary Clojure
source files. In Common Lisp, one needs to re-implement a full reader
which does not intern symbols if one wants to read Common Lisp source
files. This is kind of ironic, as the "Code is Data" mantra that we keep
repeating does not really reflect what is possible in practice.�
Soure: http://netzhansa.blogspot.com/2008/10/trying-clojure.html


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal J. Bourguignon
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <87vdrhbrkb.fsf@galatea.local>
André Thieme <······························@justmail.de> writes:

> Pascal J. Bourguignon schrieb:
>> Kaz Kylheku <········@gmail.com> writes:
>> 
>>> On 2009-02-10, Kenneth Tilton <·········@gmail.com> wrote:
>>>> In 25 words or less, why is Clojure better than Common Lisp?
>>> It has more kinds of parentheses. And symbols have to prove themselves
>>> worthy before they are interned.
>> This is why it's worse.
>
> The question at this point could be why this is worse.
> Honestly, I see only advantages here.
> The [] and {} give some hold to the eye, which I find nice.
> One can of course argue that it is less consistent, and that a „real
> Lisper” will only want to use (). But let’s not forget that () them-
> self are reader macros. And if we want to argue with consistency in
> mind, then those people should not make use of other reader macros in
> CL as well, such as  '  #'  `  ,  ,@

Let's say that it's a personal taste. (And indeed, I use (function x)
rather than #'x, and sometimes (eg for pedagogical reasons), I use
(quote x) instead of 'x.

Reducing the set of special characters used to write code let you
write it faster.  Keying in English is fast, because you only use
letters, and a very small number of punctuation, compared to keying in
popular programming languages.  If you resist the temptation of using
a lot of reader macros in lisp, then you can type lisp code as fast as
English text.


Also, it would be nice if the language didn't use all the characters,
and left some for user's reader macros. In Common Lisp, {}, [] , !?
and a few others are reserved to the user.  (Of course, with unicode
this is less of a problem).



> Passing around small hashmaps is so simple.
> (some-function {:a 10, :b 20}) vs
>
> (let ((temp (make-hash-table)))
>   (setf (gethash :a temp) 10
>         (gethash :b temp) 20)
>   (some-function temp))

This is crazy.  Nobody write such a form!

(htable :a 10 :b 20)
--> #S(HASH-TABLE :TEST EXT:FASTHASH-EQL (:B . 20) (:A . 10))


>
>
> And the other thing that Kaz said about interned symbols also makes sense.
> For example Hans Hübner writes in his blog:
> „Clojure wants to be a Lisp, but it explicitly does not try to be
> backwards compatible. This opened a rather large design space to Rich
> Hickey, and some of the choices he made really do make sense. He
> specifies a reader, yet his reader does not intern symbols. That is a
> big win, as it allows the reader to actually work with arbitary Clojure
> source files. In Common Lisp, one needs to re-implement a full reader
> which does not intern symbols if one wants to read Common Lisp source
> files. This is kind of ironic, as the "Code is Data" mantra that we keep
> repeating does not really reflect what is possible in practice.”
> Soure: http://netzhansa.blogspot.com/2008/10/trying-clojure.html

We only need to add a CDR for a READTABLE-PARSE-TOKEN hook to be able
to read uninterned sources without reimplementing the reader.

But even with the current standard, the point is that reader macros
are not to be abused for lisp programs.  It's better in lisp programs
or embeded DSL to use normal functions or macros such as (htable :a 10
:b 20) than to use a reader macro such as {:a 10 :b 20}.  

Reader macros are designed to build user level DSL. 

If you need to read a DSL source without "interning" it, then you
should use a normal parser.

-- 
__Pascal Bourguignon__
From: ··············@excite.com
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <c7832652-d652-49e4-b36d-fc59c4742d44@p2g2000prf.googlegroups.com>
On Feb 10, 10:06 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Reducing the set of special characters used to write code let you
> write it faster.  Keying in English is fast, because you only use
> letters, and a very small number of punctuation, compared to keying in
> popular programming languages.

I beg to point out that some folks can touch-type the non-letter
keys...
and although clearly farther away from home position and therefore
slower,
each non-letter used in a non-letter-rich syntax will generally
represent
many letters of lisp symbol.  non-letter-rich syntax can be an
effective
compression for 1) reading, 2) thinking, and yes also 3) typing, if
one
touch-types the non-letters.

That said, the whole reason I like and use the CL type of Lisp syntax
is
because my preferences agrees with yours on:

> But even with the current standard, the point is that reader macros
> are not to be abused for lisp programs.  It's better in lisp programs
> or embeded DSL to use normal functions or macros such as (htable :a 10
> :b 20) than to use a reader macro such as {:a 10 :b 20}.  
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gmut6v$vra$1@aioe.org>
On 2009-02-10 22:06:28 -0500, ···@informatimago.com (Pascal J. 
Bourguignon) said:

> Also, it would be nice if the language didn't use all the characters,
> and left some for user's reader macros. In Common Lisp, {}, [] , !?
> and a few others are reserved to the user.  (Of course, with unicode
> this is less of a problem).

This is not an issue for clojure:
from: <http://clojure.org/reader>
"The read table is currently not accessible to user programs."

Of course many common lisp users will think this more a bug than a feature...
-- 
Raffael Cavallaro, Ph.D.
From: Anticomuna
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <4625d88a-3dd5-4266-9e4f-693737dfd43c@m12g2000vbp.googlegroups.com>
On Feb 10, 10:25 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Pascal J. Bourguignon schrieb:
>
> > Kaz Kylheku <········@gmail.com> writes:
>
> Vectors have taken more or less the place of the list.
> One can „cons” elements to it (the function really is conj) and traverse
> it with the same performance as lists. But random access is done in near
> constant time. Also reversing a vector is much faster, though this is
> less often needed, as conj adds elements at the end of the vector, not
> to the front (as with lists).

This is the one thing I don't understand. Ok, you have just cited the
properties of a vector in comparison with a singly linked list. But
what does it change in practical terms for the developer?

If you have data that needs to be addressable directly you would use a
vector in CL.

The lists, on the other hand, make more sense because you can easily
extend them by appending objects or breaking them apart. How can you
make a "list" bigger or smaller without reallocating it or wasting
space (if smaller).
From: Kaz Kylheku
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <20090223103630.435@gmail.com>
On 2009-02-11, André Thieme <······························@justmail.de> wrote:
> Pascal J. Bourguignon schrieb:
>> Kaz Kylheku <········@gmail.com> writes:
>> 
>>> On 2009-02-10, Kenneth Tilton <·········@gmail.com> wrote:
>>>> In 25 words or less, why is Clojure better than Common Lisp?
>>> It has more kinds of parentheses. And symbols have to prove themselves
>>> worthy before they are interned.
>> 
>> This is why it's worse.
>
> And the other thing that Kaz said about interned symbols also makes sense.
> For example Hans Hübner writes in his blog:
> „Clojure wants to be a Lisp, but it explicitly does not try to be
> backwards compatible. This opened a rather large design space to Rich
> Hickey, and some of the choices he made really do make sense. He
> specifies a reader, yet his reader does not intern symbols. That is a
> big win, as it allows the reader to actually work with arbitary Clojure
> source files. In Common Lisp, one needs to re-implement a full reader
> which does not intern symbols if one wants to read Common Lisp source
> files.

There is another solution for this: go ahead and intern, but make packages use
weak references to symbols.

When the only references to a symbol emanate from one or more packages, that
symbol can be removed from the package.

This uses a well-understood and widely implemented existing mechanism, and is
highly compatible with Common Lisp (since only highly contrived, rare programs
could tell that this scavenging of unused symbols is being done).

Essentially, the argument is that responsibility of implementing behaviors that
resemble ``forgetting'' belongs to the domain of garbage collection, and
surrounding refinements.
From: Kenneth Tilton
Subject: Road to Clojure Survey 2.0
Date: 
Message-ID: <499198d0$0$3229$607ed4bc@cv.net>
What is your Clojure Status?
   - What is Clojure?
   - Never looked at it.
   - Looked but did not like because ___
   - Will use for some work because ___ but not all because ___ but 
continue to use ___ for ___ because ____.
   - Will now use instead of ___ because ____
   - Other ____


(I think the rest are for anyone who will be using Clojure)

If Java access was a big factor, why not ABCL or AllegroCL?

What do you miss from Common Lisp (or whatever the "from" language was).


Other _______
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gms98e$dm4$1@aioe.org>
On 2009-02-10 10:10:13 -0500, Kenneth Tilton <·········@gmail.com> said:

> What is your Clojure Status?

is clojure about to vault into the tilton pantheon?!

>    - What is Clojure?
>    - Never looked at it.
>    - Looked but did not like because ___
>    - Will use for some work because ___ but not all because ___ but 
> continue to use ___ for ___ because ____.

will use for some work but not all because of:

cross platform java libs, especially cross platform gui libs

integration with emacs/slime

active enthusiastic user community and much contributed code

mikel evins likes it!

built in ease of threading due to immutablility of clojure data 
structures (i.e., pure functional semantics).

possiblility of easy web deployment via applets (though not currently 
high on my list)


continue to use CCL because of excellent mac os x integration.


>    - Will now use instead of ___ because ____
>    - Other ____
> 
> 
> (I think the rest are for anyone who will be using Clojure)
> 
> If Java access was a big factor, why not ABCL or AllegroCL?
> 
> What do you miss from Common Lisp (or whatever the "from" language was).

maturity of the language. code from six months ago often doesn't work 
because breaking changes are still being made to the language.

> 
> 
> Other _______


-- 
Raffael Cavallaro, Ph.D.
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4991b329$0$3227$607ed4bc@cv.net>
Raffael Cavallaro wrote:
> On 2009-02-10 10:10:13 -0500, Kenneth Tilton <·········@gmail.com> said:
> 
>> What is your Clojure Status?
> 
> is clojure about to vault into the tilton pantheon?!

No, just curious. Thx for the survey response. Mikel is indeed a big plus.

kt

> 
>>    - What is Clojure?
>>    - Never looked at it.
>>    - Looked but did not like because ___
>>    - Will use for some work because ___ but not all because ___ but 
>> continue to use ___ for ___ because ____.
> 
> will use for some work but not all because of:
> 
> cross platform java libs, especially cross platform gui libs
> 
> integration with emacs/slime
> 
> active enthusiastic user community and much contributed code
> 
> mikel evins likes it!
> 
> built in ease of threading due to immutablility of clojure data 
> structures (i.e., pure functional semantics).
> 
> possiblility of easy web deployment via applets (though not currently 
> high on my list)
> 
> 
> continue to use CCL because of excellent mac os x integration.
> 
> 
>>    - Will now use instead of ___ because ____
>>    - Other ____
>>
>>
>> (I think the rest are for anyone who will be using Clojure)
>>
>> If Java access was a big factor, why not ABCL or AllegroCL?
>>
>> What do you miss from Common Lisp (or whatever the "from" language was).
> 
> maturity of the language. code from six months ago often doesn't work 
> because breaking changes are still being made to the language.
> 
>>
>>
>> Other _______
> 
> 
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4991fd13$0$90273$14726298@news.sunsite.dk>
 KT>    - Looked but did not like because ___

i did not like it because it is not a Common Lisp!

plus, at time i was looking at it, it threw errors in Java backtrace format,
that is, you've misplaced paren, and it throws ton of bullshit at you.
very unpleasant. (it seems they've aldready fixed this) 
From: TomSW
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <7efb8844-2c7a-42d2-b5a3-af05f81cc584@e18g2000yqo.googlegroups.com>
On Feb 10, 4:10 pm, Kenneth Tilton <·········@gmail.com> wrote:
> What is your Clojure Status?

I'm using it to learn the Java libraries without having to use Java. I
don't think I'll be lucky enough to find another Lisp job soon:
finding IT jobs in Belgium with no Dutch is hard enough. So I'm
preparing for the worst...

> If Java access was a big factor, why not ABCL or AllegroCL?

Clojure in non-proprietary and has lots of interesting features built-
in, in particular, concurrency, abstract datatypes (collections,
mappings), lazy evaluation.

> What do you miss from Common Lisp (or whatever the "from" language was).

I haven't been using Clojure for long enough to miss much of Common
Lisp.

...

Another interesting approach to leveraging Java libraries is Jnil
(http://common-lisp.net/project/jnil/), which actually translates them
into Common Lisp. The maintainer could really do with some support.

cheers,
Tom
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn2eii$6sf$1@news.motzarella.org>
Francogrex schrieb:
> On 10 feb, 16:10, Kenneth Tilton <·········@gmail.com> wrote:
>> What is your Clojure Status?
>>    - What is Clojure?
>>    - Never looked at it.
>>    - Looked but did not like because ___
>>    - Will use for some work because ___ but not all because ___ but
>> continue to use ___ for ___ because ____.
>>    - Will now use instead of ___ because ____
>>    - Other ____
> 
> I have looked at clojure but don't want to use it because simply it's
> not "common lisp" and it has that "unhealthy" connection to Java
> (either directly defined or not). In addition I am against the
> dispersal/waste of efforts that sprout different programming languages
> instead of concentrating it all to improve the already existing ones.
> I have more respect for an old language like lisp that has matured and
> evolved over the time (albeit to different dialects- of course I would
> have preferred that they stay united-). Now unless you think of
> clojure as an evolution and an extension of common lisp...

I respect your opinion, however, I would like to mention two things:
1) The connection to Java can be seen by some folks as very healthy.
2) When you argue about matureness and evolution, then Clojure could
    be interesting. The language is much more simple than Lisp. And
    some core parts of a Lisp were already provided by the JVM. For
    example the GC, the Exception system and some tenthousand ready to
    use methods. In that regard, Clojure can be seen as even more mature
    than CL implementations. As Java is the most popular programming
    language it gets on a daily basis more man hours of testing than
    all CLs got in the past years. Billions were invested by the biggest
    IT companies into the JVM, and it went through an evolutionary
    process in which it got very mature.

    Speaking of evolution: Clojure learned from Lisp. So it is not a
    new language that started from scratch. No, it inherited the DNA
    of its parents. It took the efforts of research in the past 50
    years and continued to evolve from that point. So, it is the next
    step in evolution of Lisp.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn2ffv$2pj$1@aioe.org>
On 2009-02-12 19:23:41 -0500, Andr� Thieme 
<······························@justmail.de> said:

> And
>     some core parts of a Lisp were already provided by the JVM. For
>     example the GC, the Exception system and some tenthousand ready to
>     use methods. In that regard, Clojure can be seen as even more mature
>     than CL implementations.

Not really. This argues for the maturity of the *platform* on which 
clojure is built (i.e., the jvm). Clojure itself is clearly still not 
mature. There's a thread still running on how to fix mod:

user=> (mod -3 3)
3

So clojure, the language, not the platform it is built on, is still not 
nearly as mature as common lisp.
-- 
Raffael Cavallaro, Ph.D.
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <499563c9$0$90272$14726298@news.sunsite.dk>
 AT> 1) The connection to Java can be seen by some folks as very healthy.

oh yes, it is very healthy (for a functional language!) to have "recur" 
special
operator instead of normal tail recursion because of JVM deficiency.

 AT>  In that regard, Clojure can be seen as even more mature
 AT>  than CL implementations.

platform maturity has nothing to do with language implementation maturity.
i have here a build labeled "2008-09-16", just few months ago error handling
was totally broken and weird as it was spitting java backtraces:

user=> (())(()))
java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot 
be cast to clojure.lang.IFn
java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot 
be cast to clojure.lang.IFn
        at user.eval__2290.invoke(Unknown Source)
        at clojure.lang.Compiler.eval(Compiler.java:3891)
        at clojure.lang.Repl.main(Repl.java:75)

when considerable portions of implementation get reorganized in short 
periods of time,
that is *not* called "mature" 
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn4ics$qn2$1@news.motzarella.org>
Alex Mizrahi schrieb:
>  AT> 1) The connection to Java can be seen by some folks as very healthy.
> 
> oh yes, it is very healthy (for a functional language!) to have "recur" 
> special operator instead of normal tail recursion because of JVM deficiency.

It’s true, it’s healthy to have recur.
I agree that it is not nice that the JVM does not have tail recursion
yet. But in practice that is not a real issue, as recur is available.

Let’s look at this unreadable mess in CL:

(DEFUN Y (F)
  (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
   #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))))

(FUNCALL (Y #'(LAMBDA (FN)
                 #'(LAMBDA (X)
                     (IF (ZEROP X) 0 (+ X (FUNCALL FN (- X 1)))))))
          200)
==> 20100

we can do this in Clojure:
((fn [n] (loop [x n, res 0]
            (if (zero? x) res (recur (dec x) (+ x res)))))
  12345678)

No Y-Combinator needed, much shorter, much more pleasant for the eye.
Plus: this call works.
When I gave the argument of 2000 in clisp on Windows it crashed.
Stack overflow I guess.


Or another example:
(defun fibonacci (n)
   (labels ((fibo-helper (x result)
              (if (zerop x)
                  result
                  (fibo-helper (1- x) (* x result)))))
     (fibo-helper n 1)))

would be in Clojure (without recur):
(defn fibonacci [n]
   ((fn fibo-helper [x result]
      (if (zero? x)
        result
        (fibo-helper (dec x) (* x result))))
    n 1))

The labels is not needed, as fn can be given a name (fn in Clojure is
CLs LAMBDA). Anyway, this is not stack-safe right now, as the JVM does
not support tail call optimazation (though Jon mentioned that the team
of the OpenJDK is working on that).

Now in Clojure we simply replace the call of fibo-helper with recur:
(defn fibonacci [n]
   ((fn fibo-helper [x result]
      (if (zero? x)
        result
        (recur (dec x) (* x result))))
    n 1))

That’s the only change. It is still following the idiom that is needed
in all programming languages for tail recursive calls.
This would also allow us to eliminate the function name we gave to fn.
This makes it again shorter. And if we want to, we can put in a loop:
(defn fibonacci [n]
   (loop [x n   result 1]
     (if (zero? x)
       result
       (recur (dec x) (* x result)))))

And although I am doing CL since 6 years and Clojure just 4 months or
so, this looks cleaner in my opinion than the CL version.


>  AT>  In that regard, Clojure can be seen as even more mature
>  AT>  than CL implementations.
> 
> platform maturity has nothing to do with language implementation maturity.
> i have here a build labeled "2008-09-16", just few months ago error handling
> was totally broken and weird as it was spitting java backtraces:
> 
> user=> (())(()))
> java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot 
> be cast to clojure.lang.IFn
> java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot 
> be cast to clojure.lang.IFn
>         at user.eval__2290.invoke(Unknown Source)
>         at clojure.lang.Compiler.eval(Compiler.java:3891)
>         at clojure.lang.Repl.main(Repl.java:75)
> 
> when considerable portions of implementation get reorganized in short 
> periods of time,
> that is *not* called "mature" 

Yes, I understand your position. And also thanks to Raffael, he is also
right.
In fact, Clojure did not reach 1.0 status, so yes, breaking changes can
still occur. But most of the time Rich adds more (very useful)
abstractions and tools to the language, instead of making breaking changes.

However, I also like to look at this from a more practical side.
Clojure is usable now. One can step with debuggers through the code
line by line, one can profile it, compile it into doubleclickable
.jar files (like .exe under Windows) or simply work in Emacs+Slime.
Nearly all parts of the language itself work perfectly. But when
writing real world applications one constantly can be in need of
libs, that already do parts of what you want to do.
Lisps like Allegro, Lispworks or sbcl are being worked on every
day. It’s similar to what happens to Clojure.
It is a bit unfair to make the comparison of what changes in the
core language. CLs is already defined and can not be changed.
Clojure is still open, and Rich can decide to add more to it.
So of course, this will result in more changes in the core when
compared to what happens to CLs.
I worked professionally with Allegro and also Lispworks.
In both I or my workmates discovered bugs in their libs, like
database stuff.
This is much more unlikely to happen when using Clojure, as it
simply offers some ten thousand more functions which still need
to be implemented in CL first, and which were tested some orders
of magnitude more intense than their CL equivalents.
And one could argue if it can be seen as a bug as well, if some
libs are simply not available (like a server for RESTful apps)
in CL. Although Jon writes a lot of provocative material here,
and sometimes explicitly enjoys to bring in some trolling, he
also mentioned very true things, such as that some CL libs have
like 80 users. Not 80k, but a mere 80. Development on important
stuff does not happen as much as I wish (are cursors already
available in sql libs?).
Clojure is actively and intensly used by some hundred people.
We test every new feature, and honestly, I did not stumble upon
lot’s of bugs. Rich fixes them so fast, it’s really nice.

So, if I see the whole variety of things that are available when
programming in Clojure, then only a tiny fraction of it is not
mature.
It’s true that there are some more bugs, but also check out what
SBCL changes:
http://www.sbcl.org/all-news.html

Just scroll down this list. SBCL exists since years, and not one
main developer is working on it, but 5-25.
When I look at this list I see not interesting additions to the
main language and libraries. Tons of bug fixes for core stuff.

Maybe it’s okay to call SBCL not mature, and only see the main
two commercial CLs (Allegro and Lispworks) this way.
I don’t know what they are doing, but they still do bugfixes
constantly. And although they had 15+ more years of time than
Clojure, they still need to fix core stuff. And in their libs
they have also several bugs that my companies uncorvered.

As much I understand the POV that Clojure is not mature, because
of the good reasons you and Raffaello gave, I see it differently
and would call it already mature.
It already offers right now basically everything that is needed
for professional and commercial development. What mostly happens
is that even better abstractions are added every few days.
For me it’s extremly difficult to go back doing CL, because I miss
so much. Kenny asked in this thread also what I miss from CL.
I have to think long to come up with maybe a few points.
But the other direction.. that is the real problem.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn54eo$jnr$1@aioe.org>
On 2009-02-13 14:41:14 -0500, Andr� Thieme 
<······························@justmail.de> said:

> we can do this in Clojure:
> ((fn [n] (loop [x n, res 0]
>             (if (zero? x) res (recur (dec x) (+ x res)))))
>   12345678)

we can do this in common lisp:

((lambda (n) (loop for x from n downto 0 summing x)) 12345678)

and when we do it in Clozure Common Lisp (dx86cl64) it runs 10 times as 
fast as your clojure code on the same machine.
-- 
Raffael Cavallaro, Ph.D.
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn5ba4$46i$1@news.motzarella.org>
Raffael Cavallaro schrieb:
> On 2009-02-13 14:41:14 -0500, Andr� Thieme 
> <······························@justmail.de> said:
> 
>> we can do this in Clojure:
>> ((fn [n] (loop [x n, res 0]
>>             (if (zero? x) res (recur (dec x) (+ x res)))))
>>   12345678)
> 
> we can do this in common lisp:
> 
> ((lambda (n) (loop for x from n downto 0 summing x)) 12345678)
> 
> and when we do it in Clozure Common Lisp (dx86cl64) it runs 10 times as 
> fast as your clojure code on the same machine.

We were talking about recur and its advantages. The issue was not about
performance.

It�s likely that Clozure CL or also SBCL will run much faster, as
Clojure would use boxed numbers, which have to be unboxed first and then
boxed again.
One would have to give type hints, as in:

(loop [r (long 0) n (long 12345678)] (if (zero? n) r (recur (+ r n) (dec 
n))))

Now that runs probably at very comparable speed.

Anyway, if I want to outperform your Clozure Cl code above by a factor
of 150 in Clojure, then this would do:
(defn sum [n] (+ (/ n 2) (/ (* n n) 2)))


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn5g06$851$1@aioe.org>
On 2009-02-13 21:46:26 -0500, Andr� Thieme 
<······························@justmail.de> said:

> We were talking about recur and its advantages. The issue was not about
> performance.
[snip]
> (loop [r (long 0) n (long 12345678)] (if (zero? n) r (recur (+ r n) (dec n))))

The point is that there is no advantage to recur. It's a wart 
necessitated by the jvm's lack of tail call optimization.

In any conforming scheme it's just a plain old recursive call. In any 
conforming common lisp it's just a simple loop. And in most decent 
common lisps, as long as you're not optimizing for debug to keep the 
stack frames, if you really want to wear the scheme recursive hair 
shirt, you can do it recursively too:

(labels ((loop (r n) (if (zerop n) r (loop (+ r n) (1- n)))))
    (loop 0 12345678))

but of course a real loop, not recursion, is the common lisp norm:

(loop for i upto 12345678 summing i)




-- 
Raffael Cavallaro, Ph.D.
From: John Thingstad
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <op.upbwaopxut4oq5@pandora.alfanett.no>
P� Sat, 14 Feb 2009 05:06:45 +0100, skrev Raffael Cavallaro  
<················@pas.espam.s.il.vous.plait.mac.com>:

>
> but of course a real loop, not recursion, is the common lisp norm:
>
> (loop for i upto 12345678 summing i)
>
>

Depend what you call norm. (let ((j 0)) (dotimes (i 12345678 j) (incf j  
i))) seems less offensive to loop haters. Some swear Lisp should be purely  
functional. So pehaps series? ;) The style wars will never end.. I would  
guess there are as many styles as Lispers. The developers at Clojure  
dislike that you can mix and match styles. To me it is one of the things  
that attracts me to the language.

--------------
John Thingstad
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn5u7i02m7h@enews4.newsguy.com>
Raffael Cavallaro wrote:

> but of course a real loop, not recursion, is the common lisp norm:
> 
> (loop for i upto 12345678 summing i)

Ruby:

sum=0;(1..12345678).each{|n| sum+=n}
From: Slobodan Blazeski
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <c49ee051-50e3-496b-b40b-e68f33d45b26@41g2000yqf.googlegroups.com>
On Feb 14, 9:09 am, "William James" <·········@yahoo.com> wrote:
> Raffael Cavallaro wrote:
> > but of course a real loop, not recursion, is the common lisp norm:
>
> > (loop for i upto 12345678 summing i)
>
> Ruby:
>
> sum=0;(1..12345678).each{|n| sum+=n}
That's far worse than Raffael solution.Why do you need so many tokens
for such a simple thing?
Try this:
J:
+/i.12345679
bobi
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6cki$g6b$1@news.motzarella.org>
Raffael Cavallaro schrieb:
> On 2009-02-13 21:46:26 -0500, Andr� Thieme 
> <······························@justmail.de> said:
> 
>> We were talking about recur and its advantages. The issue was not about
>> performance.
> [snip]
>> (loop [r (long 0) n (long 12345678)] (if (zero? n) r (recur (+ r n) 
>> (dec n))))
> 
> The point is that there is no advantage to recur. It's a wart 
> necessitated by the jvm's lack of tail call optimization.

I see your point, however, I personally disagree.
First of all, I would like to mention that recur also has no disadvantages.
That is not enough to introduce something into a language. Otherwise one
could add recur1, recur2, ... recur24637, ...
They all would have no disadvantages (assuming they work exactly like
recur).
But the fact that the JVM currently does not support tail call opt.
under the hood is a very plausible reason to add it.
Besides that, recur does in fact have three advantages:
1. it allows anon functions to call recurse, they can call themselves
2. it blocks you from accidently not doing tail calls, because the
    compiler can check if recur really is in the tail position
3. as a minor advantage I want to add, that it is easy to search in code
    for occurrences of �recur�, or if you spot it somewhere while flying
    over your sources, you immediately see �Ah, here we have a recursive
    call�.

So even when the JVM will support one day tail call optimization, recur
will not go.
Jon Harrop indicated that this (adding TCO) is happening at the moment
for the OpenJDK, and as Sun works on their own functional programming
language �Fortress� I suppose they will also be interested in adding it.
I will definitly continue to use recur. What I will stop to use are
trampolines.


> but of course a real loop, not recursion, is the common lisp norm:
> 
> (loop for i upto 12345678 summing i)

Yes, loop is nice. In principle it�s what I would do in CL as well,
although for this specific case I would really prefer to directly
calculate that number via (defn sum [n] (+ (/ n 2) (/ (* n n) 2))).
In Clojure I could do:
   (apply + (range 12345678)))

or use reduce instead of apply.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6lu5$6aq$1@aioe.org>
On 2009-02-14 07:15:10 -0500, Andr� Thieme 
<······························@justmail.de> said:

> First of all, I would like to mention that recur also has no disadvantages.

It can't be used for mutual recursion. Common Lisp's labels can; 
scheme's letrec can. Clojure needs a separate piece of 
work-around-the-jvm syntax for mutual recursion.



-- 
Raffael Cavallaro, Ph.D.
From: Rich Hickey
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <dd420394-7c6d-46e2-9a19-073e38a4000b@l1g2000yqj.googlegroups.com>
On Feb 14, 9:54 am, Raffael Cavallaro
<················@pas.espam.s.il.vous.plait.mac.com> wrote:
> On 2009-02-14 07:15:10 -0500, André Thieme
> <······························@justmail.de> said:
>
> > First of all, I would like to mention that recur also has no disadvantages.
>
> It can't be used for mutual recursion. Common Lisp's labels can;
> scheme's letrec can. Clojure needs a separate piece of
> work-around-the-jvm syntax for mutual recursion.
>

I'm loathe to jump into this discussion, as I see no point in 'Clojure
vs CL', but I think a few points need clarification:

Clojure of course supports recursion, it just doesn't guarantee that
it won't consume stack - same as CL. loop/recur is not a substitute
for TCO. It is just Clojure's analogue to CL's 'do', an iteration
construct that happens to look like a recursive call because I prefer
that style to that of CL's do - but it's nothing more than a simple
loop. It is workaround syntax only to the extent that CL's do is
workaround syntax - neither language guarantees TCO so both must have
iteration constructs. It is only put forth as an option to those
coming from Scheme looking for TCO in the self-call case, and always
with the caveat that it does not support mutual recursion.

Clojure has nothing against iteration, there is also dotimes and
doseq, analogues to CL's dotimes and dolist.

The absence of letrec/labels in Clojure is completely independent - I
have nothing against it and just haven't gotten around to it yet. When
I do, such mutually recursive calls may consume stack, as with CL's
labels. The absence of letrec/labels only precludes mutually recursive
local functions - mutually recursive global functions are already
supported, as are normally self-recursive local functions without
using recur:

(fn aname [arg] ... (aname 42))

I hope this clarifies things, and sorry to see the arguing,

Rich
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn9oc7$mmr$1@aioe.org>
On 2009-02-15 10:57:44 -0500, Rich Hickey <··········@gmail.com> said:

> I'm loathe to jump into this discussion, as I see no point in 'Clojure
> vs CL', but I think a few points need clarification:

First, thanks for the clarifications, and especially thanks for 
clojure. It's a great language and I'm really happy to see and use your 
innovations in the lisp language design space.

> 
> Clojure of course supports recursion, it just doesn't guarantee that
> it won't consume stack - same as CL.

You are of course right when you say that clojure has exactly the same 
capabilities wrt TCO as the common lisp standard. The thing is, it is 
common[1] for lisp implementations to go beyond the standard in this 
regard (ccl, sbcl, 64bit lispworks, allegro cl), and so, beyond what 
clojure does.

> loop/recur is not a substitute
> for TCO. It is just Clojure's analogue to CL's 'do', an iteration
> construct that happens to look like a recursive call because I prefer
> that style to that of CL's do - but it's nothing more than a simple
> loop.

With respect, I think we're just doing semantics here. To me, TCO is 
the process of taking tail recursive syntax and turning it into 
iteration. If loop/recur is tail recursive syntax (it is) that is 
transformed by the compiler into iteration (a simple loop) then it is a 
kind of TCO.

In any event, I will repeat what I wrote to Andre. The real innovations 
of clojure are the persistent (i.e., immutable) data structures, the 
egal equality semantics, the stm for mutable data, and the absence of 
explicit locks in user code, all of which together are greater than the 
sum of the parts. Clojure is a lisp which makes doing concurrency 
correctly a central part of the semantics of the language. This is, 
imho, what sets clojure apart, not loop/recur.

Again, thanks for clojure; I wish you much success with it. And sorry 
for the bickering.

regards,

Ralph




[1] bad pun, I know :(



-- 
Raffael Cavallaro, Ph.D.
From: Madhu
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <m3hc2uz6f0.fsf@moon.robolove.meer.net>
* Rich Hickey
Wrote on Sun, 15 Feb 2009 07:57:44 -0800 (PST):

| The absence of letrec/labels in Clojure is completely independent - I
| have nothing against it and just haven't gotten around to it yet. When
| I do, such mutually recursive calls may consume stack, as with CL's
| labels. The absence of letrec/labels only precludes mutually recursive
| local functions - mutually recursive global functions are already
| supported, as are normally self-recursive local functions without
| using recur:

In CL LABELS has to be a special operator because CL lacks
lambda-macros.

Given the existance of lambda in some language, mutual recursion of
global function itself can be implemented easily by the user using
multiple fixed point combinators[1]

However it is not trivial to wrap this implementation as a LABELS macro
because, according to the spec, code like

     (labels ((foo () A))  B)

can refer to #'foo in the bodies of A or B, and the macro cannot rewrite
(funcall #'foo) to the apropriate expansion.

I suspect your delay in implementing LABELS is for reasons along these
lines.

[I suspect LABELS could be implemented easily via MACROLET in Genera
though]

[1] I remember seeing a pointer on CLL to

    Mayer Goldberg.
    "A variadic extension of Curry's fixed-point combinator".
    Workshop on Scheme and Functional Programming (2002).
    October 2002.

Which is just a verbose rendering of Queinnec's code

(defun NfixN2 (&rest fs)
  "Queinnec's variadic multiple fixed point combinator. (1996)"
  (let ((d
         (lambda (w)
           (lambda (f*)
             (mapcar
              (lambda (f)
                (apply f
                       (mapcar
                        (lambda (i)
                          (lambda (&rest a)
                            (apply
                             (elt (funcall (funcall w w) f*) i)
                             a)))
                        (iota 0 (length f*)))))
              f*)))))
    (funcall (funcall d d) fs)))


#||
which is then used, for example like this:

;; define functionals
(defun $E (even? odd?) (lambda (n) (if (zerop n) t (funcall odd? (- n 1))))))
(defun $O (even? odd?) (lambda (n) (if (zerop n) nil (funcall even? (- n 1))))))

;; Find the list of fixed points for these
(setq $list-even?-odd? (funcall NfixN2 (list '$E '$O)))

;; wrap up the calls
(defun even? (x) (funcall (car $list-even?-odd?) x))
(defun odd? (x) (funcall (cadr $list-even?-odd?) x))

(list (even? 6) (odd? 4))
||#

--
Madhu
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4996e48f$0$90275$14726298@news.sunsite.dk>
 AT> First of all, I would like to mention that recur also has no
 AT> disadvantages. .... But the fact that the JVM currently does not 
support tail call opt.

if you compare Clojure without recur to Clojure with recur, obviously recur
will be seen as an advantage. but if you compare Clojure to CL, you will
find recur quite limited, and thus having recur INSTEAD of recursion is a 
disadvantage.

 AT> or if you spot it somewhere while flying
 AT>     over your sources, you immediately see �Ah, here we have a 
recursive
 AT>     call�.

it is highly subjective, it seems to me that recur is less readable because 
it
makes harder to see what is recur'ed -- one might think it calls outer 
function
while it calls inner. typically explicit is better than implicit.
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6qqe$38k$1@news.motzarella.org>
Alex Mizrahi schrieb:
>  AT> First of all, I would like to mention that recur also has no
>  AT> disadvantages. .... But the fact that the JVM currently does not 
> support tail call opt.
> 
> if you compare Clojure without recur to Clojure with recur, obviously recur
> will be seen as an advantage. but if you compare Clojure to CL, you will
> find recur quite limited, and thus having recur INSTEAD of recursion is a 
> disadvantage.

Yes, Clojure with recur (TCO) vs Clojure without it (no TCO) looks better.
However, in my opinion, if I have to chose between:
a) Clojure with    recur on a JVM that supports TCO
vs
b) Clojure without recur on a JVM that supports TCO,

then I vote for a).


>  AT> or if you spot it somewhere while flying
>  AT>     over your sources, you immediately see "Ah, here we have a 
> recursive
>  AT>     call".
> 
> it is highly subjective, it seems to me that recur is less readable because
 > it makes harder to see what is recur'ed -- one might think it calls outer
> function while it calls inner. typically explicit is better than implicit.

Recur jumps always to the most inner point, so it is always clear at the
first glimpse to where it will recur.
Also the compiler will make sure that one uses it only in tail position.
To me it happened already that I got an error message of not using recur
in TP.

Without talking specifically to you Alex, I observed that some CLers try
to jump on the recur issue, as this is in their eyes the weakest point.
The ironical thing about this is that at leats to my knowledge 100% of
those people actually never programmed in Clojure, and experience them-
selves how good/bad the situation really is.

While I fully agree that it is a weak point of the JVM that it does not
support TCO yet, I did not stumble upon any problematic situation yet.
Even when I asked people for creating artificial examples that can not
be easily solved with recur/trampolines, I did not see anything yet.

Lisp really has no easy stand today as it seems.
People see that it has a lot of parens and without trying it, they de-
cide it is nothing for them.
Clojure now reduced the amount of parens, but people now hear about
tail calls and argue that Clojure Lisp is not for them. What I find a
bit sad is that most of them are CLers.

Anyway, thanks for letting me know your opinions about recur.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn7av6$r9u$1@aioe.org>
On 2009-02-14 11:17:13 -0500, Andr� Thieme 
<······························@justmail.de> said:

> Without talking specifically to you Alex, I observed that some CLers try
> to jump on the recur issue, as this is in their eyes the weakest point.
> The ironical thing about this is that at leats to my knowledge 100% of
> those people actually never programmed in Clojure, and experience them-
> selves how good/bad the situation really is.

I think the situation is a bit more nuanced than that. I for one have 
used clojure and like it very much. But you're trying to make a virtue 
of a necessity with loop/recur. It exists because the jvm doesn't do 
tail call optimization. If the jvm did, then one would simply do 
ordinary recursive calls, and/or clojure would have the equivalent of 
scheme's letrec and named let.

The real innovations of clojure as a lisp dialect are:

1. the default functional semantics for data structures that are 
traditionally mutable in lisp (conses, lists, hash maps, vectors) but 
which are "persistent," aka, immutable, in clojure, in conjunction 
with...

2. the use of stm for those data that are mutable, eliminating explicit 
locking from user code.

These combine to make concurrency much easier to get right.[1]  You 
should be trumpeting these features, not loop/recur, which is only 
there because the underlying platform doesn't do tail call optimization.

[1] Note that I haven't included "easy access to java and java 
libraries" because there are a good number of scheme/lisp 
implementations that run on the jvm and/or allow the use of java libs. 
So access to java libs is not something that sets clojure apart from a 
number of other lisp/scheme implementations.
-- 
Raffael Cavallaro, Ph.D.
From: Slobodan Blazeski
Subject: question about  Clojure immutable structures
Date: 
Message-ID: <390e0a50-5828-46b2-8b7c-16733c1121ae@p2g2000prf.googlegroups.com>
On Feb 14, 9:53 pm, Raffael Cavallaro
<················@pas.espam.s.il.vous.plait.mac.com> wrote:
> On 2009-02-14 11:17:13 -0500, André Thieme
> <······························@justmail.de> said:
>
> > Without talking specifically to you Alex, I observed that some CLers try
> > to jump on the recur issue, as this is in their eyes the weakest point.
> > The ironical thing about this is that at leats to my knowledge 100% of
> > those people actually never programmed in Clojure, and experience them-
> > selves how good/bad the situation really is.
>
> I think the situation is a bit more nuanced than that. I for one have
> used clojure and like it very much. But you're trying to make a virtue
> of a necessity with loop/recur. It exists because the jvm doesn't do
> tail call optimization. If the jvm did, then one would simply do
> ordinary recursive calls, and/or clojure would have the equivalent of
> scheme's letrec and named let.
>
> The real innovations of clojure as a lisp dialect are:
>
> 1. the default functional semantics for data structures that are
> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
> which are "persistent," aka, immutable, in clojure, in conjunction
> with...
One question about those immutable structures, by persistent I
understand something that will stay on the disc when someone trips
over the cable.  If for example I have some paralelizable computation,
but it has some dog-slow part that thanks to god could be memoized. So
I want to have some central hash table that all the threads could
access for checking if any of the threads already computed that value
before, and also any thread will add new values once computed by it.
So how I'm gonna do that with immutable data structures?
Just for illustration consider calculating fibonacci numbers in
multiple threads with memoization into global hash table for all the
threads.

cheers
bobi
From: Pascal Costanza
Subject: Re: question about  Clojure immutable structures
Date: 
Message-ID: <6vp4poFl8ireU2@mid.individual.net>
Slobodan Blazeski wrote:
> On Feb 14, 9:53 pm, Raffael Cavallaro
> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>> On 2009-02-14 11:17:13 -0500, Andr� Thieme
>> <······························@justmail.de> said:
>>
>>> Without talking specifically to you Alex, I observed that some CLers try
>>> to jump on the recur issue, as this is in their eyes the weakest point.
>>> The ironical thing about this is that at leats to my knowledge 100% of
>>> those people actually never programmed in Clojure, and experience them-
>>> selves how good/bad the situation really is.
>> I think the situation is a bit more nuanced than that. I for one have
>> used clojure and like it very much. But you're trying to make a virtue
>> of a necessity with loop/recur. It exists because the jvm doesn't do
>> tail call optimization. If the jvm did, then one would simply do
>> ordinary recursive calls, and/or clojure would have the equivalent of
>> scheme's letrec and named let.
>>
>> The real innovations of clojure as a lisp dialect are:
>>
>> 1. the default functional semantics for data structures that are
>> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
>> which are "persistent," aka, immutable, in clojure, in conjunction
>> with...
> One question about those immutable structures, by persistent I
> understand something that will stay on the disc when someone trips
> over the cable.  If for example I have some paralelizable computation,
> but it has some dog-slow part that thanks to god could be memoized. So
> I want to have some central hash table that all the threads could
> access for checking if any of the threads already computed that value
> before, and also any thread will add new values once computed by it.
> So how I'm gonna do that with immutable data structures?
> Just for illustration consider calculating fibonacci numbers in
> multiple threads with memoization into global hash table for all the
> threads.

Most of the time, you want to avoid accesses to shared data structures 
when doing parallel computations, for performance reasons.

However, Clojure provides mutable data structures as well, they are just 
not the default ones.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: question about  Clojure immutable structures
Date: 
Message-ID: <gn7vqj$2as$1@news.motzarella.org>
Slobodan Blazeski schrieb:
> On Feb 14, 9:53 pm, Raffael Cavallaro
> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>> The real innovations of clojure as a lisp dialect are:
>>
>> 1. the default functional semantics for data structures that are
>> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
>> which are "persistent," aka, immutable, in clojure, in conjunction
>> with...
> One question about those immutable structures, by persistent I
> understand something that will stay on the disc when someone trips
> over the cable.  If for example I have some paralelizable computation,
> but it has some dog-slow part that thanks to god could be memoized. So
> I want to have some central hash table that all the threads could
> access for checking if any of the threads already computed that value
> before, and also any thread will add new values once computed by it.
> So how I'm gonna do that with immutable data structures?
> Just for illustration consider calculating fibonacci numbers in
> multiple threads with memoization into global hash table for all the
> threads.

The persistant datastructures in Clojure are immutable. It will not make
sure that they get written to disk.

About your example:
(def x {}) ==> x evaluates to the empty hashmap, and that can not be
changed.

If we want to introduce your shared memoization state, then we say:
(def *db* (atom {}))

Now *db* is an atom to an empty hashmap.
atoms can change, in a concurrency-safe way.

To add a result of a fib call to the db each thread will do:
(swap! *db* assoc n x)
where n is the arg to fib and result the x the result value.

This would safely add the key n  (argument to fibonacci) with the
value result  into the *db*.
Clojures STM makes sure that the db will stay consistent.
Here a fast hack:
(defn fib [n]
   (when-not (get @*db* n)
     (swap! *db* assoc n
            (loop [i n, f1 0, f2 1]
              (cond (zero? i) f1
                    (= i 1)   f2
                    :else (recur (dec i) f2 (+ f1 f2))))))
   (get @*db* n))

The function always returns what the get at the end returns.
If the value does not already exist it get�s calculated in the
loop and then put into the *db*.
It�s not production ready code, but instead something that can
illustrate the idea.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Slobodan Blazeski
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <19b9ded9-b171-4485-8015-c810e09ff30a@x38g2000yqj.googlegroups.com>
On Feb 15, 3:48 am, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Slobodan Blazeski schrieb:
>
>
>
>
>
> > On Feb 14, 9:53 pm, Raffael Cavallaro
> > <················@pas.espam.s.il.vous.plait.mac.com> wrote:
> >> The real innovations of clojure as a lisp dialect are:
>
> >> 1. the default functional semantics for data structures that are
> >> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
> >> which are "persistent," aka, immutable, in clojure, in conjunction
> >> with...
> > One question about those immutable structures, by persistent I
> > understand something that will stay on the disc when someone trips
> > over the cable.  If for example I have some paralelizable computation,
> > but it has some dog-slow part that thanks to god could be memoized. So
> > I want to have some central hash table that all the threads could
> > access for checking if any of the threads already computed that value
> > before, and also any thread will add new values once computed by it.
> > So how I'm gonna do that with immutable data structures?
> > Just for illustration consider calculating fibonacci numbers in
> > multiple threads with memoization into global hash table for all the
> > threads.
>
> The persistant datastructures in Clojure are immutable. It will not make
> sure that they get written to disk.
>
> About your example:
> (def x {}) ==> x evaluates to the empty hashmap, and that can not be
> changed.
>
> If we want to introduce your shared memoization state, then we say:
> (def *db* (atom {}))
>
> Now *db* is an atom to an empty hashmap.
> atoms can change, in a concurrency-safe way.
>
> To add a result of a fib call to the db each thread will do:
> (swap! *db* assoc n x)
> where n is the arg to fib and result the x the result value.
>
> This would safely add the key n  (argument to fibonacci) with the
> value result  into the *db*.
> Clojures STM makes sure that the db will stay consistent.
> Here a fast hack:
> (defn fib [n]
>    (when-not (get @*db* n)
>      (swap! *db* assoc n
>             (loop [i n, f1 0, f2 1]
>               (cond (zero? i) f1
>                     (= i 1)   f2
>                     :else (recur (dec i) f2 (+ f1 f2))))))
>    (get @*db* n))
>
> The function always returns what the get at the end returns.
> If the value does not already exist it get’s calculated in the
> loop and then put into the *db*.
> It’s not production ready code, but instead something that can
> illustrate the idea.

Cool thanks for the explanation.
bobi
>
> André
> --
> Lisp is not dead. It’s just the URL that has changed:http://clojure.org/
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: question about  Clojure immutable structures
Date: 
Message-ID: <gn81ee$fto$1@news.motzarella.org>
Madhu schrieb:
> * André Thieme <············@news.motzarella.org> :
> Wrote on Sun, 15 Feb 2009 03:48:44 +0100:
> 
> | Slobodan Blazeski schrieb:
> |> One question about those immutable structures, by persistent I
> |> understand something that will stay on the disc when someone trips
> |> over the cable.  If for example I have some paralelizable computation,
> |> but it has some dog-slow part that thanks to god could be memoized. So
> |> I want to have some central hash table that all the threads could
> |> access for checking if any of the threads already computed that value
> |> before, and also any thread will add new values once computed by it.
> |> So how I'm gonna do that with immutable data structures?
> |> Just for illustration consider calculating fibonacci numbers in
> |> multiple threads with memoization into global hash table for all the
> |> threads.
> 
> <snip>
> 
> | The function always returns what the get at the end returns.
> | If the value does not already exist it get’s calculated in the
> 
> But this misses out your best marketing feature for the language
> 
> <sarcasm>
> 
> In the time you spend waiting for the lock to the shared table to do a
> table lookup to compute a value, you can use a "free core" to do the
> computation from scratch just as quickly.
> 
> STM with multi core technology really shines on problem with solutions
> that can be expressed as simple table-lookup. --- in keeping all cores
> occupied at 100% CPU
> 
> </sarcasm>

Slobodan mentioned explicitly the fibonacci function as an example.
He wants it for more expensive calculations I suppose.
And btw, in general there is no need to wait for locks, as Clojure is
semi-optimistic. It begins writing to the datastructure in a reversible
and yet invisible way (while still in the transaction), and if it finds
out that the datastructure was modified by another thread, it will run
the transaction again. If no other thread wrote data, then a lock is
used under the hood for an extremly short amount of time, to let the
already written data go live.
It’s true that in my example this is not the case, as I don’t buffer
the result of fib in a let first and then do a swap!.
And please be fair: I wrote that this was a fast hack. I invite you to
rewrite it into a high performance version.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: question about  Clojure immutable structures
Date: 
Message-ID: <6vqipqFlcitcU1@mid.individual.net>
Andr� Thieme wrote:
> Slobodan Blazeski schrieb:
>> On Feb 14, 9:53 pm, Raffael Cavallaro
>> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>>> The real innovations of clojure as a lisp dialect are:
>>>
>>> 1. the default functional semantics for data structures that are
>>> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
>>> which are "persistent," aka, immutable, in clojure, in conjunction
>>> with...
>> One question about those immutable structures, by persistent I
>> understand something that will stay on the disc when someone trips
>> over the cable.  If for example I have some paralelizable computation,
>> but it has some dog-slow part that thanks to god could be memoized. So
>> I want to have some central hash table that all the threads could
>> access for checking if any of the threads already computed that value
>> before, and also any thread will add new values once computed by it.
>> So how I'm gonna do that with immutable data structures?
>> Just for illustration consider calculating fibonacci numbers in
>> multiple threads with memoization into global hash table for all the
>> threads.
> 
> The persistant datastructures in Clojure are immutable. 

There is a library for Common Lisp which does something similar: 
http://common-lisp.net/project/fset/


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: question about  Clojure immutable structures
Date: 
Message-ID: <gn9cim$8sc$1@news.motzarella.org>
Pascal Costanza schrieb:
> Andr� Thieme wrote:
>> Slobodan Blazeski schrieb:
>>> On Feb 14, 9:53 pm, Raffael Cavallaro
>>> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>>>> The real innovations of clojure as a lisp dialect are:
>>>>
>>>> 1. the default functional semantics for data structures that are
>>>> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
>>>> which are "persistent," aka, immutable, in clojure, in conjunction
>>>> with...
>>> One question about those immutable structures, by persistent I
>>> understand something that will stay on the disc when someone trips
>>> over the cable.  If for example I have some paralelizable computation,
>>> but it has some dog-slow part that thanks to god could be memoized. So
>>> I want to have some central hash table that all the threads could
>>> access for checking if any of the threads already computed that value
>>> before, and also any thread will add new values once computed by it.
>>> So how I'm gonna do that with immutable data structures?
>>> Just for illustration consider calculating fibonacci numbers in
>>> multiple threads with memoization into global hash table for all the
>>> threads.
>>
>> The persistant datastructures in Clojure are immutable. 
> 
> There is a library for Common Lisp which does something similar: 
> http://common-lisp.net/project/fset/

I think all major languages will get a STM with MVCC in the coming
months or years.
That will hopefully help to make further improvements to software in
general.
One problem I personally see though is, that a STM as an addition to
a language is not as good as if it was directly built into a functional
one. If the language offers imperative programming as well, and easier
access to non-persistant datastructures (such as [] in Python or () in
Lisp, ...) more than enough programmers won�t use the STM in the way
they should. Teams will have to agree on things, need meetings, and so
on. In Haskell, Clojure and Erlang the concurrency safety is the default.
But still, I hope to see soon how Franz and Lispworks will ship their
own STM.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: question about  Clojure immutable structures
Date: 
Message-ID: <6vqta5Fl619qU1@mid.individual.net>
Andr� Thieme wrote:
> Pascal Costanza schrieb:
>> Andr� Thieme wrote:
>>> Slobodan Blazeski schrieb:
>>>> On Feb 14, 9:53 pm, Raffael Cavallaro
>>>> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>>>>> The real innovations of clojure as a lisp dialect are:
>>>>>
>>>>> 1. the default functional semantics for data structures that are
>>>>> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
>>>>> which are "persistent," aka, immutable, in clojure, in conjunction
>>>>> with...
>>>> One question about those immutable structures, by persistent I
>>>> understand something that will stay on the disc when someone trips
>>>> over the cable.  If for example I have some paralelizable computation,
>>>> but it has some dog-slow part that thanks to god could be memoized. So
>>>> I want to have some central hash table that all the threads could
>>>> access for checking if any of the threads already computed that value
>>>> before, and also any thread will add new values once computed by it.
>>>> So how I'm gonna do that with immutable data structures?
>>>> Just for illustration consider calculating fibonacci numbers in
>>>> multiple threads with memoization into global hash table for all the
>>>> threads.
>>>
>>> The persistant datastructures in Clojure are immutable. 
>>
>> There is a library for Common Lisp which does something similar: 
>> http://common-lisp.net/project/fset/
> 
> I think all major languages will get a STM with MVCC in the coming
> months or years.

That's not so clear yet. See "Software Transactional Memory: why is it 
only a research toy?" at http://doi.acm.org/10.1145/1400214.1400228

> That will hopefully help to make further improvements to software in
> general.
> One problem I personally see though is, that a STM as an addition to
> a language is not as good as if it was directly built into a functional
> one. If the language offers imperative programming as well, and easier
> access to non-persistant datastructures (such as [] in Python or () in
> Lisp, ...) more than enough programmers won�t use the STM in the way
> they should. Teams will have to agree on things, need meetings, and so
> on. In Haskell, Clojure and Erlang the concurrency safety is the default.
> But still, I hope to see soon how Franz and Lispworks will ship their
> own STM.

STM is definitely an interesting approach and could turn out as a good 
abstraction to support parallel programming (although it's definitely 
not sufficient, not only because of its current shortcomings - see 
above). However, it's not the only one and there are other interesting 
high-level abstractions for parallel programming.

Currently, the typical support in CL implementations is to provide 
threads + locking + some other forms of synchronization. It seems to me 
that these are the 'right' low-level facilities to build different 
high-level facilities on top.

Traditionally, the Lisp approach is not to provide one high-level 
solution for a particular programming problem, but to provide several 
different low-level means and give programmers the expressive power to 
build their own high-level abstractions on top. That's why Lisp stresses 
metaprogramming and reflection (in the form of macros or MOPs, for 
example), because this gives you the way to reach underneath your 
current abstraction layer and influence the decisions there. And that's 
also why I currently think that threads + locking + means for 
synchronization may actually be the best Lisp dialects can offer.

Lisp doesn't force you to program in a functional style, but you can 
also program in an imperative style, in an object-oriented style, in a 
logic style, etc. The same should be true for parallel programming, 
IMHO: You shouldn't only be able to use actor-style, but also data 
parallelism, and different kinds of synchronization mechanisms. 
Otherwise you may lose too much depending on the particular kind of 
problem you want to solve.

Clojure is a very interesting project, and it's definitely interesting 
to have persistent datatypes at the core of the language. However, my 
main gripes with Clojure are the following:

- It promotes purely functional programming. That's sometimes not 
appropriate.

- It offers only STM for stateful programming. That's also sometimes not 
appropriate.

- AFAICT, the only way to reflectively extend the language is by going 
down to the Java level. That shouldn't be necessary. A good Lisp dialect 
should allow you to stay within Lisp even if you want to influence the 
implementation of the language itself.

I smell the following two typical problems for the kind of languages 
that Clojure is an example of:

- It is advertized as making programming a lot simpler than before, in 
this case as making parallel programming a lot simpler than before. 
However, all languages that started out as simple languages in the 
beginning turned out to become much more complex in the long run, and 
especially suffered from the initial simplifying assumptions.

- It makes a distinction between what the designer of the language is 
allowed to do internally in its implementation, and what 'users' of the 
language are allowed to do. This removes expressive power from the users 
/ programmers, which will eventually hurt them in the long run.

These are the main two reasons why I am skeptical of Clojure, in spite 
of it being one of the more interesting recent developments in Lisp.

Clojure is probably very useful in some scenarios, but it's most likely 
not the final answer to everything. ;)


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <17b9a844-f221-4474-b300-a721fdd2865a@w35g2000yqm.googlegroups.com>
On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
> André Thieme wrote:
> > Pascal Costanza schrieb:
> >> André Thieme wrote:
> >>> Slobodan Blazeski schrieb:
> >>>> On Feb 14, 9:53 pm, Raffael Cavallaro
> >>>> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
> >>>>> The real innovations of clojure as a lisp dialect are:
>
> >>>>> 1. the default functional semantics for data structures that are
> >>>>> traditionally mutable in lisp (conses, lists, hash maps, vectors) but
> >>>>> which are "persistent," aka, immutable, in clojure, in conjunction
> >>>>> with...
> >>>> One question about those immutable structures, by persistent I
> >>>> understand something that will stay on the disc when someone trips
> >>>> over the cable.  If for example I have some paralelizable computation,
> >>>> but it has some dog-slow part that thanks to god could be memoized. So
> >>>> I want to have some central hash table that all the threads could
> >>>> access for checking if any of the threads already computed that value
> >>>> before, and also any thread will add new values once computed by it.
> >>>> So how I'm gonna do that with immutable data structures?
> >>>> Just for illustration consider calculating fibonacci numbers in
> >>>> multiple threads with memoization into global hash table for all the
> >>>> threads.
>
> >>> The persistant datastructures in Clojure are immutable.
>
> >> There is a library for Common Lisp which does something similar:
> >>http://common-lisp.net/project/fset/
>
> > I think all major languages will get a STM with MVCC in the coming
> > months or years.
>
> That's not so clear yet. See "Software Transactional Memory: why is it
> only a research toy?" athttp://doi.acm.org/10.1145/1400214.1400228
>

That is a weak article. It criticizes STM in comparison to its
performance vs. serial execution. It doesn't compare the STM code with
equivalent versions using manual locking, neither for complexity nor
for performance. Nor does it place appropriate value on correctness.
People were (are!) skeptical of GC too, and there were (are) certainly
places where its performance rules it out. That doesn't negate its
value for people for whom its performance is sufficient and its
correctness lets them focus on their application domain.

http://queue.acm.org/detail.cfm?id=1454464

Articles that essentially state "it's not a panacea" are not that
illuminating. Also, approaches to STM vary quite widely in both their
objectives and implementations. A lot of STM research is directed at
providing STM that allows people to continue working much as they do
now - pretending they are the only process banging on bits of memory
in the machine. I disagree with that premise, and Clojure's STM is
different as a result.

> STM is definitely an interesting approach and could turn out as a good
> abstraction to support parallel programming (although it's definitely
> not sufficient, not only because of its current shortcomings - see
> above). However, it's not the only one and there are other interesting
> high-level abstractions for parallel programming.
>
> Currently, the typical support in CL implementations is to provide
> threads + locking + some other forms of synchronization. It seems to me
> that these are the 'right' low-level facilities to build different
> high-level facilities on top.
>

I think it is tricky to get a good memory model defined that deals
with all of the issues. Java tries:

http://java.sun.com/docs/books/jls/third_edition/html/memory.html

See also:

http://jcip.net/

It's certainly much more subtle and difficult than just "threads +
locking".

> Traditionally, the Lisp approach is not to provide one high-level
> solution for a particular programming problem, but to provide several
> different low-level means and give programmers the expressive power to
> build their own high-level abstractions on top. That's why Lisp stresses
> metaprogramming and reflection (in the form of macros or MOPs, for
> example), because this gives you the way to reach underneath your
> current abstraction layer and influence the decisions there. And that's
> also why I currently think that threads + locking + means for
> synchronization may actually be the best Lisp dialects can offer.
>

Providing low-level constructs doesn't obviate the need for higher-
level ones as well. A box of parts is not a car.

> Lisp doesn't force you to program in a functional style, but you can
> also program in an imperative style, in an object-oriented style, in a
> logic style, etc. The same should be true for parallel programming,
> IMHO: You shouldn't only be able to use actor-style, but also data
> parallelism, and different kinds of synchronization mechanisms.
> Otherwise you may lose too much depending on the particular kind of
> problem you want to solve.
>

Clojure forces very little. It's not Haskell with parens after all.
All those styles are possible, and higher-level support for some comes
included.

> Clojure is a very interesting project, and it's definitely interesting
> to have persistent datatypes at the core of the language. However, my
> main gripes with Clojure are the following:
>
> - It promotes purely functional programming. That's sometimes not
> appropriate.
>

I've never promoted Clojure as "purely functional programming", as I
am quite suspect of the concept implied by the words, and the term has
come to mean "having a type system that keeps the purely functional
parts separate". The presence of the reference types in Clojure makes
it clear that I don't think a purely functional style will get you all
the way there.  I also know that the typical approach to state doesn't
either, especially when concurrency comes into play. But Clojure is
definitely an impure functional language. Promoting the use of
immutable data and pure functions is not the same as limiting you to
them.

> - It offers only STM for stateful programming.

This is not true. Clojure offers no fewer than 4 managed reference
types:

STM-based refs
Actor-like asynchronous agents
Thread-local vars
CAS-like atoms

All of which have concurrency semantics. In addition you have access
to locks and all other JVM concurrency primitives.

When I give talks I emphasize the unique parts of Clojure because they
are interesting and that's where Clojure adds value, but that doesn't
mean they are the only parts. You can bash bits in Clojure just like
in CL and Java, there are mutable arrays etc, but what's interesting
about that?

> - AFAICT, the only way to reflectively extend the language is by going
> down to the Java level. That shouldn't be necessary. A good Lisp dialect
> should allow you to stay within Lisp even if you want to influence the
> implementation of the language itself.
>

This is not true. The extensibility points that are defined in terms
of Java interfaces can be extended in Clojure or Java.

> I smell the following two typical problems for the kind of languages
> that Clojure is an example of:
>
> - It is advertized as making programming a lot simpler than before, in
> this case as making parallel programming a lot simpler than before.
> However, all languages that started out as simple languages in the
> beginning turned out to become much more complex in the long run, and
> especially suffered from the initial simplifying assumptions.
>

I usually try not to say Clojure is anything-er than anything else. I
just make it, and say what it does. But don't all Lisps start out as
simple languages, and isn't that the point of Lisp?

> - It makes a distinction between what the designer of the language is
> allowed to do internally in its implementation, and what 'users' of the
> language are allowed to do. This removes expressive power from the users
> / programmers, which will eventually hurt them in the long run.
>

This is a chimera. Why couldn't I just make the cons and sequence
functions of Common Lisp extensible to user-defined types? Then I
wouldn't have had to write Clojure. There are always some things that
are built-in and some that are tweakable. At least Clojure's core
library functions are defined in a way that they can be extended to
other types.

> These are the main two reasons why I am skeptical of Clojure, in spite
> of it being one of the more interesting recent developments in Lisp.
>
> Clojure is probably very useful in some scenarios, but it's most likely
> not the final answer to everything. ;)
>

Clojure's not trying to be a panacea. It's just a tool.

Rich
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <6vrgb3Fl97ptU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
>> Andr� Thieme wrote:
>>> I think all major languages will get a STM with MVCC in the coming
>>> months or years.
>> That's not so clear yet. See "Software Transactional Memory: why is it
>> only a research toy?" athttp://doi.acm.org/10.1145/1400214.1400228
> 
> That is a weak article. It criticizes STM in comparison to its
> performance vs. serial execution. It doesn't compare the STM code with
> equivalent versions using manual locking, neither for complexity nor
> for performance. Nor does it place appropriate value on correctness.
> People were (are!) skeptical of GC too, and there were (are) certainly
> places where its performance rules it out. That doesn't negate its
> value for people for whom its performance is sufficient and its
> correctness lets them focus on their application domain.

The article has some credibility because the authors have been doing 
research on STM themselves.

I agree that is probably a good solution in the long run, but that's not 
clear yet and remains to be seen.

> http://queue.acm.org/detail.cfm?id=1454464
> 
> Articles that essentially state "it's not a panacea" are not that
> illuminating. Also, approaches to STM vary quite widely in both their
> objectives and implementations. A lot of STM research is directed at
> providing STM that allows people to continue working much as they do
> now - pretending they are the only process banging on bits of memory
> in the machine. I disagree with that premise, and Clojure's STM is
> different as a result.

Yes, it seems hard to avoid the necessity to change programming style 
when dealing with parallelism.

>> STM is definitely an interesting approach and could turn out as a good
>> abstraction to support parallel programming (although it's definitely
>> not sufficient, not only because of its current shortcomings - see
>> above). However, it's not the only one and there are other interesting
>> high-level abstractions for parallel programming.
>>
>> Currently, the typical support in CL implementations is to provide
>> threads + locking + some other forms of synchronization. It seems to me
>> that these are the 'right' low-level facilities to build different
>> high-level facilities on top.
> 
> I think it is tricky to get a good memory model defined that deals
> with all of the issues. Java tries:
> 
> http://java.sun.com/docs/books/jls/third_edition/html/memory.html
> 
> See also:
> 
> http://jcip.net/
> 
> It's certainly much more subtle and difficult than just "threads +
> locking".

You're right, and I'm sorry if I gave the wrong impression here. (I used 
"threads + locking" as general placeholder for the bunch of operations 
typically provided in multithreaded CL implementations.)

>> Traditionally, the Lisp approach is not to provide one high-level
>> solution for a particular programming problem, but to provide several
>> different low-level means and give programmers the expressive power to
>> build their own high-level abstractions on top. That's why Lisp stresses
>> metaprogramming and reflection (in the form of macros or MOPs, for
>> example), because this gives you the way to reach underneath your
>> current abstraction layer and influence the decisions there. And that's
>> also why I currently think that threads + locking + means for
>> synchronization may actually be the best Lisp dialects can offer.
> 
> Providing low-level constructs doesn't obviate the need for higher-
> level ones as well. A box of parts is not a car.

I'm not sure how to comment on this.

>> Lisp doesn't force you to program in a functional style, but you can
>> also program in an imperative style, in an object-oriented style, in a
>> logic style, etc. The same should be true for parallel programming,
>> IMHO: You shouldn't only be able to use actor-style, but also data
>> parallelism, and different kinds of synchronization mechanisms.
>> Otherwise you may lose too much depending on the particular kind of
>> problem you want to solve.
> 
> Clojure forces very little. It's not Haskell with parens after all.
> All those styles are possible, and higher-level support for some comes
> included.

OK.

>> Clojure is a very interesting project, and it's definitely interesting
>> to have persistent datatypes at the core of the language. However, my
>> main gripes with Clojure are the following:
>>
>> - It promotes purely functional programming. That's sometimes not
>> appropriate.
> 
> I've never promoted Clojure as "purely functional programming", as I
> am quite suspect of the concept implied by the words, and the term has
> come to mean "having a type system that keeps the purely functional
> parts separate". The presence of the reference types in Clojure makes
> it clear that I don't think a purely functional style will get you all
> the way there.  I also know that the typical approach to state doesn't
> either, especially when concurrency comes into play. But Clojure is
> definitely an impure functional language. Promoting the use of
> immutable data and pure functions is not the same as limiting you to
> them.

That's why I said "promote," and not "enforce." (I don't see static 
types as a necessary ingredient of purely functional programming, only 
the absence of effects.)

>> - It offers only STM for stateful programming.
> 
> This is not true. Clojure offers no fewer than 4 managed reference
> types:
> 
> STM-based refs
> Actor-like asynchronous agents
> Thread-local vars
> CAS-like atoms
> 
> All of which have concurrency semantics. In addition you have access
> to locks and all other JVM concurrency primitives.

OK, thanks for the correction. I'm sorry I misrepresented Clojure in 
this regard.

> When I give talks I emphasize the unique parts of Clojure because they
> are interesting and that's where Clojure adds value, but that doesn't
> mean they are the only parts. You can bash bits in Clojure just like
> in CL and Java, there are mutable arrays etc, but what's interesting
> about that?

So how do you deal with concurrency when mutating arrays?

>> - AFAICT, the only way to reflectively extend the language is by going
>> down to the Java level. That shouldn't be necessary. A good Lisp dialect
>> should allow you to stay within Lisp even if you want to influence the
>> implementation of the language itself.
> 
> This is not true. The extensibility points that are defined in terms
> of Java interfaces can be extended in Clojure or Java.

OK, maybe I'm wrong here. So: Could you, in principle, implement the 
four reference types in Clojure itself in terms of lower level 
constructs provided by Clojure?

>> I smell the following two typical problems for the kind of languages
>> that Clojure is an example of:
>>
>> - It is advertized as making programming a lot simpler than before, in
>> this case as making parallel programming a lot simpler than before.
>> However, all languages that started out as simple languages in the
>> beginning turned out to become much more complex in the long run, and
>> especially suffered from the initial simplifying assumptions.
> 
> I usually try not to say Clojure is anything-er than anything else. I
> just make it, and say what it does. But don't all Lisps start out as
> simple languages, and isn't that the point of Lisp?

No, I don't think that's the point of Lisp.

>> - It makes a distinction between what the designer of the language is
>> allowed to do internally in its implementation, and what 'users' of the
>> language are allowed to do. This removes expressive power from the users
>> / programmers, which will eventually hurt them in the long run.
> 
> This is a chimera. Why couldn't I just make the cons and sequence
> functions of Common Lisp extensible to user-defined types? Then I
> wouldn't have had to write Clojure. There are always some things that
> are built-in and some that are tweakable.

True, and certainly both Common Lisp and Scheme lack some important 
possibilities to tweak them as well.

> At least Clojure's core
> library functions are defined in a way that they can be extended to
> other types.

Well, I'm wondering about the ability to implement your own abstractions 
for parallel programming beyond the default ones provided by Clojure, 
within Clojure itself. If that's possible, I have to correct my 
statements about Clojure.

>> These are the main two reasons why I am skeptical of Clojure, in spite
>> of it being one of the more interesting recent developments in Lisp.
>>
>> Clojure is probably very useful in some scenarios, but it's most likely
>> not the final answer to everything. ;)
> 
> Clojure's not trying to be a panacea. It's just a tool.

Hm, it seems I have described Clojure too negatively. Sorry if that's 
the case.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <571ef081-d076-4f95-aed3-001051c95344@c12g2000yqj.googlegroups.com>
On Feb 15, 4:38 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
> >> André Thieme wrote:
> >>> I think all major languages will get a STM with MVCC in the coming
> >>> months or years.
> >> That's not so clear yet. See "Software Transactional Memory: why is it
> >> only a research toy?" athttp://doi.acm.org/10.1145/1400214.1400228
>
> > That is a weak article. It criticizes STM in comparison to its
> > performance vs. serial execution. It doesn't compare the STM code with
> > equivalent versions using manual locking, neither for complexity nor
> > for performance. Nor does it place appropriate value on correctness.
> > People were (are!) skeptical of GC too, and there were (are) certainly
> > places where its performance rules it out. That doesn't negate its
> > value for people for whom its performance is sufficient and its
> > correctness lets them focus on their application domain.
>
> The article has some credibility because the authors have been doing
> research on STM themselves.
>

I didn't mean to imply they weren't credible. But you have to be
careful when transferring their conclusions to another domain. I've
met with some researchers in the HPC area where the dynamism of Lisp,
Java, even C++ virtual function calls, are all unacceptable for
performance reasons, and the authors' main argument against STM was
performance.

> I agree that is probably a good solution in the long run, but that's not
> clear yet and remains to be seen.
>

Agreed. Also, I do not think it is a universal solution, only one of a
suite of tools.

> >> Currently, the typical support in CL implementations is to provide
> >> threads + locking + some other forms of synchronization. It seems to me
> >> that these are the 'right' low-level facilities to build different
> >> high-level facilities on top.
>
> > I think it is tricky to get a good memory model defined that deals
> > with all of the issues. Java tries:
>
> >http://java.sun.com/docs/books/jls/third_edition/html/memory.html
>
> > See also:
>
> >http://jcip.net/
>
> > It's certainly much more subtle and difficult than just "threads +
> > locking".
>
> You're right, and I'm sorry if I gave the wrong impression here. (I used
> "threads + locking" as general placeholder for the bunch of operations
> typically provided in multithreaded CL implementations.)
>

But do they have well-defined memory models as above? You definitely
need those happens-before/memory-fence models to implement something
like an STM.

> >> Traditionally, the Lisp approach is not to provide one high-level
> >> solution for a particular programming problem, but to provide several
> >> different low-level means and give programmers the expressive power to
> >> build their own high-level abstractions on top. That's why Lisp stresses
> >> metaprogramming and reflection (in the form of macros or MOPs, for
> >> example), because this gives you the way to reach underneath your
> >> current abstraction layer and influence the decisions there. And that's
> >> also why I currently think that threads + locking + means for
> >> synchronization may actually be the best Lisp dialects can offer.
>
> > Providing low-level constructs doesn't obviate the need for higher-
> > level ones as well. A box of parts is not a car.
>
> I'm not sure how to comment on this.
>

I only meant to say - why is that the best they can offer? Why stop at
low-level support?

> >> Clojure is a very interesting project, and it's definitely interesting
> >> to have persistent datatypes at the core of the language. However, my
> >> main gripes with Clojure are the following:
>
> >> - It promotes purely functional programming. That's sometimes not
> >> appropriate.
>
> > I've never promoted Clojure as "purely functional programming", as I
> > am quite suspect of the concept implied by the words, and the term has
> > come to mean "having a type system that keeps the purely functional
> > parts separate". The presence of the reference types in Clojure makes
> > it clear that I don't think a purely functional style will get you all
> > the way there.  I also know that the typical approach to state doesn't
> > either, especially when concurrency comes into play. But Clojure is
> > definitely an impure functional language. Promoting the use of
> > immutable data and pure functions is not the same as limiting you to
> > them.
>
> That's why I said "promote," and not "enforce." (I don't see static
> types as a necessary ingredient of purely functional programming, only
> the absence of effects.)
>

Then why the gripe? Plenty of Lisp/Scheme books promote using a
functional style.

> > When I give talks I emphasize the unique parts of Clojure because they
> > are interesting and that's where Clojure adds value, but that doesn't
> > mean they are the only parts. You can bash bits in Clojure just like
> > in CL and Java, there are mutable arrays etc, but what's interesting
> > about that?
>
> So how do you deal with concurrency when mutating arrays?
>

Is this a trick question? :)

I wrote Clojure's data structures so I would have something safe to
use concurrently, and I use them whenever possible. If I were to use a
mutable array, it would be within the confines of a function that
otherwise presented a functional interface, e.g. as an implementation
detail of sorting - the array would not be shared. The other case is
mutating an array once only on initialization, and never changing it
once shared. This is how Clojure's persistent data structures work,
and I've made the case they couldn't be nearly as fast if they were
implemented 'purely', i.e. only in terms of other immutable
structures.

Actual (overlapping) mutation of arrays in place, concurrently? I
avoid it. If you had to, you would need locks.

> >> - AFAICT, the only way to reflectively extend the language is by going
> >> down to the Java level. That shouldn't be necessary. A good Lisp dialect
> >> should allow you to stay within Lisp even if you want to influence the
> >> implementation of the language itself.
>
> > This is not true. The extensibility points that are defined in terms
> > of Java interfaces can be extended in Clojure or Java.
>
> OK, maybe I'm wrong here. So: Could you, in principle, implement the
> four reference types in Clojure itself in terms of lower level
> constructs provided by Clojure?
>

Extension and self-definition are two different things. But yes, you
could. Atoms were originally implemented in Clojure, and moved to Java
only to ease bootstrapping and consumption from Java. That's not to
say Clojure is as low-level as Java, so some extensions might not be
as fast as those written in Java, i.e. Clojure has no notion of
'volatile' and some of the other lowest-level constructs. There's
nothing that rules out Clojure becoming more low level, but the bottom
line is that static is faster (and uglier). Java already does static/
ugly pretty well, so is it worth it to add that ugliness to Clojure
for self-definition bragging rights? Thus far, it hasn't been worth it
to me. But certainly there are no limits for users - the bytecode
generation engine used by the Clojure compiler is embedded and
accessible by Clojure code - there are already parts of Clojure that
generate bytecode from Clojure, such bytecode having no limits in
performance or access to primitive constructs.

So, you're only a macro package away from an arbitrary bytecode
generator. Several are included with Clojure that generate classes and
interfaces for which you would otherwise have to drop into Java.

But I find the statement somewhat specious and preachy ("A good Lisp
dialect should..."), since I didn't find the kind of extensibility in
Common Lisp (in itself, or via well-defined interfaces in any
language) that I have in Clojure. CL has a hard-wired set of
privileged types. Syntactic extension is only one dimension of
extensibility (and supported by Clojure). CLOS is another, and I see
the kind of reflectivity you speak of in CLOS, but Common Lisp isn't
written in CLOS.

Could you write an efficient Common Lisp in CLOS, where the core data
structures and algorithms were extensible CLOS types and generic
functions?

> > At least Clojure's core
> > library functions are defined in a way that they can be extended to
> > other types.
>
> Well, I'm wondering about the ability to implement your own abstractions
> for parallel programming beyond the default ones provided by Clojure,
> within Clojure itself. If that's possible, I have to correct my
> statements about Clojure.
>

Well, concurrency constructs down to the CAS level, monitors,
reentrant read-write locks etc are all available in calls from Clojure
to core Java libraries, so you can do a tremendous amount of parallel
programming work in Clojure itself. Things like pmap, a concurrent,
semi-lazy, work-ahead version of map provided by Clojure, are written
in Clojure. Here's what it looks like:

(defn pmap
  "Like map, except f is applied in parallel. Semi-lazy in that the
  parallel computation stays ahead of the consumption, but doesn't
  realize the entire result unless required. Only useful for
  computationally intensive functions where the time of f dominates
  the coordination overhead."
  ([f coll]
   (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
         rets (map #(future (f %)) coll)
         step (fn step [[x & xs :as vs] fs]
                  (if fs
                    (lazy-cons (deref x) (step xs (rest fs)))
                    (map deref vs)))]
     (step rets (drop n rets))))
  ([f coll & colls]
   (let [step (fn step [cs]
                  (when (every? seq cs)
                    (lazy-cons (map first cs) (step (map rest cs)))))]
     (pmap #(apply f %) (step (cons coll colls))))))

There's one call to Java to get the processor count. Looks like
(really easy) concurrent programming in Lisp to me.

> Hm, it seems I have described Clojure too negatively. Sorry if that's
> the case.
>

No offense taken, but it seems there is a lot more to Clojure than you
might be aware of.

Rich
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <6vvtgiFlbfd9U1@mid.individual.net>
Rich Hickey wrote:
> On Feb 15, 4:38 pm, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Andr� Thieme wrote:
>>>>> I think all major languages will get a STM with MVCC in the coming
>>>>> months or years.
>>>> That's not so clear yet. See "Software Transactional Memory: why is it
>>>> only a research toy?" athttp://doi.acm.org/10.1145/1400214.1400228
>>> That is a weak article. It criticizes STM in comparison to its
>>> performance vs. serial execution. It doesn't compare the STM code with
>>> equivalent versions using manual locking, neither for complexity nor
>>> for performance. Nor does it place appropriate value on correctness.
>>> People were (are!) skeptical of GC too, and there were (are) certainly
>>> places where its performance rules it out. That doesn't negate its
>>> value for people for whom its performance is sufficient and its
>>> correctness lets them focus on their application domain.
>> The article has some credibility because the authors have been doing
>> research on STM themselves.
> 
> I didn't mean to imply they weren't credible. But you have to be
> careful when transferring their conclusions to another domain. I've
> met with some researchers in the HPC area where the dynamism of Lisp,
> Java, even C++ virtual function calls, are all unacceptable for
> performance reasons, and the authors' main argument against STM was
> performance.

Er, now I'm confused. If I remember correctly, you advertise Clojure as 
a language to be able to take advantage of multiple cores. What other 
reasons are there to want that?

>> (I used "threads + locking" as general placeholder for the bunch of
>> operations typically provided in multithreaded CL implementations.)
> 
> But do they have well-defined memory models as above? You definitely
> need those happens-before/memory-fence models to implement something
> like an STM.

Indeed. I think the situation is improving in this regard.

>>>> Traditionally, the Lisp approach is not to provide one high-level
>>>> solution for a particular programming problem, but to provide several
>>>> different low-level means and give programmers the expressive power to
>>>> build their own high-level abstractions on top. That's why Lisp stresses
>>>> metaprogramming and reflection (in the form of macros or MOPs, for
>>>> example), because this gives you the way to reach underneath your
>>>> current abstraction layer and influence the decisions there. And that's
>>>> also why I currently think that threads + locking + means for
>>>> synchronization may actually be the best Lisp dialects can offer.
>>> Providing low-level constructs doesn't obviate the need for higher-
>>> level ones as well. A box of parts is not a car.
>> I'm not sure how to comment on this.
> 
> I only meant to say - why is that the best they can offer? Why stop at
> low-level support?

I didn't mean to suggest that.

>>>> Clojure is a very interesting project, and it's definitely interesting
>>>> to have persistent datatypes at the core of the language. However, my
>>>> main gripes with Clojure are the following:
>>>> - It promotes purely functional programming. That's sometimes not
>>>> appropriate.
>>> I've never promoted Clojure as "purely functional programming", as I
>>> am quite suspect of the concept implied by the words, and the term has
>>> come to mean "having a type system that keeps the purely functional
>>> parts separate". The presence of the reference types in Clojure makes
>>> it clear that I don't think a purely functional style will get you all
>>> the way there.  I also know that the typical approach to state doesn't
>>> either, especially when concurrency comes into play. But Clojure is
>>> definitely an impure functional language. Promoting the use of
>>> immutable data and pure functions is not the same as limiting you to
>>> them.
>> That's why I said "promote," and not "enforce." (I don't see static
>> types as a necessary ingredient of purely functional programming, only
>> the absence of effects.)
> 
> Then why the gripe? Plenty of Lisp/Scheme books promote using a
> functional style.

See below.

>>> When I give talks I emphasize the unique parts of Clojure because they
>>> are interesting and that's where Clojure adds value, but that doesn't
>>> mean they are the only parts. You can bash bits in Clojure just like
>>> in CL and Java, there are mutable arrays etc, but what's interesting
>>> about that?
>> So how do you deal with concurrency when mutating arrays?
> 
> Is this a trick question? :)
> 
> I wrote Clojure's data structures so I would have something safe to
> use concurrently, and I use them whenever possible. If I were to use a
> mutable array, it would be within the confines of a function that
> otherwise presented a functional interface, e.g. as an implementation
> detail of sorting - the array would not be shared. The other case is
> mutating an array once only on initialization, and never changing it
> once shared. This is how Clojure's persistent data structures work,
> and I've made the case they couldn't be nearly as fast if they were
> implemented 'purely', i.e. only in terms of other immutable
> structures.
> 
> Actual (overlapping) mutation of arrays in place, concurrently? I
> avoid it. If you had to, you would need locks.

OK, I have to admit I don't know Clojure from using it in practice 
(obviously ;).

So: Why do you allow for mutating arrays without ensuring thread safety, 
while at the same time you disallow mutating local (non-special) 
variables? You can write thread-safe code with mutating local variables 
as well? Why is one treated specially and the other not?

My impression that you promote functional programming came from the fact 
that local variables cannot be mutated. From an outsider's perspective, 
that looks a bit odd...

>>>> - AFAICT, the only way to reflectively extend the language is by going
>>>> down to the Java level. That shouldn't be necessary. A good Lisp dialect
>>>> should allow you to stay within Lisp even if you want to influence the
>>>> implementation of the language itself.
>>> This is not true. The extensibility points that are defined in terms
>>> of Java interfaces can be extended in Clojure or Java.
>> OK, maybe I'm wrong here. So: Could you, in principle, implement the
>> four reference types in Clojure itself in terms of lower level
>> constructs provided by Clojure?
> 
> Extension and self-definition are two different things. But yes, you
> could. Atoms were originally implemented in Clojure, and moved to Java
> only to ease bootstrapping and consumption from Java. That's not to
> say Clojure is as low-level as Java, so some extensions might not be
> as fast as those written in Java, i.e. Clojure has no notion of
> 'volatile' and some of the other lowest-level constructs. There's
> nothing that rules out Clojure becoming more low level, but the bottom
> line is that static is faster (and uglier). Java already does static/
> ugly pretty well, so is it worth it to add that ugliness to Clojure
> for self-definition bragging rights? Thus far, it hasn't been worth it
> to me. But certainly there are no limits for users - the bytecode
> generation engine used by the Clojure compiler is embedded and
> accessible by Clojure code - there are already parts of Clojure that
> generate bytecode from Clojure, such bytecode having no limits in
> performance or access to primitive constructs.
> 
> So, you're only a macro package away from an arbitrary bytecode
> generator. Several are included with Clojure that generate classes and
> interfaces for which you would otherwise have to drop into Java.
> 
> But I find the statement somewhat specious and preachy ("A good Lisp
> dialect should..."), since I didn't find the kind of extensibility in
> Common Lisp (in itself, or via well-defined interfaces in any
> language) that I have in Clojure. CL has a hard-wired set of
> privileged types. Syntactic extension is only one dimension of
> extensibility (and supported by Clojure). CLOS is another, and I see
> the kind of reflectivity you speak of in CLOS, but Common Lisp isn't
> written in CLOS.
> 
> Could you write an efficient Common Lisp in CLOS, where the core data
> structures and algorithms were extensible CLOS types and generic
> functions?

Yes, why not?

>>> At least Clojure's core
>>> library functions are defined in a way that they can be extended to
>>> other types.
>> Well, I'm wondering about the ability to implement your own abstractions
>> for parallel programming beyond the default ones provided by Clojure,
>> within Clojure itself. If that's possible, I have to correct my
>> statements about Clojure.
> 
> Well, concurrency constructs down to the CAS level, monitors,
> reentrant read-write locks etc are all available in calls from Clojure
> to core Java libraries, so you can do a tremendous amount of parallel
> programming work in Clojure itself. Things like pmap, a concurrent,
> semi-lazy, work-ahead version of map provided by Clojure, are written
> in Clojure. Here's what it looks like:
> 
> (defn pmap
>   "Like map, except f is applied in parallel. Semi-lazy in that the
>   parallel computation stays ahead of the consumption, but doesn't
>   realize the entire result unless required. Only useful for
>   computationally intensive functions where the time of f dominates
>   the coordination overhead."
>   ([f coll]
>    (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
>          rets (map #(future (f %)) coll)
>          step (fn step [[x & xs :as vs] fs]
>                   (if fs
>                     (lazy-cons (deref x) (step xs (rest fs)))
>                     (map deref vs)))]
>      (step rets (drop n rets))))
>   ([f coll & colls]
>    (let [step (fn step [cs]
>                   (when (every? seq cs)
>                     (lazy-cons (map first cs) (step (map rest cs)))))]
>      (pmap #(apply f %) (step (cons coll colls))))))
> 
> There's one call to Java to get the processor count. Looks like
> (really easy) concurrent programming in Lisp to me.
> 
>> Hm, it seems I have described Clojure too negatively. Sorry if that's
>> the case.
> 
> No offense taken, but it seems there is a lot more to Clojure than you
> might be aware of.

Yes, it seems so.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <ebb21ddc-17a5-459f-baa4-ea249fc03176@j1g2000yqi.googlegroups.com>
On Feb 17, 8:48 am, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 15, 4:38 pm, Pascal Costanza <····@p-cos.net> wrote:
> >> Rich Hickey wrote:
> >>> On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
> >>>> André Thieme wrote:
> >>>>> I think all major languages will get a STM with MVCC in the coming
> >>>>> months or years.
> >>>> That's not so clear yet. See "Software Transactional Memory: why is it
> >>>> only a research toy?" athttp://doi.acm.org/10.1145/1400214.1400228
> >>> That is a weak article. It criticizes STM in comparison to its
> >>> performance vs. serial execution. It doesn't compare the STM code with
> >>> equivalent versions using manual locking, neither for complexity nor
> >>> for performance. Nor does it place appropriate value on correctness.
> >>> People were (are!) skeptical of GC too, and there were (are) certainly
> >>> places where its performance rules it out. That doesn't negate its
> >>> value for people for whom its performance is sufficient and its
> >>> correctness lets them focus on their application domain.
> >> The article has some credibility because the authors have been doing
> >> research on STM themselves.
>
> > I didn't mean to imply they weren't credible. But you have to be
> > careful when transferring their conclusions to another domain. I've
> > met with some researchers in the HPC area where the dynamism of Lisp,
> > Java, even C++ virtual function calls, are all unacceptable for
> > performance reasons, and the authors' main argument against STM was
> > performance.
>
> Er, now I'm confused. If I remember correctly, you advertise Clojure as
> a language to be able to take advantage of multiple cores. What other
> reasons are there to want that?
>

Well, there are lots of possible reasons - getting a single job done
more quickly, getting more jobs done, being more responsive etc.
People were doing cooperative multitasking and threading before there
were multiple cores (and thus no performance incentives) - why?
Because there were other advantages to organizing their programs that
way. Now with multicore they are dealing the challenges of actual
overlapping concurrency - without care, incorrect access to shared
memory could lead to corrupt data or, when using locks, deadlock.

It is worth making the simplifying distinction between concurrency and
parallelism - i.e. doing many tasks at once, vs. breaking a single
task into multiple parts for performance reasons. The latter is likely
to become readily available in all languages in the form of libraries
that encapsulate the threading and sharing. Many of these also don't
require sophisticated synchronization - e.g. separate threads
manipulating separate regions of an array. OTOH, concurrency is almost
always an application-level problem - handling multiple users + I/O +
background calculations etc. In many cases there isn't a significant
amount of sharing, or contention for shared items, but, when shared
items are accessed, the code must be correct.

Thus, there are many applications for which the results of pounding on
a concurrency construct in a highly contended benchmark is completely
irrelevant, just as there are those who wouldn't give up GC even if it
were several times slower than malloc/free.

> >>> When I give talks I emphasize the unique parts of Clojure because they
> >>> are interesting and that's where Clojure adds value, but that doesn't
> >>> mean they are the only parts. You can bash bits in Clojure just like
> >>> in CL and Java, there are mutable arrays etc, but what's interesting
> >>> about that?
> >> So how do you deal with concurrency when mutating arrays?
>
> > Is this a trick question? :)
>
> > I wrote Clojure's data structures so I would have something safe to
> > use concurrently, and I use them whenever possible. If I were to use a
> > mutable array, it would be within the confines of a function that
> > otherwise presented a functional interface, e.g. as an implementation
> > detail of sorting - the array would not be shared. The other case is
> > mutating an array once only on initialization, and never changing it
> > once shared. This is how Clojure's persistent data structures work,
> > and I've made the case they couldn't be nearly as fast if they were
> > implemented 'purely', i.e. only in terms of other immutable
> > structures.
>
> > Actual (overlapping) mutation of arrays in place, concurrently? I
> > avoid it. If you had to, you would need locks.
>
> OK, I have to admit I don't know Clojure from using it in practice
> (obviously ;).
>
> So: Why do you allow for mutating arrays without ensuring thread safety,
> while at the same time you disallow mutating local (non-special)
> variables? You can write thread-safe code with mutating local variables
> as well? Why is one treated specially and the other not?
>
> My impression that you promote functional programming came from the fact
> that local variables cannot be mutated. From an outsider's perspective,
> that looks a bit odd...
>

I do promote functional programming and don't enforce it. That was my
original point - you were painting Clojure as purely functional when
it's not. However, that doesn't imply it needs to support mutable
locals. There are an indefinite number of mutable Java things Clojure
supports but doesn't manage - arrays are among them. There are also a
set of features with robust concurrency characteristics - immutable
locals are among them. There are also the reference types which,
unlike unmoderated, unsafe, mutable locals, support change with good
concurrency semantics. If you are desperate for a arbitrarily mutable
local - use an array! It is sufficient. But I'll not add mutable
locals just to satisfy some arbitrary notion of 'complete'.

> > But I find the statement somewhat specious and preachy ("A good Lisp
> > dialect should..."), since I didn't find the kind of extensibility in
> > Common Lisp (in itself, or via well-defined interfaces in any
> > language) that I have in Clojure. CL has a hard-wired set of
> > privileged types. Syntactic extension is only one dimension of
> > extensibility (and supported by Clojure). CLOS is another, and I see
> > the kind of reflectivity you speak of in CLOS, but Common Lisp isn't
> > written in CLOS.

> > Could you write an efficient Common Lisp in CLOS, where the core data
> > structures and algorithms were extensible CLOS types and generic
> > functions?
>
> Yes, why not?
>

Well, I'd like to see it. I guess I'm just tired of theoretical
arguments and admonitions. Clojure actually exists and is quite
extensible.

Rich
From: Madhu
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <m3eixwmr7v.fsf@moon.robolove.meer.net>
* Rich Hickey
Wrote on Tue, 17 Feb 2009 17:41:54 -0800 (PST):
| On Feb 17, 8:48 am, Pascal Costanza <····@p-cos.net> wrote:
|> Er, now I'm confused. If I remember correctly, you advertise Clojure as
|> a language to be able to take advantage of multiple cores. What other
|> reasons are there to want that?

We are in the realm of pure marketing here.

| Well, there are lots of possible reasons - getting a single job done
| more quickly, getting more jobs done, being more responsive etc.

[snip]

|> My impression that you promote functional programming came from the fact
|> that local variables cannot be mutated. From an outsider's perspective,
|> that looks a bit odd...

| I do promote functional programming and don't enforce it. That was my
| original point - you were painting Clojure as purely functional when
| it's not. However, that doesn't imply it needs to support mutable
| locals. There are an indefinite number of mutable Java things Clojure
| supports but doesn't manage - arrays are among them.

[snip]

Here we have the taste of the particular language designer which is
calulated to appeal to a segment of the developer market.

But this is essentially an argument for sticking to CL and using clojure
style constructs as a library.

|  There are also a set of features with robust concurrency
| characteristics - immutable locals are among them. There are also the
| reference types which, unlike unmoderated, unsafe, mutable locals,
| support change with good concurrency semantics. If you are desperate
| for a arbitrarily mutable local - use an array! It is sufficient. But
| I'll not add mutable locals just to satisfy some arbitrary notion of
| 'complete'.
|
|> > Could you write an efficient Common Lisp in CLOS, where the core data
|> > structures and algorithms were extensible CLOS types and generic
|> > functions?
|>
|> Yes, why not?
|
| Well, I'd like to see it. I guess I'm just tired of theoretical
| arguments and admonitions. Clojure actually exists and is quite
| extensible.

CL already exists and is extensible.  Java interoperabilty (if that is
important) is available in commercial implementations.

The Hashmap and other data structures can be implemented efficiently in
any CL.  If it turns out the particular concurrency constructs advocated
by clojure are FUNDAMENTAL in any way, there is no reason why a CL
implementation cannot implement them and enable the style of programming
if needed.  The only reasons will be business related.  If JVM gets the
critical mass of consumers (like VB did) , it will prove a better
lucrative developer market to invest in than a lisp implementation.

The arguments against Clojure and its style while advocating CL are
essentially like D.E.Knuth's arguments against lisp and for using RAM
(random access) based algorithms.

[Quoted by Kenny Tilton on CLL <·························@cv.net> in
 May08, and earlier by Geoff Summerhayes in Mar03]

   "Much of the material we will discuss is often called "List 
processing," since a number of programming systems such as LISP have 
been designed to facilitate working with general kinds of structures 
called Lists.
     ...
Although List processing systems are useful in a large number of 
situations, they impose constraints on the programmer that are often 
unnecessary; it is usually better to use the methods of this chapter 
directly in one's own programs, tailoring the data format and the 
processing algorithms to the particular application. Many people 
unfortunately still feel that List processing techniques are quite 
complicated (so that it is necessary to use someone else's carefully 
written interpretive system or a prefabricated set of subroutines), and 
that List processing must be done only in a certain fixed way.
     ... "
         -D.E.Knuth, TACP vol 1, Fundamental Algorithms
          Chapter 2, Information Structures, 6th paragraph.

--
Madhu
From: Jeffrey Straszheim
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <143e189b-4c11-4e73-af61-474488691157@j39g2000yqn.googlegroups.com>
On Feb 17, 9:08 pm, Madhu <·······@meer.net> wrote:

> But this is essentially an argument for sticking to CL and using clojure
> style constructs as a library.

Which CL implementations have, right now, concurrency-ready persistent
data structures that compare with Clojure's?  Which CLs have a multi-
platform memory model that compares to the JVM?

What open source CL has real threads now?  I know SBCL does.  Do they
work on Windows yet?  Do they guarantee correct cache behavior on all
platforms?  Show me where the memory model is documented.

(I suspect that quite a few folks here have no idea of what the JVM's
memory model offers.  That is unfortunate.  Java sucks, but the JVM is
pretty great.)

"CL can do it" only works when CL has done it.

Just an aside.  Lisp is great.  Clojure is a Lisp, which happens to
have a lot to offer for concurrency that isn't available yet for CL.
If CL gets it, that will be great (I think I'd still prefer Clojure
because I like FP and I like its cleaner syntax and design, but that
is just me).
From: Madhu
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <m3ab8kmond.fsf@moon.robolove.meer.net>
* Jeffrey Straszheim 
Wrote on Tue, 17 Feb 2009 18:40:22 -0800 (PST):

|> But this is essentially an argument for sticking to CL and using clojure
|> style constructs as a library.
|
| Which CL implementations have, right now, concurrency-ready persistent
| data structures that compare with Clojure's?  Which CLs have a multi-
| platform memory model that compares to the JVM?  What open source CL
| has real threads now?  I know SBCL does.  Do they work on Windows yet?
| Do they guarantee correct cache behavior on all platforms?  Show me
| where the memory model is documented.
| (I suspect that quite a few folks here have no idea of what the JVM's
| memory model offers.  That is unfortunate.  Java sucks, but the JVM is
| pretty great.)
|
| "CL can do it" only works when CL has done it.
|
| Just an aside.  Lisp is great.  Clojure is a Lisp, which happens to
| have a lot to offer for concurrency that isn't available yet for CL.
| If CL gets it, that will be great (I think I'd still prefer Clojure
| because I like FP and I like its cleaner syntax and design, but that
| is just me).

Yes you are lucky you happen to be the target audience of clojure

You are providing more pure marketing arguments.  These can go
challenged because of Turing completeness in the domain.  NOTE I do not
advocate SBCL's threading model to the same extent I do not advocate
JVM's model.  
Do you have an application (without arguments that rely on a developer
market using it, or creating the market)?

The part I find offensive is the use of "Clojure is a Lisp" for
marketing.  Clojure provides nothing of the multiparadigm nature of CL
which makes CL great --- not without throwing most of it out and
reintroducing it via what JVM provides, which makes it a non-argument.

This is the reason why CLL suffers because as long as there are people
using Lisp, people like Harrop, Andre Thieme, the newlisp guy, the ruby
guy etc perceive a market for poaching and will not stop until they
destroy all value.

--
Madhu
From: André Thieme
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnhnf7$45g$1@news.motzarella.org>
Madhu schrieb:
> * Jeffrey Straszheim 
> Wrote on Tue, 17 Feb 2009 18:40:22 -0800 (PST):
> 
> |> But this is essentially an argument for sticking to CL and using clojure
> |> style constructs as a library.
> |
> | Which CL implementations have, right now, concurrency-ready persistent
> | data structures that compare with Clojure's?  Which CLs have a multi-
> | platform memory model that compares to the JVM?  What open source CL
> | has real threads now?  I know SBCL does.  Do they work on Windows yet?
> | Do they guarantee correct cache behavior on all platforms?  Show me
> | where the memory model is documented.
> | (I suspect that quite a few folks here have no idea of what the JVM's
> | memory model offers.  That is unfortunate.  Java sucks, but the JVM is
> | pretty great.)
> |
> | "CL can do it" only works when CL has done it.
> |
> | Just an aside.  Lisp is great.  Clojure is a Lisp, which happens to
> | have a lot to offer for concurrency that isn't available yet for CL.
> | If CL gets it, that will be great (I think I'd still prefer Clojure
> | because I like FP and I like its cleaner syntax and design, but that
> | is just me).
> 
> Yes you are lucky you happen to be the target audience of clojure

And you can be happy to be in the tiny group of the target audience for
CL.
Programming languages underly an evolutionary process, as pretty much
everything in our world. They fight for ressources (Programmers) and the
fitters ones get stronger and evolve better. More users ==> more
development ==> more modern features that appeal to the userbase.

It has to be seen which Lisp dialect will appeal to most people.


> You are providing more pure marketing arguments.

Could you please talk about things about which you have an idea?
How much Clojure code did you actually write?


> These can go
> challenged because of Turing completeness in the domain.

Yeah cool. In the last decades the Lispers always said:
�Oh boy, you can�t do the Turing argument. Lisp is better!
It will make you so much more productive, ...�


> Do you have an application (without arguments that rely on a developer
> market using it, or creating the market)?

Do *you* have one?


> The part I find offensive is the use of "Clojure is a Lisp" for
> marketing.

Where is it used as marketing?
And even if it is used as such - why not?
�Buy this Mercedes. It�s a car.�.
WTF?
Why shouldn�t one state facts for marketing?


> Clojure provides nothing of the multiparadigm nature of CL
> which makes CL great --- not without throwing most of it out and
> reintroducing it via what JVM provides, which makes it a non-argument.

If multiparadigm or not, this has nothing to do with being a Lisp or not.
THIS is total marketing bullshit. Always connected with the slogan
that language implementor should not limit the developer.
OOP now had some decades to prove that it is great.
Paul Graham writes in ANSI Common Lisp (no direct quote):
�Functional Programming plus macros outperform OOP�.
Imperative programming sucks so badly, every developer should know this.

I am glad that Clojure does not offer its oop system.
Python always talks about �There is just one way to do it�, while this
is more true for Clojure. But of course one could implement things like
setf, push, incf and use non-concurrency-ready datastructures and
totally hide from the user that they come from the JVM.
You could sit down a few days and provide a sweet layer over Java
Vetors, ArrayLists, Hashmaps, Trees, whatever, and make them look
totally Lisp. There are only your thinking skills that will hopefully
prevent you to do this.

If the language offers many ways to do stuff, it leads to incompatible
libs, as one can see in CL. Everyone reinvents the wheel, has to work
on making his lib working in nine CL implementations. This really makes
no sense.
If you like that, then fine, you have CL - be happy with it.


I don�t understand why people like you can become so damn religious
about a programming language. Why are you so scared about evolution?

Hickey could have very well put all his efforts into providing all the
nice stuff from Clojure for CL.
But where would we end up? Only a small group of people would start
using it. New users can�t look into old code, because that does not
use anything of the new features. No STM, no reader macros that each
and every person will use, not one basic programming style to follow,
etc. No Java interfaces to greatly improved productivity.
Guess what, Hickey was working on interfaces to Java for some years.
Didn�t work out. The object models are too different. Same problems
for Python and Ruby which try to run on the JVM.
If you want a *good* integration to the biggest lib collection, then
you need something different than CL.

Now instead we have something that some people percieve as much nicer
than CL. Lots of good stuff from CL exists in Clojure.
The direction CL ==> Clojure was so easy for me.
But hacking CL now really hurts. It makes me unproductive. It feels very
much like the blub experience about which Graham talked. It�s again
about Lisp, only that this time it is against CL, and in favour of
another Lisp.


> This is the reason why CLL suffers because as long as there are people
> using Lisp, people like Harrop, Andre Thieme, the newlisp guy, the ruby
> guy etc perceive a market for poaching and will not stop until they
> destroy all value.

Yeah, thank you asshole.
Please compare me with others too if you enjoy it.
You are really so mad. Like a Hu! ;)
Really, you could be much more productive.
If you are so scared about evolution in progress, then sit down as
Hickey did for some years, shut up and hack something up.
Bring it all to CL. Not talking �Oh, Clojure this, Clojure that, blah
blah balh, its baaad, CL is waaay better, blah blah�. You can do it.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Madhu
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <m3fxiblehb.fsf@moon.robolove.meer.net>
I will be away from the internet for a while so will not follow up after
today.  My goal was precisely not to get into a conversation with you to
debate the issues you are so hot on debating.  The point is not to
debate but to show that the context in which the debate you (and Rich
Hickey) are engaging is not a fair ground --- along the lines of arguing
with semanticists where they decide what the meaning is, or arguing with
logicians where they specify the inference rules.  You have to step
outside the arena to see the picture.  I see no to follow the rest of
CLL in treating Rich with fawning deference instead of calling bullshit
on the rules when I see it.

I'll leave you with a quote for your edification. 

CL's big problem is that it is not a good first language. It is a
language for people who have suffered, but the industry is staffed
with people about to suffer for the first time. As soon as someone has
suffered they are either made a manager, or fired.
	-- tim <···············@corp.supernews.com>


[Rich Hickey may be setting you up in your niche, and thats great as
 long as we don't have to hear about it in every post of yours]

-- Madhu


* André Thieme <············@news.motzarella.org> :
Wrote on Wed, 18 Feb 2009 20:27:30 +0100:

| Madhu schrieb:
|> * Jeffrey Straszheim Wrote on Tue, 17 Feb 2009 18:40:22 -0800 (PST):
|>
|> |> But this is essentially an argument for sticking to CL and using clojure
|> |> style constructs as a library.
|> |
|> | Which CL implementations have, right now, concurrency-ready persistent
|> | data structures that compare with Clojure's?  Which CLs have a multi-
|> | platform memory model that compares to the JVM?  What open source CL
|> | has real threads now?  I know SBCL does.  Do they work on Windows yet?
|> | Do they guarantee correct cache behavior on all platforms?  Show me
|> | where the memory model is documented.
|> | (I suspect that quite a few folks here have no idea of what the JVM's
|> | memory model offers.  That is unfortunate.  Java sucks, but the JVM is
|> | pretty great.)
|> |
|> | "CL can do it" only works when CL has done it.
|> |
|> | Just an aside.  Lisp is great.  Clojure is a Lisp, which happens to
|> | have a lot to offer for concurrency that isn't available yet for CL.
|> | If CL gets it, that will be great (I think I'd still prefer Clojure
|> | because I like FP and I like its cleaner syntax and design, but that
|> | is just me).
|>
|> Yes you are lucky you happen to be the target audience of clojure
|
| And you can be happy to be in the tiny group of the target audience for
| CL.
| Programming languages underly an evolutionary process, as pretty much
| everything in our world. They fight for ressources (Programmers) and the
| fitters ones get stronger and evolve better. More users ==> more
| development ==> more modern features that appeal to the userbase.
|
| It has to be seen which Lisp dialect will appeal to most people.
|
|
|> You are providing more pure marketing arguments.
|
| Could you please talk about things about which you have an idea?
| How much Clojure code did you actually write?
|
|
|> These can go
|> challenged because of Turing completeness in the domain.
|
| Yeah cool. In the last decades the Lispers always said:
| „Oh boy, you can’t do the Turing argument. Lisp is better!
| It will make you so much more productive, ...”
|
|
|> Do you have an application (without arguments that rely on a developer
|> market using it, or creating the market)?
|
| Do *you* have one?
|
|
|> The part I find offensive is the use of "Clojure is a Lisp" for
|> marketing.
|
| Where is it used as marketing?
| And even if it is used as such - why not?
| “Buy this Mercedes. It’s a car.”.
| WTF?
| Why shouldn’t one state facts for marketing?
|
|
|> Clojure provides nothing of the multiparadigm nature of CL
|> which makes CL great --- not without throwing most of it out and
|> reintroducing it via what JVM provides, which makes it a non-argument.
|
| If multiparadigm or not, this has nothing to do with being a Lisp or not.
| THIS is total marketing bullshit. Always connected with the slogan
| that language implementor should not limit the developer.
| OOP now had some decades to prove that it is great.
| Paul Graham writes in ANSI Common Lisp (no direct quote):
| „Functional Programming plus macros outperform OOP”.
| Imperative programming sucks so badly, every developer should know this.
|
| I am glad that Clojure does not offer its oop system.
| Python always talks about „There is just one way to do it”, while this
| is more true for Clojure. But of course one could implement things like
| setf, push, incf and use non-concurrency-ready datastructures and
| totally hide from the user that they come from the JVM.
| You could sit down a few days and provide a sweet layer over Java
| Vetors, ArrayLists, Hashmaps, Trees, whatever, and make them look
| totally Lisp. There are only your thinking skills that will hopefully
| prevent you to do this.
|
| If the language offers many ways to do stuff, it leads to incompatible
| libs, as one can see in CL. Everyone reinvents the wheel, has to work
| on making his lib working in nine CL implementations. This really makes
| no sense.
| If you like that, then fine, you have CL - be happy with it.
|
|
| I don’t understand why people like you can become so damn religious
| about a programming language. Why are you so scared about evolution?
|
| Hickey could have very well put all his efforts into providing all the
| nice stuff from Clojure for CL.
| But where would we end up? Only a small group of people would start
| using it. New users can’t look into old code, because that does not
| use anything of the new features. No STM, no reader macros that each
| and every person will use, not one basic programming style to follow,
| etc. No Java interfaces to greatly improved productivity.
| Guess what, Hickey was working on interfaces to Java for some years.
| Didn’t work out. The object models are too different. Same problems
| for Python and Ruby which try to run on the JVM.
| If you want a *good* integration to the biggest lib collection, then
| you need something different than CL.
|
| Now instead we have something that some people percieve as much nicer
| than CL. Lots of good stuff from CL exists in Clojure.
| The direction CL ==> Clojure was so easy for me.
| But hacking CL now really hurts. It makes me unproductive. It feels very
| much like the blub experience about which Graham talked. It’s again
| about Lisp, only that this time it is against CL, and in favour of
| another Lisp.
|
|
|> This is the reason why CLL suffers because as long as there are people
|> using Lisp, people like Harrop, Andre Thieme, the newlisp guy, the ruby
|> guy etc perceive a market for poaching and will not stop until they
|> destroy all value.
|
| Yeah, thank you asshole.
| Please compare me with others too if you enjoy it.
| You are really so mad. Like a Hu! ;)
| Really, you could be much more productive.
| If you are so scared about evolution in progress, then sit down as
| Hickey did for some years, shut up and hack something up.
| Bring it all to CL. Not talking „Oh, Clojure this, Clojure that, blah
| blah balh, its baaad, CL is waaay better, blah blah”. You can do it.
|
|
| André
From: Vsevolod
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <052410f2-4cc8-479c-9174-129bf8c3bda9@33g2000yqm.googlegroups.com>
On Feb 18, 9:27 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> And you can be happy to be in the tiny group of the target audience for
> CL.
> Programming languages underly an evolutionary process, as pretty much
> everything in our world. They fight for ressources (Programmers) and the
> fitters ones get stronger and evolve better. More users ==> more
> development ==> more modern features that appeal to the userbase.
Luckily, the tiny group of CL developers produces a lot of great ideas
one can learn from and use, and, besides, can even afford itself send
messengers to other people to show them the way to better programming
(like Rich Hickey). ;)
That's metaphorically speaking.

> If the language offers many ways to do stuff, it leads to incompatible
> libs, as one can see in CL. Everyone reinvents the wheel, has to work
> on making his lib working in nine CL implementations. This really makes
> no sense.
Libs is the mantra of nowadays. But, look, most of the popular
languages of today emerged from 0 libs and still could make an impact,
so this may lead to a conclusion, that there's more to programming,
than libs, eh?

> But where would we end up? Only a small group of people would start
> using it. New users can’t look into old code, because that does not
> use anything of the new features. No STM, no reader macros that each
> and every person will use, not one basic programming style to follow,
> etc. No Java interfaces to greatly improved productivity.
And what about Java? Are Clojure users allowed to look into 'old' Java
code, not using all the fabulous new features? ;) So how do they then
interface with it?

> Now instead we have something that some people percieve as much nicer
> than CL. Lots of good stuff from CL exists in Clojure.
Python, Haskell, Ruby etc. guys say the same. As I see it, it's just a
question of preference. I think, what irritates the people like Madhu
is that you preach that as dogmas. You perceive Clojure to be better,
than CL. That's great. I don't perceive anything in that regard. I
just use CL and it gives me what I need. Maybe I will try to implement
some ideas from Clojure in CL, if I find them relevant to my tasks.
(And some people have already did that: FSet). Would it be ugly in
your opinion? Or, vice versa should I go to comp.lang.clojure and post
about how this same feature is implemented in CL?

> Bring it all to CL. Not talking „Oh, Clojure this, Clojure that, blah
> blah balh, its baaad, CL is waaay better, blah blah”. You can do it.
You are right, André. But who is provoking discussions? No one says,
that CL is better for, say, doing parallel stuff or interfacing with
Java. They say, that, in their opinion, it's better for their tasks.
Can you really prove the opposite? (You tried in the thread about
NewLisp's fexprs. Do you think, that your solution was outstanding?
IMO, each one, except for the Kazimir's one, of course :), had it's
merits. My personal favorite was Joswig's. But well, it's a matter of
preference, isn't it?..)

> Lisp is not dead. It’s just the URL that has changed:http://clojure.org/
Finally, all boils down to the "URL on the cereal box"... :)

PS. Speaking about evolution, it seems to me, that Clojure is not the
main trunk of Lisp evolution, it's one of the big boughs with some
great and unique (at list to Lisp) ideas. On the opposite side of the
tree you'll find Qi, and Mark Tarver will eagerly tell you what the
modern Lisp should look like. If PG is still interested in Arc, he
could jump in and explain, what the 100-year-from-now Lisp should be.
Guys, you have great languages for your likes, but you won't persuade
one another. That's not even mentioning Scheme.
Surely Common Lisp is not the ultimate Lisp, but I guess it will move
on in that direction. Even if not, it will still be that general (or
let's say common?) lisp, quite usable, and what's most important a
great (I don't say perfect) manifestation of lisp's core ideas. And
there's nothing bad or good about that, it's just the fact.

Cheers,
Vsevolod
From: André Thieme
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnl417$5rj$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 18, 9:27 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
>> And you can be happy to be in the tiny group of the target audience for
>> CL.
>> Programming languages underly an evolutionary process, as pretty much
>> everything in our world. They fight for ressources (Programmers) and the
>> fitters ones get stronger and evolve better. More users ==> more
>> development ==> more modern features that appeal to the userbase.
> Luckily, the tiny group of CL developers produces a lot of great ideas
> one can learn from and use, and, besides, can even afford itself send
> messengers to other people to show them the way to better programming
> (like Rich Hickey). ;)
> That's metaphorically speaking.

Yes, Hickey learned a lot of Lisp it seems.
Wasn�t it Newton who said something like:
�I can only see so far because I am standing on the shoulders of giants�.


>> If the language offers many ways to do stuff, it leads to incompatible
>> libs, as one can see in CL. Everyone reinvents the wheel, has to work
>> on making his lib working in nine CL implementations. This really makes
>> no sense.
> Libs is the mantra of nowadays. But, look, most of the popular
> languages of today emerged from 0 libs and still could make an impact,
> so this may lead to a conclusion, that there's more to programming,
> than libs, eh?

Of course, there is more to it.
It�s just that libs are what boosts productivity more than anything else.
Even with CL being such an expressive multiparadigm language, offering
macros and the condition system, it still means some days of work to get
decent REST server running.
Imagine how it felt before there was Hunchentoot or AllegroServe to
develop webapps. Devs interested in that would not want to miss those
libs.


>> But where would we end up? Only a small group of people would start
>> using it. New users can�t look into old code, because that does not
>> use anything of the new features. No STM, no reader macros that each
>> and every person will use, not one basic programming style to follow,
>> etc. No Java interfaces to greatly improved productivity.
> And what about Java? Are Clojure users allowed to look into 'old' Java
> code, not using all the fabulous new features? ;) So how do they then
> interface with it?

Java is a different language.
It just happens to run on the same VM.
But if we remove the V and just say M, meaning for example a typical
Intel CPU and Windows, then C runs on it as well as Prolog. But that
doesn�t help.
If one wants to see Clojure code that makes use of the STM then one can
find lots of ressources.
If CL now gets a STM (I hope/think it will), then none of the old code
will be using that.

If Clojure adds new features in 8 years, then those won�t be available
in old code as well, sure. But those new features will then also not be
as integrated as the current ones that are available directly in the
beginning.
In 5-15 years some new promising language will show up on the horizon :)


>> Now instead we have something that some people percieve as much nicer
>> than CL. Lots of good stuff from CL exists in Clojure.
> Python, Haskell, Ruby etc. guys say the same. As I see it, it's just a
> question of preference. I think, what irritates the people like Madhu
> is that you preach that as dogmas. You perceive Clojure to be better,
> than CL.

In my quoted text I did not say: �Now we have something that is much
nicer than CL�. This could indeed be understood as dogmatic.
But I just mentioned the existance of such people...


 > That's great. I don't perceive anything in that regard. I
> just use CL and it gives me what I need.

Fair enough.
It�s Paul Grahams blub argument though.


> Maybe I will try to implement
> some ideas from Clojure in CL, if I find them relevant to my tasks.
> (And some people have already did that: FSet). Would it be ugly in
> your opinion?

I can�t say how something would be that you could do but didn�t do yet.
But in principle it�s possible to implement basically every important
feature of Clojure in an elegant/beautiful way in CL.
Via ABCL it could be even very easy to get all Clojure features into
that CL very fast.


> Or, vice versa should I go to comp.lang.clojure and post
> about how this same feature is implemented in CL?

Well, that would be offtopic there.
In a general Lisp forum such as c.l.l it�s okay imo.


>> Bring it all to CL. Not talking �Oh, Clojure this, Clojure that, blah
>> blah balh, its baaad, CL is waaay better, blah blah�. You can do it.
> You are right, Andr�. But who is provoking discussions? No one says,
> that CL is better for, say, doing parallel stuff or interfacing with
> Java. They say, that, in their opinion, it's better for their tasks.

It�s perfectly okay to state that.
But what you just said does not match what I experienced.
In the last weeks I often found people arguing about recursion and the
JVM, although they never used Clojure.
I personally did not jump into postings where someone said:
�CL is nice, I like it, it helps me to get the job done�
and with my reply: �Hahaha, Clojure is waaay better!!eleven!1!�.

It began with more or less neutral comments about Clojure (from myself
or someone else) until tempers got heated up.
Some people give me the impression that they have a religious
relationship to CL. Now when a new Lisp dialect shows up, it just has
to suck (like basically all other Lisps announced here in the past 6
years).


> Can you really prove the opposite? (You tried in the thread about
> NewLisp's fexprs. Do you think, that your solution was outstanding?
> IMO, each one, except for the Kazimir's one, of course :), had it's
> merits. My personal favorite was Joswig's. But well, it's a matter of
> preference, isn't it?..)

I did not find my solution particular outstanding. But to some extent
yes. It used some other approach/tools for solving the task.
And btw, I did not want to prove anything to the CL guys in that thread.
CL is my second favourite programming language, I was doing it in the
past 6 years, currently have a CL job, had one before, left my city and
even my country to get a CL job and still read in c.l.l which can be
seen as the �home of CL�.
Not everyone knows my history, but for me it is obvious that I have
nothing against CL.
My comments were directed to the NewLisp guy. He said something along
the lines that his solution was the best/shortest/most readable one.
It�s his opinion and it�s okay for me, but I strongly disagreed.
I tried to understand his code, but it took several explanations of
experts like Kaz to increase my understanding.
The Clojure code that I posted however was at least in my personal
opinion the most elegant solution. Plus it was very short, and different
than the NewLisp solution, it actually was working under the conditions
that Rainer mentioned.
His solution was the first to fullfil these criteria, and his code has
typically a good quality.


>> Lisp is not dead. It�s just the URL that has changed:http://clojure.org/
> Finally, all boils down to the "URL on the cereal box"... :)

The URL will keep changing... evolution is still in progress, the fight
for ressources/programmers has not ended. But evolution does not happen
over night.


> PS. Speaking about evolution, it seems to me, that Clojure is not the
> main trunk of Lisp evolution, it's one of the big boughs with some
> great and unique (at list to Lisp) ideas. On the opposite side of the
> tree you'll find Qi, and Mark Tarver will eagerly tell you what the
> modern Lisp should look like.

Yes, I find Marks work very interesting.
He rewrote Qi a few times by now from scratch, as I understood it.
Perhaps he can decide to do it again, but this time porting Qi to
Clojure ;)
This would also offer to him several advantages. Perhaps I should
ask him what he thinks about it.


> If PG is still interested in Arc, he
> could jump in and explain, what the 100-year-from-now Lisp should be.

Do you think Arc is the main trunk of Lisp evolution?
Seriously, I mostly see Clojure, but also the ideas of Qi as it.


> Surely Common Lisp is not the ultimate Lisp, but I guess it will move
> on in that direction.

Evolutionary speaking: it will have to become fitter and most likely
will.


> Even if not, it will still be that general (or
> let's say common?) lisp, quite usable, and what's most important a
> great (I don't say perfect) manifestation of lisp's core ideas. And
> there's nothing bad or good about that, it's just the fact.

Fair enough.
Thanks for sharing your opinions, I found it very interesting.
You managed to express it, without this extreme wording that others like
to use (sometimes including me *g*).


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: ···············@gmail.com
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <96d4ea33-b84b-4a9d-a8d4-75713d026d6d@j8g2000yql.googlegroups.com>
> Can you really prove the opposite? (You tried in the thread about
> NewLisp's fexprs. Do you think, that your solution was outstanding?
> IMO, each one, except for the Kazimir's one, of course :), had it's
> merits. My personal favorite was Joswig's. But well, it's a matter of
> preference, isn't it?..)

If someone is interested in that
discussion, my resume is here:

http://kazimirmajorinc.blogspot.com/2009/01/challenged-by-common-lispers.html



Similar point of view is expressed in
following articles:

Steve Yegge on Common Lisp macros:

http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html


Rick Jelliffe on eval:

http://blogs.oreilly.com/digitalmedia/2004/12/lisp-is-better-than-xml-but-wo.html
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <7026u8FmbbvjU1@mid.individual.net>
Jeffrey Straszheim wrote:
> On Feb 17, 9:08 pm, Madhu <·······@meer.net> wrote:
> 
>> But this is essentially an argument for sticking to CL and using clojure
>> style constructs as a library.
> 
> Which CL implementations have, right now, concurrency-ready persistent
> data structures that compare with Clojure's?

That can be provide as a library. See FSet.

> Which CLs have a multi-
> platform memory model that compares to the JVM?

None, but the situation is improving.

> What open source CL has real threads now?  I know SBCL does.  Do they
> work on Windows yet?

Also Clozure Common Lisp, which also exists on Windows.

> Do they guarantee correct cache behavior on all
> platforms?  Show me where the memory model is documented.

Not there yet, as far as I can tell, but the situation is improving.

> (I suspect that quite a few folks here have no idea of what the JVM's
> memory model offers.  That is unfortunate.  Java sucks, but the JVM is
> pretty great.)

The JVM is an amazing piece of engineering and definitely excellent in 
many respects, especially with regard to dynamic optimization techniques 
and the detail to which it specifies its memory model. Yes, we can all 
learn from that. (The JVM also suffers from a number of unnecessary 
limitations inherited from the general Java Language approach, though. 
But they seem to be working on dropping some of these limitations.)


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Slobodan Blazeski
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <cea0b3a7-e456-44f8-853b-3380758f94f3@v39g2000yqm.googlegroups.com>
On Feb 18, 3:40 am, Jeffrey Straszheim <·················@gmail.com>
wrote:
> On Feb 17, 9:08 pm, Madhu <·······@meer.net> wrote:
>
> > But this is essentially an argument for sticking to CL and using clojure
> > style constructs as a library.
>
> Which CL implementations have, right now, concurrency-ready persistent
> data structures that compare with Clojure's?  Which CLs have a multi-
> platform memory model that compares to the JVM?
Don't make me lough. The memory model of JVM is little bit better then
acquiring the memory and not releasing it until reboot. Its unreliable
performance hog. Last week we had to work around java middleware bugs.
And could someone please, please tell  me which version of JVM should
use without breaking some other dumb a java app. JVM is like vista
there are plenty  of features but the overall quality sucks.

cheers
bobi
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <707p28Fn248bU1@mid.individual.net>
Slobodan Blazeski wrote:
> On Feb 18, 3:40 am, Jeffrey Straszheim <·················@gmail.com>
> wrote:
>> On Feb 17, 9:08 pm, Madhu <·······@meer.net> wrote:
>>
>>> But this is essentially an argument for sticking to CL and using clojure
>>> style constructs as a library.
>> Which CL implementations have, right now, concurrency-ready persistent
>> data structures that compare with Clojure's?  Which CLs have a multi-
>> platform memory model that compares to the JVM?
> Don't make me lough. The memory model of JVM is little bit better then
> acquiring the memory and not releasing it until reboot. Its unreliable
> performance hog. Last week we had to work around java middleware bugs.
> And could someone please, please tell  me which version of JVM should
> use without breaking some other dumb a java app. JVM is like vista
> there are plenty  of features but the overall quality sucks.

The big advantage of the JVM memory model is that it is well specified, 
to much more detail than in other languages, so you know better what you 
can and cannot rely on.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Wooding
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <873ae2363n.fsf.mdw@metalzone.distorted.org.uk>
Jeffrey Straszheim <·················@gmail.com> writes:

> What open source CL has real threads now?  I know SBCL does.  Do they
> work on Windows yet?  Do they guarantee correct cache behavior on all
> platforms?  Show me where the memory model is documented.

I suspect that ABCL's memory model is documented approximately as well
as Clojure's. ;-)

> (I suspect that quite a few folks here have no idea of what the JVM's
> memory model offers.  That is unfortunate.  Java sucks, but the JVM is
> pretty great.)

The specification of the JVM memory model was one of the most valuable
contributions that Java had to offer.  But even the first versions of
the memory model were broken in various ways (which have now been
fixed).

The JVM is a long way from being perfect, though.  I agree that the Java
language sucks greatly; unfortunately, the JVM inherits several aspects
of this suckage.

> Clojure is a Lisp,

I'm not sure that

        (cons 1 2)

should signal an error in a `Lisp'.  The idea of a cons cell as being a
simple pair of objects runs rather deep in Lisp culture.  (The fact that
CONS doesn't actually make cons cells is also strange.)

> which happens to have a lot to offer for concurrency that isn't
> available yet for CL.  If CL gets it, that will be great (I think I'd
> still prefer Clojure because I like FP and I like its cleaner syntax
> and design, but that is just me).

I think I must be weird.  One of the things that I like most about
Common Lisp is its conspicuously rich tradition.  Yes, it's inconsistent
in places, and you can see the joins where new stuff was added to old,
but to me that's all part of the charm.  By comparison, Clojure feels
rather sterile to me.

Despite everything I've said (and am likely to say in future), I think
that Clojure is an interesting language, deserving use and study.  The
world is certainly enriched by its existence.

-- [mdw]
From: Kaz Kylheku
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <20090304164539.67@gmail.com>
On 2009-02-25, Mark Wooding <···@distorted.org.uk> wrote:
> Jeffrey Straszheim <·················@gmail.com> writes:
>> Clojure is a Lisp,
>
> I'm not sure that
>
>         (cons 1 2)
>
> should signal an error in a `Lisp'.

Ouch, are you serious?
From: Dimiter "malkia" Stanev
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <go46q7$afl$2@malkia.motzarella.org>
Kaz Kylheku wrote:
> On 2009-02-25, Mark Wooding <···@distorted.org.uk> wrote:
>> Jeffrey Straszheim <·················@gmail.com> writes:
>>> Clojure is a Lisp,
>> I'm not sure that
>>
>>         (cons 1 2)
>>
>> should signal an error in a `Lisp'.
> 
> Ouch, are you serious?

Wouldn't that do dotted cons?

I'm probably missing something...

CL-USER 13 > (cons 1 2)
(1 . 2)
From: Brian Adkins
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <m2wsbe9tfy.fsf@gmail.com>
"Dimiter \"malkia\" Stanev" <······@mac.com> writes:

> Kaz Kylheku wrote:
>> On 2009-02-25, Mark Wooding <···@distorted.org.uk> wrote:
>>> Jeffrey Straszheim <·················@gmail.com> writes:
>>>> Clojure is a Lisp,
>>> I'm not sure that
>>>
>>>         (cons 1 2)
>>>
>>> should signal an error in a `Lisp'.
>>
>> Ouch, are you serious?
>
> Wouldn't that do dotted cons?
>
> I'm probably missing something...
>
> CL-USER 13 > (cons 1 2)
> (1 . 2)

I initially parsed Mark's statement incorrectly also and almost
replied with sbcl output :) He's saying that a Lisp should *not*
signal an error with (cons 1 2), but Clojure does throw an exception:

~/Desktop/clojure_20080916$ rlwrap java -server -cp clojure.jar clojure.lang.Repl
Clojure
user=> (cons 1 2)
java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
	at clojure.lang.RT.seqFrom(RT.java:465)
	at clojure.lang.RT.seq(RT.java:448)
	at clojure.lang.RT.cons(RT.java:505)
	at clojure.cons__4.invoke(boot.clj:21)
	at user.eval__2290.invoke(Unknown Source)
	at clojure.lang.Compiler.eval(Compiler.java:3891)
	at clojure.lang.Repl.main(Repl.java:75)

-- 
Brian Adkins
http://lojic.com/
From: Dimiter "malkia" Stanev
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <go48cc$so2$1@malkia.motzarella.org>
Brian Adkins wrote:
> "Dimiter \"malkia\" Stanev" <······@mac.com> writes:
> 
>> Kaz Kylheku wrote:
>>> On 2009-02-25, Mark Wooding <···@distorted.org.uk> wrote:
>>>> Jeffrey Straszheim <·················@gmail.com> writes:
>>>>> Clojure is a Lisp,
>>>> I'm not sure that
>>>>
>>>>         (cons 1 2)
>>>>
>>>> should signal an error in a `Lisp'.
>>> Ouch, are you serious?
>> Wouldn't that do dotted cons?
>>
>> I'm probably missing something...
>>
>> CL-USER 13 > (cons 1 2)
>> (1 . 2)
> 
> I initially parsed Mark's statement incorrectly also and almost
> replied with sbcl output :) He's saying that a Lisp should *not*
> signal an error with (cons 1 2), but Clojure does throw an exception:
> 
> ~/Desktop/clojure_20080916$ rlwrap java -server -cp clojure.jar clojure.lang.Repl
> Clojure
> user=> (cons 1 2)
> java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
> java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
> 	at clojure.lang.RT.seqFrom(RT.java:465)
> 	at clojure.lang.RT.seq(RT.java:448)
> 	at clojure.lang.RT.cons(RT.java:505)
> 	at clojure.cons__4.invoke(boot.clj:21)
> 	at user.eval__2290.invoke(Unknown Source)
> 	at clojure.lang.Compiler.eval(Compiler.java:3891)
> 	at clojure.lang.Repl.main(Repl.java:75)
> 

Ops... I was blindly thinking Common Lisp.
From: Mark Wooding
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <87iqmuo5nt.fsf.mdw@metalzone.distorted.org.uk>
Kaz Kylheku <········@gmail.com> writes:

> On 2009-02-25, Mark Wooding <···@distorted.org.uk> wrote:
>> Jeffrey Straszheim <·················@gmail.com> writes:
>>> Clojure is a Lisp,
>>
>> I'm not sure that
>>
>>         (cons 1 2)
>>
>> should signal an error in a `Lisp'.
>
> Ouch, are you serious?

Completely serious, for once.  (Did you misundersand me?  I realise now
that I didn't write as clearly as I ought to have done, though I believe
that what I wrote says what I meant.)

I can't tell whether you're expressing surprise at (a) my remark that a
Lisp ought to accept (cons 1 2) and evaluate it, (b) a misunderstanding
that actually I said the opposite, or (c) the (correct) implication that
Clojure fails to evaluate the above expression.

Anyway, for the avoidance of doubt: should a Lisp do this?

        user=> (cons 1 2)
        java.lang.IllegalArgumentException: Don't know how to create
	ISeq from: Integer (NO_SOURCE_FILE:0)

`Lisp' is at best fuzzily and subjectively defined; but it has a long
and rich tradition.  One aspect of this tradition is that CONS builds a
new composite object constructed from its two arguments, somewhat
arbitrarily naming the two components CAR and CDR.  The types of the
components are irrelevant to CONS.  It just accepts two values, and
aggregates them into a single composite value.

The cons cell, constructed and named after the CONS operation, is
simple -- almost trivial -- but very versatile.  It can be used to build
a variety of useful data structures, such as lists, alists, trees of
various kinds, stacks, queues, and so on.

Cons cells are traditionally mutable, which has a number of effects.
Firstly, and positively, it extends the variety of data structures which
can be built from cons cells.  Secondly, and negatively, mutation can
make reasoning about program behaviour very complicated.  It doesn't
seem to me that this mutation is as fundamental a piece of Lisp
tradition as CONS itself, though.

There are a number of other features I'd expect from a proper Lisp.
Homoiconicity is one.  For example, I'm not actually sure whether Scheme
is homoiconic any more; R5RS doesn't describe parsing code in terms of
READ, for example, though there is still EVAL.

As far as my own, subjective, definition of Lisp goes, I don't think
that I actually have a list of necessary features, omission of any one
of which condemns a language to non-Lisp-hood.  Rather, I have an
informal `scoring' system.  Clojure's homoiconicity and macros certainly
give it a high Lispiness score.  Whether this is enough to offset
aspects such as CONS being picky about the types of CDRs, objects other
than lists printing as lists, or the existence of two distinct `false'
values (`nil' and `false') I haven't decided.  (I said it was a
subjective definition: therefore I do have the final decision, but I
don't get to tell you that you're wrong for having a different
definition.)

(I've used upper-case for symbol names above because that's what Common
Lisp does and it makes them visually distinctive without tedious
quoting; I don't mean to exclude Lisps like Emacs Lisp, which have
case-sensitive symbols written in lower-case, but `cons' does `the right
thing'.)

And again, (and I'll say this positively to avoid misunderstanding): I
think Clojure is a valuable contribution, regardless of whether it is or
isn't a `true' Lisp, whatever that might actually mean.  Clojure seems
to have some novel ideas, and to combine some existing ideas in novel
ways; whether these innovations will stand the test of time remains to
be seen, of course, but I hope that at least some will.  So, thank you,
Rich Hickey, for designing and implementing a thought-provoking
language.

-- [mdw]
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <7026jpFm3p18U1@mid.individual.net>
Rich Hickey wrote:
> On Feb 17, 8:48 am, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 15, 4:38 pm, Pascal Costanza <····@p-cos.net> wrote:
>>>> Rich Hickey wrote:
>>>>> On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
>>>>>> Andr� Thieme wrote:
>>>>>>> I think all major languages will get a STM with MVCC in the coming
>>>>>>> months or years.
>>>>>> That's not so clear yet. See "Software Transactional Memory: why is it
>>>>>> only a research toy?" athttp://doi.acm.org/10.1145/1400214.1400228
>>>>> That is a weak article. It criticizes STM in comparison to its
>>>>> performance vs. serial execution. It doesn't compare the STM code with
>>>>> equivalent versions using manual locking, neither for complexity nor
>>>>> for performance. Nor does it place appropriate value on correctness.
>>>>> People were (are!) skeptical of GC too, and there were (are) certainly
>>>>> places where its performance rules it out. That doesn't negate its
>>>>> value for people for whom its performance is sufficient and its
>>>>> correctness lets them focus on their application domain.
>>>> The article has some credibility because the authors have been doing
>>>> research on STM themselves.
>>> I didn't mean to imply they weren't credible. But you have to be
>>> careful when transferring their conclusions to another domain. I've
>>> met with some researchers in the HPC area where the dynamism of Lisp,
>>> Java, even C++ virtual function calls, are all unacceptable for
>>> performance reasons, and the authors' main argument against STM was
>>> performance.
>> Er, now I'm confused. If I remember correctly, you advertise Clojure as
>> a language to be able to take advantage of multiple cores. What other
>> reasons are there to want that?
> 
> Well, there are lots of possible reasons - getting a single job done
> more quickly, getting more jobs done, being more responsive etc.
> People were doing cooperative multitasking and threading before there
> were multiple cores (and thus no performance incentives) - why?
> Because there were other advantages to organizing their programs that
> way. Now with multicore they are dealing the challenges of actual
> overlapping concurrency - without care, incorrect access to shared
> memory could lead to corrupt data or, when using locks, deadlock.
> 
> It is worth making the simplifying distinction between concurrency and
> parallelism - i.e. doing many tasks at once, vs. breaking a single
> task into multiple parts for performance reasons. The latter is likely
> to become readily available in all languages in the form of libraries
> that encapsulate the threading and sharing. Many of these also don't
> require sophisticated synchronization - e.g. separate threads
> manipulating separate regions of an array. OTOH, concurrency is almost
> always an application-level problem - handling multiple users + I/O +
> background calculations etc. In many cases there isn't a significant
> amount of sharing, or contention for shared items, but, when shared
> items are accessed, the code must be correct.
> 
> Thus, there are many applications for which the results of pounding on
> a concurrency construct in a highly contended benchmark is completely
> irrelevant, just as there are those who wouldn't give up GC even if it
> were several times slower than malloc/free.

Hm, ok.

>>>>> When I give talks I emphasize the unique parts of Clojure because they
>>>>> are interesting and that's where Clojure adds value, but that doesn't
>>>>> mean they are the only parts. You can bash bits in Clojure just like
>>>>> in CL and Java, there are mutable arrays etc, but what's interesting
>>>>> about that?
>>>> So how do you deal with concurrency when mutating arrays?
>>> Is this a trick question? :)
>>> I wrote Clojure's data structures so I would have something safe to
>>> use concurrently, and I use them whenever possible. If I were to use a
>>> mutable array, it would be within the confines of a function that
>>> otherwise presented a functional interface, e.g. as an implementation
>>> detail of sorting - the array would not be shared. The other case is
>>> mutating an array once only on initialization, and never changing it
>>> once shared. This is how Clojure's persistent data structures work,
>>> and I've made the case they couldn't be nearly as fast if they were
>>> implemented 'purely', i.e. only in terms of other immutable
>>> structures.
>>> Actual (overlapping) mutation of arrays in place, concurrently? I
>>> avoid it. If you had to, you would need locks.
>> OK, I have to admit I don't know Clojure from using it in practice
>> (obviously ;).
>>
>> So: Why do you allow for mutating arrays without ensuring thread safety,
>> while at the same time you disallow mutating local (non-special)
>> variables? You can write thread-safe code with mutating local variables
>> as well? Why is one treated specially and the other not?
>>
>> My impression that you promote functional programming came from the fact
>> that local variables cannot be mutated. From an outsider's perspective,
>> that looks a bit odd...
> 
> I do promote functional programming and don't enforce it. That was my
> original point - you were painting Clojure as purely functional when
> it's not. However, that doesn't imply it needs to support mutable
> locals. There are an indefinite number of mutable Java things Clojure
> supports but doesn't manage - arrays are among them. There are also a
> set of features with robust concurrency characteristics - immutable
> locals are among them. There are also the reference types which,
> unlike unmoderated, unsafe, mutable locals, support change with good
> concurrency semantics. If you are desperate for a arbitrarily mutable
> local - use an array! It is sufficient. But I'll not add mutable
> locals just to satisfy some arbitrary notion of 'complete'.

OK, I better understand your take on things now. (I don't think you will 
be able to stick to such 'incompleteness' in the long run. But that 
remains to be seen.)

>>> But I find the statement somewhat specious and preachy ("A good Lisp
>>> dialect should..."), since I didn't find the kind of extensibility in
>>> Common Lisp (in itself, or via well-defined interfaces in any
>>> language) that I have in Clojure. CL has a hard-wired set of
>>> privileged types. Syntactic extension is only one dimension of
>>> extensibility (and supported by Clojure). CLOS is another, and I see
>>> the kind of reflectivity you speak of in CLOS, but Common Lisp isn't
>>> written in CLOS.
> 
>>> Could you write an efficient Common Lisp in CLOS, where the core data
>>> structures and algorithms were extensible CLOS types and generic
>>> functions?
>> Yes, why not?
> 
> Well, I'd like to see it. I guess I'm just tired of theoretical
> arguments and admonitions. Clojure actually exists and is quite
> extensible.

This is a weird statement. You implemented Clojure on top of Java. Why 
should it not be possible to implement it on top of Common Lisp?

You seem to mean something else, but I don't get it.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <cecbbf83-30b6-4023-a619-f71d86e1619a@x10g2000yqk.googlegroups.com>
On Feb 18, 5:35 am, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 17, 8:48 am, Pascal Costanza <····@p-cos.net> wrote:
> >> Rich Hickey wrote:
> >>> On Feb 15, 4:38 pm, Pascal Costanza <····@p-cos.net> wrote:
> >>>> Rich Hickey wrote:
> >>>>> On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:

> >>> But I find the statement somewhat specious and preachy ("A good Lisp
> >>> dialect should..."), since I didn't find the kind of extensibility in
> >>> Common Lisp (in itself, or via well-defined interfaces in any
> >>> language) that I have in Clojure. CL has a hard-wired set of
> >>> privileged types. Syntactic extension is only one dimension of
> >>> extensibility (and supported by Clojure). CLOS is another, and I see
> >>> the kind of reflectivity you speak of in CLOS, but Common Lisp isn't
> >>> written in CLOS.
>
> >>> Could you write an efficient Common Lisp in CLOS, where the core data
> >>> structures and algorithms were extensible CLOS types and generic
> >>> functions?
> >> Yes, why not?
>
> > Well, I'd like to see it. I guess I'm just tired of theoretical
> > arguments and admonitions. Clojure actually exists and is quite
> > extensible.
>
> This is a weird statement. You implemented Clojure on top of Java. Why
> should it not be possible to implement it on top of Common Lisp?
>

I certainly could have written Clojure in CLOS, and did in early
prototypes, but then I'd still have two languages, with the host
language (CLOS) providing a paucity of libraries, no concurrency
semantics and minimal industry support. Given a CL with a good memory
model and decent concurrency primitives, it would be an interesting
exercise, as CL runtimes do still have advantages in some areas over
the JVM, e.g. tagged numbers, multivalue returns, tail calls etc. But
I'm skeptical of them ever catching up in other areas such as dynamic
optimization, concurrent GC, security etc, the libraries issue aside.

> You seem to mean something else, but I don't get it.
>

I'm still bothered by your statement:

>> - AFAICT, the only way to reflectively extend the language is by going
>> down to the Java level. That shouldn't be necessary. A good Lisp dialect
>> should allow you to stay within Lisp even if you want to influence the
>> implementation of the language itself.

When I look at CL I see this kind of reflective, polymorphic
extensibility only at the CLOS layer. CLOS is implemented in a lower-
level language (Lisp without CLOS, and the Lisp, in turn, in C or
something like it) that does not offer polymorphic extensibility.
Clojure is written in a language that does. So, e.g. Clojure's first/
rest (and the things built on them) can be polymorphically extended by
users (in Clojure or Java) in way that car and cdr, in all Lisps I
know of, cannot. Until CL is written in CLOS, and car and cdr are
generic functions, it will not be as extensible as Clojure in this
regard, thus I resent the "A good Lisp dialect should allow you to
stay within Lisp even if you want to influence the implementation of
the language itself", since, in this aspect, most don't. Nor, often,
do they offer a path to such extension in any language, as their
implementation languages don't support polymorphic extensibility
either.

User extensibility has far less to do with a language being written in
itself than it has to do with it being written extensibly.

Rich
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <702r3iFmjioiU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 18, 5:35 am, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 17, 8:48 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Rich Hickey wrote:
>>>>> On Feb 15, 4:38 pm, Pascal Costanza <····@p-cos.net> wrote:
>>>>>> Rich Hickey wrote:
>>>>>>> On Feb 15, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:
> 
>>>>> But I find the statement somewhat specious and preachy ("A good Lisp
>>>>> dialect should..."), since I didn't find the kind of extensibility in
>>>>> Common Lisp (in itself, or via well-defined interfaces in any
>>>>> language) that I have in Clojure. CL has a hard-wired set of
>>>>> privileged types. Syntactic extension is only one dimension of
>>>>> extensibility (and supported by Clojure). CLOS is another, and I see
>>>>> the kind of reflectivity you speak of in CLOS, but Common Lisp isn't
>>>>> written in CLOS.
>>>>> Could you write an efficient Common Lisp in CLOS, where the core data
>>>>> structures and algorithms were extensible CLOS types and generic
>>>>> functions?
>>>> Yes, why not?
>>> Well, I'd like to see it. I guess I'm just tired of theoretical
>>> arguments and admonitions. Clojure actually exists and is quite
>>> extensible.
>> This is a weird statement. You implemented Clojure on top of Java. Why
>> should it not be possible to implement it on top of Common Lisp?
> 
> I certainly could have written Clojure in CLOS, and did in early
> prototypes, but then I'd still have two languages, with the host
> language (CLOS) providing a paucity of libraries, no concurrency
> semantics and minimal industry support. Given a CL with a good memory
> model and decent concurrency primitives, it would be an interesting
> exercise, as CL runtimes do still have advantages in some areas over
> the JVM, e.g. tagged numbers, multivalue returns, tail calls etc. But
> I'm skeptical of them ever catching up in other areas such as dynamic
> optimization, concurrent GC, security etc, the libraries issue aside.

OK.

>> You seem to mean something else, but I don't get it.
> 
> I'm still bothered by your statement:
> 
>>> - AFAICT, the only way to reflectively extend the language is by going
>>> down to the Java level. That shouldn't be necessary. A good Lisp dialect
>>> should allow you to stay within Lisp even if you want to influence the
>>> implementation of the language itself.
> 
> When I look at CL I see this kind of reflective, polymorphic
> extensibility only at the CLOS layer. CLOS is implemented in a lower-
> level language (Lisp without CLOS, and the Lisp, in turn, in C or
> something like it) that does not offer polymorphic extensibility.
> Clojure is written in a language that does. So, e.g. Clojure's first/
> rest (and the things built on them) can be polymorphically extended by
> users (in Clojure or Java) in way that car and cdr, in all Lisps I
> know of, cannot. Until CL is written in CLOS, and car and cdr are
> generic functions, it will not be as extensible as Clojure in this
> regard, thus I resent the "A good Lisp dialect should allow you to
> stay within Lisp even if you want to influence the implementation of
> the language itself", since, in this aspect, most don't. Nor, often,
> do they offer a path to such extension in any language, as their
> implementation languages don't support polymorphic extensibility
> either.

Common Lisp provides user-extensibility primarily by way of macros, as a 
subset of more general reflection capabilities. My original comment was 
targeted at being able to develop high-level parallel programming 
constructs within the language itself. In a Common Lisp implementation 
that provides a good memory model and good concurrency primitives, you 
would be able to do this using the usual combination of functional and 
macro abstractions. The user-extensibility of generic functions is a 
different kind of extensibility in this regard. Yes, Clojure is more 
flexible in that regard.

I stick to my claim that a good Lisp dialect should allow you to stay 
within Lisp even if you want to influence the implementation of the 
language itself. In some respects, Common Lisp indeed doesn't qualify as 
good Lisp dialect in that regard - in the history of Lisp and Scheme, 
some compromises were made that shouldn't be necessary anymore. In 
general, though, the user-extensibility of Common Lisp and Scheme is 
pretty good, you can easily create at least the illusion of staying 
within the language itself.

I am also convinced that it's not just an academic exercise to ensure 
that a language is extensible in terms of itself: If you can make a 
language 'kernel' flexible enough that major portions of a language can 
be implemented in terms of this language kernel by way of user-defined 
extensions, you can make much better promises with regard to 
user-extensibility for domain-specific extensions in the general case. 
(User-extensibility is not something that you can design in a vacuum, it 
has to be tried and tested!)

Whenever you have to resort to an outside language to achieve a certain 
kind of extension, to me that's a sign that there is some fundamental 
form of user-extensibility missing. And _that's_ the main feature that 
turns a Lisp into a Lisp, IMHO. (That's also why I am skeptical about 
some limitations that Clojure has by design. But again, these are just 
my 0.20�. ;)

> User extensibility has far less to do with a language being written in
> itself than it has to do with it being written extensibly.

It has to do with both.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnhl9301tpm@enews4.newsguy.com>
Pascal Costanza wrote:

> > User extensibility has far less to do with a language being
> > written in itself than it has to do with it being written
> > extensibly.
> 
> It has to do with both.

You're agreeing with him, but you lack the capacity to realize
it.  I think you will be very happy with Commune Lisp.
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <703hndFmei9uU1@mid.individual.net>
William James wrote:
> Pascal Costanza wrote:
> 
>>> User extensibility has far less to do with a language being
>>> written in itself than it has to do with it being written
>>> extensibly.
>> It has to do with both.
> 
> You're agreeing with him, but you lack the capacity to realize
> it.  I think you will be very happy with Commune Lisp.

I think it's clear that I agree with Rich in some regards, but not in 
others. So it's more subtle than you think it is.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Tobias C. Rittweiler
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <873aecrnx1.fsf@freebits.de>
> This is a weird statement. You implemented Clojure on top of Java. Why
> should it not be possible to implement it on top of Common Lisp?

Financial resources. Time constraints. Your line of argument is awefully
academic.

  -T.
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <702k3nFm7eo1U1@mid.individual.net>
Tobias C. Rittweiler wrote:
>> This is a weird statement. You implemented Clojure on top of Java. Why
>> should it not be possible to implement it on top of Common Lisp?
> 
> Financial resources. Time constraints. 

I think these are myths.

> Your line of argument is awefully academic.

I don't agree.

We have examples of languages built on top of Common Lisp (like QI, 
Pseudoscheme, etc.), so it clearly shows that it can be done, within a 
reasonable amount of work. We also have examples of how Common Lisp can 
be extended with more flexible data structures (like cl-containers, 
fset, etc.), also within a reasonable amount of work.

It's also relatively easy to build new languages on top of Common Lisp. 
See http://users.csc.calpoly.edu/~clements/papers/fdpe05-bc.pdf for an 
example in Scheme. You can do similar things with the Common Lisp 
package system.


[I don't want to make this sounds like a CL vs. Clojure fight. To stress 
this again: Clojure is one of the most interesting recent developments 
in Lisp!]


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Tobias C. Rittweiler
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <87y6w3rdb6.fsf@freebits.de>
Pascal Costanza <...> writes:

> We have examples of languages built on top of Common Lisp (like QI,
> Pseudoscheme, etc.), so it clearly shows that it can be done, within a
> reasonable amount of work.

Nobody disputes that. In fact, you're preaching to the choir. :-)

That doesn't change the fact that the JVM may indeed be a very good fit
for Clojure which is explicitly designed for multithreaded
programming---a better fit than targetting Common Lisp. But please tell
what advantages Common Lisp would provide in that context.

  -T.
From: Pascal Costanza
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <702q61Fmlda4U1@mid.individual.net>
Tobias C. Rittweiler wrote:
> Pascal Costanza <...> writes:
> 
>> We have examples of languages built on top of Common Lisp (like QI,
>> Pseudoscheme, etc.), so it clearly shows that it can be done, within a
>> reasonable amount of work.
> 
> Nobody disputes that. In fact, you're preaching to the choir. :-)

;)

> That doesn't change the fact that the JVM may indeed be a very good fit
> for Clojure which is explicitly designed for multithreaded
> programming---a better fit than targetting Common Lisp. But please tell
> what advantages Common Lisp would provide in that context.

If Common Lisp implementations eventually catch up with regard to 
providing low-level support for multithreading and parallelism [1], what 
you get as advantages are the following:

+ In Common Lisp, due to type and optimization declarations, you can go 
arbitrarily low-level and efficient while staying within Lisp itself.

+ Plus you don't suffer from some of the gratuitous limitations of the 
JVM framework (single dispatch, single inheritance, focus on OOP, etc.).


I think if you want to use multicore architectures for performance 
reasons (and I still don't see other really good reasons), the chance 
that you can get performance out of Common Lisp are probably higher than 
in the case of Java. (My guess, can't back it.)

If you want to use forms of multithreading for the sake of having more 
freedom in your programming model, that's less important, of course.


Pascal

[1] ...and in this regard, the future looks much brighter than you may 
think. ;)

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: budden
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <71796b82-312e-4740-8632-097cc54a53e6@j38g2000yqa.googlegroups.com>
> I think if you want to use multicore architectures for performance
> reasons (and I still don't see other really good reasons), the chance
> that you can get performance out of Common Lisp are probably higher than
> in the case of Java. (My guess, can't back it.)
Unfortunately for CL, it looks like Java is about to outperform CL
today.
If Java programs were not so memory-consuming, I'd say for sure that
Java
is faster.

http://shootout.alioth.debian.org/u32/lisp.php
From: Isaac Gouy
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <a3ccbbdc-1d7c-4928-99d4-87e1b5c6a8c6@g1g2000pra.googlegroups.com>
On Feb 18, 8:47 am, budden <···········@mail.ru> wrote:
> > I think if you want to use multicore architectures for performance
> > reasons (and I still don't see other really good reasons), the chance
> > that you can get performance out of Common Lisp are probably higher than
> > in the case of Java. (My guess, can't back it.)
>
> Unfortunately for CL, it looks like Java is about to outperform CL
> today.
> If Java programs were not so memory-consuming, I'd say for sure that
> Java
> is faster.
>
> http://shootout.alioth.debian.org/u32/lisp.php


That shows the programs forced onto one core, this shows multicore -

http://shootout.alioth.debian.org/u32q/lisp.php
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnhll901u5r@enews4.newsguy.com>
budden wrote:

> > I think if you want to use multicore architectures for
> > performance reasons (and I still don't see other really
> > good reasons), the chance that you can get performance out
> > of Common Lisp are probably higher than in the case of
> > Java. (My guess, can't back it.)
> Unfortunately for CL, it looks like Java is about to
> outperform CL today.
> If Java programs were not so memory-consuming, I'd say for
> sure that Java
> is faster.
> 
> http://shootout.alioth.debian.org/u32/lisp.php

Clojure runs this very swiftly.  (Be sure to use java -server.)
Can Commune Lisp do as well?

(def runs 100)
(def max_iterations 1000)

(defn iter [ci cr]
  (let [max_iter (int max_iterations)
        ci (double ci)
        cr (double cr)]
    (loop [zi (double ci)   zr (double cr)   i (int 1)]
      (if (<= i max_iter)
        (let [zr2 (* zr zr)   zi2 (* zi zi)]
          (if (<= (+ zr2 zi2) (double 4.0))
            (recur (+ (* (* zr zi) (double 2.0)) ci)
                   (+ (- zr2 zi2) cr)
                   (inc i))
	          i))
        0))))

(defn mand [n]
  (doseq [y (range -39 39)]
    (when (= 1 n) (print "\n"))
    (doseq [x (range -39 39)]
      (let [i (iter (/ x 40.0) (- (/ y 40.0) 0.5))]
        (when (= 1 n) (print (if (= 0 i) "*" " ")))))))

(defn time-mand []
  (time
   (doseq [i (range 1 (inc runs))]
     (mand i))))

(time-mand)
From: Marco Antoniotti
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <0ea570b0-e454-449b-85e9-24a66799e0f2@n10g2000vbl.googlegroups.com>
On Feb 18, 7:56 pm, "William James" <> wrote:
> budden wrote:
> > > I think if you want to use multicore architectures for
> > > performance reasons (and I still don't see other really
> > > good reasons), the chance that you can get performance out
> > > of Common Lisp are probably higher than in the case of
> > > Java. (My guess, can't back it.)
> > Unfortunately for CL, it looks like Java is about to
> > outperform CL today.
> > If Java programs were not so memory-consuming, I'd say for
> > sure that Java
> > is faster.
>
> >http://shootout.alioth.debian.org/u32/lisp.php
>
> Clojure runs this very swiftly.  (Be sure to use java -server.)
> Can Commune Lisp do as well?
>
> (def runs 100)
> (def max_iterations 1000)
>
> (defn iter [ci cr]
>   (let [max_iter (int max_iterations)
>         ci (double ci)
>         cr (double cr)]
>     (loop [zi (double ci)   zr (double cr)   i (int 1)]
>       (if (<= i max_iter)
>         (let [zr2 (* zr zr)   zi2 (* zi zi)]
>           (if (<= (+ zr2 zi2) (double 4.0))
>             (recur (+ (* (* zr zi) (double 2.0)) ci)
>                    (+ (- zr2 zi2) cr)
>                    (inc i))
>                   i))
>         0))))
>
> (defn mand [n]
>   (doseq [y (range -39 39)]
>     (when (= 1 n) (print "\n"))
>     (doseq [x (range -39 39)]
>       (let [i (iter (/ x 40.0) (- (/ y 40.0) 0.5))]
>         (when (= 1 n) (print (if (= 0 i) "*" " ")))))))
>
> (defn time-mand []
>   (time
>    (doseq [i (range 1 (inc runs))]
>      (mand i))))
>
> (time-mand)

Well.  How does Ruby fare on this? :)

Cheers
--
Marco
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gni0sj023c@enews2.newsguy.com>
Marco Antoniotti wrote:

> Well.  How does Ruby fare on this? :)

list = [ {:lang,'Ruby', :time, 666.6},
         {:lang,'F#', :time, 2.475} ]
    ==>[{:lang=>"Ruby", :time=>666.6}, {:lang=>"F#",
:time=>2.475}]

list.sort_by{|x| x[:time]}.reverse.first
    ==>{:lang=>"Ruby", :time=>666.6}


Ruby is first!
From: Marco Antoniotti
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <a921b5e1-0350-42da-b443-e26f5ea452d7@k19g2000yqg.googlegroups.com>
On Feb 18, 11:08 pm, "William James" <> wrote:
> Marco Antoniotti wrote:
> > Well.  How does Ruby fare on this? :)
>
> list = [ {:lang,'Ruby', :time, 666.6},
>          {:lang,'F#', :time, 2.475} ]
>     ==>[{:lang=>"Ruby", :time=>666.6}, {:lang=>"F#",
> :time=>2.475}]
>
> list.sort_by{|x| x[:time]}.reverse.first
>     ==>{:lang=>"Ruby", :time=>666.6}
>
> Ruby is first!

Now, don't get so touchy on the subject...  You are missing clojure
from your little Ruby snippet... Plus, I think you should also throw
in a bit of Intercal.

Cheers
--
Marco
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <26739144-334e-4a43-a0c3-921f6936c22d@33g2000yqm.googlegroups.com>
On Feb 18, 9:09 am, Pascal Costanza <····@p-cos.net> wrote:
>
> + In Common Lisp, due to type and optimization declarations, you can go
> arbitrarily low-level and efficient while staying within Lisp itself.
>
> + Plus you don't suffer from some of the gratuitous limitations of the
> JVM framework (single dispatch, single inheritance, focus on OOP, etc.).
>

In Common Lisp, without using FFI to a C or assembly library, can I
implement a dot product using SSE instructions?  What about new
instructions in SSE4?  I'm not saying you can do this in Clojure/Java
either, but "arbitrarily low-level" is probably not an accurate
statement.  Staying within [Common] Lisp, I suspect you have some
limitations too.
From: ·····@franz.com
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <3e655287-ca36-4e3b-8fe6-1a4fa441a1a1@b8g2000pre.googlegroups.com>
On Feb 18, 9:09 pm, Scott <·······@gmail.com> wrote:
> On Feb 18, 9:09 am, Pascal Costanza <····@p-cos.net> wrote:
>
>
>
> > + In Common Lisp, due to type and optimization declarations, you can go
> > arbitrarily low-level and efficient while staying within Lisp itself.
>
> > + Plus you don't suffer from some of the gratuitous limitations of the
> > JVM framework (single dispatch, single inheritance, focus on OOP, etc.).
>
> In Common Lisp, without using FFI to a C or assembly library, can I
> implement a dot product using SSE instructions?  What about new
> instructions in SSE4?

Well, maybe not everyone, but an implementor certainly can do so.  If
you were familiar with an open-source implementation, you could
probably study up on its compiler and add new lap codes to the
internal assembler (of course, this implies that the compiler
implementation is not a byte compiler).

And you don't even necessarily have to be an implementor, nor do you
necessarily need to have source.  Once, while he was still active in
CL programming at least publicly, Erik Naggum made a good case and
asked me for information on lap codes for SSE instruction generation
(this was before our Intel Mac or x86-64 versions existed, and it was
right after SSE/SSE2 came on the scene) and as far as I know he was
able to use the info to generate new instructions, all done in Lisp
without any FFI.

  I'm not saying you can do this in Clojure/Java
> either, but "arbitrarily low-level" is probably not an accurate
> statement.  Staying within [Common] Lisp, I suspect you have some
> limitations too.

Not really. In general, Lisp (including Common Lisp) is extensible,
and that extensibility can be upward (toward more complexity) or
downward (toward the bit level).  The only real limitations to what
can be done are when you get to the hardware level itself - it is
likely to be hard to extend past what the hardware allows :-)

Duane
From: Thomas F. Burdick
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <c23550f5-4cae-478a-9bdb-edc427e35151@l39g2000yqn.googlegroups.com>
On Feb 19, 10:51 am, ·····@franz.com wrote:
> On Feb 18, 9:09 pm, Scott <·······@gmail.com> wrote:
>
> > On Feb 18, 9:09 am, Pascal Costanza <····@p-cos.net> wrote:
>
> > > + In Common Lisp, due to type and optimization declarations, you can go
> > > arbitrarily low-level and efficient while staying within Lisp itself.
>
> > > + Plus you don't suffer from some of the gratuitous limitations of the
> > > JVM framework (single dispatch, single inheritance, focus on OOP, etc.).
>
> > In Common Lisp, without using FFI to a C or assembly library, can I
> > implement a dot product using SSE instructions?  What about new
> > instructions in SSE4?
>
> Well, maybe not everyone, but an implementor certainly can do so.  If
> you were familiar with an open-source implementation, you could
> probably study up on its compiler and add new lap codes to the
> internal assembler (of course, this implies that the compiler
> implementation is not a byte compiler).
>
> And you don't even necessarily have to be an implementor, nor do you
> necessarily need to have source.  Once, while he was still active in
> CL programming at least publicly, Erik Naggum made a good case and
> asked me for information on lap codes for SSE instruction generation
> (this was before our Intel Mac or x86-64 versions existed, and it was
> right after SSE/SSE2 came on the scene) and as far as I know he was
> able to use the info to generate new instructions, all done in Lisp
> without any FFI.

A fairly public example of this sort of thing was FPC-PPC, which was
an MCL contrib that let you do extremely efficient double-float
operations. The same technique could have been used to add Altivec
support.
From: Dimiter "malkia" Stanev
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnkcud$3cj$1@malkia.motzarella.org>
Thomas F. Burdick wrote:
> On Feb 19, 10:51 am, ·····@franz.com wrote:
>> On Feb 18, 9:09 pm, Scott <·······@gmail.com> wrote:
>>
>>> On Feb 18, 9:09 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> + In Common Lisp, due to type and optimization declarations, you can go
>>>> arbitrarily low-level and efficient while staying within Lisp itself.
>>>> + Plus you don't suffer from some of the gratuitous limitations of the
>>>> JVM framework (single dispatch, single inheritance, focus on OOP, etc..).
>>> In Common Lisp, without using FFI to a C or assembly library, can I
>>> implement a dot product using SSE instructions?  What about new
>>> instructions in SSE4?
>> Well, maybe not everyone, but an implementor certainly can do so.  If
>> you were familiar with an open-source implementation, you could
>> probably study up on its compiler and add new lap codes to the
>> internal assembler (of course, this implies that the compiler
>> implementation is not a byte compiler).
>>
>> And you don't even necessarily have to be an implementor, nor do you
>> necessarily need to have source.  Once, while he was still active in
>> CL programming at least publicly, Erik Naggum made a good case and
>> asked me for information on lap codes for SSE instruction generation
>> (this was before our Intel Mac or x86-64 versions existed, and it was
>> right after SSE/SSE2 came on the scene) and as far as I know he was
>> able to use the info to generate new instructions, all done in Lisp
>> without any FFI.
> 
> A fairly public example of this sort of thing was FPC-PPC, which was
> an MCL contrib that let you do extremely efficient double-float
> operations. The same technique could have been used to add Altivec
> support.

There is also SB-SIMD, haven't used it, but I know it exists:
http://common-lisp.net/project/sb-simd/
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <d55dd1ad-d3cf-4fe3-aede-4ca9c60ab8d0@b16g2000yqb.googlegroups.com>
On Feb 19, 2:51 am, ·····@franz.com wrote:
>
> Well, maybe not everyone, but an implementor certainly can do so.  If
> you were familiar with an open-source implementation, you could
> probably study up on its compiler and add new lap codes to the
> internal assembler (of course, this implies that the compiler
> implementation is not a byte compiler).
>

The statement that type declarations and optimization settings will
get you there is pretty clearly false.  There are plenty of other
comments like that in this thread.  I just picked one to call BS on.
From: ·····@franz.com
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <70f44299-f384-4cda-a313-0801802a75a0@z10g2000prl.googlegroups.com>
On Feb 19, 6:00 pm, Scott <·······@gmail.com> wrote:
> On Feb 19, 2:51 am, ·····@franz.com wrote:
>
> > Well, maybe not everyone, but an implementor certainly can do so.  If
> > you were familiar with an open-source implementation, you could
> > probably study up on its compiler and add new lap codes to the
> > internal assembler (of course, this implies that the compiler
> > implementation is not a byte compiler).
>
> The statement that type declarations and optimization settings will
> get you there is pretty clearly false.  There are plenty of other
> comments like that in this thread.  I just picked one to call BS on.

But I wasn't commenting on Pascal's statement, I was commenting on
yours.  Pascal's statement is not theoretically wrong, because an
implementor can choose to use declarations to provide access to low-
level machinery in the compiler.  In fact, using Environments Access
(http://www.lispwire.com/entry-proganal-envaccess-des) and by
providing a declaration definition, it should be possible to hook into
any low-level compilation architecture desired.  This is what Willem
Broekema did when he first wrote the CL-Python compiler in Allegro CL
(yes, he found ways to hook into other CLs without using define-
declaration, but I think he still considers his first approach the
most elegant).

What I _was_ commenting on was your question:

| In Common Lisp, without using FFI to a C or assembly library, can I
| implement a dot product using SSE instructions?  What about new
| instructions in SSE4?

and clearly the answer is "yes", if you want to jump through a few
hoops.  CL is extensible that way.

Duane
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <aeef14d3-ae9f-4474-bce8-7303770434cd@d32g2000yqe.googlegroups.com>
On Feb 20, 11:32 am, ·····@franz.com wrote:
>
> Pascal's statement is not theoretically wrong, because an
> implementor can choose to use declarations to provide access
> to low-level machinery in the compiler.
>

I like reading Pascal's comments.  He seems smart and helpful.
Moreover, I *was* wrong to contradict his particular statement because
he clearly qualified it with

  > If Common Lisp implementations eventually catch up
  > with regard to providing low-level support for
  > multithreading and parallelism [...]

and specified that this condition might be true in the near future.

Now since that condition isn't met yet, the whole statement isn't
theoretically false.  Given ~A, A -> B is conventionally said to be a
true statement.  But you're being pedantic, and you can't do what I
asked with just declarations and optimization settings today.  And
even if you add that tomorrow, Intel/AMD will come out with a new
instruction or 256 bit register type that your assembler doesn't use
next week.  So fair enough - the fully qualified statement is "not
false", but it isn't "usefully true" either.


> What I _was_ commenting on was your question:
>
> | In Common Lisp, without using FFI to a C or assembly library, can I
> | implement a dot product using SSE instructions?  What about new
> | instructions in SSE4?
>
> and clearly the answer is "yes", if you want to jump through a few
> hoops.  CL is extensible that way.

Pretty much every language is extensible if you want to jump through
those kind of hoops.  There is even an assembler written in AWK.
Apparently your implementation exposes it's assembler.  You chose to
cut out the part where I quoted Pascal's text about declarations and
optimization settings, but my question _was_ a direct reply to his
statement.  I don't think LAP codes are in the spirit he intended.


That said, another one of Pascal's claims is that a good lisp gives
it's users as much power as it's implementers.  Here's an obnoxious
question that I ask only because you're calling out what the
implementations can but don't necessarily provide: Why did Eric Naggum
have to make a good case and ask you for details about the LAP codes?
From: ·····@franz.com
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <0ada9cbc-b496-4034-8623-5b4cca0f4436@n10g2000vbl.googlegroups.com>
On Feb 20, 4:12 pm, Scott <·······@gmail.com> wrote:
> On Feb 20, 11:32 am, ·····@franz.com wrote:
>
>
>
> > Pascal's statement is not theoretically wrong, because an
> > implementor can choose to use declarations to provide access
> > to low-level machinery in the compiler.
>
> I like reading Pascal's comments.  He seems smart and helpful.

Yes, this is true.

> Moreover, I *was* wrong to contradict his particular statement because
> he clearly qualified it with
>
>   > If Common Lisp implementations eventually catch up
>   > with regard to providing low-level support for
>   > multithreading and parallelism [...]
>
> and specified that this condition might be true in the near future.

Agreed.  However, your comment had no such qualification, and that is
why I stepped in.  I am gratified that you see the error in your
statement.  See below for more.

> Now since that condition isn't met yet, the whole statement isn't
> theoretically false.  Given ~A, A -> B is conventionally said to be a
> true statement.  But you're being pedantic, and you can't do what I
> asked with just declarations and optimization settings today.  And
> even if you add that tomorrow, Intel/AMD will come out with a new
> instruction or 256 bit register type that your assembler doesn't use
> next week.  So fair enough - the fully qualified statement is "not
> false", but it isn't "usefully true" either.

Looks to me like you're the one being pedantic.  I have no problem
with qualified statements, and I try to make sure that my own
statements are properly qualified.  What I do take issue with, and
what I commented on, was your unqualified statement that Pascal's
comment was false.  And although you have now retracted that
statement, now you're attempting to salvage that retraction with
nonsense about it not being "usefully true".  It's true, period, and
whether it is useful depends not on your opinion, but on whether users
find it to be useful.  Nor is Pascal's qualification exhaustive; he
mentioned multiprocessing and parallelism, but such items are not
necessary to make use of SSEn instructions.  And they're certainly not
necessary to create a dot-product.

> > What I _was_ commenting on was your question:
>
> > | In Common Lisp, without using FFI to a C or assembly library, can I
> > | implement a dot product using SSE instructions?  What about new
> > | instructions in SSE4?
>
> > and clearly the answer is "yes", if you want to jump through a few
> > hoops.  CL is extensible that way.
>
> Pretty much every language is extensible if you want to jump through
> those kind of hoops.  There is even an assembler written in AWK.
> Apparently your implementation exposes it's assembler.

It depends on what you call "exposes".  We do not publish our
assembler, so no, I would not call it exposed.  However, we do quite
often provide customers who ask for specific capabilities with the
internals necessary to extend what we have for themselves.

  You chose to
> cut out the part where I quoted Pascal's text about declarations and
> optimization settings, but my question _was_ a direct reply to his
> statement.  I don't think LAP codes are in the spirit he intended.

No, you were the one who cut that out.  In your original article, to
which I responded, only Pascal's text mentioned declarations:

| On Feb 18, 9:09 am, Pascal Costanza <····@p-cos.net> wrote:
|
| > + In Common Lisp, due to type and optimization declarations, you
can go
| 
> arbitrarily low-level and efficient while staying within Lisp
itself.
|
| > + Plus you don't suffer from some of the gratuitous limitations of
the
| 
> JVM framework (single dispatch, single inheritance, focus on OOP,
etc.).
|
| In Common Lisp, without using FFI to a C or assembly library, can I
| implement a dot product using SSE instructions?  What about new
| instructions in SSE4?  I'm not saying you can do this in Clojure/
Java
| either, but "arbitrarily low-level" is probably not an accurate
| statement.  Staying within [Common] Lisp, I suspect you have some
| limitations too.

and your question had nothing to do with declarations, and even less
to do with multithreading and parallelism, and that is what I
responded to.  Again, I had no problem with what Pascal had said; I
was reacting to your response.  Specifically, your challenge was about
doing a dot-product without using an FFI.  None of that has anything
to do with multiprocessing, and you left out any mention of
declarations.  Perhaps you intended us to assume that you meant to
include Pascal's context, but as a reader myself of this response, the
fact that you arbitrarily added FFI as a new factor removes all
context.  Perhaps you believe that I'm being pedantic now, and perhaps
I am, but I'm trying to get you to understand how what you thought you
said was not how it came across to me.

> That said, another one of Pascal's claims is that a good lisp gives
> it's users as much power as it's implementers.  Here's an obnoxious
> question that I ask only because you're calling out what the
> implementations can but don't necessarily provide: Why did Eric Naggum
> have to make a good case and ask you for details about the LAP codes?

Allegro CL is not open-source.  We provide a large amount of interface
machinery (and source code, though not free, is in fact available),
but we also make a clear distinction between published and unpublished
interfaces.  This provides protection for both our customers and us,
so that our customers know when they try something out that we make no
guarantees that it won't change at a later time, and it also protects
us from customers getting angry with us because we've changed an
unpublished interface out from under their code.  Usually when these
changes take place those customers that have extensions ask us what
the current interface is, and we give it to them.

Some of these interfaces are more volatile than others. An assembler
is not only volatile, in that new op-codes might be needed (and in
cases such as the Power series, rs6000/powerpc/powerN, op-codes might
become obsolete), but also an assembler is obviously very architecture-
dependent.  So in general, we tend to discourage customers from
wasting their time trying to hook into such unpublished interfaces,
due to the high volatility.  Well, Erik's argument took all of those
things into consideration, and since it was at the very beginning of
the SSE/SSE2 movement, his argument convinced us that he and we wanted
to go into that kind of relationship wrt the x86 assembler.

Duane
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <0728348a-432c-411f-b135-6f72338864df@p13g2000yqc.googlegroups.com>
On Feb 21, 1:29 am, ·····@franz.com wrote:

>
> However, your comment had no such qualification, and that is why I stepped in.
>

Thank you for rescuing me and the unwitting readers of this newsgroup
from the error in my ways.  :-)

As an aside:  Please don't take anything I say too harshly.  I enjoy
these debates, but I'm sure I get a little carried away, and I
probably don't pull my punches enough.  I'd have to put a smiley after
pretty much every line if I wanted to convey my actual tone about the
matter...  Of course if I put that many smileys in, I'd look like a
bimbo.

The "mentioning FFI eliminates all context and quoted text" rule is
new to me.  I'll have to be more careful about that in the future.
Pascal's (entire) claim was:

|
| If Common Lisp implementations eventually catch up with regard to
| providing low-level support for multithreading and parallelism [1],
what
| you get as advantages are the following:
|
| + In Common Lisp, due to type and optimization declarations, you can
go
| arbitrarily low-level and efficient while staying within Lisp
itself.
|
| + Plus you don't suffer from some of the gratuitous limitations of
the
| JVM framework (single dispatch, single inheritance, focus on OOP,
etc.).

[...]

| [1] ...and in this regard, the future looks much brighter than you
may
| think. ;)

I made the mistake of leaving out the big IF qualifier (with its
optimistic footnote).  I'm willing to accept that Pascal believes the
IF will be true in the future but knows it isn't at this time.
(Assuming Pascal uses Allegro, you've got some work to do...  Don't
get me wrong, it's certainly possible that the other vendors have even
more work to do to meet Pascal's future expectations.)


>
> What I do take issue with, and what I commented on,
> was your unqualified statement that Pascal's
> comment was false.
>

Now I assume you're talking about my second message in response to
your first.  I said, "The statement that type declarations and
optimization settings will get you there is pretty clearly false."
And by "there", I meant the "arbitrarily low-level" that Pascal
claimed.  I think I qualified clearly enough, and I didn't mention FFI
either!  What rule did I break this time?


>
> And although you have now retracted that
> statement, now you're attempting to salvage that retraction with
> nonsense about it not being "usefully true".  It's true, period, and
> whether it is useful depends not on your opinion, but on whether users
> find it to be useful.
>

Yeah, it's pretty tough for me to concede very much on this issue - I
don't think I'm wrong.

Let's assume that Pascal's antecedent is true, and the Common Lisp
vendors "catch up", then I think it's fair to debate the consequent
directly and ignore that it came from a conditional statement.  It's
like saying "if pigs can fly, then you can get bacon from the sky".
Since pigs can't fly yet, the conditional statement is true (period -
as you so forcefully say).  However, if we assume pigs can fly (or
will be able to soon) - we should then be able to talk about whether
or not I'm really going to get any bacon.

If we drop all the context and qualifiers, can you can tell me what
declaration, optimization settings, or other reasonable things to add
so that Allegro (or any other implementation) will turn a silly little
dot product into something that effectively use the SSE "mulps" and
"addps" instructions:

    (defun dot (a b)
      (loop
        for x across a
        for y across b
        sum (* x y)))

Feel free to assume that the vectors a and b are the same length, 16
byte aligned, a multiple of 4 in length, single precision floating
point, and anything else you need to.  I know I could write an
assembler, but that's really quite above and beyond Pascal's claims,
and it doesn't look like you believe your LAP codes solution is
appropriate for the masses that are being told they should implement
their new languages on top of Common Lisp either.

If you can't do that, or at least won't do that soon, saying you
*could* do that is not really any more "usefully true" than if I were
to start telling people they should build their languages on top of
Python because sufficiently advanced decorators *could* exist in the
future:

  @using_the_latest_x86_instructions
  def vector_dot_product(a, b):
      sum = 0.0
      for i in range(len(a)):
          sum += a[i]*b[i]

Python actually has utilities comparable to this in a limited way, but
I wouldn't say they let anyone go "arbitrarily low level", and I
wouldn't use it as justification to tell someone they should implement
their new languages on top of Python.

There are valid reasons to favor Common Lisp, but it does put some
limitations on how low level the user can go, and it's not much below
how far Clojure on Java lets you go.  So I think it's weak sauce
trying to use that as a justification for why Rich Hickey or Tobias C.
Rittweiler should use Common Lisp instead of the JVM to build a
language.

I've got other gripes about some statements in this thread too, but
I'll spare you those for now.


Please note, I'm not advocating Clojure or the JVM.  I think Clojure's
data structures are sexier than most, but I'm not in love with the
JVM, and I'm undecided about STM.  Every now and then, I just like to
object to false claims made about the superiority of Common Lisp.

If you don't see my point, don't sweat it.  We can agree to disagree,
and the masses will favor your side.  I don't think the topic
warranted much more discussion than my initial comment.
From: Rob Warnock
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <oo-dnT3bsudNNz3UnZ2dnUVZ_geWnZ2d@speakeasy.net>
Scott  <·······@gmail.com> wrote:
+---------------
| If we drop all the context and qualifiers, can you can tell me what
| declaration, optimization settings, or other reasonable things to add
| so that Allegro (or any other implementation) will turn a silly little
| dot product into something that effectively use the SSE "mulps" and
| "addps" instructions:
| 
|     (defun dot (a b)
|       (loop
|         for x across a
|         for y across b
|         sum (* x y)))
+---------------

One tiny thing that might help would be to replace "FOR Y" with "AND Y",
which immediately tells the compiler that X & Y are being stepped in
parallel, not sequentially. Yes, a "sufficiently-smart compiler" can
easily figure that out from the lack of data-flow dependency from
X to Y (or A to B), but I suspect that the very first SSE generators
might be more template-based [just to get something useful out the
door -- might even be just a compiler macro on LOOP!] and might be
looking for the AND...   ;-}


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Andrew Reilly
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <70covfFefrkU1@mid.individual.net>
On Sat, 21 Feb 2009 19:30:56 -0600, Rob Warnock wrote:

> Scott  <·······@gmail.com> wrote:
> +---------------
> | If we drop all the context and qualifiers, can you can tell me what |
> declaration, optimization settings, or other reasonable things to add |
> so that Allegro (or any other implementation) will turn a silly little |
> dot product into something that effectively use the SSE "mulps" and |
> "addps" instructions:
> |
> |     (defun dot (a b)
> |       (loop
> |         for x across a
> |         for y across b
> |         sum (* x y)))
> +---------------
> 
> One tiny thing that might help would be to replace "FOR Y" with "AND Y",
> which immediately tells the compiler that X & Y are being stepped in
> parallel, not sequentially. Yes, a "sufficiently-smart compiler" can
> easily figure that out from the lack of data-flow dependency from X to Y
> (or A to B), but I suspect that the very first SSE generators might be
> more template-based [just to get something useful out the door -- might
> even be just a compiler macro on LOOP!] and might be looking for the
> AND...   ;-}

Is there really a sense in which there can be a "sufficiently smart 
compiler" for this particular piece of code?  I would have expected that 
a prerequisite for using mulps+addps was at least that A and B were 
aligned uniform  float vectors, rather than lists.  Or does loop know 
about vectors as well as lists?

Cheers,

-- 
Andrew
From: Pascal J. Bourguignon
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <87eixqeo1b.fsf@galatea.local>
Andrew Reilly <···············@areilly.bpc-users.org> writes:

> On Sat, 21 Feb 2009 19:30:56 -0600, Rob Warnock wrote:
>
>> Scott  <·······@gmail.com> wrote:
>> +---------------
>> | If we drop all the context and qualifiers, can you can tell me what |
>> declaration, optimization settings, or other reasonable things to add |
>> so that Allegro (or any other implementation) will turn a silly little |
>> dot product into something that effectively use the SSE "mulps" and |
>> "addps" instructions:
>> |
>> |     (defun dot (a b)
>> |       (loop
>> |         for x across a
>> |         for y across b
>> |         sum (* x y)))
>> +---------------
>> 
>> One tiny thing that might help would be to replace "FOR Y" with "AND Y",
>> which immediately tells the compiler that X & Y are being stepped in
>> parallel, not sequentially. Yes, a "sufficiently-smart compiler" can
>> easily figure that out from the lack of data-flow dependency from X to Y
>> (or A to B), but I suspect that the very first SSE generators might be
>> more template-based [just to get something useful out the door -- might
>> even be just a compiler macro on LOOP!] and might be looking for the
>> AND...   ;-}
>
> Is there really a sense in which there can be a "sufficiently smart 
> compiler" for this particular piece of code?  I would have expected that 
> a prerequisite for using mulps+addps was at least that A and B were 
> aligned uniform  float vectors, rather than lists.  Or does loop know 
> about vectors as well as lists?

Yes it does distinguish lists and vectors (unfortunately).  The
keyword :ACROSS is the hint indicating that A and B are vectors, not
lists. Otherwise the keyword :IN would have had to be used.

-- 
__Pascal Bourguignon__
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnsfrc0rnk@enews2.newsguy.com>
Pascal J. Bourguignon wrote:

> >> |
> >> |     (defun dot (a b)
> >> |       (loop
> >> |         for x across a
> >> |         for y across b
> >> |         sum (* x y)))
> >> +---------------
> >> 
> >> One tiny thing that might help would be to replace "FOR Y" with
> "AND Y", >> which immediately tells the compiler that X & Y are being
> stepped in >> parallel, not sequentially. Yes, a "sufficiently-smart
> compiler" can >> easily figure that out from the lack of data-flow
> dependency from X to Y >> (or A to B),

I believe that Clojure's "pmap" operates in parallel and tries to
use more than one core.

(reduce + (pmap * [2.0 3.0 4.0] [10 20 30]))
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnsguj$ql2$2@news.motzarella.org>
William James schrieb:
> Pascal J. Bourguignon wrote:
> 
>>>> |
>>>> |     (defun dot (a b)
>>>> |       (loop
>>>> |         for x across a
>>>> |         for y across b
>>>> |         sum (* x y)))
>>>> +---------------
>>>>
>>>> One tiny thing that might help would be to replace "FOR Y" with
>> "AND Y", >> which immediately tells the compiler that X & Y are being
>> stepped in >> parallel, not sequentially. Yes, a "sufficiently-smart
>> compiler" can >> easily figure that out from the lack of data-flow
>> dependency from X to Y >> (or A to B),
> 
> I believe that Clojure's "pmap" operates in parallel and tries to
> use more than one core.
> 
> (reduce + (pmap * [2.0 3.0 4.0] [10 20 30]))

You are right again.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Pascal J. Bourguignon
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <871vtqdtf9.fsf@galatea.local>
Andr� Thieme <······························@justmail.de> writes:

> William James schrieb:
>> Pascal J. Bourguignon wrote:
>> 
>>>>> |
>>>>> |     (defun dot (a b)
>>>>> |       (loop
>>>>> |         for x across a
>>>>> |         for y across b
>>>>> |         sum (* x y)))
>>>>> +---------------
>>>>>
>>>>> One tiny thing that might help would be to replace "FOR Y" with
>>> "AND Y", >> which immediately tells the compiler that X & Y are being
>>> stepped in >> parallel, not sequentially. Yes, a "sufficiently-smart
>>> compiler" can >> easily figure that out from the lack of data-flow
>>> dependency from X to Y >> (or A to B),
>> I believe that Clojure's "pmap" operates in parallel and tries to
>> use more than one core.
>> (reduce + (pmap * [2.0 3.0 4.0] [10 20 30]))
>
> You are right again.
>
>
> Andr�

I didn't write one byte of the above quotations.

-- 
__Pascal Bourguignon__
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnsjn602hg3@enews4.newsguy.com>
Pascal J. Bourguignon wrote:

> Andr� Thieme <······························@justmail.de> writes:
> 
> > William James schrieb:
> >> Pascal J. Bourguignon wrote:
> >> 
> >>>>> |
> >>>>> |     (defun dot (a b)
> >>>>> |       (loop
> >>>>> |         for x across a
> >>>>> |         for y across b
> >>>>> |         sum (* x y)))
> >>>>> +---------------
> > > > > > 
> >>>>> One tiny thing that might help would be to replace "FOR Y" with
> >>> "AND Y", >> which immediately tells the compiler that X & Y are
> being >>> stepped in >> parallel, not sequentially. Yes, a
> "sufficiently-smart >>> compiler" can >> easily figure that out from
> the lack of data-flow >>> dependency from X to Y >> (or A to B),
> >> I believe that Clojure's "pmap" operates in parallel and tries to
> >> use more than one core.
> >> (reduce + (pmap * [2.0 3.0 4.0] [10 20 30]))
> > 
> > You are right again.
> > 
> > 
> > Andr�
> 
> I didn't write one byte of the above quotations.

My newsreader messed up the quoting.
(It thought the lines were too long.)
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnq6s40osl@enews5.newsguy.com>
Scott wrote:

> 
>   @using_the_latest_x86_instructions
>   def vector_dot_product(a, b):
>       sum = 0.0
>       for i in range(len(a)):
>           sum += a[i]*b[i]

Clojure:

user=> (reduce + (map * [2.0 3.0 4.0] [10 20 30]))
200.0
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <c09a83e8-6814-4bae-b038-d1043804c600@f3g2000yqf.googlegroups.com>
On Feb 21, 5:39 pm, "William James" <·········@yahoo.com> wrote:
>
> Clojure:
>
> user=> (reduce + (map * [2.0 3.0 4.0] [10 20 30]))
> 200.0

Really?  Out of my whole boring rant, all you got out of it was that I
wanted a dot product!?  I'll need to pick even sillier functions to
use as rhetorical questions.  :-)

I'll assume you just scanned the post and looked for the function.  In
that case, this sort of thing is really quite beneath you.  I'd like
to see how to do it in PostScript.  Extra credit if you can prove that
the PostScript interpreter is using the latest round of SIMD opcodes.
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnqa6g0s2b@enews5.newsguy.com>
William James wrote:

> Scott wrote:
> 
> > 
> >   @using_the_latest_x86_instructions
> >   def vector_dot_product(a, b):
> >       sum = 0.0
> >       for i in range(len(a)):
> >           sum += a[i]*b[i]
> 
> Clojure:
> 
> user=> (reduce + (map * [2.0 3.0 4.0] [10 20 30]))
> 200.0

I forgot to mention: always remember that

"We don't need no stinkin' loops!"
From: DanL
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <5c933f1e-4a1c-4c77-91fd-657288c259c2@o36g2000yqh.googlegroups.com>
On 22 Feb., 01:39, "William James" <·········@yahoo.com> wrote:
> Clojure:
>
> user=> (reduce + (map * [2.03.04.0] [102030]))
> 200.0

CL-USER> (collect-sum (#m* #z(2 3 4) #z(10 20 30)))
200
From: Thomas F. Burdick
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <4465601f-a1a2-46fa-aa3b-7f18e38fa528@w35g2000yqm.googlegroups.com>
It looks like you're mostly arguing for arguing's sake, but I'll jump
in here anyway.

On 22 fév, 00:46, Scott <·······@gmail.com> wrote:

> If we drop all the context and qualifiers, can you can tell me what
> declaration, optimization settings, or other reasonable things to add
> so that Allegro (or any other implementation) will turn a silly little
> dot product into something that effectively use the SSE "mulps" and
> "addps" instructions:
>
>     (defun dot (a b)
>       (loop
>         for x across a
>         for y across b
>         sum (* x y)))

You could do it using some altivec hacks I played around with in SBCL
on my G4, as follows:

(defun dot (a b)
  (declare (type (simple-array single-float (*)) a b)
           (aligned-end a b)
           (optimize (speed 3) (safety 1))
  (let ((z 0.0s0))
    (declare (reduce-target z single-float))
    (map nil
         (lambda (a b)
           (setq z (+ z (* x y))))
         a b)
    z))

It was just a toy, but worked in principle. I don't know where sb-simd
hooks into sbcl, but I assume such a thing could be done there; if
not, it's not too hard to add the right declarations and transforms.
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <eb14c9e7-7e6a-4405-a098-9681615f127e@41g2000yqf.googlegroups.com>
On Feb 22, 6:30 am, "Thomas F. Burdick" <········@gmail.com> wrote:
>
> It looks like you're mostly arguing for arguing's sake, but I'll jump
> in here anyway.
>

Yup, that's fair enough.  I like to argue, and I think I've gone on
enough about this topic.  In my defense, I do try to pick cases where
people aren't using the same measuring stick when doing their
comparisons.

Thanks for the example.  I think you're missing a closing paren on the
first declaration, and I don't see where x and y came into existence.
That's all beside the point though.

Cheers,
    -Scott
From: Matthew D Swank
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <PVHnl.17782$xQ5.12796@newsfe23.iad>
On Thu, 19 Feb 2009 01:51:21 -0800, duane wrote:

> On Feb 18, 9:09 pm, Scott <·······@gmail.com> wrote:
>
>> In Common Lisp, without using FFI to a C or assembly library, can I
>> implement a dot product using SSE instructions?  What about new
>> instructions in SSE4?
> 
> Well, maybe not everyone, but an implementor certainly can do so.  If
> you were familiar with an open-source implementation, you could probably
> study up on its compiler and add new lap codes to the internal assembler
> (of course, this implies that the compiler implementation is not a byte
> compiler).
> 
> And you don't even necessarily have to be an implementor, nor do you
> necessarily need to have source.  Once, while he was still active in CL
> programming at least publicly, Erik Naggum made a good case and asked me
> for information on lap codes for SSE instruction generation (this was
> before our Intel Mac or x86-64 versions existed, and it was right after
> SSE/SSE2 came on the scene) and as far as I know he was able to use the
> info to generate new instructions, all done in Lisp without any FFI.
> 

How would something like this work; write a mini assembler that outputs a 
correctly formatted fasl?     

-- 
Excellent day for putting Slinkies on an escalator.
From: Scott
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <3d965db4-40dd-462c-b498-1ad32cfa8be1@j35g2000yqh.googlegroups.com>
On Feb 20, 5:29 pm, Matthew D Swank <··················@gmail.com>
wrote:
> On Thu, 19 Feb 2009 01:51:21 -0800, duane wrote:
>
> > And you don't even necessarily have to be an implementor, nor do you
> > necessarily need to have source.  Once, while he was still active in CL
> > programming at least publicly, Erik Naggum made a good case and asked me
> > for information on lap codes for SSE instruction generation (this was
> > before our Intel Mac or x86-64 versions existed, and it was right after
> > SSE/SSE2 came on the scene) and as far as I know he was able to use the
> > info to generate new instructions, all done in Lisp without any FFI.
>
> How would something like this work; write a mini assembler that outputs a
> correctly formatted fasl?    
>

I Googled around, and I think he is talking about this approach:

    http://www.dreamsongs.com/Files/cp.pdf
From: ·····@franz.com
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <4527a67f-5067-429e-a7f6-13adf8af5a7f@s38g2000prg.googlegroups.com>
On Feb 20, 4:29 pm, Matthew D Swank <··················@gmail.com>
wrote:
> On Thu, 19 Feb 2009 01:51:21 -0800, duane wrote:
> > On Feb 18, 9:09 pm, Scott <·······@gmail.com> wrote:
>
> >> In Common Lisp, without using FFI to a C or assembly library, can I
> >> implement a dot product using SSE instructions?  What about new
> >> instructions in SSE4?
>
> > Well, maybe not everyone, but an implementor certainly can do so.  If
> > you were familiar with an open-source implementation, you could probably
> > study up on its compiler and add new lap codes to the internal assembler
> > (of course, this implies that the compiler implementation is not a byte
> > compiler).
>
> > And you don't even necessarily have to be an implementor, nor do you
> > necessarily need to have source.  Once, while he was still active in CL
> > programming at least publicly, Erik Naggum made a good case and asked me
> > for information on lap codes for SSE instruction generation (this was
> > before our Intel Mac or x86-64 versions existed, and it was right after
> > SSE/SSE2 came on the scene) and as far as I know he was able to use the
> > info to generate new instructions, all done in Lisp without any FFI.
>
> How would something like this work; write a mini assembler that outputs a
> correctly formatted fasl?    
>
> --
> Excellent day for putting Slinkies on an escalator.

Check out ftp://ftp.ranz.com/pub/duane/ilc07, and especially the
script files hack-compiler-output.lisp and assemble-function-body.lisp
for examples.  These are not examples of hooks into the assembler
itself, but instead they show hooks into the compiler for the
assembler operation.  You can get a pretty good idea of how the lap
codes look for any particular architecture by using the hack*.lisp
example, and substituting your own functions in there.

Duane
From: William James
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnj13j01v1s@enews2.newsguy.com>
Scott wrote:

> On Feb 18, 9:09�am, Pascal Costanza <····@p-cos.net> wrote:
> > 
> > + In Common Lisp, due to type and optimization declarations, you
> > can go arbitrarily low-level and efficient while staying within
> > Lisp itself.
> > 
> > + Plus you don't suffer from some of the gratuitous limitations of
> > the JVM framework (single dispatch, single inheritance, focus on
> > OOP, etc.).
> > 
> 
> In Common Lisp, without using FFI to a C or assembly library, can I
> implement a dot product using SSE instructions?  What about new
> instructions in SSE4?  I'm not saying you can do this in Clojure/Java
> either, but "arbitrarily low-level" is probably not an accurate
> statement.  Staying within [Common] Lisp, I suspect you have some
> limitations too.

You're right, but you can't argue with a man about his
religion.
From: Madhu
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <m3prhflqbw.fsf@moon.robolove.meer.net>
* "Tobias C. Rittweiler" <··············@freebits.de> :
Wrote on Wed, 18 Feb 2009 16:10:21 +0100:

| Pascal Costanza <...> writes:
|
|> We have examples of languages built on top of Common Lisp (like QI,
|> Pseudoscheme, etc.), so it clearly shows that it can be done, within a
|> reasonable amount of work.
|
| Nobody disputes that. In fact, you're preaching to the choir. :-)

I seriously doubt he's preaching to the choir here,  Because of the
following question


| That doesn't change the fact that the JVM may indeed be a very good fit
| for Clojure which is explicitly designed for multithreaded
| programming---a better fit than targetting Common Lisp. But please tell
| what advantages Common Lisp would provide in that context.
      ^^^^^^^^^^^^^^^^^^^^

--
Madhu
From: Nicolas Neuss
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <87vdr7bvvl.fsf@ma-patru.mathematik.uni-karlsruhe.de>
Pascal Costanza <··@p-cos.net> writes:

> We have examples of languages built on top of Common Lisp (like QI,
> Pseudoscheme, etc.), so it clearly shows that it can be done, within a
> reasonable amount of work. We also have examples of how Common Lisp can
> be extended with more flexible data structures (like cl-containers, fset,
> etc.), also within a reasonable amount of work.

Also interesting would be, if Clojure could be extended towards CL
(including CLOS, Readmacros, etc).  Would that be possible easily in a
well-integrated and performant way?  I.e. something like the following
should work

(in-package :cl-user)
;;; CL code
(in-package :clojure)
;;; Clojure code

Finally: Which direction would be more work?

Nicolas
From: Madhu
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <m3k57nlp7r.fsf@moon.robolove.meer.net>
* Nicolas Neuss <··············@ma-patru.mathematik.uni-karlsruhe.de> :
Wrote on Wed, 18 Feb 2009 16:35:58 +0100:

| Pascal Costanza <··@p-cos.net> writes:
|
|> We have examples of languages built on top of Common Lisp (like QI,
|> Pseudoscheme, etc.), so it clearly shows that it can be done, within a
|> reasonable amount of work. We also have examples of how Common Lisp can
|> be extended with more flexible data structures (like cl-containers, fset,
|> etc.), also within a reasonable amount of work.
|
| Also interesting would be, if Clojure could be extended towards CL
| (including CLOS, Readmacros, etc).  Would that be possible easily in a
| well-integrated and performant way?  I.e. something like the following
| should work
|
| (in-package :cl-user)
| ;;; CL code
| (in-package :clojure)
| ;;; Clojure code
|
| Finally: Which direction would be more work?

I suspect you will hear more non-reasons (time money etc.) for not doing
this from the Clojure camp.

On gaining enough traction I'd bet on seeing a Clojure for the dotnet
CLR before seeing Clojure for Common Lisp.

The charter of Clojure appears to be very different --- disclaiming at
the outset any intention of interaction with Common Lisp.  The goal
appears to be to sell JVM technology, while using the name of Lisp,
multi-cores and STM for advertising and brouchre material and creation
myths.

If one could leverage the advantages of CL while using what clojure
brings to the table, that would probably be a failure in Clojure's
goals

--
Madhu
From: Tobias C. Rittweiler
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <87eixvhfdq.fsf@freebits.de>
Madhu <...> writes:

> I suspect you will hear more non-reasons (time money etc.) for not doing
> this from the Clojure camp.

To be fair, as far I see, I was the only one who gave the time, money
non-reasons. I do not use Clojure, however.

  -T.
From: André Thieme
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <gnhr7n$ijc$1@news.motzarella.org>
Madhu schrieb:
> * Nicolas Neuss <··············@ma-patru.mathematik.uni-karlsruhe.de> :
> Wrote on Wed, 18 Feb 2009 16:35:58 +0100:
> 
> | Pascal Costanza <··@p-cos.net> writes:
> |
> |> We have examples of languages built on top of Common Lisp (like QI,
> |> Pseudoscheme, etc.), so it clearly shows that it can be done, within a
> |> reasonable amount of work. We also have examples of how Common Lisp can
> |> be extended with more flexible data structures (like cl-containers, fset,
> |> etc.), also within a reasonable amount of work.
> |
> | Also interesting would be, if Clojure could be extended towards CL
> | (including CLOS, Readmacros, etc).  Would that be possible easily in a
> | well-integrated and performant way?  I.e. something like the following
> | should work
> |
> | (in-package :cl-user)
> | ;;; CL code
> | (in-package :clojure)
> | ;;; Clojure code
> |
> | Finally: Which direction would be more work?
> 
> I suspect you will hear more non-reasons (time money etc.) for not doing
> this from the Clojure camp.

In fact, I would suggest to work on ABCL.
That already is a working CL for the JVM. One could use this way both
for the same program: CL and Clojure.
Not in one and the same source file, but still, perhaps this would not
be the killer feature anyway.

Also: one can already use all Clojure libs in any (major) language
implementation for the JVM (such as ABCL, Python, Ruby, Scala. Oh, and
Java *g*).
So, from ABCL you can use Clojures persistant datastructures, the STM,
and so on.
Within a few days/weeks of work all the communication nonsense could
be abstracted away, and these libs can look lispy and natural from
within CL as well.
And probably it would also be trivial to interface into ABCL which runs
in the same JVM, and can then access CLOS and basically everything that
ABCL provides.
It�s just that ABCL needs much more work.


> On gaining enough traction I'd bet on seeing a Clojure for the dotnet
> CLR before seeing Clojure for Common Lisp.

I hope so.
With the Java compatibility layer in .NET it could perhaps be even
doable in finite time.
Would be nice to have something that is close to Clojure and could work
in the CLR.


> The charter of Clojure appears to be very different --- disclaiming at
> the outset any intention of interaction with Common Lisp.  The goal
> appears to be to sell JVM technology, while using the name of Lisp,
> multi-cores and STM for advertising and brouchre material and creation
> myths.

A major misunderstanding.
Try to use Clojure for some weeks, and then tell the world what you
think about it.


> If one could leverage the advantages of CL while using what clojure
> brings to the table, that would probably be a failure in Clojure's
> goals.

I don�t see this. A language implementations that target the JVM can
in principle share whatever they offer.
Java, Scala, Ruby, Python, CL and Clojure can potentially work together.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Kenneth Tilton
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <499cfe5a$0$5906$607ed4bc@cv.net>
> No offense taken, but it seems there is a lot more to Clojure than you
> might be aware of.

Just stick to CLOS and he'll do fine. Well, syntax-wise, not so much 
when to use it...

hth, kenny
From: Pascal J. Bourguignon
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <87ab8nmjz6.fsf@galatea.local>
Pascal Costanza <··@p-cos.net> writes:
>>> Traditionally, the Lisp approach is not to provide one high-level
>>> solution for a particular programming problem, but to provide several
>>> different low-level means and give programmers the expressive power to
>>> build their own high-level abstractions on top. That's why Lisp stresses
>>> metaprogramming and reflection (in the form of macros or MOPs, for
>>> example), because this gives you the way to reach underneath your
>>> current abstraction layer and influence the decisions there. And that's
>>> also why I currently think that threads + locking + means for
>>> synchronization may actually be the best Lisp dialects can offer.
>> Providing low-level constructs doesn't obviate the need for higher-
>> level ones as well. A box of parts is not a car.
>
> I'm not sure how to comment on this.

Programming is not like using a car, it's like building a car.

When you want to build a car, having a prebuilt car is not an
advantage: you'd have first to disassemble it, and they you would only
have the pieces needed to build this model of cars, not the wide range
of random pieces that would allow you to build whatever kind of cars
you may want to build.

On the other hand, with a box of parts, you can build whatever car you
want directly with no hasles.

-- 
__Pascal Bourguignon__
From: Bakul Shah
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <49989C0F.9070104@bitblocks.com>
Pascal J. Bourguignon wrote:
> Pascal Costanza <··@p-cos.net> writes:
>>>> Traditionally, the Lisp approach is not to provide one high-level
>>>> solution for a particular programming problem, but to provide several
>>>> different low-level means and give programmers the expressive power to
>>>> build their own high-level abstractions on top. That's why Lisp stresses
>>>> metaprogramming and reflection (in the form of macros or MOPs, for
>>>> example), because this gives you the way to reach underneath your
>>>> current abstraction layer and influence the decisions there. And that's
>>>> also why I currently think that threads + locking + means for
>>>> synchronization may actually be the best Lisp dialects can offer.
>>> Providing low-level constructs doesn't obviate the need for higher-
>>> level ones as well. A box of parts is not a car.
>> I'm not sure how to comment on this.
> 
> Programming is not like using a car, it's like building a car.
 >
> When you want to build a car, having a prebuilt car is not an
> advantage: you'd have first to disassemble it, and they you would only
> have the pieces needed to build this model of cars, not the wide range
> of random pieces that would allow you to build whatever kind of cars
> you may want to build.
> 
> On the other hand, with a box of parts, you can build whatever car you
> want directly with no hasles.

Building everything from scratch every time gets to be a real pain
and is frequently error-prone. Appropriate sub-assemblies (or, if you
prefer, "abstractions") can usually help quite a bit. There is no
joy in discovering deadlocks for the nth time because different
components acquired locks in a different order. Even if I were as
smart as Dijkstra, Hoare or Brinch Hansen, it would be pointless for
my to rediscover _critical regions_ on my own when they have done a
superb job.
From: Pascal J. Bourguignon
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <8763jbmhkr.fsf@galatea.local>
Bakul Shah <············@bitblocks.com> writes:

> Pascal J. Bourguignon wrote:
>> Pascal Costanza <··@p-cos.net> writes:
>>>>> Traditionally, the Lisp approach is not to provide one high-level
>>>>> solution for a particular programming problem, but to provide several
>>>>> different low-level means and give programmers the expressive power to
>>>>> build their own high-level abstractions on top. That's why Lisp stresses
>>>>> metaprogramming and reflection (in the form of macros or MOPs, for
>>>>> example), because this gives you the way to reach underneath your
>>>>> current abstraction layer and influence the decisions there. And that's
>>>>> also why I currently think that threads + locking + means for
>>>>> synchronization may actually be the best Lisp dialects can offer.
>>>> Providing low-level constructs doesn't obviate the need for higher-
>>>> level ones as well. A box of parts is not a car.
>>> I'm not sure how to comment on this.
>> Programming is not like using a car, it's like building a car.
>>
>> When you want to build a car, having a prebuilt car is not an
>> advantage: you'd have first to disassemble it, and they you would only
>> have the pieces needed to build this model of cars, not the wide range
>> of random pieces that would allow you to build whatever kind of cars
>> you may want to build.
>> On the other hand, with a box of parts, you can build whatever car
>> you
>> want directly with no hasles.
>
> Building everything from scratch every time gets to be a real pain
> and is frequently error-prone. Appropriate sub-assemblies (or, if you
> prefer, "abstractions") can usually help quite a bit. There is no
> joy in discovering deadlocks for the nth time because different
> components acquired locks in a different order. Even if I were as
> smart as Dijkstra, Hoare or Brinch Hansen, it would be pointless for
> my to rediscover _critical regions_ on my own when they have done a
> superb job.

Who said there was only energy in the box of parts, or even only atoms?

-- 
__Pascal Bourguignon__
From: Kenneth Tilton
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <499cff6c$0$5916$607ed4bc@cv.net>
> The article has some credibility because the authors have been doing 
> research on STM themselves.

Oooooh, research!? White coats and clipboards and everything? Not just 
using it? Wow! Let's ignore all the factual points Rich made and focus 
on the fact that they are doing /research/! If they have PhDs, whoa, 
case closed!

kenny
From: Vend
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <53c57d92-def4-4a00-a97e-7b0a7b94c95c@13g2000yql.googlegroups.com>
<snip>

How do you implement immutable structures in Clojure?

I've found a paper about hash tries, but it appears to describe
destructive updates.
From: Scott Burson
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <dd6ea143-dc91-4707-a359-5c79e58b891a@g39g2000pri.googlegroups.com>
On Feb 14, 3:45 pm, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Feb 14, 9:53 pm, Raffael Cavallaro
>
> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>
> > The real innovations of clojure as a lisp dialect are:
>
> > 1. the default functional semantics for data structures that are
> > traditionally mutable in lisp (conses, lists, hash maps, vectors) but
> > which are "persistent," aka, immutable, in clojure, in conjunction
> > with...
>
> One question about those immutable structures, by persistent I
> understand something that will stay on the disc when someone trips
> over the cable.

No, it's a different meaning of the word "persistent".  See:

  http://en.wikipedia.org/wiki/Persistent_data_structure

-- Scott
From: Marco Antoniotti
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <982f60d6-05aa-44f8-a14c-405cb5166cf3@m42g2000yqb.googlegroups.com>
On Feb 17, 8:40 pm, Scott Burson <········@gmail.com> wrote:
> On Feb 14, 3:45 pm, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
> > On Feb 14, 9:53 pm, Raffael Cavallaro
>
> > <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>
> > > The real innovations of clojure as a lisp dialect are:
>
> > > 1. the default functional semantics for data structures that are
> > > traditionally mutable in lisp (conses, lists, hash maps, vectors) but
> > > which are "persistent," aka, immutable, in clojure, in conjunction
> > > with...
>
> > One question about those immutable structures, by persistent I
> > understand something that will stay on the disc when someone trips
> > over the cable.
>
> No, it's a different meaning of the word "persistent".  See:
>
>  http://en.wikipedia.org/wiki/Persistent_data_structure
>

... as in

(defun tree-insert (k v tree)
   (cond ((null tree) (make-node k v))
         ((> k (node-key tree))
          (make-node (node-key tree)
                     (node-value tree)
                     (node-left tree)
                     (tree-insert k v (node-right tree))))
         ((< k (node-key tree)
          (make-node (node-key tree)
                     (node-value tree)
                     (tree-insert k v (node-left tree))
                     (node-right tree)))
         ((= k (node-key tree))
          (make-node k v (node-left tree) (node-right tree)))))

(defvar t1 (tree-insert 42 'the-answer nil))
(defvar t2 (tree-insert 666 'the-beast t1))
(defvar t3 (tree-insert 66 'the-highway t2))
(defvar t4 (tree-insert 451 'fahreneit t3))
...

Each tree is kept in memory.  A standard reference for this is C.
Okasaki, Purely Functional Data Structures, Cambridge University
Press, 1998.

Cheers
--Marco


PS.  Now you do TREE-DELETE :)

Cheers
--
Marco
From: Vend
Subject: Re: question about Clojure immutable structures
Date: 
Message-ID: <3c972bfe-c2bb-487c-8a5e-fc9d5d65db8b@h16g2000yqj.googlegroups.com>
On 15 Feb, 00:45, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Feb 14, 9:53 pm, Raffael Cavallaro
>
> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
> > On 2009-02-14 11:17:13 -0500, André Thieme
> > <······························@justmail.de> said:
>
> > > Without talking specifically to you Alex, I observed that some CLers try
> > > to jump on the recur issue, as this is in their eyes the weakest point.
> > > The ironical thing about this is that at leats to my knowledge 100% of
> > > those people actually never programmed in Clojure, and experience them-
> > > selves how good/bad the situation really is.
>
> > I think the situation is a bit more nuanced than that. I for one have
> > used clojure and like it very much. But you're trying to make a virtue
> > of a necessity with loop/recur. It exists because the jvm doesn't do
> > tail call optimization. If the jvm did, then one would simply do
> > ordinary recursive calls, and/or clojure would have the equivalent of
> > scheme's letrec and named let.
>
> > The real innovations of clojure as a lisp dialect are:
>
> > 1. the default functional semantics for data structures that are
> > traditionally mutable in lisp (conses, lists, hash maps, vectors) but
> > which are "persistent," aka, immutable, in clojure, in conjunction
> > with...
>
> One question about those immutable structures, by persistent I
> understand something that will stay on the disc when someone trips
> over the cable.  If for example I have some paralelizable computation,
> but it has some dog-slow part that thanks to god could be memoized. So
> I want to have some central hash table that all the threads could
> access for checking if any of the threads already computed that value
> before, and also any thread will add new values once computed by it.
> So how I'm gonna do that with immutable data structures?

If I understand correctly in Clojure you can use mutable references to
immutable structures.

I suppose that in a pure functional language like Haskell or Clean you
would have to hope that the compiler/vm is smart enought to do
memoization under the hood. Or perhaps you could do using the hacks
(IO monand/unique World object) to manipulate the program state, but
it would probably get ugly.

> Just for illustration consider calculating fibonacci numbers in
> multiple threads with memoization into global hash table for all the
> threads.
>
> cheers
> bobi
From: Tamas K Papp
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <6vo9o8Fla8obU1@mid.individual.net>
On Sat, 14 Feb 2009 17:17:13 +0100, André Thieme wrote:

> Lisp really has no easy stand today as it seems. People see that it has
> a lot of parens and without trying it, they de- cide it is nothing for
> them.
> Clojure now reduced the amount of parens, but people now hear about tail
> calls and argue that Clojure Lisp is not for them. What I find a bit sad
> is that most of them are CLers.

I have only had cursory look at Clojure, so I don't know much about
it.  My guess is that both Clojure/CL would make it into the top 5
languages for most CL/Clojure users.  So one might prefer CL over
Clojure and argue about tail calls etc, but still strongly prefer
Clojure to, say, Java or (horribile dictu) F#.  Given this, I don't
see anything sad with people preferring Clojure/CL over CL/Clojure --
not all changes are innovations for everyone.

Tamas
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6vam$kvi$1@news.motzarella.org>
Tamas K Papp schrieb:
> On Sat, 14 Feb 2009 17:17:13 +0100, André Thieme wrote:
> 
>> Lisp really has no easy stand today as it seems. People see that it has
>> a lot of parens and without trying it, they de- cide it is nothing for
>> them.
>> Clojure now reduced the amount of parens, but people now hear about tail
>> calls and argue that Clojure Lisp is not for them. What I find a bit sad
>> is that most of them are CLers.
> 
> I have only had cursory look at Clojure, so I don't know much about
> it.  My guess is that both Clojure/CL would make it into the top 5
> languages for most CL/Clojure users.  So one might prefer CL over
> Clojure and argue about tail calls etc, but still strongly prefer
> Clojure to, say, Java or (horribile dictu) F#.  Given this, I don't
> see anything sad with people preferring Clojure/CL over CL/Clojure --
> not all changes are innovations for everyone.

What you present sounds very realistic to me.
I myself still have a nice CL project (about AI) that I will continue
to develop with SBCL.

What I find sad is that some CL users have a really negative opinion
about Clojure.
I can understand it when looking at it from this POV:
since years I am reading c.l.l, and every few weeks someone jumps in
and explains us how to improve Lisp, how to make it more popular, how
to remove parens, and such. Every few months some guy presents his own
Lisp. Those new Lisps basically all suck very very bad.
When I read about Clojure, I did not look at it all all. Why should I?
Another guy who thinks he can produce something useful!

We, who we read c.l.l know these situations, and they "reprogrammed"
us, so that we automatically think a new dialect of Lisp just has to
be bullshit, like the 37 others were, that were presented in the last
years.

Out of curiosity I visited one day the Clojure homepage, after a friend
suggested me to do it. It took only moments to get me hooked.
I watched the movies on the website and read it completely, and began
to install/use it. Over the course of some days I read the sources of
Clojure and realized that for me personally it is what I was waiting
for.
Immediately I understood that Clojure is the ticket for thousands of
Lispers to get a Lisp job. For now that can be done by sneaking into
small Java companies and offer them the productivity of a Lisp in their
environment. Only a subset of those companies will agree on that. But
a subset of hundreds to thousands of Java companies per (big) city
is still substantial enough to have a realistic chance.

So, back to the issue:
by repeating over years again and again that other Lisps suck and that
CL rules some here came to believe this, as if it were an objective
fact.
Some see a "danger" in Clojure. As long it is not CL, it must be bad.
This is too religious for me. Heck, programming languages are tools.

Obviously, I can’t speak for all CLers. Several experts already use
Clojure and have a different POV as I have.
Clojure is Lisp, it is an evolutionary step, CL does not suddenly
become bad only because Clojure exists, and Lispers should not be
scared by it, or "fight" against it without even having tried it out
for some time.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4996e57e$0$90270$14726298@news.sunsite.dk>
 AT> First of all, I would like to mention that recur also has no
 AT> disadvantages.

btw, we might compare "recur" to a compiler that will automatically
detects such cases of recursion and optimizes them accordingly.
(i believe most compilers do this, even C ones). then one might argue
that recur has a disadvantage making code less readable, as it might
be hard to see what is called 
From: Dimiter "malkia" Stanev
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gni1a4$v8l$1@malkia.motzarella.org>
Alex Mizrahi wrote:
>  AT> First of all, I would like to mention that recur also has no
>  AT> disadvantages.
> 
> btw, we might compare "recur" to a compiler that will automatically
> detects such cases of recursion and optimizes them accordingly.
> (i believe most compilers do this, even C ones). then one might argue
> that recur has a disadvantage making code less readable, as it might
> be hard to see what is called 
> 
> 

Actually for some strange fetish reason, I'm finding loop/recur more 
natural than the usual way. Being a workaround, it comes with more 
strict semantics, and it would allow only tailcals, and no recursion.

I'm still loving CL, but secretly starting to admire Clojure. Then again 
I'll probably never gave up C. The important lesson - I love languages 
starting with C, as long as they don't have ++ in their name.
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn74670hga@enews5.newsguy.com>
Andr� Thieme wrote:

> Besides that, recur does in fact have three advantages:
> 1. it allows anon functions to call recurse, they can call themselves
> 2. it blocks you from accidently not doing tail calls, because the
>    compiler can check if recur really is in the tail position
> 3. as a minor advantage I want to add, that it is easy to search in
> code    for occurrences of �recur�, or if you spot it somewhere while
> flying    over your sources, you immediately see �Ah, here we have a
> recursive    call�.

+1

ANS Forth uses "recurse":

: fac  dup 2 < if drop 1 else dup 1- recurse * endif ;


> 
> So even when the JVM will support one day tail call optimization,
> recur will not go.
> Jon Harrop indicated that this (adding TCO) is happening at the moment
> for the OpenJDK, and as Sun works on their own functional programming
> language �Fortress� I suppose they will also be interested in adding
> it.  I will definitly continue to use recur. What I will stop to use
> are trampolines.
> 
> 
> > but of course a real loop, not recursion, is the common lisp norm:
> > 
> > (loop for i upto 12345678 summing i)
> 
> Yes, loop is nice. In principle it�s what I would do in CL as well,
> although for this specific case I would really prefer to directly
> calculate that number via (defn sum [n] (+ (/ n 2) (/ (* n n) 2))).
> In Clojure I could do:
>   (apply + (range 12345678)))
> 
> or use reduce instead of apply.

Wouldn't it be inefficient to create a list or array of size 12345678?
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <3050eaf5-a236-4ff8-a77e-34f0d3b5ba5c@s1g2000prg.googlegroups.com>
On Feb 14, 7:57 pm, "William James" <·········@yahoo.com> wrote:
> André Thieme wrote:
> > Besides that, recur does in fact have three advantages:
> > 1. it allows anon functions to call recurse, they can call themselves
> > 2. it blocks you from accidently not doing tail calls, because the
> >    compiler can check if recur really is in the tail position
> > 3. as a minor advantage I want to add, that it is easy to search in
> > code    for occurrences of “recur”, or if you spot it somewhere while
> > flying    over your sources, you immediately see “Ah, here we have a
> > recursive    call”.
>
> +1
>
> ANS Forth uses "recurse":
>
> : fac  dup 2 < if drop 1 else dup 1- recurse * endif ;
>
>
>
>
>
> > So even when the JVM will support one day tail call optimization,
> > recur will not go.
> > Jon Harrop indicated that this (adding TCO) is happening at the moment
> > for the OpenJDK, and as Sun works on their own functional programming
> > language “Fortress” I suppose they will also be interested in adding
> > it.  I will definitly continue to use recur. What I will stop to use
> > are trampolines.
>
> > > but of course a real loop, not recursion, is the common lisp norm:
>
> > > (loop for i upto 12345678 summing i)
>
> > Yes, loop is nice. In principle it’s what I would do in CL as well,
> > although for this specific case I would really prefer to directly
> > calculate that number via (defn sum [n] (+ (/ n 2) (/ (* n n) 2))).
> > In Clojure I could do:
> >   (apply + (range 12345678)))
>
> > or use reduce instead of apply.
>
> Wouldn't it be inefficient to create a list or array of size 12345678?

Only if 'range' is eager.  Clojure returns a lazy range.

Cheers
--
Marco
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn7d4u$ag1$1@news.motzarella.org>
William James schrieb:
> Andr� Thieme wrote:

>> In Clojure I could do:
>>   (apply + (range 12345678)))
>>
>> or use reduce instead of apply.
> 
> Wouldn't it be inefficient to create a list or array of size 12345678?

The inefficiency comes from the JVMs boxing behaviour.
range creates a lazy sequence:
user> (class (range 5))
clojure.lang.Range
user> (class [1 2 3 4 5])
clojure.lang.LazilyPersistentVector
user> (class '(1 2 3 4 5))
clojure.lang.PersistentList

(class tells us what type an object has)
range will create a boxed number object, unbox it for use in + and box
the result again.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn5s2d02keh@enews4.newsguy.com>
Raffael Cavallaro wrote:

> On 2009-02-13 14:41:14 -0500, Andr� Thieme
> <······························@justmail.de> said:
> 
> > we can do this in Clojure:
> > ((fn [n] (loop [x n, res 0]
> >            (if (zero? x) res (recur (dec x) (+ x res)))))
> >  12345678)
> 
> we can do this in common lisp:
> 
> ((lambda (n) (loop for x from n downto 0 summing x)) 12345678)

Reduce:

for n:=1:12345678 sum n;

76207888812681
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4b97bc62-c292-4471-9e82-f47c1613ae09@v39g2000yqm.googlegroups.com>
On Feb 14, 8:32 am, "William James" <·········@yahoo.com> wrote:
> Raffael Cavallaro wrote:
> > On 2009-02-13 14:41:14 -0500, André Thieme
> > <······························@justmail.de> said:
>
> > > we can do this in Clojure:
> > > ((fn [n] (loop [x n, res 0]
> > >            (if (zero? x) res (recur (dec x) (+ x res)))))
> > >  12345678)
>
> > we can do this in common lisp:
>
> > ((lambda (n) (loop for x from n downto 0 summing x)) 12345678)
>
> Reduce:
>
> for n:=1:12345678 sum n;
>
> 76207888812681

In Reduce it should be

for n := 1:12345678 sum n;

In CL it is

(loop for n from 1 below 12345678 sum n)

Longer, but same thing.

Cheers
--
Marco
From: Alexander Lehmann
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn61vc$qqv$1@online.de>
William James wrote:
> Raffael Cavallaro wrote:
> 
>> On 2009-02-13 14:41:14 -0500, Andr� Thieme
>> <······························@justmail.de> said:
>>
>>> we can do this in Clojure:
>>> ((fn [n] (loop [x n, res 0]
>>>            (if (zero? x) res (recur (dec x) (+ x res)))))
>>>  12345678)
>> we can do this in common lisp:
>>
>> ((lambda (n) (loop for x from n downto 0 summing x)) 12345678)
> 
> Reduce:
> 
> for n:=1:12345678 sum n;

(/ (* 12345678 12345679) 2)

Longer, but faster :)
From: Slobodan Blazeski
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <7d5362ab-67ed-4524-b1b2-2b4cf0010c56@m40g2000yqh.googlegroups.com>
On Feb 14, 10:13 am, Alexander Lehmann <········@in.tum.de> wrote:
> William James wrote:
> > Raffael Cavallaro wrote:
>
> >> On 2009-02-13 14:41:14 -0500, André Thieme
> >> <······························@justmail.de> said:
>
> >>> we can do this in Clojure:
> >>> ((fn [n] (loop [x n, res 0]
> >>>            (if (zero? x) res (recur (dec x) (+ x res)))))
> >>>  12345678)
> >> we can do this in common lisp:
>
> >> ((lambda (n) (loop for x from n downto 0 summing x)) 12345678)
>
> > Reduce:
>
> > for n:=1:12345678 sum n;
>
> (/ (* 12345678 12345679) 2)
>
> Longer, but faster :)

Cheater :)

cheers
bobi
From: Alexander Lehmann
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6ci8$4vi$1@online.de>
Slobodan Blazeski wrote:
> On Feb 14, 10:13 am, Alexander Lehmann <········@in.tum.de> wrote:
>> (/ (* 12345678 12345679) 2)
>>
>> Longer, but faster :)
> 
> Cheater :)

SCNR *g*
From: Slobodan Blazeski
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <81bc4c8f-9123-42a5-9b26-89fb18d365f4@v5g2000prm.googlegroups.com>
On Feb 14, 1:13 pm, Alexander Lehmann <········@in.tum.de> wrote:
> Slobodan Blazeski wrote:
> > On Feb 14, 10:13 am, Alexander Lehmann <········@in.tum.de> wrote:
> >> (/ (* 12345678 12345679) 2)
>
> >> Longer, but faster :)
>
> > Cheater :)
>
> SCNR *g*

There was a joke about NASA(or RFSA) spending a lot of money for pens
that could write in zero gravity. When they announced their
masterpiece reporters asked them why they don't use pencils?

cheers
bobi
From: Rob Warnock
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <xKadnZaa36qi7QrUnZ2dnUVZ_qvinZ2d@speakeasy.net>
Slobodan Blazeski  <·················@gmail.com> wrote:
+---------------
| There was a joke about NASA(or RFSA) spending a lot of money for pens
| that could write in zero gravity. When they announced their
| masterpiece reporters asked them why they don't use pencils?
+---------------

Closer to libel than a joke, actually:

    http://en.wikipedia.org/wiki/Space_Pen
    http://en.wikipedia.org/wiki/Writing_in_space

The Fisher Space Pen (and others similar to it) was developed with
private funds:

    There exists a common urban legend claiming that the Americans spent
    $11 million developing the Space Pen, and the Russians used a pencil.
    In fact, NASA programs have used pencils (for example a 1965 order
    of mechanical pencils) but because of the danger that a broken-off
    pencil tip poses in zero gravity and the flammable nature of the wood
    present in pencils a better solution was needed.

    NASA never approached Paul Fisher to develop a pen, nor did Fisher
    receive any government funding for the pen's development. Fisher
    invented it independently, and then asked NASA to try it. After the
    introduction of the AG7 Space Pen, both the American and Soviet
    (later Russian) space agencies adopted it. Previously both the
    Russian and American astronauts used grease pencils and plastic slates.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnaa59$1v3$1@news.motzarella.org>
Raffael Cavallaro schrieb:
> On 2009-02-13 14:41:14 -0500, Andr� Thieme 
> <······························@justmail.de> said:
> 
>> we can do this in Clojure:
>> ((fn [n] (loop [x n, res 0]
>>             (if (zero? x) res (recur (dec x) (+ x res)))))
>>   12345678)
> 
> we can do this in common lisp:
> 
> ((lambda (n) (loop for x from n downto 0 summing x)) 12345678)
> 
> and when we do it in Clozure Common Lisp (dx86cl64) it runs 10 times as 
> fast as your clojure code on the same machine.

I now had the time to measure it approximatly. I did not have access
to Clozure, but to SBCL64, which might perform even better?!

And there I found +/- the timing that you suggested.
Running it a few times in SBCL gave me:
* (time ((lambda (n) (loop for x from n downto 0 summing x)) 12345678))

Evaluation took:
   0.060 seconds of real time
   0.060000 seconds of total run time (0.060000 user, 0.000000 system)
   100.00% CPU
   160,589,730 processor cycles
   0 bytes consed
76207888812681


On the same machine, I tested the 64-Bit Server-JVM with my code from
above:
user=>  (time ((fn [n] (loop [x n, res 0]
           (if (zero? x) res (recur (dec x) (+ x res)))))
12345678))
"Elapsed time: 360.236864 msecs"
76207888812681

Not only is my code longer, but also takes 5x more time than your
version.

If I try my shorter version, but with unboxed types I get:
user=> (time (loop [r (long 0) n (long 12345678)] (if (zero? n) r (recur
(+ r n) (dec n)))))
"Elapsed time: 32.118159 msecs"
76207888812681

With some declarations it may be possible to improve the SBCL version
further, so that it can outperform Clojure.

For fun I also tested Python and Ruby.

Summary:
1. Clojure:       33 msecs
2. SBCL:          60 msecs
3. Python 2.5.2:  2040 msecs
4. Ruby 1.8:      13620 msecs

All on a Intel(R) Core(TM)2 Duo CPU E7300  @ 2.66GHz running
Ubuntu 8.10 (64-Bit)


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnahgr$avm$1@aioe.org>
On 2009-02-15 18:57:20 -0500, Andr� Thieme 
<······························@justmail.de> said:

> With some declarations it may be possible to improve the SBCL version
> further, so that it can outperform Clojure.

fwiw, these declarations take it from 60 msecs down to 25 msecs in ccl:

(time ((lambda (n)
        (declare (optimize (speed 3) (safety 0) (debug 0)) (fixnum n))
        (loop for x fixnum from n downto 0 summing x)) 12345678))
-- 
Raffael Cavallaro, Ph.D.
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnajf40qli@enews2.newsguy.com>
Andr� Thieme wrote:

> 
> If I try my shorter version, but with unboxed types I get:
> user=> (time (loop [r (long 0) n (long 12345678)] (if (zero? n) r
> (recur (+ r n) (dec n)))))
> "Elapsed time: 32.118159 msecs"
> 76207888812681

"long" means int64, I presume.  Ruby and Python are using unlimited
precision integers (bignums).  Try it that way.


F#:


let rec sum_iota n sum =
  if 0L = n then sum else sum_iota (n - 1L) (sum + n);;

let timer = System.Diagnostics.Stopwatch.StartNew () in
let result = sum_iota 12345678L 0L  in
printfn "%d ms" timer.ElapsedMilliseconds;
printfn "%d" result


63 ms on a 2GHz laptop.
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <7aac95f6-06ad-49ed-a89f-e575fc56b4e3@x10g2000yqk.googlegroups.com>
On Feb 16, 3:36 am, "William James" <·········@yahoo.com> wrote:
> André Thieme wrote:
>
> > If I try my shorter version, but with unboxed types I get:
> > user=> (time (loop [r (long 0) n (long 12345678)] (if (zero? n) r
> > (recur (+ r n) (dec n)))))
> > "Elapsed time: 32.118159 msecs"
> > 76207888812681
>
> "long" means int64, I presume.  Ruby and Python are using unlimited
> precision integers (bignums).  Try it that way.
>
> F#:
>
> let rec sum_iota n sum =
>   if 0L = n then sum else sum_iota (n - 1L) (sum + n);;
>
> let timer = System.Diagnostics.Stopwatch.StartNew () in
> let result = sum_iota 12345678L 0L  in
> printfn "%d ms" timer.ElapsedMilliseconds;
> printfn "%d" result
>
> 63 ms on a 2GHz laptop.

Nope.  You are not allowed to use F#.  You can only use Ruby.

Cheers
--
Marco
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gncml3$h8f$1@news.motzarella.org>
William James schrieb:
> Andr� Thieme wrote:
> 
>> If I try my shorter version, but with unboxed types I get:
>> user=> (time (loop [r (long 0) n (long 12345678)] (if (zero? n) r
>> (recur (+ r n) (dec n)))))
>> "Elapsed time: 32.118159 msecs"
>> 76207888812681
> 
> "long" means int64, I presume.  Ruby and Python are using unlimited
> precision integers (bignums).  Try it that way.
> 
> 
> F#:
> 
> 
> let rec sum_iota n sum =
>   if 0L = n then sum else sum_iota (n - 1L) (sum + n);;
> 
> let timer = System.Diagnostics.Stopwatch.StartNew () in
> let result = sum_iota 12345678L 0L  in
> printfn "%d ms" timer.ElapsedMilliseconds;
> printfn "%d" result
> 
> 
> 63 ms on a 2GHz laptop.

I don�t know what the L is doing there, which you appended to
the numbers 0, 1 and 12345678.
If I don�t use (long 0) and (long 12345678) then Clojure would use the
boxed numbers. The JVM does not yet support a feature that Rich Hickey
would love to be added... this automated tagging (don�t know how it is
called), where extra information is put on the heap into the area that
usually is filled with zeros for alignment.
In that space one could encode the info, that the object is an unboxed
one, and that would allow some nice optimizations, how they are possible
in some CLs today.
But yes, the 63ms that you report make sense to me. On my machine they
would probably be in the area of what Clojure got, so, around 25-40 msecs.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gncsl809qt@enews4.newsguy.com>
Andr� Thieme wrote:

> > F#:
> > 
> > 
> > let rec sum_iota n sum =
> >  if 0L = n then sum else sum_iota (n - 1L) (sum + n);;
> > 
> > let timer = System.Diagnostics.Stopwatch.StartNew () in
> > let result = sum_iota 12345678L 0L  in
> > printfn "%d ms" timer.ElapsedMilliseconds;
> > printfn "%d" result
> > 
> > 
> > 63 ms on a 2GHz laptop.
> 
> I don�t know what the L is doing there, which you appended to
> the numbers 0, 1 and 12345678.

It indicates a 64-bit integer.
From: Slobodan Blazeski
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <1b70c2f5-e7e1-4387-8aa9-47ada2259722@w39g2000prb.googlegroups.com>
On Feb 13, 8:41 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Alex Mizrahi schrieb:
>
> >  AT> 1) The connection to Java can be seen by some folks as very healthy.
>
> > oh yes, it is very healthy (for a functional language!) to have "recur"
> > special operator instead of normal tail recursion because of JVM deficiency.
>
> It’s true, it’s healthy to have recur.
> I agree that it is not nice that the JVM does not have tail recursion
> yet. But in practice that is not a real issue, as recur is available.
>
> Let’s look at this unreadable mess in CL:
>
> (DEFUN Y (F)
>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))))
>
> (FUNCALL (Y #'(LAMBDA (FN)
>                  #'(LAMBDA (X)
>                      (IF (ZEROP X) 0 (+ X (FUNCALL FN (- X 1)))))))
>           200)
> ==> 20100
>
> we can do this in Clojure:
> ((fn [n] (loop [x n, res 0]
>             (if (zero? x) res (recur (dec x) (+ x res)))))
>   12345678)
>
> No Y-Combinator needed, much shorter, much more pleasant for the eye.
> Plus: this call works.
> When I gave the argument of 2000 in clisp on Windows it crashed.
> Stack overflow I guess.
>
> Or another example:
> (defun fibonacci (n)
>    (labels ((fibo-helper (x result)
>               (if (zerop x)
>                   result
>                   (fibo-helper (1- x) (* x result)))))
>      (fibo-helper n 1)))
This is code for factorial not fibonacci
(defun fact (n &optional (r 1))
   (if (zerop n) r (fact (1- n) (* n r))))
This is fibonacci
(defun fib (n)
  (if (< n 2) n
    (+ (fib (1- n)) (fib (- n 2)))))

cheers
bobi
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4996b17d$0$90263$14726298@news.sunsite.dk>
 ??>> oh yes, it is very healthy (for a functional language!) to have
 ??>> "recur" special operator instead of normal tail recursion because of
 ??>> JVM deficiency.

 AT> It's true, it's healthy to have recur.
 AT> I agree that it is not nice that the JVM does not have tail recursion
 AT> yet. But in practice that is not a real issue, as recur is available.

this reminds me a soviet anecdote: when there is no meat in the butcher's 
shop (it was often the case)
 they  place an announcement at the shop's door: "there is no necessity in a 
meat today".
are you as brainwashed as soviet's?

recursion is not limited to the cases when you just call current function in 
a tail-call fashion. in functional
programming often you need to call function in an alternating fashion -- foo 
calls bar, bar calls foo back
etc. and recur simply cannot do this. it can only emulate simple loops.

educate yourself: http://en.wikipedia.org/wiki/Mutual_recursion

 AT> Let's look at this unreadable mess in CL:

 AT> (DEFUN Y (F)
 AT>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
 AT>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G))
 AT> H)))))

this is a piece of cheap propaganda, i can't believe you're writing this 
seriously.
you've tried hard to make it looks like an unreadable mess, and now you 
claim it is unreadable mess.
whoa. NOBODY WRITES CODE LIKE THIS.

if you need to do recursive call of a local function in CL, use labels.

 AT> (FUNCALL (Y #'(LAMBDA (FN)
 AT>                  #'(LAMBDA (X)
 AT>                      (IF (ZEROP X) 0 (+ X (FUNCALL FN (- X 1)))))))
 AT>           200)
 AT> ==> 20100

it is not tail recursive, btw. tail recursive version with labels:

(labels ((sum (x acc) (if (zerop x)
                                     acc
                                     (sum (- x 1) (+ acc x)))))
         (sum 200 0))

 AT> we can do this in Clojure:
 AT> ((fn [n] (loop [x n, res 0]
 AT>             (if (zero? x) res (recur (dec x) (+ x res)))))
 AT>   12345678)

 AT> No Y-Combinator needed, much shorter, much more pleasant for the eye.

no Y combinator is needed in Common Lisp either, and code is quite similar 
when you
remove it. you might argue that anonimous functions/loops are somehow 
better, but i
find named ones more readable.

what would be even "more pleasant for the eye": (loop for i from 1 to n 
summing i)

 AT> Plus: this call works.
 AT> Stack overflow I guess.

sure it does, because it was not tail calls. you should admit you know very 
little
about functional programming, as you do not know even basics.

 AT> When I gave the argument of 2000 in clisp on Windows it crashed.

CLISP does not optimize tail calls in debug mode, iirc.
in SBCL it works fine with in default mode:

CL-USER> (labels ((sum (x acc) (if (zerop x)
                                     acc
                                     (sum (- x 1) (+ acc x)))))
         (sum 20000000 0))

200000010000000

 AT> Or another example:
 AT> (defun fibonacci (n)
 AT>    (labels ((fibo-helper (x result)
 AT>               (if (zerop x)
 AT>                   result
 AT>                   (fibo-helper (1- x) (* x result)))))
 AT>      (fibo-helper n 1)))

wow, so now you know about labels and tail recursion. good for you.
it is not fibonacci, it is factorial, btw.

 AT> This would also allow us to eliminate the function name we gave to fn.

you say it like it is some unique feature of Clojure. with a simple macro
you can make recur like in Clojure in CL. but you cannot add support for
tail calls in Clojure in any way, until they fix it in JVM.

 AT> This makes it again shorter. And if we want to, we can put in a loop:
 AT> (defn fibonacci [n]
 AT>    (loop [x n   result 1]
 AT>      (if (zero? x)
 AT>        result
 AT>        (recur (dec x) (* x result)))))

 AT> And although I am doing CL since 6 years and Clojure just 4 months or
 AT> so, this looks cleaner in my opinion than the CL version.

than version you've wrote in CL. i would write it like this:

(defun factorial (n)
    (loop with p = 1
              for i from 1 to n
              do (setf p (* p i))
              finally (return p)))

IMHO that's cleaner. or if i absolutely must use recursion:

(defun factorial (n &optional (result 1))
    (if (zerop n)
        result
        (factorial (- n 1) (* n result))))

it is even shorter than your Clojure thing.

 AT> However, I also like to look at this from a more practical side.
 AT> Clojure is usable now.

many people find PHP usable and mature -- it does not bother them
that it lacks important features or that it often gets incompatible changes.
From: Slobodan Blazeski
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <d2787f58-6d31-42b1-9295-a9e836e4501f@i24g2000prf.googlegroups.com>
On Feb 14, 12:56 pm, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  ??>> oh yes, it is very healthy (for a functional language!) to have
>  ??>> "recur" special operator instead of normal tail recursion because of
>  ??>> JVM deficiency.
>
>  AT> It's true, it's healthy to have recur.
>  AT> I agree that it is not nice that the JVM does not have tail recursion
>  AT> yet. But in practice that is not a real issue, as recur is available.
>
> this reminds me a soviet anecdote: when there is no meat in the butcher's
> shop (it was often the case)
>  they  place an announcement at the shop's door: "there is no necessity in a
> meat today".
> are you as brainwashed as soviet's?
I'm afraid he is. If you still feel the urge to reason with him read
his posts in Making Lisp Popular thread.
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/be5630a07e123df2/86c5dd4ef015ef37?#86c5dd4ef015ef37
>
> recursion is not limited to the cases when you just call current function in
> a tail-call fashion. in functional
> programming often you need to call function in an alternating fashion -- foo
> calls bar, bar calls foo back
> etc. and recur simply cannot do this. it can only emulate simple loops.
>
> educate yourself:http://en.wikipedia.org/wiki/Mutual_recursion
>
>  AT> Let's look at this unreadable mess in CL:
>
>  AT> (DEFUN Y (F)
>  AT>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
>  AT>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G))
>  AT> H)))))
>
> this is a piece of cheap propaganda, i can't believe you're writing this
> seriously.
> you've tried hard to make it looks like an unreadable mess, and now you
> claim it is unreadable mess.
> whoa. NOBODY WRITES CODE LIKE THIS.
Above is just a Kent Pittman historical perspective code taken out of
context.The more I read Mr Thieme posts the more I believe that he has
a spamming frog disorder, uncurable desease I'm afraid.


cheers
bobi
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6ot6$cf1$1@news.motzarella.org>
Slobodan Blazeski schrieb:
> On Feb 14, 12:56 pm, "Alex Mizrahi" <········@users.sourceforge.net>
> wrote:
>>  ??>> oh yes, it is very healthy (for a functional language!) to have
>>  ??>> "recur" special operator instead of normal tail recursion because of
>>  ??>> JVM deficiency.
>>
>>  AT> It's true, it's healthy to have recur.
>>  AT> I agree that it is not nice that the JVM does not have tail recursion
>>  AT> yet. But in practice that is not a real issue, as recur is available.
>>
>> this reminds me a soviet anecdote: when there is no meat in the butcher's
>> shop (it was often the case)
>>  they  place an announcement at the shop's door: "there is no necessity in a
>> meat today".
>> are you as brainwashed as soviet's?
> I'm afraid he is. If you still feel the urge to reason with him read
> his posts in Making Lisp Popular thread.
> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/be5630a07e123df2/86c5dd4ef015ef37?#86c5dd4ef015ef37

I don�t understand why you are so angry.
You said some bullshit and were not able to defend it. Instead of going
back and correct yourself, such as:
"Ok ok, sorry. I wanted to say that it is easier to *implement* Lisps in
their own VM instead of the JVM".
But no, you need to stick with the word "better", although this makes no
sense at all.
I see that you are lurking around here since long time, abusing other
people, claiming that they know *nothing* about X and Y, even when this
is not correct. Why not trying to be more rational?


>> recursion is not limited to the cases when you just call current function in
>> a tail-call fashion. in functional
>> programming often you need to call function in an alternating fashion -- foo
>> calls bar, bar calls foo back
>> etc. and recur simply cannot do this. it can only emulate simple loops.
>>
>> educate yourself:http://en.wikipedia.org/wiki/Mutual_recursion
>>
>>  AT> Let's look at this unreadable mess in CL:
>>
>>  AT> (DEFUN Y (F)
>>  AT>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
>>  AT>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G))
>>  AT> H)))))
>>
>> this is a piece of cheap propaganda, i can't believe you're writing this
>> seriously.
>> you've tried hard to make it looks like an unreadable mess, and now you
>> claim it is unreadable mess.
>> whoa. NOBODY WRITES CODE LIKE THIS.
> Above is just a Kent Pittman historical perspective code taken out of
> context.

OMG, the context is that recur allows anon functions to call themselves.
The y-combinator also allows this. This absolutely *is* context.


 > The more I read Mr Thieme posts the more I believe that he has
> a spamming frog disorder, uncurable desease I'm afraid.

Again, nonsense.
You are angry and aggressive, and it simply is not needed.
This is a phenomenon that I observe with many people when they are out
of arguments. I invite you to join rational discussions about Lisp.
No reason to feel unsecure when a new and promising Lisp dialect shows up.
*That* would be really being brainwashed.
Defending CL for every price, no matter how bad it sucks.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Slobodan Blazeski
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <e6142e01-25e0-43e9-8b06-517497165113@p2g2000prf.googlegroups.com>
On Feb 14, 4:44 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Slobodan Blazeski schrieb:
>
>
>
>
>
> > On Feb 14, 12:56 pm, "Alex Mizrahi" <········@users.sourceforge.net>
> > wrote:
> >>  ??>> oh yes, it is very healthy (for a functional language!) to have
> >>  ??>> "recur" special operator instead of normal tail recursion because of
> >>  ??>> JVM deficiency.
>
> >>  AT> It's true, it's healthy to have recur.
> >>  AT> I agree that it is not nice that the JVM does not have tail recursion
> >>  AT> yet. But in practice that is not a real issue, as recur is available.
>
> >> this reminds me a soviet anecdote: when there is no meat in the butcher's
> >> shop (it was often the case)
> >>  they  place an announcement at the shop's door: "there is no necessity in a
> >> meat today".
> >> are you as brainwashed as soviet's?
> > I'm afraid he is. If you still feel the urge to reason with him read
> > his posts in Making Lisp Popular thread.
> >http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/be...
>
> I don’t understand why you are so angry.
> You said some bullshit and were not able to defend it. Instead of going
> back and correct yourself, such as:
> "Ok ok, sorry. I wanted to say that it is easier to *implement* Lisps in
> their own VM instead of the JVM".
> But no, you need to stick with the word "better", although this makes no
> sense at all.
Yes it does.
http://www.mindspring.com/~mfpatton/sketch.htm
> I see that you are lurking around here since long time, abusing other
> people, claiming that they know *nothing* about X and Y, even when this
> is not correct. Why not trying to be more rational?
Rational? I don't want spammers and fundamentalists who can't defend
their positions with code, but instead are going for under the belt
tricks spread nonsense in this group.  What could be more rational
then that?  You don't want to hear anything except only the best about
Clojure. Ok Clojure has some nice things, I agree, but its a frickin'
language it has flaws too. And recur and stupid tarmplones are one of
them. Instead of writing nonsense go and help Hinley with fixing the
implementation. The problem could be fixed, you could use CPS or some
other technique that are used by implementations running on JVM but
still manage to use recursion without jumping through hoops.
>
>
>
> >> recursion is not limited to the cases when you just call current function in
> >> a tail-call fashion. in functional
> >> programming often you need to call function in an alternating fashion -- foo
> >> calls bar, bar calls foo back
> >> etc. and recur simply cannot do this. it can only emulate simple loops.
>
> >> educate yourself:http://en.wikipedia.org/wiki/Mutual_recursion
>
> >>  AT> Let's look at this unreadable mess in CL:
>
> >>  AT> (DEFUN Y (F)
> >>  AT>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
> >>  AT>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G))
> >>  AT> H)))))
>
> >> this is a piece of cheap propaganda, i can't believe you're writing this
> >> seriously.
> >> you've tried hard to make it looks like an unreadable mess, and now you
> >> claim it is unreadable mess.
> >> whoa. NOBODY WRITES CODE LIKE THIS.
> > Above is just a Kent Pittman historical perspective code taken out of
> > context.
>
> OMG, the context is that recur allows anon functions to call themselves.
> The y-combinator also allows this. This absolutely *is* context.
Bullshit. You show us code that nobody will write, except to
demonstrate some historical staff about various lisp dialects and
imply that lispers make such mess. Well we don't.
>
>  > The more I read Mr Thieme posts the more I believe that he has
>
> > a spamming frog disorder, uncurable desease I'm afraid.
>
> Again, nonsense.
> You are angry and aggressive, and it simply is not needed.
> This is a phenomenon that I observe with many people when they are out
> of arguments.
I'm sure they are when speaking with you.
Andre Thieme: The ocean is red.
Unlucky Person: It is usually blue.
Andre Thieme: No its red.
Unlucky Person:[Tries to explain  that ocean is blue or blue-green]
Andre Thieme: No its red. Ever heard of red sea?
Unlucky Person:[Tries to explain again and put some supporting links ]
Andre Thieme:[Starts speaking bullshit for very long time while
several people try to put some light on his crup]
... [Several hours later]
Unlucky Person:[Gets angry]
>I invite you to join rational discussions about Lisp.
Then you have to  make sense what you're talking about.You don't do
that now. You only care how many long posts should you make before
people get tired and stop correct you weak I wouldn't call them
arguments.
> No reason to feel unsecure when a new and promising Lisp dialect shows up.
New and promising Lisps show up every year. But they  don't stay new
for long, nor promising.
> *That* would be really being brainwashed.
> Defending CL for every price, no matter how bad it sucks.
Its not cl that sucks. Change your diapers.

bobi
>
> André
> --
> Lisp is not dead. It’s just the URL that has changed:http://clojure.org/
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn7bvc$t38$1@news.motzarella.org>
Slobodan Blazeski schrieb:

> You don't want to hear anything except only the best about Clojure.
 > Ok Clojure has some nice things, I agree, but its a frickin' language
 > it has flaws too. And recur and stupid tarmplones are one of them.

You are mistaken if you think that I want to only hear what others like
about Clojure. To be able to do that one actually has to be a Clojure
user.
But in c.l.l it�s only the guys who don�t use Clojure who tell me what
is wrong with it, which is kind of amazing (and not in the good sense).
Write 1000-2000 lines of Clojure code, play with it for two month, and
then come back telling me what�s wrong with it.

I agree that Clojure has flaws. Recur is not one of them.
One could say that trampolines are. When I use a JVM with TCO I would
not use trampolines anymore. I could then also stop using recur, but
I won�t.

You guys who defend CL (I am one of those guys also) against attacks
from outsiders should better accept your own arguments, that this time
are used in favour of a different dialect.

I beg to differentiate between warts in Clojure vs those in the JVM.
Just because the GC of the JVM outperforms easily the one of the
commercial Lisp vendors is no weakness of CL itself.
It�s an implementation detail, which can fall back to the language
which is hosted on the VM.
I heared people making the most ridiculous statements about CL, because
it does not have threads or networking libs.
A non-CL user comes here, says �CL sucks, one can�t do multithreading�,
and we shake our heads.
Today:
CL guys come here, never used Clojure, and they say:
�Waah, Clojure sucks badly, it has no recursion. BTW recur is an evil
  design error, hahaha!�
Again, head-shaking on the side of the experts, who actually know it
better.

I always agreed that the absence of TCO in todays JVMs is a disad-
vantage. And I also see the trampolines in Clojure as a non-optimal
solution, as it introduces a (very small) extra complexity (bot not
zero), and slows down our programs.
Anyway, a flaw in the JVM that weights more is the behaviour of the
number boxing. CLs already mention this very well, and can outperform
Clojure code that does not use unboxed numbers.
Many people have this on their wishlist for the JVM.

One little wart in Clojure in my opinion are the mechanisms to generate
a class or an interface.
gen-class is a macro that takes up to 12 args (can be compared in a way
with CLs defclass). Of course, it is not Hickeys fault. The oop system
just requires this kind of complexity. But it�s the part in Clojure that
I dislike most.
Fortunately this is not needed very often.


> I'm sure they are when speaking with you.
> Andre Thieme: The ocean is red.
> Unlucky Person: It is usually blue.
> Andre Thieme: No its red.
> Unlucky Person:[Tries to explain  that ocean is blue or blue-green]
> Andre Thieme: No its red. Ever heard of red sea?

Haha, that one was actually good! :)
*thumbs up*


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6eqn$4b0$1@news.motzarella.org>
Alex Mizrahi schrieb:

> recursion is not limited to the cases when you just call current function in 
> a tail-call fashion. in functional
> programming often you need to call function in an alternating fashion -- foo 
> calls bar, bar calls foo back
> etc. and recur simply cannot do this. it can only emulate simple loops.
> 
> educate yourself: http://en.wikipedia.org/wiki/Mutual_recursion

For that case Clojure offers trampolines.
Yes, one can argue that trampolines are a specific idiom which one needs
to learn. It’s true. But let us not forget that tail recursion itself
already is such an idiom. It is an optimization hack.
No programming system currently allows you to write recursion as in a
way that is closest to math.
We always need to apply the design pattern “Tail recursion”.
So there already is something complex that one needs to do. Now what is
different in Clojure is, that you don’t make the calll
  (fun 1 2 3)  but instead
#(fun 1 2 3)  when you use trampolines, and it is stack-safe again.
It’s not that hard to remember. But yes, it is one key stroke more complex.
Still I would stop using trampolines as soon the JVM will introduce that
kind of optimization. I will however continue to use recur, for the
typical recursion, which makes like 99% of all recursion I usually use.


>  AT> Let's look at this unreadable mess in CL:
> 
>  AT> (DEFUN Y (F)
>  AT>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
>  AT>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G))
>  AT> H)))))
> 
> this is a piece of cheap propaganda, i can't believe you're writing this 
> seriously.
> you've tried hard to make it looks like an unreadable mess, and now you 
> claim it is unreadable mess.
> whoa. NOBODY WRITES CODE LIKE THIS.

Well, it’s from Kent Pitman.
http://www.nhplace.com/kent/Papers/Technical-Issues.html


> if you need to do recursive call of a local function in CL, use labels.
> 
>  AT> (FUNCALL (Y #'(LAMBDA (FN)
>  AT>                  #'(LAMBDA (X)
>  AT>                      (IF (ZEROP X) 0 (+ X (FUNCALL FN (- X 1)))))))
>  AT>           200)
>  AT> ==> 20100
> 
> it is not tail recursive, btw. tail recursive version with labels:
> 
> (labels ((sum (x acc) (if (zerop x)
>                                      acc
>                                      (sum (- x 1) (+ acc x)))))
>          (sum 200 0))

Where is the anonymous function here?
recur allows you anon functions to call themself.


> what would be even "more pleasant for the eye": (loop for i from 1 to n 
> summing i)

Yes true, for that specific task it is much nicer.
I like it nearly as much as (apply + (range n)).



>  AT> Plus: this call works.
>  AT> Stack overflow I guess.
> 
> sure it does, because it was not tail calls. you should admit you know very 
> little about functional programming, as you do not know even basics.

I see no reason to admit that at this point, as I was fully aware about
this. What I was doing was talking about anon functions calling themselves.



>  AT> Or another example:
>  AT> (defun fibonacci (n)
>  AT>    (labels ((fibo-helper (x result)
>  AT>               (if (zerop x)
>  AT>                   result
>  AT>                   (fibo-helper (1- x) (* x result)))))
>  AT>      (fibo-helper n 1)))
> 
> wow, so now you know about labels and tail recursion. good for you.
> it is not fibonacci, it is factorial, btw.

Yes right, how embarrassing :-/


>  AT> This would also allow us to eliminate the function name we gave to fn.
> 
> you say it like it is some unique feature of Clojure. with a simple macro
> you can make recur like in Clojure in CL. but you cannot add support for
> tail calls in Clojure in any way, until they fix it in JVM.

Let’s say you have a Lisp with no support for TCO.
Then you would also be forced to wait until your vendor fixes it.
Or you have an open source solution and do it yourself (as it currently
happens with the OpenJDK).
And of course one can add recur also in CL. Everything that Clojure has
can be done in CL and vice versa.


>  AT> This makes it again shorter. And if we want to, we can put in a loop:
>  AT> (defn fibonacci [n]
>  AT>    (loop [x n   result 1]
>  AT>      (if (zero? x)
>  AT>        result
>  AT>        (recur (dec x) (* x result)))))
> 
>  AT> And although I am doing CL since 6 years and Clojure just 4 months or
>  AT> so, this looks cleaner in my opinion than the CL version.
> 
> than version you've wrote in CL. i would write it like this:
> 
> (defun factorial (n)
>     (loop with p = 1
>               for i from 1 to n
>               do (setf p (* p i))
>               finally (return p)))
> 
> IMHO that's cleaner.

After some months of functional programming I don’t like code with setf
anymore. But your solution is working perfectly, and it’s only my taste,
not a technical issue.

In Clojure I would probably do:
(defn factorial [n] (apply * (range 1 (inc n))))

or if I want the set of all factorials, then
(def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))

This is my favourite. No function needed, just a variable bound to an
infinite lazy sequence.
This also has the nice advantage of being automatically memoized.


 > or if i absolutely must use recursion:
> 
> (defun factorial (n &optional (result 1))
>     (if (zerop n)
>         result
>         (factorial (- n 1) (* n result))))
> 
> it is even shorter than your Clojure thing.

It’s true, but I don’t like this solution at all, because it introduces
an optional argument which can’t be used at the user site.
Peter Seibel calls this a leaky abstraction.
For hobby programming it is okay, but a clean solution would be
(defun factorial (n)
   (labels ((helper (n result)
              (if (zerop n)
                  result
                  (helper (1- n) (* result n)))))
     (helper n 1)))


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <c30b19c1-ae1a-45b0-aef6-1ba65e229b23@k36g2000pri.googlegroups.com>
On Feb 14, 1:52 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Alex Mizrahi schrieb:
>
> > recursion is not limited to the cases when you just call current function in
> > a tail-call fashion. in functional
> > programming often you need to call function in an alternating fashion -- foo
> > calls bar, bar calls foo back
> > etc. and recur simply cannot do this. it can only emulate simple loops.
>
> > educate yourself:http://en.wikipedia.org/wiki/Mutual_recursion
>
> For that case Clojure offers trampolines.
> Yes, one can argue that trampolines are a specific idiom which one needs
> to learn. It’s true. But let us not forget that tail recursion itself
> already is such an idiom. It is an optimization hack.
> No programming system currently allows you to write recursion as in a
> way that is closest to math.
> We always need to apply the design pattern “Tail recursion”.
> So there already is something complex that one needs to do. Now what is
> different in Clojure is, that you don’t make the calll
>   (fun 1 2 3)  but instead
> #(fun 1 2 3)  when you use trampolines, and it is stack-safe again.
> It’s not that hard to remember. But yes, it is one key stroke more complex.
> Still I would stop using trampolines as soon the JVM will introduce that
> kind of optimization. I will however continue to use recur, for the
> typical recursion, which makes like 99% of all recursion I usually use.
>
> >  AT> Let's look at this unreadable mess in CL:
>
> >  AT> (DEFUN Y (F)
> >  AT>   (  (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
> >  AT>    #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G))
> >  AT> H)))))
>
> > this is a piece of cheap propaganda, i can't believe you're writing this
> > seriously.
> > you've tried hard to make it looks like an unreadable mess, and now you
> > claim it is unreadable mess.
> > whoa. NOBODY WRITES CODE LIKE THIS.
>
> Well, it’s from Kent Pitman.http://www.nhplace.com/kent/Papers/Technical-Issues.html
>
> > if you need to do recursive call of a local function in CL, use labels.
>
> >  AT> (FUNCALL (Y #'(LAMBDA (FN)
> >  AT>                  #'(LAMBDA (X)
> >  AT>                      (IF (ZEROP X) 0 (+ X (FUNCALL FN (- X 1)))))))
> >  AT>           200)
> >  AT> ==> 20100
>
> > it is not tail recursive, btw. tail recursive version with labels:
>
> > (labels ((sum (x acc) (if (zerop x)
> >                                      acc
> >                                      (sum (- x 1) (+ acc x)))))
> >          (sum 200 0))
>
> Where is the anonymous function here?
> recur allows you anon functions to call themself.
>
> > what would be even "more pleasant for the eye": (loop for i from 1 to n
> > summing i)
>
> Yes true, for that specific task it is much nicer.
> I like it nearly as much as (apply + (range n)).
>
> >  AT> Plus: this call works.
> >  AT> Stack overflow I guess.
>
> > sure it does, because it was not tail calls. you should admit you know very
> > little about functional programming, as you do not know even basics.
>
> I see no reason to admit that at this point, as I was fully aware about
> this. What I was doing was talking about anon functions calling themselves.
>
> >  AT> Or another example:
> >  AT> (defun fibonacci (n)
> >  AT>    (labels ((fibo-helper (x result)
> >  AT>               (if (zerop x)
> >  AT>                   result
> >  AT>                   (fibo-helper (1- x) (* x result)))))
> >  AT>      (fibo-helper n 1)))
>
> > wow, so now you know about labels and tail recursion. good for you.
> > it is not fibonacci, it is factorial, btw.
>
> Yes right, how embarrassing :-/
>
> >  AT> This would also allow us to eliminate the function name we gave to fn.
>
> > you say it like it is some unique feature of Clojure. with a simple macro
> > you can make recur like in Clojure in CL. but you cannot add support for
> > tail calls in Clojure in any way, until they fix it in JVM.
>
> Let’s say you have a Lisp with no support for TCO.
> Then you would also be forced to wait until your vendor fixes it.
> Or you have an open source solution and do it yourself (as it currently
> happens with the OpenJDK).
> And of course one can add recur also in CL. Everything that Clojure has
> can be done in CL and vice versa.
>
>
>
> >  AT> This makes it again shorter. And if we want to, we can put in a loop:
> >  AT> (defn fibonacci [n]
> >  AT>    (loop [x n   result 1]
> >  AT>      (if (zero? x)
> >  AT>        result
> >  AT>        (recur (dec x) (* x result)))))
>
> >  AT> And although I am doing CL since 6 years and Clojure just 4 months or
> >  AT> so, this looks cleaner in my opinion than the CL version.
>
> > than version you've wrote in CL. i would write it like this:
>
> > (defun factorial (n)
> >     (loop with p = 1
> >               for i from 1 to n
> >               do (setf p (* p i))
> >               finally (return p)))
>
> > IMHO that's cleaner.
>
> After some months of functional programming I don’t like code with setf
> anymore. But your solution is working perfectly, and it’s only my taste,
> not a technical issue.
>
> In Clojure I would probably do:
> (defn factorial [n] (apply * (range 1 (inc n))))

As in

  (defun factorial (n) (apply '* (iota 1 n)))

It isn't very compelling...

> or if I want the set of all factorials, then
> (def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))
>
> This is my favourite. No function needed, just a variable bound to an
> infinite lazy sequence.
> This also has the nice advantage of being automatically memoized.

As in

(defparameter fibs (streams:cat 0 1 (streams:map-stream '+ fibs
(streams:tail fibs)))

... again this is not very compelling either.  This is SICP.

Cheers
--
Marco
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6s6c$j1c$1@news.motzarella.org>
Marco Antoniotti schrieb:

>> In Clojure I would probably do:
>> (defn factorial [n] (apply * (range 1 (inc n))))
> 
> As in
> 
>   (defun factorial (n) (apply '* (iota 1 n)))
> 
> It isn't very compelling...
> 
>> or if I want the set of all factorials, then
>> (def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))
>>
>> This is my favourite. No function needed, just a variable bound to an
>> infinite lazy sequence.
>> This also has the nice advantage of being automatically memoized.
> 
> As in
> 
> (defparameter fibs (streams:cat 0 1 (streams:map-stream '+ fibs
> (streams:tail fibs)))
> 
> ... again this is not very compelling either.  This is SICP.

All of my examples can of course be translated into CL, Scheme or
other turing complete programming langauges.
I would not be surprised if all CL programs could be translated into
Clojure as well.

Anyway, I see the strong point of Clojure in offering all these tools
in the core language. This means that everyone will use them.
The iota function has, no idea, 92 users in the world.
Probably 7 who use it regularily.
(I don�t mean these numbers literally, but I have not seen that anyone
  used those, neither in open source, nor in my professional work).

If something ships with the language then in most cases everyone
will use that, instead of trying an alternative library.
Now there are 26 pattern matching libs for CL, and they have an
accumulated number of 17 users worldwide.
CLers like if the language offers already good bit of reusable code.
Otherwise they may have become Scheme users.
Clojure goes some steps forward. Unlike CL it is not bound to limit
itself with the functions defined by the HS.
Those functions are available to all Clojure developers, and there is
a big agreement to use them. This makes code and libs more compatible
and much easier to read.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <3bfca82b-8754-47fa-9889-521ff757472e@x6g2000pre.googlegroups.com>
On Feb 14, 5:40 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Marco Antoniotti schrieb:
>
>
>
> >> In Clojure I would probably do:
> >> (defn factorial [n] (apply * (range 1 (inc n))))
>
> > As in
>
> >   (defun factorial (n) (apply '* (iota 1 n)))
>
> > It isn't very compelling...
>
> >> or if I want the set of all factorials, then
> >> (def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))
>
> >> This is my favourite. No function needed, just a variable bound to an
> >> infinite lazy sequence.
> >> This also has the nice advantage of being automatically memoized.
>
> > As in
>
> > (defparameter fibs (streams:cat 0 1 (streams:map-stream '+ fibs
> > (streams:tail fibs)))
>
> > ... again this is not very compelling either.  This is SICP.
>
> All of my examples can of course be translated into CL, Scheme or
> other turing complete programming langauges.
> I would not be surprised if all CL programs could be translated into
> Clojure as well.

From what I saw I woul dnot be surprised.

> Anyway, I see the strong point of Clojure in offering all these tools
> in the core language. This means that everyone will use them.
> The iota function has, no idea, 92 users in the world.
> Probably 7 who use it regularily.
> (I don’t mean these numbers literally, but I have not seen that anyone
>   used those, neither in open source, nor in my professional work).

Maybe. There is definitively a lot of advantages in "standards".
Maybe IOTA (or 'range' and 'xrange') are not all that useful ax
examples.

> If something ships with the language then in most cases everyone
> will use that, instead of trying an alternative library.
> Now there are 26 pattern matching libs for CL, and they have an
> accumulated number of 17 users worldwide.

Now, now, now... :) there is only *one* all-encopassing pattern
matching (and more) library which accounts for most of the 17 users:
CL-UNIFICATION (shameless plug).

> CLers like if the language offers already good bit of reusable code.
> Otherwise they may have become Scheme users.

I think this is a non-sequitur :)

> Clojure goes some steps forward. Unlike CL it is not bound to limit
> itself with the functions defined by the HS.
> Those functions are available to all Clojure developers, and there is
> a big agreement to use them. This makes code and libs more compatible
> and much easier to read.

Sounds good to me.  I just think that you are not making any good case
with your snippets and your arguments are not much different from
CLers telling Schemers that they should use CL and viceversa.

Cheers
--
Marco
From: Rob Warnock
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <k5GdnQM7O_aa6grUnZ2dnUVZ_j2dnZ2d@speakeasy.net>
Andr� Thieme  <······························@justmail.de> wrote:
+---------------
| Marco Antoniotti schrieb:
| >> In Clojure I would probably do:
| >> (defn factorial [n] (apply * (range 1 (inc n))))
| > 
| > As in
| >   (defun factorial (n) (apply '* (iota 1 n)))
| > It isn't very compelling...
...
| The iota function has, no idea, 92 users in the world.
| Probably 7 who use it regularily.
| (I don�t mean these numbers literally, but I have not seen that anyone
|   used those, neither in open source, nor in my professional work).
+---------------

Then you must not have been reading "comp.lang.lisp" very long. ;-}
A quick search shows some 170 articles mentioning it, including
several by me:  ;-}  ;-}

    Newsgroups: comp.lang.lisp
    Date: Sat, 18 Oct 2008 04:50:42 -0500
    Subject: Re: Lisp 50 event at OOPSLA - worth going?
    From: ····@rpw3.org (Rob Warnock)
    Message-ID: <································@speakeasy.net>

    ...  I even baked a cake!!  ;-}  ;-}

    > (format t "~%+~62,,,··@·······@t*~36r ~36r, ··········@t|~%~
                 | ~{~<|~%| ~1,70:;Candle #~d~>~^, ~
                 ~:*~[ ~; ~; ~; ~; ~; ~; ~; ~; ~; ~]~}  |~%+~62,,,··@a~%~%"
                 #\+ 29053366 902869993114 1004137 (iota 50 1) #\+)


    Newsgroups: comp.lang.lisp
    Date: Mon, 26 May 2008 04:23:15 -0500
    Subject: Re: Separate the lisp environment from the shell (and other things)
    From: ····@rpw3.org (Rob Warnock)
    Message-ID: <································@speakeasy.net>

    Rares Marian  <············@gmail.com> wrote:
    +---------------
    | We should be at a point where we can start lisp programs
    | from the shell or desktop just like any other binary.
    +---------------

    Been there, done that, years & years ago. Works just fine:

	$ iota 10
	0 1 2 3 4 5 6 7 8 9
	$ iota 10 20
	20 21 22 23 24 25 26 27 28 29
	$ iota 10 20 5
	20 25 30 35 40 45 50 55 60 65
	$ cat `which iota`
	#!/usr/local/bin/cmucl -script

	(defun iota (count &optional (start 0) (step 1))
	  (loop repeat count for i from start by step collect i))

	(format t "~{~a~^ ~}~%"
		  (apply 'iota (mapcar #'read-from-string *script-args*)))
	$ 
    ...
    p.s. See <http://rpw3.org/hacks/lisp/site-switch-script.lisp>
    if you use CMUCL and haven't hacked your own "-script" or equiv.

Then there was a whole thread in late 2007 on ARRAY-IOTA.

And we haven't even started in on the Scheme users, yet...  ;-}
[They like it over there, too!]

Anyway, to the larger point...

For me, the issue isn't so much whether Implementation X provides a
given CL extension or not, it's whether the meme is sufficiently stable
and widespread that one can use it with some confidence that you will
be understood by others without lengthy explanations. IOTA has *long*
ago passed that threshold [though there is still some variations in
the wild, e.g., the order of the optional START & STEP arguments].
And DEFLEX (or DEFLEXICAL) is getting there too, I think...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Scott
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <d9752e04-1ba0-48aa-abfd-d3ea21fb8e2d@b38g2000prf.googlegroups.com>
On Feb 14, 6:59 pm, ····@rpw3.org (Rob Warnock) wrote:
>
>     > (format t "~%+~62,,,··@·······@t*~36r ~36r, ··········@t|~%~
>                  | ~{~<|~%| ~1,70:;Candle #~d~>~^, ~
>                  ~:*~[ ~; ~; ~; ~; ~; ~; ~; ~; ~; ~]~}  |~%+~62,,,··@a~%~%"
>                  #\+ 29053366 902869993114 1004137 (iota 50 1) #\+)
>

Is that APL?


j/k
From: Rob Warnock
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <xrmdnfSRK8AjLArUnZ2dnUVZ_u6dnZ2d@speakeasy.net>
Scott  <·······@gmail.com> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) wrote:
| > > (format t "~%+~62,,,··@·······@t*~36r ~36r, ··········@t|~%~
| >              | ~{~<|~%| ~1,70:;Candle #~d~>~^, ~
| >              ~:*~[ ~; ~; ~; ~; ~; ~; ~; ~; ~; ~]~}  |~%+~62,,,··@a~%~%"
| >              #\+ 29053366 902869993114 1004137 (iota 50 1) #\+)
| 
| Is that APL?  j/k
+---------------

I think it's called FORMAT pr0n!  ;-}  ;-}


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rob Warnock
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <xrmdnfWRK8CuLQrUnZ2dnUVZ_u6dnZ2d@speakeasy.net>
Madhu  <·······@meer.net> wrote:
+---------------
| * (Rob Warnock) <································@speakeasy.net> :
| | Then there was a whole thread in late 2007 on ARRAY-IOTA.
| 
| Which reminds me to ask: could you consider and releasing OPFR?
+---------------

Sure, no problem. I'll put that on the "to do real soon" list,
and will post here when that happens.

+---------------
| (From the descriptions i think It could serve as a reference for other
| efforts along the lines)
+---------------

Perhaps. ;-}  Even though I've been inflicting it on innocent live
users for over a decade(!), I'm still not completely decided on how it
really "ought" to work, since that seems to vary considerably depending
on what application and user group it's being used with. E.g., I've
flip-flopped back & forth several times on how to handle exceptions:
Show an (abbreviated) backtrace. or just PRINC the condition? Drop into
the debuuger or just bounce back to the top-level prompt? "It depends",
as they say. For these reasons (and others), it really should be
considered as merely one instance of a general pattern, rather than
any kind of cast-in-stone "library" or "module" that one can just
grab off the shelf and use blindly.  [You have been warned...  ;-}  ]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rob Warnock
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <k8mdnfwg6N___S7UnZ2dnUVZ_sbinZ2d@speakeasy.net>
Almost a month ago, I promised:
+---------------
| Madhu <·······@meer.net> wrote:
| +---------------
| | Which reminds me to ask: could you consider and releasing OPFR?
| +---------------
| 
| Sure, no problem. I'll put that on the "to do real soon" list,
| and will post here when that happens.
+---------------

Sorry it's taken so much longer than I expected -- a week's illness
and a couple of sysadmin crises got in the way, not not to mention
having to weed through about a dozen variations I had lying around
[I *did* mention that I tend to treat OPFR as a "pattern", not a
"library", yes? And freely hack up random variations at need?].
But I now have a (somewhat-)cleaned-up reference version up on my
web site, along with an example "shell script" driver for CMUCL
[the one I usually use] and a *very*-lightly-tested one for CLISP:

    http://rpw3.org/hacks/lisp/opfr.lisp     ; 11554 bytes
    http://rpw3.org/hacks/lisp/opfr.cmucl    ;  2541 bytes
    http://rpw3.org/hacks/lisp/opfr.clisp    ;  1972 bytes

All have "ISC/OpenBSD"-style licenses. [Like "MIT", but shorter.]

You can COMPILE-FILE "opfr.lisp", if you like, though since it runs
at human speed the performance of interpreting source shouldn't be
an issue.

The only documentation is comments in the source. [Note: There *are*
a couple of documented bugs/limitations! But they've never been an
issue in any of the uses I've made of it.] You will almost certainly
need to tweak the paths in the driver scripts.

Have fun!


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rob Warnock
Subject: OPFR ("Outer-Parenthesis-Free REPL") released
Date: 
Message-ID: <jPudnXzHkK7r_y7UnZ2dnUVZ_sHinZ2d@speakeasy.net>
To recap: OPFR ("Outer-Parenthesis-Free REPL") is a meme/pattern/library(?)
for a reader that wraps a set of parens around whatever the user types
and then passes that to EVAL (then PRINTs & LOOPs).

Almost a month ago [in the "Road to Clojure Survey 2.0" thread],
I promised Madhu:
+---------------
| Madhu <·······@meer.net> wrote:
| +---------------
| | Which reminds me to ask: could you consider and releasing OPFR?
| +---------------
| 
| Sure, no problem. I'll put that on the "to do real soon" list,
| and will post here when that happens.
+---------------

Sorry it's taken so much longer than I expected -- a week's illness
and a couple of sysadmin crises got in the way, not not to mention
having to weed through about a dozen variations I had lying around
[I *did* mention that I tend to treat OPFR as a "pattern", not a
"library", yes? And freely hack up random variations at need?].
But I now have a (somewhat-)cleaned-up reference version up on my
web site, along with an example "shell script" driver for CMUCL
[the one I usually use] and a *very*-lightly-tested one for CLISP:

    http://rpw3.org/hacks/lisp/opfr.lisp     ; 11554 bytes
    http://rpw3.org/hacks/lisp/opfr.cmucl    ;  2541 bytes
    http://rpw3.org/hacks/lisp/opfr.clisp    ;  1972 bytes

All have "ISC/OpenBSD"-style licenses. [Like "MIT", but shorter.]

You can COMPILE-FILE "opfr.lisp", if you like, though since it runs
at human speed the performance of interpreting source shouldn't be
an issue.

The only documentation is comments in the source. [Note: There *are*
a couple of documented bugs/limitations! But they've never been an
issue in any of the uses I've made of it.] You will almost certainly
need to tweak the paths in the driver scripts.

Have fun!


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Evans Winner
Subject: Re: OPFR ("Outer-Parenthesis-Free REPL") released
Date: 
Message-ID: <86d4cr5nva.fsf@timbral.net>
····@rpw3.org (Rob Warnock) writes:

    To recap: OPFR ("Outer-Parenthesis-Free REPL") is a
    meme/pattern/library(?)  for a reader that wraps a set
    of parens around whatever the user types and then passes
    that to EVAL (then PRINTs & LOOPs).

What is this used for?  I have thought that this kind of
thing would be a nice feature in a lisp-based command
language.  For that matter, a really feature-full such
command language seems like it would be an easy thing for
those we-have-to-make-lisp-more-popular people to come up
with.  Not that I'm volunteering, because, you know, people
can just roll their own if they need it.
From: Rob Warnock
Subject: Re: OPFR ("Outer-Parenthesis-Free REPL") released
Date: 
Message-ID: <ZvqdnatzJ976iSjUnZ2dnUVZ_gqWnZ2d@speakeasy.net>
Evans Winner  <······@timbral.net> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) writes:
| > To recap: OPFR ("Outer-Parenthesis-Free REPL") is a
| > meme/pattern/library(?)  for a reader that wraps a set
| > of parens around whatever the user types and then passes
| > that to EVAL (then PRINTs & LOOPs).
| 
| What is this used for?  I have thought that this kind of
| thing would be a nice feature in a lisp-based command language.
+---------------

Yup, if you qualify that with "domain-specific", that's exactly what
it provides. You can search for the sveeral previous tiems I've talked
about it here, but briefly, OPFR is intended for making domain-specific
"command languages" that happen to be written in CL, via the simple trick
of providing parens around each input line and then calling EVAL. To make
sure that the end user seldom (if ever) needs to type a real Lisp sexp,
one should also provide sufficient pre-defined domain-specific functions
that can take simple constant arguments [though possibly allowing optional
and keyword args], so that users rarely need to type parens.

But because the "command language" is *such* a thin shim over the
CL REPL, the full power of CL is instantly available to "power users"
who want to do more than the application designer initially provided
them in the pre-defined functions. E.g., suppose you have written a
hardware test control program (call it HTC), and have provided a few
"commands" (functions) such as RESET-BOARD, RELOAD-BOARD, & START-BOARD:

    htc> reset-board 3
    htc> reload-board 3 chip 17 file "foo.bin"
    htc> start-board 3
    htc> 

A power user will quickly [or slowly, whatever] pester you and
learn that they can write:

    htc> loop for b in boards do (reset-board b)
    htc> 

Pretty soon, they're writing nasty/fun stuff like this:

    htc> (loop for b in boards do
	   (loop for c in chips do
	     (reset-board b)
	     (reload-board b chip c file (format nil "foo-~d-~d.bin" b c))
	     (start-board b)))
    htc> 

and then realizing they can put such things into their own scripts with:

    $ cat my-script
    #!/usr/bin/env htc
    (loop for b in boards do
      (loop for c in chips do
	(reset-board b)
	(reload-board b chip c file (format nil "foo-~d-~d.bin" b c))
	(start-board b)))
    $ 

And for the ones who're not quite so eager, you just make sure that
your "htc" program is written so that when run with no arguments one
gets an OPFR REPL, but when run with args it takes them as one "command"
on the line. Then instead of typing this:

    $ htc
    htc> reset-board 3
    htc> reload-board 3 chip 17 file "foo.bin"
    htc> start-board 3
    htc> ^D
    $ 

the "half-power users" will type this to the shell [yes, there's that
bit of nastiness about single-quoting the double quotes -- oh, well!]:

    $ htc reset-board 3
    $ htc reload-board 3 chip 17 file '"foo.bin"'
    $ htc start-board 3
    $ 

and the "3/4-power users" will write scripts like this:

    $ cat my-script
    #!/bin/sh
    for b in `cat boards`
    do for c in `cat chips`
       do htc reset-board $b
          htc reload-board $b chip 17 file "\"foo-$b-$c.bin\""
          htc start-board $b
       done
    done
    $ 

+---------------
| For that matter, a really feature-full such command language seems
| like it would be an easy thing for those we-have-to-make-lisp-more-
| popular people to come up with.
+---------------

1. Note: I'm *NOT* one of thos "we-have-to-make-lisp-more-popular" people.
   I'm quite willing for it to remain a "secret weapon" [albeit an open
   secret].  ;-}  ;-}

   I just want to be *permitted* to use Lisp to write little domain-specific
   apps that other people in my work environment will need to run from time
   to time. Using OPFR as the interface permits just enough reduction in
   the ambient parenthephobia for using CL to be tolerated.

2. Since in practice you can get >90% of what is needed for command-line
   apps from OPFR plus a handful of domain-specific functions, there's
   no benefit in wasting time on developing a "really feature-full command
   language". The few power users who could benefit from the "features"
   can just be taught to use the full CL EVAL.

+---------------
| Not that I'm volunteering, because, you know, people can just roll
| their own if they need it.
+---------------

Exactly, which is why OPFR is more a "meme" or "pattern", rather than
a "library". I don't really expect anyone to use it for anything serious
without whacking on it a bit to make it fit their own local requirements.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <2bd4bc43-612b-4523-91be-db5aedbd3f0b@f20g2000yqg.googlegroups.com>
On Feb 15, 3:39 am, Madhu <·······@meer.net> wrote:
> * (Rob Warnock) <································@speakeasy.net> :
> Wrote on Sat, 14 Feb 2009 19:59:35 -0600:
>
> | Then there was a whole thread in late 2007 on ARRAY-IOTA.
>
> Which reminds me to ask: could you consider and releasing OPFR?

Wow.  I *am* getting old.  What is a OPFR?

Cheers
--
Marco
From: Rob Warnock
Subject: OPFR  [was: Re: Road to Clojure...]
Date: 
Message-ID: <N7Sdndz4CMggcQrUnZ2dnUVZ_qfinZ2d@speakeasy.net>
Marco Antoniotti  <·······@gmail.com> wrote:
+---------------
| Madhu <·······@meer.net> wrote:
| > (Rob Warnock) <································@speakeasy.net> wrote:
| > | Then there was a whole thread in late 2007 on ARRAY-IOTA.
| >
| > Which reminds me to ask: could you consider and releasing OPFR?
| 
| Wow.  I *am* getting old.  What is a OPFR?
+---------------

"OPFR" == "Outer-Parenthesis-Free REPL". It's a meme/pattern/library(?)
that I've been talking about & using since early 1995 [if not earlier!],
first in Scheme, then in Common Lisp. The idea is simplicity itself:
a command-line reader that wrap a set of parens around whatever the user
types and then passes that to EVAL [with some minor tweaks so the most
common cases "do the right thing"]. The "rationale" comment from the
current CL version [soon to be public]:

    ;;; OPFR provides a simple command-line read-eval-print loop (REPL) for
    ;;; programs written in Common Lisp where the primary user community
    ;;; is uncomfortable using normal Lisp symbolic expressions (sexps).
    ;;; The simplicity and utility of OPFR derives from the observation
    ;;; that most such people are actually surprisingly accepting of an
    ;;; sexp-based interface *provided* that they are not required
    ;;; to manually type the outer pair of parentheses, *even if* any
    ;;; sub-expressions are still in pure Lisp sexp form!! This effect
    ;;; is even stronger when the majority of the command functions in the
    ;;; using application are provided as functions or macros, which only
    ;;; seldom require the typing of sub-expressions.
    ;;;
    ;;; This short example compares the syntaxes. First, normal Common Lisp:
    ;;;     > (+ 1 2)
    ;;;     3
    ;;;     > (defvar x 34)
    ;;;     X
    ;;;     > (defvar y 25)
    ;;;     Y
    ;;;     > (expt x y)
    ;;;     193630125104980427932766033374162714624
    ;;;     > (expt x (- y 12))
    ;;;     81138303245565435904
    ;;;     > 
    ;;; Now, exactly the same sequence of operations using OPFR syntax:
    ;;;     opfr> + 1 2
    ;;;      ==> 3
    ;;;     opfr> defvar x 34
    ;;;      ==> X
    ;;;     opfr> defvar y 25
    ;;;      ==> Y
    ;;;     opfr> expt x y
    ;;;      ==> 193630125104980427932766033374162714624
    ;;;     opfr> expt x (- y 12)
    ;;;      ==> 81138303245565435904
    ;;;     opfr>
    ;;;
    ;;; Note: The average Lisp programmer will see no significant advantage to
    ;;; the OPFR syntax (and some disadvantages, such as the need to resolve
    ;;; the ambiguity of a naked symbol -- should OPFR print its value as
    ;;; a global variable or call it as a "command" function?), especially
    ;;; since sub-expressions must still be fully-parenthesized (as in the
    ;;; last example above). Nevertheless, experience with real users has
    ;;; shown that the acceptance of the OPFR syntax is *enormously* greater
    ;;; than the "pure" Lisp sexp. [Go figure... (*sigh*)]

Search for me & OPFR or me & HWTOOL and you'll see lots more examples, e.g.:

    Subject: Re: Why is LISP syntax superior?
    Message-ID: <································@speakeasy.net>

    Subject: Re: sweet-expressions instead of s-expressions?
    Message-ID: <································@speakeasy.net>

    Subject: Re: MUSING: standard bodies vs benevolent dictators, popularity
    Message-ID: <······················@speakeasy.net>

-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Marco Antoniotti
Subject: Re: OPFR [was: Re: Road to Clojure...]
Date: 
Message-ID: <34cf28fe-3883-420a-a625-f82e9cfdbd26@p20g2000yqi.googlegroups.com>
On Feb 15, 11:21 am, ····@rpw3.org (Rob Warnock) wrote:
> Marco Antoniotti  <·······@gmail.com> wrote:
> +---------------| Madhu <·······@meer.net> wrote:
>
> | > (Rob Warnock) <································@speakeasy.net> wrote:
> | > | Then there was a whole thread in late 2007 on ARRAY-IOTA.
> | >
> | > Which reminds me to ask: could you consider and releasing OPFR?
> |
> | Wow.  I *am* getting old.  What is a OPFR?
> +---------------
>
> "OPFR" == "Outer-Parenthesis-Free REPL". It's a meme/pattern/library(?)
> that I've been talking about & using since early 1995 [if not earlier!],
> first in Scheme, then in Common Lisp. The idea is simplicity itself:
> a command-line reader that wrap a set of parens around whatever the user
> types and then passes that to EVAL [with some minor tweaks so the most
> common cases "do the right thing"]. The "rationale" comment from the
> current CL version [soon to be public]:
>
>     ;;; OPFR provides a simple command-line read-eval-print loop (REPL) for
>     ;;; programs written in Common Lisp where the primary user community
>     ;;; is uncomfortable using normal Lisp symbolic expressions (sexps).
>     ;;; The simplicity and utility of OPFR derives from the observation
>     ;;; that most such people are actually surprisingly accepting of an
>     ;;; sexp-based interface *provided* that they are not required
>     ;;; to manually type the outer pair of parentheses, *even if* any
>     ;;; sub-expressions are still in pure Lisp sexp form!! This effect
>     ;;; is even stronger when the majority of the command functions in the
>     ;;; using application are provided as functions or macros, which only
>     ;;; seldom require the typing of sub-expressions.
>     ;;;
>     ;;; This short example compares the syntaxes. First, normal Common Lisp:
>     ;;;     > (+ 1 2)
>     ;;;     3
>     ;;;     > (defvar x 34)
>     ;;;     X
>     ;;;     > (defvar y 25)
>     ;;;     Y
>     ;;;     > (expt x y)
>     ;;;     193630125104980427932766033374162714624
>     ;;;     > (expt x (- y 12))
>     ;;;     81138303245565435904
>     ;;;     >
>     ;;; Now, exactly the same sequence of operations using OPFR syntax:
>     ;;;     opfr> + 1 2
>     ;;;      ==> 3
>     ;;;     opfr> defvar x 34
>     ;;;      ==> X
>     ;;;     opfr> defvar y 25
>     ;;;      ==> Y
>     ;;;     opfr> expt x y
>     ;;;      ==> 193630125104980427932766033374162714624
>     ;;;     opfr> expt x (- y 12)
>     ;;;      ==> 81138303245565435904
>     ;;;     opfr>
>     ;;;
>     ;;; Note: The average Lisp programmer will see no significant advantage to
>     ;;; the OPFR syntax (and some disadvantages, such as the need to resolve
>     ;;; the ambiguity of a naked symbol -- should OPFR print its value as
>     ;;; a global variable or call it as a "command" function?), especially
>     ;;; since sub-expressions must still be fully-parenthesized (as in the
>     ;;; last example above). Nevertheless, experience with real users has
>     ;;; shown that the acceptance of the OPFR syntax is *enormously* greater
>     ;;; than the "pure" Lisp sexp. [Go figure... (*sigh*)]
>
> Search for me & OPFR or me & HWTOOL and you'll see lots more examples, e.g.:
>
>     Subject: Re: Why is LISP syntax superior?
>     Message-ID: <································@speakeasy.net>
>
>     Subject: Re: sweet-expressions instead of s-expressions?
>     Message-ID: <································@speakeasy.net>
>
>     Subject: Re: MUSING: standard bodies vs benevolent dictators, popularity
>     Message-ID: <······················@speakeasy.net>
>

Ok. I use it pretty often in LW.  It does exactly that.

Cheers
--
Marco
From: Rob Warnock
Subject: Re: OPFR [was: Re: Road to Clojure...]
Date: 
Message-ID: <bb-dnRsq1aPmgQXUnZ2dnUVZ_tCWnZ2d@speakeasy.net>
Marco Antoniotti  <·······@gmail.com> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) wrote:
| > "OPFR" == "Outer-Parenthesis-Free REPL". It's a meme/pattern/library(?)...
| > ...a command-line reader that wrap a set of parens around whatever the
| > user types and then passes that to EVAL [with some minor tweaks so the
| > most common cases "do the right thing"]. ...
...
| 
| Ok. I use it pretty often in LW.  It does exactly that.
+---------------

Interesting. A couple of questions about the LW version:

- Will it let you continue a line? E.g.,

     opfr> + 1 2 \
	     3 4

     10
     opfr> 

- OPFR tries to guess whether a single symbol on a line is a function
  or a value and "do the right thing". This creates an ambiguity if
  a symbol has both a functional and variable value. OPFR favors the
  functional value, since you can always get the variable value by
  prefixing it with VALUES, e.g.:

      opfr> get-universal-time

      3443692633
      opfr> most-positive-fixnum

      536870911
      opfr> defun foo () "A function value"

      FOO
      opfr> defvar foo "A variable value"

      FOO
      opfr> foo

      "A function value"
      opfr> values foo

      "A variable value"
      opfr> 

  How does LW handle that?

- Because of the previous, one can overload naked keywords as "commands",
  if one likes. OPFR currently uses only :Q (and :QUIT), but others
  could be added easily. Does LW do anything like that?


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Marco Antoniotti
Subject: Re: OPFR [was: Re: Road to Clojure...]
Date: 
Message-ID: <3e932ba6-b4ee-46a1-be82-6e2e8fdcf9ef@k8g2000yqn.googlegroups.com>
On Feb 15, 2:45 pm, ····@rpw3.org (Rob Warnock) wrote:
> Marco Antoniotti  <·······@gmail.com> wrote:
> +---------------
> | ····@rpw3.org (Rob Warnock) wrote:
> | > "OPFR" == "Outer-Parenthesis-Free REPL". It's a meme/pattern/library(?)...
> | > ...a command-line reader that wrap a set of parens around whatever the
> | > user types and then passes that to EVAL [with some minor tweaks so the
> | > most common cases "do the right thing"]. ...
> ...
> |
> | Ok. I use it pretty often in LW.  It does exactly that.
> +---------------
>
> Interesting. A couple of questions about the LW version:
>
> - Will it let you continue a line? E.g.,
>
>      opfr> + 1 2 \
>              3 4
>
>      10
>      opfr>
>
> - OPFR tries to guess whether a single symbol on a line is a function
>   or a value and "do the right thing". This creates an ambiguity if
>   a symbol has both a functional and variable value. OPFR favors the
>   functional value, since you can always get the variable value by
>   prefixing it with VALUES, e.g.:
>
>       opfr> get-universal-time
>
>       3443692633
>       opfr> most-positive-fixnum
>
>       536870911
>       opfr> defun foo () "A function value"
>
>       FOO
>       opfr> defvar foo "A variable value"
>
>       FOO
>       opfr> foo
>
>       "A function value"
>       opfr> values foo
>
>       "A variable value"
>       opfr>
>
>   How does LW handle that?
>
> - Because of the previous, one can overload naked keywords as "commands",
>   if one likes. OPFR currently uses only :Q (and :QUIT), but others
>   could be added easily. Does LW do anything like that?
>

It is not as sophisticated as what you propose....

Cheers
--
Marco
From: =?ISO-8859-15?Q?Andr=E9_Thieme?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn8057$2as$2@news.motzarella.org>
Rob Warnock schrieb:
> Andr� Thieme  <······························@justmail.de> wrote:
> +---------------
> | Marco Antoniotti schrieb:
> | >> In Clojure I would probably do:
> | >> (defn factorial [n] (apply * (range 1 (inc n))))
> | > 
> | > As in
> | >   (defun factorial (n) (apply '* (iota 1 n)))
> | > It isn't very compelling...
> ...
> | The iota function has, no idea, 92 users in the world.
> | Probably 7 who use it regularily.
> | (I don't mean these numbers literally, but I have not seen that anyone
> |   used those, neither in open source, nor in my professional work).
> +---------------
> 
> Then you must not have been reading "comp.lang.lisp" very long. ;-}
> A quick search shows some 170 articles mentioning it, including
> several by me:  ;-}  ;-}

Oh oki, thanks for correcting me!
I am reading c.l.l since early 2003, but it seems I missed those.


Andr�
-- 
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn8i7g01mkl@enews2.newsguy.com>
Rob Warnock wrote:

> ...  I even baked a cake!!  ;-}  ;-}
> 
>     > (format t "~%+~62,,,··@·······@t*~36r ~36r, ··········@t|~%~
>                  | ~{~<|~%| ~1,70:;Candle #~d~>~^, ~
>                  ~:*~[ ~; ~; ~; ~; ~; ~; ~; ~; ~; ~]~}
> |~%+~62,,,··@a~%~%"                  #\+ 29053366 902869993114
> 1004137 (iota 50 1) #\+)

Ruby:

c=proc{|s|puts"|#{s.center(61)}|"};puts s="+#{'-'*61}+"
c["*%s %s, %s!!*"%[25970909,742283400809,1106826].map{|n|n.to_s 35}]
1.step(50,5){|i|c[(i..i+4).map{|n|"Candle #%-3s"%"#{n},"}.join" "]}
puts s

+-------------------------------------------------------------+
|                  *happy birthday, psil!!*                   |
| Candle #1,  Candle #2,  Candle #3,  Candle #4,  Candle #5,  |
| Candle #6,  Candle #7,  Candle #8,  Candle #9,  Candle #10, |
| Candle #11, Candle #12, Candle #13, Candle #14, Candle #15, |
| Candle #16, Candle #17, Candle #18, Candle #19, Candle #20, |
| Candle #21, Candle #22, Candle #23, Candle #24, Candle #25, |
| Candle #26, Candle #27, Candle #28, Candle #29, Candle #30, |
| Candle #31, Candle #32, Candle #33, Candle #34, Candle #35, |
| Candle #36, Candle #37, Candle #38, Candle #39, Candle #40, |
| Candle #41, Candle #42, Candle #43, Candle #44, Candle #45, |
| Candle #46, Candle #47, Candle #48, Candle #49, Candle #50, |
+-------------------------------------------------------------+
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn8k7701og3@enews2.newsguy.com>
William James wrote:

> Rob Warnock wrote:
> 
> > ...  I even baked a cake!!  ;-}  ;-}
> > 
> >     > (format t "~%+~62,,,··@·······@t*~36r ~36r, ··········@t|~%~
> >                  | ~{~<|~%| ~1,70:;Candle #~d~>~^, ~
> >                  ~:*~[ ~; ~; ~; ~; ~; ~; ~; ~; ~; ~]~}
> > > ~%+~62,,,··@a~%~%"                  #\+ 29053366 902869993114
> > 1004137 (iota 50 1) #\+)
> 
> Ruby:
> 
> c=proc{|s|puts"|#{s.center(61)}|"};puts s="+#{'-'*61}+"
> c["*%s %s, %s!!*"%[25970909,742283400809,1106826].map{|n|n.to_s 35}]
> 1.step(50,5){|i|c[(i..i+4).map{|n|"Candle #%-3s"%"#{n},"}.join" "]}
> puts s
> 
> +-------------------------------------------------------------+
> >                   *happy birthday, psil!!*                   |
> >  Candle #1,  Candle #2,  Candle #3,  Candle #4,  Candle #5,  |
> >  Candle #6,  Candle #7,  Candle #8,  Candle #9,  Candle #10, |
> >  Candle #11, Candle #12, Candle #13, Candle #14, Candle #15, |
> >  Candle #16, Candle #17, Candle #18, Candle #19, Candle #20, |
> >  Candle #21, Candle #22, Candle #23, Candle #24, Candle #25, |
> >  Candle #26, Candle #27, Candle #28, Candle #29, Candle #30, |
> >  Candle #31, Candle #32, Candle #33, Candle #34, Candle #35, |
> >  Candle #36, Candle #37, Candle #38, Candle #39, Candle #40, |
> >  Candle #41, Candle #42, Candle #43, Candle #44, Candle #45, |
> >  Candle #46, Candle #47, Candle #48, Candle #49, Candle #50, |
> +-------------------------------------------------------------+

One too many commas.


c=proc{|s|puts"|#{s.sub(/5.,/,"50").center 61}|"};puts s="+#{'-'*61}+"
c["*%s %s, %s!!*"%[25970909,742283400809,1106826].map{|n|n.to_s 35}]
1.step(50,5){|i|c[(i..i+4).map{|n|"Candle #%-3s"%"#{n},"}.join" "]}
puts s

+-------------------------------------------------------------+
|                  *happy birthday, psil!!*                   |
| Candle #1,  Candle #2,  Candle #3,  Candle #4,  Candle #5,  |
| Candle #6,  Candle #7,  Candle #8,  Candle #9,  Candle #10, |
| Candle #11, Candle #12, Candle #13, Candle #14, Candle #15, |
| Candle #16, Candle #17, Candle #18, Candle #19, Candle #20, |
| Candle #21, Candle #22, Candle #23, Candle #24, Candle #25, |
| Candle #26, Candle #27, Candle #28, Candle #29, Candle #30, |
| Candle #31, Candle #32, Candle #33, Candle #34, Candle #35, |
| Candle #36, Candle #37, Candle #38, Candle #39, Candle #40, |
| Candle #41, Candle #42, Candle #43, Candle #44, Candle #45, |
| Candle #46, Candle #47, Candle #48, Candle #49, Candle #50  |
+-------------------------------------------------------------+
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <16f6eb2c-49b4-4e88-8cb6-ff16c6eb00d3@41g2000yqf.googlegroups.com>
Hi!

Thanks everyone for comments, topic is very interesting. I'm looking
at clojure with a great interest, but something scares me.

If I get it right, memoization example does not guarantee that
function being memoized is evaluated one time only for every argument
set. Let it be super expensive. If I want to guarantee that it is
called no more than once in concurrent environment, I need some kind
of exculisive write lock anyway (even if we call it by some other
name :). This can be done rather easy and efficiently with explicit
locks, but I see no good way to do that in clojure. And the only way I
see is to emulate locks with sleep/retry loop. I could do it with
agents instead of atoms, but clients of that memoization facility
would likely need to become agents too.

Also, for production-level memoization, some calls are expensive while
some are cheap, and one should expect a high concurrency, so it is not
always reasonable to store entire memoization table in one atom. If I
do so, retry rate would be very high.

So I need to keep efficient mapping (hash table?) from argument list
to an atom containing calculated value.
Is it possible with clojure?

I can't see what does "must be clear from side effects" mean for
atoms. How would I do tracing of pure functions? Is trace facility
there? May I run some unpure code on trace event?

Thanks
From: Jeffrey Straszheim
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <538f9d9e-0b5e-4692-a668-10ec38bd854f@h20g2000yqn.googlegroups.com>
You are correct about the example.  Keep in mind, however, that the
full body of locks/semaphores/queues and such are available from the
Java side for when you *need* them.

However, in this case, where you have expensive computations you want
to be sure don't get done twice, you can run them using a Clojure
synchonization tool called an Agent.  The code is not much more
complex than that for the Atom.  Also, in a large production system, I
would not keep a single Agent/PersistantHashMap, but have a higher
level of hashing to select among several Agents, all hidden behind a
nice library interface.

Code like this is easy to do in Clojure.

On Feb 16, 4:55 pm, budden <···········@mail.ru> wrote:
> Hi!
>
> Thanks everyone for comments, topic is very interesting. I'm looking
> at clojure with a great interest, but something scares me.
>
> If I get it right, memoization example does not guarantee that
> function being memoized is evaluated one time only for every argument
> set. Let it be super expensive. If I want to guarantee that it is
> called no more than once in concurrent environment, I need some kind
> of exculisive write lock anyway (even if we call it by some other
> name :). This can be done rather easy and efficiently with explicit
> locks, but I see no good way to do that in clojure. And the only way I
> see is to emulate locks with sleep/retry loop. I could do it with
> agents instead of atoms, but clients of that memoization facility
> would likely need to become agents too.
>
> Also, for production-level memoization, some calls are expensive while
> some are cheap, and one should expect a high concurrency, so it is not
> always reasonable to store entire memoization table in one atom. If I
> do so, retry rate would be very high.
>
> So I need to keep efficient mapping (hash table?) from argument list
> to an atom containing calculated value.
> Is it possible with clojure?
>
> I can't see what does "must be clear from side effects" mean for
> atoms. How would I do tracing of pure functions? Is trace facility
> there? May I run some unpure code on trace event?
>
> Thanks
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <9dd97c19-ffd5-49e6-8129-25095db75bb1@33g2000yqm.googlegroups.com>
> You are correct about the example.  Keep in mind, however, that the
> full body of locks/semaphores/queues and such are available from the
> Java side for when you *need* them.
This answer does not satifsy me. Clojure has an integral design and
its
design components are inter-related. I prefer using things that have
good
design from the beginning. Common Lisp have *almost* good design and
that's why
I'm here.

For me, it still seems that locks are missing from clojure MP design.
In general user
always suffer from the destruction of design integrity when he adds
lowlevel workarounds to
the integral (but limited) design. I still see no excuse for not
having locks.

And, for now, I conclude that RDBMS design is better. It is pragmatic
and allows for creating of efficient concurrent and dynamic programs
easily. There are transactions,
locks and even deadlock monitors which guarantee that no process would
hang up indefinitely
in a deadlock situation. Also there are lock monitoring tools. My
practice convinces
me that this approach is useful though RDDBMS sometimes miss other
important things.

> where you have expensive computations you want to be sure don't get done twice, you can
run them using a Clojure synchonization tool called an Agent.

Anyway, client thread which causes computation should be able to know
when the computation
is finished. I see no good way to achieve this. Either I need sleep/
retry loop or my client thread must be an
Agent too which is a limitation. Am I wrong?
From: Rich Hickey
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <3ed05a11-794e-4ea1-9e9a-aa7e349a14b2@k19g2000yqg.googlegroups.com>
On Feb 17, 4:36 am, budden <···········@mail.ru> wrote:
> > You are correct about the example.  Keep in mind, however, that the
> > full body of locks/semaphores/queues and such are available from the
> > Java side for when you *need* them.
>
> This answer does not satifsy me. Clojure has an integral design and
> its
> design components are inter-related. I prefer using things that have
> good
> design from the beginning. Common Lisp have *almost* good design and
> that's why
> I'm here.
>
> For me, it still seems that locks are missing from clojure MP design.
> In general user
> always suffer from the destruction of design integrity when he adds
> lowlevel workarounds to
> the integral (but limited) design. I still see no excuse for not
> having locks.
>
> And, for now, I conclude that RDBMS design is better. It is pragmatic
> and allows for creating of efficient concurrent and dynamic programs
> easily. There are transactions,
> locks and even deadlock monitors which guarantee that no process would
> hang up indefinitely
> in a deadlock situation. Also there are lock monitoring tools. My
> practice convinces
> me that this approach is useful though RDDBMS sometimes miss other
> important things.
>
> > where you have expensive computations you want to be sure don't get done twice, you can
>
> run them using a Clojure synchonization tool called an Agent.
>
> Anyway, client thread which causes computation should be able to know
> when the computation
> is finished. I see no good way to achieve this. Either I need sleep/
> retry loop or my client thread must be an
> Agent too which is a limitation. Am I wrong?

Yes. Clojure has support for locks:

http://clojure.org/api#locking

Rich
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <a06393db-dee9-433b-9e44-3273c18ec781@l39g2000yqn.googlegroups.com>
> Yes. Clojure has support for locks:
> http://clojure.org/api#locking
Thanks, this is much better. This is not a complete locking API, but
that's enough
if we use locking combined with other concurrency tools.

Well. What about storing a hash table of atoms?
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnf5ps$b5s$1@news.motzarella.org>
budden schrieb:
>> Yes. Clojure has support for locks:
>> http://clojure.org/api#locking
> Thanks, this is much better. This is not a complete locking API, but
> that's enough
> if we use locking combined with other concurrency tools.

 From Clojure you can access everything that the JVM offers.
Threads, locks, executors, futures, threadpools, and and and.
Java arrays, Java hashmaps (not threadsafe), Java Hashtables
(threadsafe, but not concurrency ready), Clojure Hashmaps
(concurrency ready), and so on.
The API is more complete than in any CL implementation.

If you come into a situation where you have, say, 20 objects
that need to be changed in one transaction, and you have tons
of threads trying to do that at the same time, then in principle
Clojure could run into a live-lock situation, for this extreme
case.
Here the programmer could establish a lock and make sure all
threads can work off that specific job, instead of using the
mechanism that Clojure made its default.
It�s just that the default is great for nearly all needs and
just works. No trouble, no locks in your code.


 > Well. What about storing a hash table of atoms?

What do you mean by this?
Well, you can have a Java Hashtable and store Clojure Atoms in it.
Or you can just use a Clojure hashmap to store them there:
(def *counters* {:points (atom 0), :energy (atom 100)})


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <b3c0bae3-8b61-4f8a-859b-7a3d1b8a8d4d@h16g2000yqj.googlegroups.com>
> > Well. What about storing a hash table of atoms?
> What do you mean by this?
I mean just a finer granularity of memoization. In fact, I want to
cheat ideology and have a mutable hash table.
For what?
E.g. there is an expensive function. Say, one core calculates it for 1
minute. There are 4 cores available. And there
are 4 clients wanting to calculate. What we do with that memoization
example in tutorial? If we have no locks,
function value for some arguments will be calculated twice. Well, we
use locks. If we lock entire memoization table,
only one calculation can occur at a time and three cores might be
idle.

What is the right decision? Make locks finer. Lock just one set of
arguments. Then, say, client1 and client2 ask f(1). Client1 makes a
lock first on memoization cell f(1) and calculation starts. client2
waits for it to end. Meantime, client3 asks for f(2). This is not
locked, so second core starts to calculate it. This corresponds to a
hashtable full of atoms.

Well, you gave an answer.
(def *counters* {:points (atom 0), :energy (atom 100)})

I'm confused... This is _very_ good for me, but what does term
"immutable" means then?
This hashtable looks like it just isolates mutable parts of itself,
but IMHO it _is_
mutable.
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnff76$ruc$1@news.motzarella.org>
budden schrieb:
>>> Well. What about storing a hash table of atoms?
>> What do you mean by this?
> I mean just a finer granularity of memoization. In fact, I want to
> cheat ideology and have a mutable hash table.
> For what?
> E.g. there is an expensive function. Say, one core calculates it for 1
> minute. There are 4 cores available. And there
> are 4 clients wanting to calculate. What we do with that memoization
> example in tutorial? If we have no locks,
> function value for some arguments will be calculated twice. Well, we
> use locks. If we lock entire memoization table,
> only one calculation can occur at a time and three cores might be
> idle.

It really depends on what your requirements are.
As I understand your example above, you are referring to a recursive
function. So, to calculate (f 200) one needs to calculate (f 1),
(f 2), ...  first.
That is probably what you meant with �some arguments will be
calculated twice�.

What you are talking about is a serial algorithm, as long f is not
memoized. Building up a memoization table in such a scenario isn�t
a parallelizable problem.

So, if each calculation is expensive, and you start many threads at
exactly the same time, and they all either return the memoized value
or begin at (f 1), working their way up then in principle it could
happen what you fear: all n threads (in your example 4) begin to
calculate f1, as this is not in the memo-table yet, and they all
finish at about the same time. One will be lucky to store the result
first in there.
The others learn about this and continue to calculate the next value
(f 2) without storing data in the memo-table.
Thread 1 is slightly ahead, because it was so lucky to be the first
to finish. It will be now first with calculation (f 2), as it could
start a very little bit before the others.
It saves into the memo-table and continues with (f 3). The others
finish calculating (f 2) and realize that the function value for
that already is memoized. They go ahead with (f 3), and so on.
Some time Thread 1 finishes because it calculated (f 50), while
Thread 2 wants to go to (f 55), Thread 3 to (f 60) and thread 4 to
(f 65).
In that scenario this could mean that with Clojures default techniques
for parallelization you effectively run with the speed of just one
CPU core. In more realistic scenarios the amount of duplicated
calculation will be smaller.


> What is the right decision? Make locks finer. Lock just one set of
> arguments. Then, say, client1 and client2 ask f(1). Client1 makes a
> lock first on memoization cell f(1) and calculation starts. client2
> waits for it to end.

So, as long there is a lock for (f 1) it means: all 3 other threads
will have to wait. The same situation as above with Clojure. You are
effectively doing single threaded work.

> Meantime, client3 asks for f(2). This is not locked, so second core
 > starts to calculate it. This corresponds to a hashtable full of atoms.

If (f 2) depends on the result of (f 1) it will have to wait until that
result is available in the memo-table, or until the lock is released.

If (f 2) does not depend on (f 1) then chances are good that your
algorithm is flawed. Why is more than one thread calculating (f 1)?
In such a case your algorithm can be parallelized well:

(pmap deep-calculation (range 50))

This calls the parallel version of map, and independently calculates
it for all 50 args. No need to call (deep-calculation 7) several
times at the same time.

So, if a call to (f n+1) depends on the result of (f n) then you run
that serial task on one core.
Instead of
(pmap deep-calculation [50 55 60 65]) you could do:

(map deep-calculation [50 55 60 65])


> Well, you gave an answer.
> (def *counters* {:points (atom 0), :energy (atom 100)})
> 
> I'm confused... This is _very_ good for me, but what does term
> "immutable" means then?

Clojure is a realistic functional programming language.
Programs without state don�t make too much sense, do they?
Immutability is Clojures default. You will need some little extra
effort to get mutable stuff.
Immutable data does not need to be dereferenced, and it does not need
to be put into transactions, etc.

In my example above the hashmap *counters* is not mutable.
It will always see this hashmap of two keys and values.
Even the values will always be the same atom objects.
What is mutable though is the inner state of the atoms. So, the atoms
are mutable. The can produce different results when you do
(deref (get *counters* :points)).
But the atom objects themselves will always be the same. Also the 
objects which they refer to can not be muted. The 0 and the 100 will
always stay constants. (I assume most people guessed that part).


> This hashtable looks like it just isolates mutable parts of itself,
> but IMHO it _is_ mutable.

I understand the idea behind your opinion, and I can share this opinion
easily. If we both worked on a project together, I would probably tell
you that I �changed� *counters*.
But if someone asks me if I really did that I could tell her:
�No I didn�t, as that is an immutable object�.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <eb24fbd7-c725-46c8-87d2-005cad691b95@b16g2000yqb.googlegroups.com>
> So, to calculate (f 200) one needs to calculate (f 1),
> (f 2), ...  first.
No, I didn't mean that. Sorry that I didn't specify it more
precisely.
Think (f foo) and (f bar). Two threads ask for (f foo) simultaneously
and if we have no locks it will be calculated more than once. We can
avoid that if we lock entire memoization table.

Now consider situation where client1 and client2 ask (f foo) and
client3 asks for (f bar), where (f bar) may be independent on (f
foo).
If we lock entire memoization table, client3 has to wait even if there
are free cores on the host.

To avoid this, we should put locks on memoization cells for foo and
for bar
separatedly, but not on the entire memoization table. That is why I
asked for
hash-table of atoms.

My example is no way artificial. Consider numeric simulations. They
are extremely
expensive, they may be independent and may be dependent, and argument
space is
infinite. Factorial or Fibonacci example is more artificial in fact.

Well, I have to think more about that... For now, it seems that
immutability is too
limiting. I need a general purpose language. Most of my time I'm using
CL as a "scripting" language,
and concurency-related are only about 10% of my activity (excluding
SQL which works well and need
no replacement). So I am an exclusive owner of all my data structures,
and imperative coding style
seems to be more appropriate. So it might turn out that having
immutable stuctures as default is
too expensive for me. I'll need to pay 90% of time for features that I
don't need that 90% of time.

Also, as memoization example (hopefully) shows, concurrency is
inherently
complex thing and no "simple" defaults would deliver from that. This
is a reason for not having
these defaults at all. Let us express simple (concurrency-free) things
in a simple manner and
let us express complex (concurrent) things in a language which is
adequate to their complexity.
That is my style and I see clojure's style is different.

There is still an advantage of immutable data structures over CL. CL
is ignorant vs data sharing.
There is no const declaration in CL, and sharing behavior is
frequently unspecified. So it is very easy to
smash data. Taking this into account, I can't say that CL is "safe"
language as it pretends to be.
Some solution is definitely required here and FP is one of possible
approaches to that.
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnhjmb$onn$1@news.motzarella.org>
budden schrieb:
>> So, to calculate (f 200) one needs to calculate (f 1),
>> (f 2), ...  first.
> No, I didn't mean that. Sorry that I didn't specify it more
> precisely.
> Think (f foo) and (f bar). Two threads ask for (f foo) simultaneously
> and if we have no locks it will be calculated more than once. We can
> avoid that if we lock entire memoization table.

And this locking would do?
Help saving a bit CO2, okay.
But speedwise it would make no difference.
Now instead of calculating it, client-2 will have to wait for the same
amount of time until client-1 finished.
And your scenario seems unlikely in practice.
If users kick of the calculation in the application, then it will not
happen very often that two start such a calculation at the same time.


> Now consider situation where client1 and client2 ask (f foo) and
> client3 asks for (f bar), where (f bar) may be independent on (f
> foo).
> If we lock entire memoization table, client3 has to wait even if there
> are free cores on the host.

Yes, for this specific scenario your idea would help.
As client-2 would be in sleep mode, the OS could run client-3s request
on the same core and fully use it.
With the default of Clojure both clients (1 and 2) would do the same
work and use up two full cores. Now all 3 clients will get their result
a little bit later, while in your scenario all 3 could get their results
around the same time.


> To avoid this, we should put locks on memoization cells for foo and
> for bar separatedly, but not on the entire memoization table.
 > That is why I asked for hash-table of atoms.

What you ask for can be done without much problems in Clojure.
I just think its a very specific task.


> My example is no way artificial. Consider numeric simulations. They
> are extremely expensive, they may be independent and may be dependent,
 > and argument space is infinite. Factorial or Fibonacci example is more
 > artificial in fact.

Your example is not artificial, but it�s specific imo.
At least we know that it can be done without problems in Clojure.


> Also, as memoization example (hopefully) shows, concurrency is
> inherently
> complex thing and no "simple" defaults would deliver from that. This
> is a reason for not having
> these defaults at all. Let us express simple (concurrency-free) things
> in a simple manner and
> let us express complex (concurrent) things in a language which is
> adequate to their complexity.
> That is my style and I see clojure's style is different.

Without even trying it your opinion will always stay a vague idea.
At the moment you seem to be a bit confused about how it actually
feels to work with immutable data, and Clojures refs/agents/vars/atoms.
I suggest you to try it out for some weeks and then see how much you
can use it. If you don�t like it, then you can stop so easily to use it.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <eccfb4c0-3b5e-4a11-a031-e138c9363030@h16g2000yqj.googlegroups.com>
Hi!

> > Think (f foo) and (f bar). Two threads ask for (f foo) simultaneously
> > and if we have no locks it will be calculated more than once. We can
> > avoid that if we lock entire memoization table.
>
> And this locking would do?
> Help saving a bit CO2, okay.
> But speedwise it would make no difference.
I'm afraid it would make significant difference anyway. If functions
are expensive and
calculations are frequent, my approach (mutable hashtable of lockable
per-argument-set cells)
is N times faster until everything is memoized compared to your atoms
example, where
N is an average number of concurrent requests "pending". In this case,
N=3 and my code would be 3 times
faster. This does not depend on number of cores. It is also N times
less memory-consuming
(provided that calculation allocates many memory).

> Now instead of calculating it, client-2 will have to wait for the same
> amount of time until client-1 finished.
> And your scenario seems unlikely in practice.
This scenario is likely with memoization in a concurrent environment
and it is very
general when we use caching instead of memoization so that fresh
calculations would always occur
from time to time. Consider rendering earth maps on web server as an
example of that. Maps
are relatively expensive, they are partially dependent, they change
(no memoization is possible)
and there is a concurrent access.

If we would generally talk about immutability, it costs. I'm known
with immutability idea of FP
long enough and I never found it useful. For me, it costs more than it
helps. When it goes to clojure,
first of all, if I get it right, I can't print atoms readably and this
is extremely expensive. Also, 90% of
time I'm not interested to know what parts of my mutable structure are
immutable to watch at the
mutable/immutable parts boundaries in the printed representation.

So, to convince myself to use clojure, I need at least a way to
redefine a reader so that I could use {} for
my own (mutable) structures. This way clojure would be just a lispy
syntax and dynamic environment for Java which is
very good already and which is what I'm looking for.
From: Raffael Cavallaro
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnjqto$1hi$1@aioe.org>
On 2009-02-19 06:38:18 -0500, budden <···········@mail.ru> said:

> So, to convince myself to use clojure, I need at least a way to
> redefine a reader so that I could use {} for
> my own (mutable) structures.

Unsurprisingly, clojure, like common lisp, fails to rise to the high 
standards of the budden.

Color me shocked.

-- 
Raffael Cavallaro, Ph.D.
From: Dimiter "malkia" Stanev
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnkd6i$n34$1@malkia.motzarella.org>
What you talkin, reminds of the old days of Computer Graphics.

For example the Star Control II game, used to take care of not redrawing 
everything on the screen, but only where the sprites have changed. This 
was done, because frame access was slow.

Nowadays any modern game redraws every frame 60fps, without keeping the 
old data (ok... certain effects might use it, but usually not done in 
general).

Now think why modern 3D games went with this "functional" approach where 
they recreate the buffer data everytime, rather than what old sprite 
games were doing?
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnkj2o$phd$1@news.motzarella.org>
Dimiter "malkia" Stanev schrieb:
> What you talkin, reminds of the old days of Computer Graphics.
> 
> For example the Star Control II game, used to take care of not redrawing 
> everything on the screen, but only where the sprites have changed. This 
> was done, because frame access was slow.
> 
> Nowadays any modern game redraws every frame 60fps, without keeping the 
> old data (ok... certain effects might use it, but usually not done in 
> general).
> 
> Now think why modern 3D games went with this "functional" approach where 
> they recreate the buffer data everytime, rather than what old sprite 
> games were doing?

About this recreating the buffer data everytime compared to functional
programming: it really looks *as if* those implementations of functional
languages recreated every time.
But all modern implementations use some magic under the hood that will
in reality do modify existing datastructures.
We don�t want to have a 300 MB Hashmap and "add" an element to it, and
then having that beast really needing to copy everything...
After it was added it will look as if it is a fresh new object.
Hickey did some nice wizardry with the tries.
Even when some threads are currently changing a collection then other
threads can get a concurrency safe snapshot of the contents, and thanks
to MVCC continue to work with it!
MVCC can make it look like as if there were 15 of those 900 MB Vectors
in your 2gigs of Ram at the same time.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnkiib$i9p$1@news.motzarella.org>
budden schrieb:
> Hi!
> 
>>> Think (f foo) and (f bar). Two threads ask for (f foo) simultaneously
>>> and if we have no locks it will be calculated more than once. We can
>>> avoid that if we lock entire memoization table.
>> And this locking would do?
>> Help saving a bit CO2, okay.
>> But speedwise it would make no difference.
> I'm afraid it would make significant difference anyway. If functions
> are expensive and
> calculations are frequent, my approach (mutable hashtable of lockable
> per-argument-set cells)
> is N times faster until everything is memoized

How can it be faster when all the threads that are locked have to wait
until the calculating thread finished?
4 clients call (f foo) --> 1 runs f, 3 wait until it is finished.
Great, we just made a quadcore machine effectively singlecore.


(defn f [arg]
   (with-lock arg
     (if (in-memo? arg)
       (get-memo-for arg)
       (let [result (deep-calculation arg)]
         (memoize arg result)
         result))))

Thread 1 will get the lock, and in-memo? is false for arg.
The other 3 threads will sleep in the with-lock until thread 1 has
finished. Then one of the 3 will get the lock and go into the if which
sees that now arg is already memoized. They can return the memoized result.
Then one of the remaining two will get the lock and also return the
memoized result. And then the last thread gets the lock and also returns
the result.
No 3x increase in speed.


> If we would generally talk about immutability, it costs. I'm known
> with immutability idea of FP long enough and I never found it useful.
 > For me, it costs more than it helps.

If you do everything in one thread then yes, Clojure will perform worse
if you use its immutable data structures. No one forces you to do so,
you could simply use these very fast mutable ones that are included in
the JVM.
But of course we see that quad-core cpus cost 115�.
This year we will have 6-core and maybe also octa-core CPUs. For next
year 12 cores are coming. In two years Intel will ship its 80-core
server cpu. Have a dual 80-core box and enjoy the 160 cores :)

If you want to use them then you are facing some problems with mutable
data structures. Locks bring you back to single-core land.
Clojures semi-optimistic STM with MVCC and immutable data structures
however let you solve such tasks way easier. Safety built in.


> When it goes to clojure,
> first of all, if I get it right, I can't print atoms readably

Right to some extent:
user=> (atom 0)
#<····@84cc09: 0>

The issue here is your current level of understanding about this issue.
If you say (def counter (atom 0)) then you are not supposed to
(print counter) but instead use (deref counter), or comfortably the
built in reader macro @
So (+ 2 @counter) ==> 2


 > and this is extremely expensive.

<sarcasm>
Yes, it�s true.

user=> (def x @(atom "budden"))

user=> (time (dotimes [i 1000]))
"Elapsed time: 0.305359 msecs"

user=> (time (dotimes [i 1000] @x))
"Elapsed time: 0.638292 msecs"

So, an empty dotimes runs 305 microseconds.
That means we can subtract that from the 638 microseconds from the
second dotimes in which we are doing the deref.
Leaves us with 1000 derefs in 0.332933 msecs.
It means you can deref an atom only 3 million times per second and
core on my slow mobile CPU. This is really *extremly* expensive for
concurrency safe reads. Yeah.
</sarcasm>

I think you should really try out Clojure. You seem to have nice plans,
but currently simply not looked deeply enough into it, to see that it
could be better than you think.


> Also, 90% of
> time I'm not interested to know what parts of my mutable structure are
> immutable to watch at the
> mutable/immutable parts boundaries in the printed representation.

Use the @.


> So, to convince myself to use clojure, I need at least a way to
> redefine a reader so that I could use {} for
> my own (mutable) structures. This way clojure would be just a lispy
> syntax and dynamic environment for Java which is
> very good already and which is what I'm looking for.

You can download the sources of Clojure and in probably 1-3 days you
can have [] for Java arrays and {} for Java hashmaps.
But you can also define a new class in Clojure that you build upon the
built in ones.
Then you could say:
user=> (mutable-hashmap :a 10, :b 20, :c 30)
{:a 10, :b 20, :c 30}

This would give you of course just a printed representation.
Anyway, before you are so sceptical about Clojure, I can suggest you to
simply try out some of your ideas. With the built in Clojure data
structures. Only then you will find out if you like it.
Have you already seen some of the Clojure movies?
Try  http://blip.tv/file/812787


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Phil Armitage
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <8a5c6da7-25f6-4b51-9f5b-df37b63f00b1@x10g2000yqk.googlegroups.com>
On Feb 19, 9:22 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:

> But of course we see that quad-core cpus cost 115€.
> This year we will have 6-core and maybe also octa-core CPUs. For next
> year 12 cores are coming. In two years Intel will ship its 80-core
> server cpu. Have a dual 80-core box and enjoy the 160 cores :)
>
> If you want to use them then you are facing some problems with mutable
> data structures. Locks bring you back to single-core land.
> Clojures semi-optimistic STM with MVCC and immutable data structures
> however let you solve such tasks way easier. Safety built in.

This is just my opinion which may turn out to be embarrassing in a few
years time but it seems that some people are getting quite worked up
about the need to keep all those cores busy with one instance of a
program.

If I have 160 cores in my computer then I'm going to be running more
than one program on it at a time! Workstations running consumer OS'
already run many processes and high performance server programs could
be designed as multiple instances thereby gaining not only in
performance and scalability but also from fail-over, redundancy and
stability.

Some of us are already writing our software this way rather than
betting everything on single applications that soak up every cycle of
every core using as yet unproven technologies.

I'm obviously not saying that all programs should have just one thread
of execution, but rather that not that many programs need hundreds
(and yes, you can come up with examples that do but there are many
orders of magnitude more that don't).

--
Phil
http://phil.nullable.eu/
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnkoqt$t2b$1@news.motzarella.org>
Phil Armitage schrieb:
> On Feb 19, 9:22 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
> 
>> But of course we see that quad-core cpus cost 115�.
>> This year we will have 6-core and maybe also octa-core CPUs. For next
>> year 12 cores are coming. In two years Intel will ship its 80-core
>> server cpu. Have a dual 80-core box and enjoy the 160 cores :)
>>
>> If you want to use them then you are facing some problems with mutable
>> data structures. Locks bring you back to single-core land.
>> Clojures semi-optimistic STM with MVCC and immutable data structures
>> however let you solve such tasks way easier. Safety built in.
> 
> This is just my opinion which may turn out to be embarrassing in a few
> years time but it seems that some people are getting quite worked up
> about the need to keep all those cores busy with one instance of a
> program.
> 
> If I have 160 cores in my computer then I'm going to be running more
> than one program on it at a time! Workstations running consumer OS'
> already run many processes and high performance server programs could
> be designed as multiple instances thereby gaining not only in
> performance and scalability but also from fail-over, redundancy and
> stability.
> 
> Some of us are already writing our software this way rather than
> betting everything on single applications that soak up every cycle of
> every core using as yet unproven technologies.
> 
> I'm obviously not saying that all programs should have just one thread
> of execution, but rather that not that many programs need hundreds
> (and yes, you can come up with examples that do but there are many
> orders of magnitude more that don't).

I agree with you on most points.
Out of the set of 80% of the most widely used programs tons of cores are
not needed. Even with 2-4 probably most of those 80% run quite well.
The cores help to improve the user feeling when running more programs.

One thing that is very possible though is that many programs could
profit from massive parallelism for some parts of their code base.
Enough applications ship with some kind of search. If you have 8000
emails in your mail software and want to search for one then you could
profit if 80 cores each have to search inside max 100 mails.
I keep the default setting of 90 days history in my firefox.
Ctrl+Shift+h should bring up the full history and make it searchable.
Firefox gets very very slow on my Dual-Core Notebook.
Letting each of my 13 tabs in Firefox run on their own core may also
help a little to further improve my user experience.

Clojure allows you to write much more parts in your software in a way,
such that they can run in parallel. Without these features you would
not even have cared about putting those things into their own threads.
But with the Clojure system your software will automatically adopt to
how many cores are available.


I personally have an interest that is one of those exceptional cases
that you mentioned, and that is Genetic Programming (and AI in general).
Honestly, I could easily use 100% CPU power of a Billion-Core CPU system
and still wish to have more cores.

The real need for that kind of systems lies in my opinion in an upcoming
Matrix and in AI systems.
When our software will typically be enabled to learn, and get its own
neural network, then we want to run several parts of these brains in
parallel.
Human brains are the most massive parallel computers we know. They have
vastly more powerful capabilities than we find it todays software.
Looking at the human brain tells us, that parallelism is good for thinking.
Both work very well together. And that is going to happen IMO with our
computers as well. We will expect to have conversations with our
computers, and we would maybe like to hear their opinion about a new
movie, etc.
These pieces of software will become (in the future) our new main
applications. Not Word, Thunderbird and Firefox anymore.

And about this Matrix stuff:
Even today some nice successes can be found in the area of Retina Displays.
They could be very well become cheap enough around 2015 for private
persons. As I see it, Retina Displays will become the major plattform
for visual information. Everyone wants to have his RD in his glasses,
and a few years later in his contact lenses available everywhere.
We will expect from our mobile phones/computers to have much more
computational power than todays top systems. Because we want to be
able to fill our complete field of sight with visual 3d information
that must look extremly realistic. Hopefully indistinguishable from
�reality� ;)

Those upcoming applications will replace a lot of the software that
is most widely used today.
Yes I know, this all was a bit philosophical, and not all of this
will be here in the next 3 years (and some of it may never become
reality, but who knows?), but those �Centurion-CPUs� (100 cores)
each running on 140 GHz are also still some years away.

But again back to the top: I think it is fair to say that many
typical applications which we write today can load their work for
peaks to many CPUs. So, the cores can help to make those peaks nicer.
And server side software that needs to deal with hundreds of users
at the same time... obvious.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal J. Bourguignon
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <87zlghin0m.fsf@galatea.local>
Andr� Thieme <······························@justmail.de> writes:
> One thing that is very possible though is that many programs could
> profit from massive parallelism for some parts of their code base.
> Enough applications ship with some kind of search. If you have 8000
> emails in your mail software and want to search for one then you could
> profit if 80 cores each have to search inside max 100 mails.

*IF* you have 80 hard disks with 80 buses.


If you have only 8000 mails, it won't make a difference whether you
search inside 8000 or inside 100.  If you have more, then the
bottleneck won't be the processor time, it'll be I/O as it has always
been and keeps being worse every day (relatively to processor speed).


On servers of course cores will be useful.

On desktop, well everytime I type ps ax  I only see most processes
sleeping so my computer wouldn't go faster with 80 cores.

I see only one application of 80 cores: GAMES
      (physics simulation, 3D rendering, AI).

-- 
__Pascal Bourguignon__
From: Kojak
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <20090220090721.36ae69c2@thor.janville.org>
Le Fri, 20 Feb 2009 08:30:01 +0100,
Pascal J. Bourguignon a écrit :

> I see only one application of 80 cores: GAMES
>       (physics simulation, 3D rendering, AI).

Hey, and compilation with "make -j 80" ! No ?  :-D

-- 
Jacques.
From: Andrew Reilly
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <70793eFmigkdU2@mid.individual.net>
On Fri, 20 Feb 2009 09:07:21 +0100, Kojak wrote:

> Le Fri, 20 Feb 2009 08:30:01 +0100,
> Pascal J. Bourguignon a écrit :
> 
>> I see only one application of 80 cores: GAMES
>>       (physics simulation, 3D rendering, AI).
> 
> Hey, and compilation with "make -j 80" ! No ?  :-D


Perhaps with SCons.  Anecdotally, most OS-style projects see make -j top 
out at around eight processors, I think.  Make (well, current versions) 
doesn't build parallel tasks down into sub-makes, I think, so there are 
frequent single-threaded bottlenecks.

Cheers,

-- 
Andrew
From: Kojak
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <20090220103209.7291d64b@thor.janville.org>
Le 20 Feb 2009 08:48:47 GMT,
Andrew Reilly a écrit :

> On Fri, 20 Feb 2009 09:07:21 +0100, Kojak wrote:
> > Hey, and compilation with "make -j 80" ! No ?  :-D
> 
> Perhaps with SCons.  Anecdotally, most OS-style projects see make -j
> top out at around eight processors, I think.  Make (well, current
> versions) doesn't build parallel tasks down into sub-makes, I think,
> so there are frequent single-threaded bottlenecks.

Yes, indeed, it seems that actually "make" have some headache with
parallel build. That said, it's hoped that this kind of problem will
quickly be solved when we all have 80+ cores computer on hand... :-)

-- 
Jacques.
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <bda6c702-05c6-4fe2-9e54-5ae896a40009@33g2000yqm.googlegroups.com>
> How can it be faster when all the threads
> that are locked have to wait
> until the calculating thread finished?
It can and it is. I have estimated gain
incorrectly as I didn't understand comple-
tely how the example works, but I still
have some essential gain with locking.
You can run this for yourself and see
the difference (my computer is single-core)

(import '(java.util.concurrent Executors))

(defn memoize1 [f]
   (let [mem (atom {})]
    (fn [& args]
;     (locking :what-can-we-lock?
      (if-let [e (find @mem args)]
        (val e)
        (let [ret (apply f args)]
          (swap! mem assoc args ret)
          ret)))))
;     )

(defn expensive [arg]
 (println `(:starting :with ~arg))
 (dotimes [i 1000000000])
 (println `(:done :with ~arg))
 arg)

(def expensive-m (memoize1 expensive))

(defn test-memo []
  (let [pool  (Executors/newFixedThreadPool 3)
        tasks
         (list (fn []
                (. Thread sleep 1)
                (expensive-m :a))
               (fn []
                (. Thread sleep 100)
                (expensive-m :a))
               (fn []
                (. Thread sleep 200)
                (expensive-m :b)))]
    (doseq [future (.invokeAll pool tasks)]
      (.get future))
    (.shutdown pool)
    ))

(time (test-memo))
Initially it prints:
user=> (load-file "d:/clojure/memo.cj.txt")
(:starting :with :a)
(:starting :with :a)
(:starting :with :b)
(:done :with :b)
(:done :with :a)
(:done :with :a)
"Elapsed time: 5697.388355 msecs"
nil
When you uncomment two lines that
are commented out, you'll get
blocking and see:
user=> (load-file "d:/clojure/memo.cj.txt")
(:starting :with :a)
(:done :with :a)
(:starting :with :b)
(:done :with :b)
"Elapsed time: 4359.851043 msecs"
nil

You see, with locking we have made 1.5
times less calculations even w/o finer
grained locking, as we avoided unnecessary
double calculation of (expansive :a). So,
regardless of architecture, we produced 1.5
times less CO2.
Under heavy load this would be essential.
Try also to replace

(locking :what-can-we-lock?

with

(locking (first args)

and you'll might see better performance on
multiple cores (if threads would be really
distributed to two cores).

> Right to some extent:
>user=> (atom 0)
>#<····@84cc09: 0>
>
>The issue here is your current level
> of understanding about this issue.
>If you say (def counter (atom 0))
> then you are not supposed to
>(print counter) but instead use
>(deref counter), or comfortably the
>built in reader macro @

I think issue is your current
level of understanding of lisp :)

In a lisp, I can print-readably many
kinds of objects and this is useful,
e.g. to save for future session or
for passing to other application via
stream (think of SLIME). If I can't
print them readably "from the box", I
can modify printer/reader to do so. I
also didn't mention #= and *print-circle*
in common lisp. I know no other language
which allows for so simple and flexible
serialization. I use #= very seldom, but
its absence is hard to work around.
What you suggest is not a substitution
of that print-readably feature.

> You can download the sources of
> Clojure and in probably 1-3 days you
>can have [] for Java arrays and {}
> for Java hashmaps. But you can also
> define a new class in Clojure that you
> build upon the
>built in ones.
>Then you could say:
>user=> (mutable-hashmap :a 10, :b 20, :c 30)
>{:a 10, :b 20, :c 30}

Ok, thanks, that's fine. I think I'll take
a look. My first clojure code left me
felt satisfied. It is not as verbose as
CL and that's fine.
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnkvq0$tv4$1@news.motzarella.org>
Hi budden.


budden schrieb:
>> How can it be faster when all the threads
>> that are locked have to wait
>> until the calculating thread finished?
> It can and it is.

I don�t believe it. At least not for the scenario that I mentioned in my
previous posting: running 4 calls with the same arg at the same time.


 > I have estimated gain
> incorrectly as I didn't understand comple-
> tely how the example works, but I still
> have some essential gain with locking.
> You can run this for yourself and see
> the difference (my computer is single-core)

I tested your code on my dual core notebook
(both cores clocked down to 50%, but both usable)




> (import '(java.util.concurrent Executors))
> 
> (defn memoize1 [f]
>    (let [mem (atom {})]
>     (fn [& args]
> ;     (locking :what-can-we-lock?
>       (if-let [e (find @mem args)]
>         (val e)
>         (let [ret (apply f args)]
>           (swap! mem assoc args ret)
>           ret)))))
> ;     )

Instead of (find @mem args) you can say  (@mem args)
And instead of (val e) just e if you removed the find.
Find is useful if you want a key/value pair.
Otherwise you can use get.  (get map key) ==> value
or (get map key default) ==> either value or default if
key does not exist.
But here we use the nice Clojure syntax:
(collection key) ==> value
Example:
([10 20 30 40 50] 2) ==> 30
because index 0 ==> 10, index 1 ==> 20, index 2 ==> 30
or
({"key 1" "val 1", :key2 "val 2"} "key 1") ==> "val 1"



> (defn expensive [arg]
>  (println `(:starting :with ~arg))
>  (dotimes [i 1000000000])
>  (println `(:done :with ~arg))
>  arg)

You don�t need the backquote and ~
(println [:starting :with arg])  is also fine.
But much better is: (println "Starting with" arg)

Okay, the dotimes is causing load on the CPU, right.
In principle one could let the thread sleep here for
simulating a slow calculation, but in fact I like your idea
here, as the load helps us to see how my dual core system
performs.



> (def expensive-m (memoize1 expensive))
> 
> (defn test-memo []
>   (let [pool  (Executors/newFixedThreadPool 3)
>         tasks
>          (list (fn []
>                 (. Thread sleep 1)
>                 (expensive-m :a))
>                (fn []
>                 (. Thread sleep 100)
>                 (expensive-m :a))
>                (fn []
>                 (. Thread sleep 200)
>                 (expensive-m :b)))]
>     (doseq [future (.invokeAll pool tasks)]
>       (.get future))
>     (.shutdown pool)
>     ))

The two closing parens in the last line should really go one line up.
The typical way for calling static methods such as sleep is:
(Thread/sleep 100)

But besides that, you may be using an older Clojure version.
Clojure does support futures.
You could simply say:
(future
   (Thread/sleep 100)
   (expensive-m :a))

No need for your import at the top, no need for your pool, no need
for shutting it down, etc.
What you did is good and shows that you can use all those constructs.
I just mean that it would not be needed in a more recent version of
Clojure. All that work is done in background for you, with default
settings that make sense.
If you don�t like the defaults then of course you can always do it
as you showed above. Otherwise:

(defn test-memo2 []
   (doseq [f [(future (expensive-m :a))
              (future (expensive-m :a))
              (future (expensive-m :b))]]
     (.get f)))

or even

(defn test-memo3 []
   (doseq [f (map #(future (expensive-m %)) [:a :a :b])]
     (.get f)))


> (time (test-memo))
> Initially it prints:
> user=> (load-file "d:/clojure/memo.cj.txt")
> (:starting :with :a)
> (:starting :with :a)
> (:starting :with :b)
> (:done :with :b)
> (:done :with :a)
> (:done :with :a)
> "Elapsed time: 5697.388355 msecs"
> nil

Ooh, either you have an extremly old machine or, much more likely, you
are running inside a client JVM.
Okay, let me use a client as well. My compi is a bit faster.
Here with the commented out lines, so, without locking:

user=> (load-file "/path/memo-test.clj")
Starting with :a
Starting with :a
Starting with :b
(:done :with :a)
(:done :with :a)
(:done :with :b)
"Elapsed time: 2481.83177 msecs"

I tried this 5 times in a row, and always got timings around that area.
When I looked into the windows task manager, then I saw 100% CPU usage
for a second or so.


> When you uncomment two lines that
> are commented out, you'll get
> blocking and see:
> user=> (load-file "d:/clojure/memo.cj.txt")
> (:starting :with :a)
> (:done :with :a)
> (:starting :with :b)
> (:done :with :b)
> "Elapsed time: 4359.851043 msecs"

Ok, I put the two lines in, which means now locks were used.
Again, I ran this 5 times in a row and always got similar timings:
user=> (load-file "/path/memo-test.clj")
Starting with :a
(:done :with :a)
Starting with :b
(:done :with :b)
"Elapsed time: 2918.423081 msecs"

On my dual core system the code without locks runs 17.5% faster.

The results in the server VM are practically identical, with locks and
without:

user=> (load-file "/path/memo-test.clj")
Starting with :a
(:done :with :a)
Starting with :b
(:done :with :b)
"Elapsed time: 204.583753 msecs"


The dotimes does run just 4 msecs in the server vm, vs 2150 msecs in the
client vm.
These 200 msecs in there come from your (Thread/sleep 200).


> You see, with locking we have made 1.5
> times less calculations even w/o finer
> grained locking, as we avoided unnecessary
> double calculation of (expansive :a). So,
> regardless of architecture, we produced 1.5
> times less CO2.

No, when I look at your timings I get:
user=> (/ 5967.38 4359.85)
1.368712226338062

So, just 36% less time needed for you, not 50%.
And one can maybe explain this with the one core that you have.
Although it would be strange that the threading overhead really
costs so much. Are you sure you got the near 6 seconds with the
(locking :what-can-we-lock? ...) or was it the more granular one?
Anyway, on my computer the version without locking is 17,5% faster
in a client VM.


> Under heavy load this would be essential.

Yes.


> Try also to replace
> 
> (locking :what-can-we-lock?
> 
> with
> 
> (locking (first args)
> 
> and you'll might see better performance on
> multiple cores (if threads would be really
> distributed to two cores).

Yes, of course the program from above runs faster with this
granular locking.
This was explained in one of my previous postings, where I agreed to
you that some gains are possible, because the threads waiting in the
lock don�t need CPU ressources. Now other threads can run.
In your example we have three threads running.
2x for :a  and 1x for :b.
With your granular locks one thread for :a would use one of my cores
to 100%. The second :a thread is sleeping, needing practically zero
ressources. And the third thread, the one for :b can run on my second
core at 100%.
That�s why we gain speed.
But what I stated was that if we run 4x with the argument of :a.
And indeed, on my compi this gave me a timing of around 1470 msecs,
regardless if with a general lock, or with your granular lock, or with
no locks at all, using default Clojure behaviour.

So, to summarize it:
I agree with you that if you *really* have so specific needs that you
have to run expensive referentially transparent functions several times
at the same time, then your granular locking can help, as long you have
other threads running which can use the CPU that are currently not
touched by your locked threads.
At the same time I say that I find this is a specific need. Usually one
does not have to call side-effect free functions more than one time, if
one wants to memoize them.
Example:
(defn test-memo3 []
   (doseq [f (pmap #(future (expensive-m %)) [:x :y])]
     (.get f)))

Note the use of pmap vs map.
Our argument list is just [:x :y], but it could contain 30 more values.
Each thing runs in its own thread, and typically also on its own core.
 From then on a call to your memoized function is just a fast lookup.
That case I guess is way more typical for most apps. Maybe not for what
you need. But anyway, you managed to do what you want with your granular
locks very well!


> Ok, thanks, that's fine. I think I'll take
> a look. My first clojure code left me
> felt satisfied. It is not as verbose as
> CL and that's fine.

Yeah, grats to your code! If that was your first try, then it was more
exciting than mine was :)
I am glad that you actually sat down and *did* something. Others here in
c.l.l. just like to bash Clojure (out of religious feelings for CL) and
explain why it isn�t needed and why it doesn�t work, without having
even tried it.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnl09c$2lf$1@news.motzarella.org>
budden schrieb:
> (import '(java.util.concurrent Executors))
> 
> (defn memoize1 [f]
>    (let [mem (atom {})]
>     (fn [& args]
> ;     (locking :what-can-we-lock?
>       (if-let [e (find @mem args)]
>         (val e)
>         (let [ret (apply f args)]
>           (swap! mem assoc args ret)
>           ret)))))
> ;     )
> 
> (defn expensive [arg]
>  (println `(:starting :with ~arg))
>  (dotimes [i 1000000000])
>  (println `(:done :with ~arg))
>  arg)
> 
> (def expensive-m (memoize1 expensive))
> 
> (defn test-memo []
>   (let [pool  (Executors/newFixedThreadPool 3)
>         tasks
>          (list (fn []
>                 (. Thread sleep 1)
>                 (expensive-m :a))
>                (fn []
>                 (. Thread sleep 100)
>                 (expensive-m :a))
>                (fn []
>                 (. Thread sleep 200)
>                 (expensive-m :b)))]
>     (doseq [future (.invokeAll pool tasks)]
>       (.get future))
>     (.shutdown pool)
>     ))
> 
> (time (test-memo))

Ah, I forgot the full code in my other post:

(defn expensive [arg]
   (println "Starting with" arg)
   (dotimes [i 1000000000])
   (println "Done with" arg)
   arg)

(def expensive-m (memoize expensive))

(defn test-memo []
   (doseq [f (pmap #(future (expensive-m %)) [:a :b :c])]
     (.get f)))

(time (test-memo))


memoize, pmap and future come with Clojure (from the SVN).


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <5cfee35b-187a-47ea-999c-3e25494f4cbf@c12g2000yqj.googlegroups.com>
Hi André, list!

> Ah, I forgot the full code in my other post:
>
> (defn expensive [arg]
>    (println "Starting with" arg)
>    (dotimes [i 1000000000])
>    (println "Done with" arg)
>    arg)
>
> (def expensive-m (memoize expensive))
>
> (defn test-memo []
>    (doseq [f (pmap #(future (expensive-m %)) [:a :b :c])]
>      (.get f)))
>
> (time (test-memo))
>
> memoize, pmap and future come with Clojure (from the SVN).
Thanks for code clarification. I have just combined examples
from the documentation to get what I've posted so it was
really far from perfect.

I got near 5.7 seconds with concurrent execution (no locks)
With locks I get around 4.4, regardless of granularity
(granular was slower as threading costs, don't remember exact
number).
All this is no wonder on single-core machine.

But let me undreline again that we have 1.5 times less calculations
with locking: we evaluate (expensive :a) one time with locking
and two times w/o locking. Second calculation of (expensive :a) is
unnecessary and it can't be avoided here without locking.
Regardless of number of cores, it is better to run expensive
calculation 2 times than 3 times. It is incorrect to assume that
we are unlimited in CPU (unless we're selling hardware :)

With four (expensive :a) requests and no locks we calculate
it four times. We produce 4x of CO2 and use 4x of CPU.
So, conclusion:

"no locking" might waste CPU on concurrent access and it can use free
cores.
"general locking" minimzes CPU and it fails to use free cores.
"granular locking" minimizes CPU and it can use free cores.
-----------------------
totally: granular locking is the best of all three
approaches for memoization of expensive functions in a
concurrent environment.

I'd be glad if you admit this fact finally as I have
wasted lot of time making this example and writing here
(and even had to learn new programming
language). I want my effort be rewarded :)
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnotd9$f8p$1@news.motzarella.org>
budden schrieb:
> Hi Andr�, list!
> 
>> Ah, I forgot the full code in my other post:
>>
>> (defn expensive [arg]
>>    (println "Starting with" arg)
>>    (dotimes [i 1000000000])
>>    (println "Done with" arg)
>>    arg)
>>
>> (def expensive-m (memoize expensive))
>>
>> (defn test-memo []
>>    (doseq [f (pmap #(future (expensive-m %)) [:a :b :c])]
>>      (.get f)))
>>
>> (time (test-memo))
>>
>> memoize, pmap and future come with Clojure (from the SVN).
> Thanks for code clarification. I have just combined examples
> from the documentation to get what I've posted so it was
> really far from perfect.
> 
> I got near 5.7 seconds with concurrent execution (no locks)
> With locks I get around 4.4, regardless of granularity
> (granular was slower as threading costs, don't remember exact
> number).
> All this is no wonder on single-core machine.
> 
> But let me undreline again that we have 1.5 times less calculations
> with locking: we evaluate (expensive :a) one time with locking
> and two times w/o locking. Second calculation of (expensive :a) is
> unnecessary and it can't be avoided here without locking.

Yes, it�s true. The locking will not make it any bit faster to
calculate (expensive :a) if it starts off n times at the same time,
but it will reduce the amount of calculations done on :a.


> Regardless of number of cores, it is better to run expensive
> calculation 2 times than 3 times.

This is not always true.
If your program typically is doing 99% of different calculations,
then it can be faster to simply run them as soon they show up in
the code and live with the 1% of wasted cycles.
But in that case the code will be more clear, contain no locks and
can even run faster because less work needs to be done (no locking
mechanism, which would run in your code).



> With four (expensive :a) requests and no locks we calculate
> it four times. We produce 4x of CO2 and use 4x of CPU.

Right, locks can help in this scenario to protect the environment.
And you can use them so easily in Clojure.


> So, conclusion:
> 
> "no locking" might waste CPU on concurrent access and it can use free
> cores.

Right, it might do that. But it might also save CPU cycles in other
scenarios, and no locking makes programs less complex and easier
maintainable.
Each time the other programmers in your company stumble upon your locks
they will have to understand why they were needed.
You will need meetings to discuss the places why and where you put
locks into the code, etc.


> "general locking" minimzes CPU and it fails to use free cores.
> "granular locking" minimizes CPU and it can use free cores.

Both kinds of locking also reduce readability and increase the
complexity of your code.
What you said about failing and not failing to use free cores
needs a bit more explanation.
When a thread is waiting for a lock, then it will fail to use
free cores in both cases.
The only advantage that a lock brings is, that it will not waste
CPU cycles, so completely independend threads car run their tasks
on free cores.
However, we should also mention that this kind of behaviour is
highly untypical for most programs. More about it in my next
paragraph.


> -----------------------
> totally: granular locking is the best of all three
> approaches for memoization of expensive functions in a
> concurrent environment.
> 
> I'd be glad if you admit this fact finally as I have
> wasted lot of time making this example and writing here
> (and even had to learn new programming
> language). I want my effort be rewarded :)

I already admitted it some postings before:
in the scenario where you have an expensive functions that you want
to memoize, and which you want to call several times at the same time
with the same arguments (however unrealistic that might be), then your
idea of granular locking will mean that your code can run more efficient
because the locked threads don�t eat CPU, and others that happen to do
something else than calculating (foo 10) have ressources which they can
use.

Depending on your application it can be a good idea to have a memoize
function that supports granular locking.
I agree with you.

Just allow me to state my opinion, that I don�t think this is generally
a realistic situation.
If we have a web application with hundreds of users that each can kick
of expensive calculations from time to time then it�s possible that a
few times user A and B click nearly at the same time their mouse button
to run the same thing. But in a complex environment that part of the
program will only make a few percent of the whole thing, and out of
those few percent the unlikely case need to occur that several people
work on the same stuff at exactly the same time.

For nearly all applications this sounds like premature optimization IMO.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: budden
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4c078c36-3fcf-41d6-b19a-311d3420d048@p13g2000yqc.googlegroups.com>
Hi André, list!

Thanks, André.

> This is not always true.
> If your program typically is doing 99% of different calculations,
> then it can be faster to simply run them as soon they show up in
> the code and live with the 1% of wasted cycles.
Agree. My example was not to show best practice for all cases. It
was just to show that there might be different tasks and different
optimization goals. Clojure docs emphasises that "no user locks" are
required. My point is that ideology is often misleading. The same
goes to immutability, but it is harder to construct an counter-example
and I have no resources for that.

> But in that case the code will be more clear, contain no locks and
> can even run faster because less work needs to be done (no locking
> mechanism, which would run in your code).
Retries may be much more expensive than locks. Hope my example
illustrates that well.

> Each time the other programmers in your company stumble upon your locks
> they will have to understand why they were needed.
No way to avoid complexity of concurrent programming. No simple
default would
help. And there is one idea I've mentioned several times. Look at
RDBMS design.
There are deadlock detection agents. I'm sure it would be more
productive to introduce
deadlock detection agents to clojure instead of discouraging using
locks. Deadlock
detection agent would _work_instead_of_me_ while limitation to not
having user locks
would only force me to work in some predefined AND to make ugly
workarounds sometimes. Are
computers made to work instead of humans or what?
From: Scott Burson
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <1757ec95-330f-4556-bf2a-6cfbd8044af4@w39g2000prb.googlegroups.com>
On Feb 18, 12:06 am, budden <···········@mail.ru> wrote:
> There is still an advantage of immutable data structures over CL. CL
> is ignorant vs data sharing.
> There is no const declaration in CL, and sharing behavior is
> frequently unspecified. So it is very easy to
> smash data. Taking this into account, I can't say that CL is "safe"
> language as it pretends to be.
> Some solution is definitely required here and FP is one of possible
> approaches to that.

FSet has been mentioned a couple of times in this discussion, but I'll
take the liberty of mentioning it again.  It provides several
functional (immutable) collection types for CL, with lots of handy
operations on each.

http://common-lisp.net/project/fset/

-- Scott
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4996f1e3$0$90265$14726298@news.sunsite.dk>
 AT>   (fun 1 2 3)  but instead
 AT> #(fun 1 2 3)  when you use trampolines, and it is stack-safe again.

how does it work? does it inline fun instead of calling it, or what?
if it works via inlining, that it is not a solution..

 AT> Still I would stop using trampolines as soon the JVM will
 AT> introduce that kind of optimization.

if trampolines somehow automagically fix the problem with "one
keystroke", then why compiler cannot detect such situation and insert
these "#"? it seems you're not saying all the truth.. ot Clojure's compiler
is dumb

 ??>> NOBODY WRITES  CODE LIKE THIS.

 AT> Well, it's from Kent Pitman.
 AT> http://www.nhplace.com/kent/Papers/Technical-Issues.html

it was an example of code that is not elegant in Lisp2, this is not
a code in CL's style. btw, i haven't seen any practical use of Y combinator
so far, even in Haskell they just use their analog of LABELS.


 ??>> (labels ((sum (x acc) (if (zerop x)
 ??>>                                      acc
 ??>>                                      (sum (- x 1) (+ acc x)))))
 ??>>          (sum 200 0))

 AT> Where is the anonymous function here?
 AT> recur allows you anon functions to call themself.

and why do we need one here? code is pretty readable as it is.

we could make anonymous functions with recur in CL
with a simple macro like this:

(defmacro lambdarec (args &body body)
    `(labels ((recur (,@args) ,@body))
      (function recur)))

and it will work just like in Clojure:

(funcall (lambdarec (x accum)
                 (if (zerop x)
                     accum
                     (recur (- x 1) (+ accum x))))
             200 0)

(except in function position, unfortunately CL does not macroexpand it).
but i don't think this is even remotely useful..

 ??>> sure it does, because it was not tail calls. you should admit you know
 ??>> very little about functional programming, as you do not know even
 ??>> basics.

 AT> I see no reason to admit that at this point, as I was fully aware about
 AT> this.

why did you complain about stack overflow then? either you're an idiot,
or you're going to treat me like an idiot, i see no other possibilities 
here.

if you write random bullshit like this into newsgroups, you'll get no 
respect.

 AT>  What I was doing was talking about anon functions calling themselves.

"anon functions calling themselves" is not a benefit of itself, it is not 
obvious
that it allows one to solve real programming tasks even a bit better.

 AT> Let's say you have a Lisp with no support for TCO.
 AT> Then you would also be forced to wait until your vendor fixes it.

if Lisp does not have support for TCO, then probably it has good support
for imperative programming -- like tagbody and mutable variables, that can
be used to implement quite a hairy stuff.

as i understand, Clojure does not have support for imperative programming
constructs, and neither it has good support for functional programming 
constructs.
this makes me think that it is not such a good language.

 AT> And of course one can add recur also in CL. Everything that Clojure has
 AT> can be done in CL and vice versa.

emm, we can add recur from CL itself, but you cannot add TCO from Clojure
itself, can you?

perhaps you can write some smart compiler that will do it for you, but
that would be really hard (and thus impractical), while adding recur into CL
is trivial.

 AT> or if I want the set of all factorials, then
 AT> (def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))

 AT> This is my favourite.

why don't you use Haskell then? :)

 AT> After some months of functional programming I don't like code with setf
 AT> anymore.

one can do it with internal LOOP's variable rebinding feature, which i think
is semantically equivalent to recur's variable rebinding:

(loop for i from 1 to n
          for result = 1 then (* result i)
          finally (return result))
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn6u5u$8sm$1@news.motzarella.org>
Alex Mizrahi schrieb:
>  AT>   (fun 1 2 3)  but instead
>  AT> #(fun 1 2 3)  when you use trampolines, and it is stack-safe again.
> 
> how does it work? does it inline fun instead of calling it, or what?
> if it works via inlining, that it is not a solution..

http://code.google.com/p/clojure/source/browse/trunk/src/clj/clojure/core.clj?=1276#3744


>  AT> Still I would stop using trampolines as soon the JVM will
>  AT> introduce that kind of optimization.
> 
> if trampolines somehow automagically fix the problem with "one
> keystroke", then why compiler cannot detect such situation and insert
> these "#"? it seems you're not saying all the truth.. ot Clojure's compiler
> is dumb

http://groups.google.com/group/clojure/msg/3addf875319c5c10


>  AT> I see no reason to admit that at this point, as I was fully aware about
>  AT> this.
> 
> why did you complain about stack overflow then? either you're an idiot,
> or you're going to treat me like an idiot, i see no other possibilities 
> here.

No problem, I will tell you what the other possibility is:
I was making a sarcastic comment and you missed that. I gave an example
about how an anon function can call itself.


> if you write random bullshit like this into newsgroups, you'll get no 
> respect.

I am sure that with "this" you were referring to your own sentence.
Btw, I am not here for getting respect from random people on c.l.l.
Some people though need that... at least one source of respect and
attention.
(not referring to you!)


> if Lisp does not have support for TCO, then probably it has good support
> for imperative programming -- like tagbody and mutable variables, that can
> be used to implement quite a hairy stuff.

Yes, for CL it’s good.
And even today some small programs can be written in imperative style.


> as i understand, Clojure does not have support for imperative programming
> constructs, and neither it has good support for functional programming 
> constructs.
> this makes me think that it is not such a good language.

Ah oki, you never tried Clojure and heared some rumors somewhere.
It’s our human property to build up an opinion, although we don’t know
enough facts to have the right to have an opinion.
Just see the people who look into Lisp. Only a minority like us stayed.

I have no problems at all if people don’t like Clojure. I personally
just like it way more than CL. Basically every problem in my
professional programming I can solve in a more productive way. And this
does not always have to do with the sheer mount of code available for
the JVM.
But CL stays on rank 2, with a noticable distance to 1.
If Rich continues to work so hard on Clojure, it will soon outnumber the
CL users. Evolution in progress.


>  AT> And of course one can add recur also in CL. Everything that Clojure has
>  AT> can be done in CL and vice versa.
> 
> emm, we can add recur from CL itself, but you cannot add TCO from Clojure
> itself, can you?
> perhaps you can write some smart compiler that will do it for you, but
> that would be really hard (and thus impractical), while adding recur into CL
> is trivial.

Yes.
I think it makes most sense to just use what is available today.
I have not met on person who used Clojure for a few months who complained
about any problems with recur or recursion in Clojure.
It is much more a fantasy issue of people who actually never
touched Clojure.  Since I use it every day (be it professionally
or for private stuff) I find no way of going back to CL, which
by now feels really old to me.


>  AT> or if I want the set of all factorials, then
>  AT> (def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))
> 
>  AT> This is my favourite.
> 
> why don't you use Haskell then? :)

Because I can do it in Lisp, which I like.
Lisp can be used more practical, as so many libs from the JVM are available.
But Haskell is very cool, and I am glad that Clojure learned some
concepts from it. Makes sense.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Aatu Koskensilta
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <87vdrdezzj.fsf@alatheia.dsl.inet.fi>
"Alex Mizrahi" <········@users.sourceforge.net> writes:

> btw, i haven't seen any practical use of Y combinator so far, even
> in Haskell they just use their analog of LABELS.

What is the Haskell analogue of LABELS?

-- 
Aatu Koskensilta (················@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
 - Ludwig Wittgenstein, Tractatus Logico-Philosophicus
From: Tobias C. Rittweiler
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <878wo9otjd.fsf@freebits.de>
Aatu Koskensilta <················@uta.fi> writes:

> What is the Haskell analogue of LABELS?

A better question would be what is the Haskell analogue of FLET? :-)

  -T.
From: Alex Mizrahi
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <49972fde$0$90270$14726298@news.sunsite.dk>
 ??>> btw, i haven't seen any practical use of Y combinator so far, even
 ??>> in Haskell they just use their analog of LABELS.

 AK> What is the Haskell analogue of LABELS?

let .. in or where:

(labels ((sum (x acc) (if (zerop x) acc (sum (- x 1) (+ acc x))))
       (sum 200 0)

main = let sum x acc = if x == 0 then acc else sum (x - 1) (acc + x)
             in sum 200 0


main = sum 200 0
    where sum x acc = if x == 0 then acc else sum (x - 1) (acc + x)
From: Aatu Koskensilta
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <87iqncfszc.fsf@alatheia.dsl.inet.fi>
"Alex Mizrahi" <········@users.sourceforge.net> writes:

>  AK> What is the Haskell analogue of LABELS?
>
> let .. in or where:

Ah, so LABELS is essentially equivalent to recursive let (for
functions)?

-- 
Aatu Koskensilta (················@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
 - Ludwig Wittgenstein, Tractatus Logico-Philosophicus
From: Pascal Costanza
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <6vq5sgFl9qroU1@mid.individual.net>
Aatu Koskensilta wrote:
> "Alex Mizrahi" <········@users.sourceforge.net> writes:
> 
>>  AK> What is the Haskell analogue of LABELS?
>>
>> let .. in or where:
> 
> Ah, so LABELS is essentially equivalent to recursive let (for
> functions)?

Yes. LABELS was actually also the original name for letrec in Scheme - 
they only switched from labels to letrec at some later stage.

LABELS stems from the original LABEL form in Lisp 1.5, which allowed you 
to write one (!) function that can call itself.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mark Wooding
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <877i3f3g7r.fsf.mdw@metalzone.distorted.org.uk>
André Thieme <······························@justmail.de> writes:

> 2) When you argue about matureness and evolution, then Clojure could
>    be interesting. The language is much more simple than Lisp. And
>    some core parts of a Lisp were already provided by the JVM. For
>    example the GC, the Exception system and some tenthousand ready to
>    use methods. 

The downside is that a JVM-based system inherits the JVM's mistakes --
and they're numerous.  F'rinstance:

  * The exception system is inefficient and demented.  A new language
    can provide CL-style separation between responding to conditions and
    non-local flow control; but that doesn't help the numerous existing
    interfaces which don't work like this.

  * Java's `character' type tells lies, because it's stuck at being able
    to represent only 65536 different values from before Unicode
    extended its repertoire.  The result is that what appears to be a
    character might in fact only be half of one.

  * The JVM's integer arithmetic silently wraps around on overflow; this
    ought to be unacceptable in a Lisp.  However, even if Clojure
    correctly switches to bignum arithmetic when necessary, a large
    proportion of library functions which do arithmetic will still
    behave incorrectly.

All of these problems can be addressed.  ABCL is an adequate Common Lisp
running on the JVM (it only handles 8-bit characters, but the rest seems
all right).  The difficulty is that each time a language deviates from
the platform standards by unilaterally fixing a defect, it integrates
less well with the rest of the platform.

-- [mdw]
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <go1cmb$thc$1@news.motzarella.org>
Mark Wooding schrieb:
> André Thieme <······························@justmail.de> writes:
> 
>> 2) When you argue about matureness and evolution, then Clojure could
>>    be interesting. The language is much more simple than Lisp. And
>>    some core parts of a Lisp were already provided by the JVM. For
>>    example the GC, the Exception system and some tenthousand ready to
>>    use methods. 
> 
> The downside is that a JVM-based system inherits the JVM's mistakes --
> and they're numerous.  F'rinstance:
> 
>   * The exception system is inefficient and demented.  A new language
>     can provide CL-style separation between responding to conditions and
>     non-local flow control; but that doesn't help the numerous existing
>     interfaces which don't work like this.
> 
>   * Java's `character' type tells lies, because it's stuck at being able
>     to represent only 65536 different values from before Unicode
>     extended its repertoire.  The result is that what appears to be a
>     character might in fact only be half of one.
> 
>   * The JVM's integer arithmetic silently wraps around on overflow; this
>     ought to be unacceptable in a Lisp.  However, even if Clojure
>     correctly switches to bignum arithmetic when necessary, a large
>     proportion of library functions which do arithmetic will still
>     behave incorrectly.
> 
> All of these problems can be addressed.  ABCL is an adequate Common Lisp
> running on the JVM (it only handles 8-bit characters, but the rest seems
> all right).  The difficulty is that each time a language deviates from
> the platform standards by unilaterally fixing a defect, it integrates
> less well with the rest of the platform.

Thanks Mark, good points.
Having what the CL condition system provides which goes beyond exception
handling is indeed a nice thing, but for me not interesting. I see it as
a feature, but still, I don’t miss it. But it’s new to me that the JVMs
exception system is inefficient. So, that counts as a disadvantage.
And your second point also counts in my opinion. 65k different chars are
nice to have, but having all of them would be the right thing of course.

The last point is addressed by Clojure.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/
From: Mark Wooding
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <87y6vu1b2r.fsf.mdw@metalzone.distorted.org.uk>
André Thieme <······························@justmail.de> writes:

> Mark Wooding schrieb:
>>   * The JVM's integer arithmetic silently wraps around on overflow
[...]
> The last point is addressed by Clojure.

It is, sort of.  Clojure's own integer arithmetic seems correct, which
is great.[1]

But I said more:

>>     However, even if Clojure correctly switches to bignum arithmetic
>>     when necessary, a large proportion of library functions which do
>>     arithmetic will still behave incorrectly.

Since you were touting as an advantage of Clojure the ability to use
Java libraries, the fact that Java libraries have incorrect and
unreliable integer arithmetic is surely a concern!

> And your second point also counts in my opinion. 65k different chars are
> nice to have, but having all of them would be the right thing of course.

It's not that the other Unicode planes are unavailable.  They are --
through surrogate pairs.  But a surrogate is not a character -- and
therefore Java's character type is lying.  (A Java `char' is a UTF-16
encoding unit.  Which is a pretty useless thing to deal with.)

[1] At the time, I'd not actually tried running Clojure, which was bad
    of me.  I try not to criticize things I've not used.  The rest of
    the thread persuaded me to actually do this.

-- [mdw]
From: Vend
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <e1f3cdd9-9eca-4947-aec8-641ebdef7a91@33g2000yqm.googlegroups.com>
On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
> André Thieme <······························@justmail.de> writes:
> > Mark Wooding schrieb:
> >>   * The JVM's integer arithmetic silently wraps around on overflow
> [...]
> > The last point is addressed by Clojure.
>
> It is, sort of.  Clojure's own integer arithmetic seems correct, which
> is great.[1]
>
> But I said more:
>
> >>     However, even if Clojure correctly switches to bignum arithmetic
> >>     when necessary, a large proportion of library functions which do
> >>     arithmetic will still behave incorrectly.
>
> Since you were touting as an advantage of Clojure the ability to use
> Java libraries, the fact that Java libraries have incorrect and
> unreliable integer arithmetic is surely a concern!

Java integer arithmetic has a precisely defined semantics, hence this
claim is mostly false.

I said mostly, because my only concern with Java integers is that
their size is fixed and specified by the language, while there is no
specification for the maximum number of objects you can create.
If the VM allows you to create more than 2^32 (or 2^64) objects and
you have a routine that uses an int (or a long) to enumerate them,
then it can fail silently due to overflow.

A solution would be to include an integer type whose size is a
function of the internal pointer size.

> > And your second point also counts in my opinion. 65k different chars are
> > nice to have, but having all of them would be the right thing of course.
>
> It's not that the other Unicode planes are unavailable.  They are --
> through surrogate pairs.  But a surrogate is not a character -- and
> therefore Java's character type is lying.  (A Java `char' is a UTF-16
> encoding unit.  Which is a pretty useless thing to deal with.)
>
> [1] At the time, I'd not actually tried running Clojure, which was bad
>     of me.  I try not to criticize things I've not used.  The rest of
>     the thread persuaded me to actually do this.
>
> -- [mdw]
From: Mark Wooding
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <87wsbboci1.fsf.mdw@metalzone.distorted.org.uk>
Vend <······@virgilio.it> writes:

> On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
>> Since you were touting as an advantage of Clojure the ability to use
>> Java libraries, the fact that Java libraries have incorrect and
>> unreliable integer arithmetic is surely a concern!
>
> Java integer arithmetic has a precisely defined semantics, hence this
> claim is mostly false.

That doesn't matter.  The problem is that Java integer arithmetic is
precisely defined to be incorrect and unreliable.  If you evaluate 23!
using Java integers -- even longs -- you'll silently (`unreliable') get
the wrong answer (`incorrect').

> A solution would be to include an integer type whose size is a
> function of the internal pointer size.

The ideal solution would be to have arithmetic which gracefully falls
back to bignums when the results won't fit into fixnums.  Or at least to
issue exceptions on overflow rather than wrapping around silently.  I
don't see what good it does to introduce another type for doing
incorrect arithmetic.

-- [mdw]
From: William James
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <go9mis02a5p@enews2.newsguy.com>
Mark Wooding wrote:

> Vend <······@virgilio.it> writes:
> 
> > On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
> >> Since you were touting as an advantage of Clojure the ability to
> use >> Java libraries, the fact that Java libraries have incorrect and
> >> unreliable integer arithmetic is surely a concern!
> > 
> > Java integer arithmetic has a precisely defined semantics, hence
> > this claim is mostly false.
> 
> That doesn't matter.  The problem is that Java integer arithmetic is
> precisely defined to be incorrect and unreliable.  If you evaluate 23!
> using Java integers -- even longs -- you'll silently (`unreliable')
> get the wrong answer (`incorrect').

Duh.

So this prissy pedant thinks that every program written in C should
be abandoned---including all those implementations of Commune Lisp.
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <49a87121$0$5901$607ed4bc@cv.net>
William James wrote:
> Mark Wooding wrote:
> 
>> Vend <······@virgilio.it> writes:
>>
>>> On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
>>>> Since you were touting as an advantage of Clojure the ability to
>> use >> Java libraries, the fact that Java libraries have incorrect and
>>>> unreliable integer arithmetic is surely a concern!
>>> Java integer arithmetic has a precisely defined semantics, hence
>>> this claim is mostly false.

Documenting a bug to make it a feature was a joke, not a language design 
philosophy.

>> That doesn't matter.  The problem is that Java integer arithmetic is
>> precisely defined to be incorrect and unreliable.  If you evaluate 23!
>> using Java integers -- even longs -- you'll silently (`unreliable')
>> get the wrong answer (`incorrect').
> 
> Duh.
> 
> So this prissy pedant thinks that every program written in C should
> be abandoned---including all those implementations of Commune Lisp.

This prissy pedant thinks that as long as language is going to be prissy 
and demand I handle every possible condition that I should be able to 
rely on the damn thing generating conditions when bad things happen.

ie, no, just because they are straining for performance having screwed 
up with the all objects all the time thing and being too lazy to write 
compilers does not give them permission to leak C limitations into the 
world they give programmers.

kt
From: John Thingstad
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <op.up07g6cfut4oq5@pandora.alfanett.no>
P� Fri, 27 Feb 2009 22:39:40 +0100, skrev William James :

> Mark Wooding wrote:
>
>> Vend <······@virgilio.it> writes:
>>
>> > On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
>> >> Since you were touting as an advantage of Clojure the ability to
>> use >> Java libraries, the fact that Java libraries have incorrect and
>> >> unreliable integer arithmetic is surely a concern!
>> >
>> > Java integer arithmetic has a precisely defined semantics, hence
>> > this claim is mostly false.
>>
>> That doesn't matter.  The problem is that Java integer arithmetic is
>> precisely defined to be incorrect and unreliable.  If you evaluate 23!
>> using Java integers -- even longs -- you'll silently (`unreliable')
>> get the wrong answer (`incorrect').
>
> Duh.
>
> So this prissy pedant thinks that every program written in C should
> be abandoned---including all those implementations of Commune Lisp.

Common Lisp is in the most part written in itself (a meta circular  
compiler) for most implementations (not CLisp).
Exceptions are the garbage collector, parts of the FFI and the  
bootstrapping code. (SBCL needs a CL to bootstrap I think.)

It's slow interpreted languages like RUBY that need to have most of it's  
code written in C to have adequate performance.

--------------
John Thingstad
From: Marco Antoniotti
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <4e87b840-11da-42b1-b1a8-827e8e782d21@z9g2000yqi.googlegroups.com>
On Feb 27, 10:39 pm, "William James" <> wrote:
> Mark Wooding wrote:
> > Vend <······@virgilio.it> writes:
>
> > > On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
> > >> Since you were touting as an advantage of Clojure the ability to
> > use >> Java libraries, the fact that Java libraries have incorrect and
> > >> unreliable integer arithmetic is surely a concern!
>
> > > Java integer arithmetic has a precisely defined semantics, hence
> > > this claim is mostly false.
>
> > That doesn't matter.  The problem is that Java integer arithmetic is
> > precisely defined to be incorrect and unreliable.  If you evaluate 23!
> > using Java integers -- even longs -- you'll silently (`unreliable')
> > get the wrong answer (`incorrect').
>
> Duh.
>
> So this prissy pedant thinks that every program written in C should
> be abandoned---including all those implementations of Commune Lisp.

Absolutely not. How are we going to use the multidimensional arrays of
C (Java just copies them) to dispatch on the 'volatile auto' declared
method combinations?

Cheers
--
Marco
From: Vend
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <5d27c029-0d60-48d4-8ed9-66359dca1af4@j38g2000yqa.googlegroups.com>
On 27 Feb, 21:23, Mark Wooding <····@distorted.org.uk> wrote:
> Vend <······@virgilio.it> writes:
> > On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
> >> Since you were touting as an advantage of Clojure the ability to use
> >> Java libraries, the fact that Java libraries have incorrect and
> >> unreliable integer arithmetic is surely a concern!
>
> > Java integer arithmetic has a precisely defined semantics, hence this
> > claim is mostly false.
>
> That doesn't matter.  The problem is that Java integer arithmetic is
> precisely defined to be incorrect and unreliable.  If you evaluate 23!
> using Java integers -- even longs -- you'll silently (`unreliable') get
> the wrong answer (`incorrect').

If you attempt to evaluate 23! using Java fixed size integers then
your code is incorrect and unreliable, not Java.

By the same tokem, if you attempt to evaluate gamma(24.1) in common
lisp using floats and you get the wrong answer, the error is in your
code, not in common lisp.

> > A solution would be to include an integer type whose size is a
> > function of the internal pointer size.
>
> The ideal solution would be to have arithmetic which gracefully falls
> back to bignums when the results won't fit into fixnums.  Or at least to
> issue exceptions on overflow rather than wrapping around silently.  I
> don't see what good it does to introduce another type for doing
> incorrect arithmetic.

The pointer sized integers allows you to count allocated objects
without possibly overflowing.

> -- [mdw]
From: Pascal Costanza
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <70slm1Fi1n6iU1@mid.individual.net>
Vend wrote:
> On 27 Feb, 21:23, Mark Wooding <····@distorted.org.uk> wrote:
>> Vend <······@virgilio.it> writes:
>>> On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
>>>> Since you were touting as an advantage of Clojure the ability to use
>>>> Java libraries, the fact that Java libraries have incorrect and
>>>> unreliable integer arithmetic is surely a concern!
>>> Java integer arithmetic has a precisely defined semantics, hence this
>>> claim is mostly false.
>> That doesn't matter.  The problem is that Java integer arithmetic is
>> precisely defined to be incorrect and unreliable.  If you evaluate 23!
>> using Java integers -- even longs -- you'll silently (`unreliable') get
>> the wrong answer (`incorrect').
> 
> If you attempt to evaluate 23! using Java fixed size integers then
> your code is incorrect and unreliable, not Java.

The problem with Java in this regard is that it makes it too easy to use 
a representation for numbers that gives you incorrect code, while it 
makes it too hard to use a representation that gives you correct code.

> By the same tokem, if you attempt to evaluate gamma(24.1) in common
> lisp using floats and you get the wrong answer, the error is in your
> code, not in common lisp.

Why would you expect a problem here? Common Lisp has a "full" numerical 
tower...


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Vend
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <2b99a483-ecbb-4903-97bd-43ff7d00946c@l38g2000vba.googlegroups.com>
On 28 Feb, 12:32, Pascal Costanza <····@p-cos.net> wrote:
> Vend wrote:
> > On 27 Feb, 21:23, Mark Wooding <····@distorted.org.uk> wrote:
> >> Vend <······@virgilio.it> writes:
> >>> On 25 Feb, 22:05, Mark Wooding <····@distorted.org.uk> wrote:
> >>>> Since you were touting as an advantage of Clojure the ability to use
> >>>> Java libraries, the fact that Java libraries have incorrect and
> >>>> unreliable integer arithmetic is surely a concern!
> >>> Java integer arithmetic has a precisely defined semantics, hence this
> >>> claim is mostly false.
> >> That doesn't matter.  The problem is that Java integer arithmetic is
> >> precisely defined to be incorrect and unreliable.  If you evaluate 23!
> >> using Java integers -- even longs -- you'll silently (`unreliable') get
> >> the wrong answer (`incorrect').
>
> > If you attempt to evaluate 23! using Java fixed size integers then
> > your code is incorrect and unreliable, not Java.
>
> The problem with Java in this regard is that it makes it too easy to use
> a representation for numbers that gives you incorrect code, while it
> makes it too hard to use a representation that gives you correct code.

That's true, the bignum library is ugly and difficult to use because
Java lacks operator overloading.

> > By the same tokem, if you attempt to evaluate gamma(24.1) in common
> > lisp using floats and you get the wrong answer, the error is in your
> > code, not in common lisp.
>
> Why would you expect a problem here? Common Lisp has a "full" numerical
> tower...

Common Lisp floating point numbers are fixed sized, hence they can
overflow.

Moreover, the size and exact semantics of CL floats is left up to
implementation, while Java floats come in two implementation-
independent sizes and their semantics is mostly defined by the
standard (and can be forced by the programmer to a fully defined
semantics).
From: Pascal J. Bourguignon
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <87myc66149.fsf@galatea.local>
Vend <······@virgilio.it> writes:
>> Why would you expect a problem here? Common Lisp has a "full" numerical
>> tower...
>
> Common Lisp floating point numbers are fixed sized, hence they can
> overflow.
>
> Moreover, the size and exact semantics of CL floats is left up to
> implementation, while Java floats come in two implementation-
> independent sizes and their semantics is mostly defined by the
> standard (and can be forced by the programmer to a fully defined
> semantics).

However, this leaves an implementation allow you to do that:

C/USER[884]> pi
3.1415926535897932384626433832795028842L0
C/USER[885]> (setf (EXT:LONG-FLOAT-DIGITS) 1000)
1000
C/USER[886]> pi
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587L0
C/USER[887]> 


I don't think that fixed size floating point is a problem when you get
to fix the size yourself...

-- 
__Pascal Bourguignon__
From: John Thingstad
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <op.up2km7fdut4oq5@pandora.alfanett.no>
P� Sat, 28 Feb 2009 16:18:46 +0100, skrev Pascal J. Bourguignon  
<···@informatimago.com>:

> Vend <······@virgilio.it> writes:
>>> Why would you expect a problem here? Common Lisp has a "full" numerical
>>> tower...
>>
>> Common Lisp floating point numbers are fixed sized, hence they can
>> overflow.
>>
>> Moreover, the size and exact semantics of CL floats is left up to
>> implementation, while Java floats come in two implementation-
>> independent sizes and their semantics is mostly defined by the
>> standard (and can be forced by the programmer to a fully defined
>> semantics).
>
> However, this leaves an implementation allow you to do that:
>
> C/USER[884]> pi
> 3.1415926535897932384626433832795028842L0
> C/USER[885]> (setf (EXT:LONG-FLOAT-DIGITS) 1000)
> 1000
> C/USER[886]> pi
> 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587L0
> C/USER[887]>
>
>
> I don't think that fixed size floating point is a problem when you get
> to fix the size yourself...
>

That is because CLisp uses the GNU MP library which allovs arbitrary  
precision arithmetic, operating on signed integers, rational numbers, and  
floating point numbers. Of cource most users of this library use C++...  
(and that this HOPELESS? language had no problem implementing this  
fuctionality..)

--------------
John Thingstad
From: Tamas K Papp
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <70t83eFid1ibU1@mid.individual.net>
On Sat, 28 Feb 2009 17:12:33 +0100, John Thingstad wrote:

> That is because CLisp uses the GNU MP library which allovs arbitrary
> precision arithmetic, operating on signed integers, rational numbers,
> and floating point numbers. Of cource most users of this library use
> C++... (and that this HOPELESS? language had no problem implementing
> this fuctionality..)

Have you heard about Turing-completeness?  No reasonable language
would have a problem implementing this library.  Also, arbitrary
precision arithmetic is a relatively straightforward and well-defined
problem, this is not where the advantage of "good" languages is the 
largest.

Nevertheless, not including at least smoothly integrated bignums (like
CL) was a really brain-dead decision for the designers of Java, for
which there is no excuse.

Tamas
From: Vend
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <ce5ad022-4887-46bf-a6ad-3386129e3e29@t7g2000yqa.googlegroups.com>
On 28 Feb, 17:46, Tamas K Papp <······@gmail.com> wrote:
> On Sat, 28 Feb 2009 17:12:33 +0100, John Thingstad wrote:
> > That is because CLisp uses the GNU MP library which allovs arbitrary
> > precision arithmetic, operating on signed integers, rational numbers,
> > and floating point numbers. Of cource most users of this library use
> > C++... (and that this HOPELESS? language had no problem implementing
> > this fuctionality..)
>
> Have you heard about Turing-completeness?  No reasonable language
> would have a problem implementing this library.  Also, arbitrary
> precision arithmetic is a relatively straightforward and well-defined
> problem, this is not where the advantage of "good" languages is the
> largest.

Arbitrary precision arithmetic is performance-critical, Turing-
completeness is not very relevant in this case.

> Nevertheless, not including at least smoothly integrated bignums (like
> CL) was a really brain-dead decision for the designers of Java, for
> which there is no excuse.
>
> Tamas
From: Tamas K Papp
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <70ts2lFickupU1@mid.individual.net>
On Sat, 28 Feb 2009 13:33:41 -0800, Vend wrote:

> Arbitrary precision arithmetic is performance-critical

Indeed.  That's why it makes sense to offer bignums as the baseline
case, and then allow optimizations where they are necessary (again,
like CL does it).

Performance loss from bignum integer libraries is not expensive,
compared to the cost of f*cked up results in case of silent overflows.

Similarly to garbage collection vs manual allocation: you can claim
the former is "performance critical", but that helps little when your
C program crashes.  At least Java got this right, but for not making
bignums default, they have no excuse.

Tamas
From: Vend
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <6401c475-a0ca-4ff2-a0bd-06260cd09a2d@v15g2000yqn.googlegroups.com>
On 28 Feb, 23:27, Tamas K Papp <······@gmail.com> wrote:
> On Sat, 28 Feb 2009 13:33:41 -0800, Vend wrote:
> > Arbitrary precision arithmetic is performance-critical
>
> Indeed.  That's why it makes sense to offer bignums as the baseline
> case, and then allow optimizations where they are necessary (again,
> like CL does it).
>
> Performance loss from bignum integer libraries is not expensive,
> compared to the cost of f*cked up results in case of silent overflows.

I don't think that errors due to unintended fixnum overflows are
common.

> Similarly to garbage collection vs manual allocation: you can claim
> the former is "performance critical", but that helps little when your
> C program crashes.  At least Java got this right, but for not making
> bignums default, they have no excuse.

I think that C vulnerability to memory errors doesn't have lots to do
with its lack of garbage collection.
It is due to the lack of compile-time constraints and run-time checks
on memory usage:
you can get a pointer to an uninitialized memory area, dereference it,
deallocate an area twice or deallocate from a pointer refernencing an
intermediate location of an allocated memory area, or referencing the
stack, etc.

If such operations weren't permitted C programs would at most leak or
terminate eagerly with meaningful exceptions, even without garbage
collection.

Adding garbage collection to C (using the Boehm-Demers-Weiser
collector, for instance), prevents leaks and some deallocation errors,
but still doesn't make program memory safe.
From: John Thingstad
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <op.up3c2qjrut4oq5@pandora.alfanett.no>
P� Sun, 01 Mar 2009 00:20:08 +0100, skrev Vend <······@virgilio.it>:

> On 28 Feb, 23:27, Tamas K Papp <······@gmail.com> wrote:
>> On Sat, 28 Feb 2009 13:33:41 -0800, Vend wrote:
>> > Arbitrary precision arithmetic is performance-critical
>>
>> Indeed. �That's why it makes sense to offer bignums as the baseline
>> case, and then allow optimizations where they are necessary (again,
>> like CL does it).
>>
>> Performance loss from bignum integer libraries is not expensive,
>> compared to the cost of f*cked up results in case of silent overflows.
>
> I don't think that errors due to unintended fixnum overflows are
> common.
>
>> Similarly to garbage collection vs manual allocation: you can claim
>> the former is "performance critical", but that helps little when your
>> C program crashes. �At least Java got this right, but for not making
>> bignums default, they have no excuse.
>
> I think that C vulnerability to memory errors doesn't have lots to do
> with its lack of garbage collection.
> It is due to the lack of compile-time constraints and run-time checks
> on memory usage:
> you can get a pointer to an uninitialized memory area, dereference it,
> deallocate an area twice or deallocate from a pointer refernencing an
> intermediate location of an allocated memory area, or referencing the
> stack, etc.
>
> If such operations weren't permitted C programs would at most leak or
> terminate eagerly with meaningful exceptions, even without garbage
> collection.
>
> Adding garbage collection to C (using the Boehm-Demers-Weiser
> collector, for instance), prevents leaks and some deallocation errors,
> but still doesn't make program memory safe.
>
>

Acually you have programs like bounds checker that check for that. memory  
allocation errors are mostly a problem of the past.
You can also turn on checking for array boundaries etc (in Visual C++). It  
will also check for stack overflow, stack overwrite..

--------------
John Thingstad
From: Vend
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <292cf1f3-441d-41ae-a360-05ab5dfd6bb6@j35g2000yqh.googlegroups.com>
On 1 Mar, 03:26, "John Thingstad" <·······@online.no> wrote:
> På Sun, 01 Mar 2009 00:20:08 +0100, skrev Vend <······@virgilio.it>:
>
>
>
> > On 28 Feb, 23:27, Tamas K Papp <······@gmail.com> wrote:
> >> On Sat, 28 Feb 2009 13:33:41 -0800, Vend wrote:
> >> > Arbitrary precision arithmetic is performance-critical
>
> >> Indeed.  That's why it makes sense to offer bignums as the baseline
> >> case, and then allow optimizations where they are necessary (again,
> >> like CL does it).
>
> >> Performance loss from bignum integer libraries is not expensive,
> >> compared to the cost of f*cked up results in case of silent overflows.
>
> > I don't think that errors due to unintended fixnum overflows are
> > common.
>
> >> Similarly to garbage collection vs manual allocation: you can claim
> >> the former is "performance critical", but that helps little when your
> >> C program crashes.  At least Java got this right, but for not making
> >> bignums default, they have no excuse.
>
> > I think that C vulnerability to memory errors doesn't have lots to do
> > with its lack of garbage collection.
> > It is due to the lack of compile-time constraints and run-time checks
> > on memory usage:
> > you can get a pointer to an uninitialized memory area, dereference it,
> > deallocate an area twice or deallocate from a pointer refernencing an
> > intermediate location of an allocated memory area, or referencing the
> > stack, etc.
>
> > If such operations weren't permitted C programs would at most leak or
> > terminate eagerly with meaningful exceptions, even without garbage
> > collection.
>
> > Adding garbage collection to C (using the Boehm-Demers-Weiser
> > collector, for instance), prevents leaks and some deallocation errors,
> > but still doesn't make program memory safe.
>
> Acually you have programs like bounds checker that check for that. memory  
> allocation errors are mostly a problem of the past.
> You can also turn on checking for array boundaries etc (in Visual C++). It  
> will also check for stack overflow, stack overwrite..

Non standard features.

> --------------
> John Thingstad
From: Scott Burson
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <7ba941bd-f584-4a27-b6d4-337b544ddcb2@k19g2000prh.googlegroups.com>
On Feb 28, 8:46 am, Tamas K Papp <······@gmail.com> wrote:
> Nevertheless, not including at least smoothly integrated bignums (like
> CL) was a really brain-dead decision for the designers of Java, for
> which there is no excuse.

I have to agree.  I have a lot of respect for Gosling, but he whiffed
on this one.

-- Scott
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gn2eul$adg$1@news.motzarella.org>
Kenneth Tilton schrieb:
> What is your Clojure Status?
>   - What is Clojure?
>   - Never looked at it.
>   - Looked but did not like because ___
>   - Will use for some work because ___ but not all because ___ but 
> continue to use ___ for ___ because ____.
>   - Will now use instead of ___ because ____
>   - Other ____

It is: I use it daily for professional work, but also nearly every day
for personal programming fun.
I use Clojure now instead of CL mostly, and will port my code.


> (I think the rest are for anyone who will be using Clojure)
> 
> If Java access was a big factor, why not ABCL or AllegroCL?

Because those are CL implementations which come with clos.
I like clos more than the object system of Java, but this is just my
opinion. A fact however is, that those object models are not compatible.
It is very ugly to work with Java from within CL.
So, if access to Java would be a big factor, then one should definitly
use a language which was designed with that idea in mind.


> What do you miss from Common Lisp (or whatever the "from" language was).

 From CL I miss in principle nothing.
I am glad that Clojure has no object system, but instead goes the path
of functional programming.
What I miss though are features of specific CL implementations.
For example SBCLs type inference engine.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Scott Burson
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <ee2dbb09-76dd-48ee-891e-7d6a8d5b3b80@g39g2000pri.googlegroups.com>
On Feb 10, 7:10 am, Kenneth Tilton <·········@gmail.com> wrote:
> What is your Clojure Status?

I've looked at it, but I have a bunch of code in CL that I'm working
on and see no compelling reason to switch.

If I should decide I need my app to run on the JVM at some point --
which is possible -- I would consider Clojure, but I would also
consider Scala.

-- Scott
From: Luc
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <99a2e4d4-a221-4c4f-83c9-462063af676e@m4g2000vbp.googlegroups.com>
On Feb 13, 2:07 pm, Scott Burson <········@gmail.com> wrote:
> On Feb 10, 7:10 am, Kenneth Tilton <·········@gmail.com> wrote:
>
> > What is your Clojure Status?
>

In production since beginning of January. No problems, great
stability. It never failed us since then.
We use a combinations of Spring beans and Clojure code.

Currently there are changes being implemented that will force us to
change some function names
but we are just waiting for the dust to settle and are confident the
transition will be smooth.

Like anything new open source software you have to be careful to
monitor what's undergoing changes.
Once we put our hands on a version between these changes it's been
very resilient.

We upgraded the runtime three times up to now and it's been a breeze.

Our application does message routing stuff and it's been an area where
Clojure allowed us to
get the code out very fast compared to other alternatives.

So overall it's obviously a positive gain...

Of course our need for the mod function may not be as high as other
folks :))))

Luc Préfontaine
From: Luc
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <24010412-f676-4881-8435-31b540fd62e0@r22g2000vbp.googlegroups.com>
Just to be clear about my last post, you should read between the lines
that:

a) Clojure works.

b) It runs in a complex system in production today after a year of
incubation or so on the internet.
    Version 1.0 is not even out...

c) It allows us to leverage all the Java libraries out there without
having to write wrappers of any kind.

d) It relegates Java to low level stuff and that's fine. Nobody wants
to write/maintain thousands of line
    of Java anymore.

e) Any discussions about the merits/inconvenience of Clojure versus
Lisp/Ruby/... versus the bad/evil
    of the JVM looks to us a bit infantile. There are many practical
things to be done to improve the software
    we write. Clojure is one of these things. Usable now by everyone,
not after 2 years of
    learning curve,  not after 10 years of maturation, just on the
door step.

It's there now, it's accessible to non-lispers, it's not disconnected
from the stuff the industry invested in
up to now and it saves time and $$$. It has all the potential to
spread in day to day applications.

Many of the posts I read up to know are endless discussions about the
sex of angels...
There are better ways to invest your time to make things the software
industry move forward.

Do not get me wrong here, I started to work with Lisp around 1980,
used in some product prototypes,
it's great but it did not took off. That's the bottom line.

Today there are millions of Java programmers and thousands of Java
library and applications.
We cannot write software the way we have been doing it for the last 9
years.
We need a viable accessible alternative to the average Java
programmer. It could be Clojure.

Luc Préfontaine

A (very) old developer and business owner
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <49a0e0c7$0$20300$607ed4bc@cv.net>
Luc wrote:
> Just to be clear about my last post, you should read between the lines
> that:
> 
> a) Clojure works.
> 
> b) It runs in a complex system in production today after a year of
> incubation or so on the internet.
>     Version 1.0 is not even out...
> 
> c) It allows us to leverage all the Java libraries out there without
> having to write wrappers of any kind.
> 
> d) It relegates Java to low level stuff and that's fine. Nobody wants
> to write/maintain thousands of line
>     of Java anymore.
> 
> e) Any discussions about the merits/inconvenience of Clojure versus
> Lisp/Ruby/... versus the bad/evil
>     of the JVM looks to us a bit infantile. There are many practical
> things to be done to improve the software
>     we write. Clojure is one of these things. Usable now by everyone,
> not after 2 years of
>     learning curve,  not after 10 years of maturation, just on the
> door step.
> 
> It's there now, it's accessible to non-lispers, it's not disconnected
> from the stuff the industry invested in
> up to now and it saves time and $$$. It has all the potential to
> spread in day to day applications.
> 
> Many of the posts I read up to know are endless discussions about the
> sex of angels...
> There are better ways to invest your time to make things the software
> industry move forward.
> 
> Do not get me wrong here, I started to work with Lisp around 1980,
> used in some product prototypes,
> it's great but it did not took off. That's the bottom line.
> 
> Today there are millions of Java programmers and thousands of Java
> library and applications.
> We cannot write software the way we have been doing it for the last 9
> years.
> We need a viable accessible alternative to the average Java
> programmer. It could be Clojure.
> 

This is actually good timing, I might be involved in a Lisp/Java project 
soon.

Do you have any sense of how pure Java types react to Clojure?

kt
From: Luc
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <fb96e8af-a584-44c3-aba5-4a7938351ff7@j1g2000yqi.googlegroups.com>
On Feb 22, 12:21 am, Kenneth Tilton <·········@gmail.com> wrote:

> This is actually good timing, I might be involved in a Lisp/Java project
> soon.
>
> Do you have any sense of how pure Java types react to Clojure?
>
> kt

Because we end up with a mix of Ruby, Java and Clojure, we used YAML
to encode/decode the data structures shared on the message bus.

We reduced everything to a basic Java map/list/vector/... on the
message bus
so any component can access it whatever the language it's been written
in.

The YAML encoding/decoding is done by a Java library.
When data comes into Clojure, we just convert the YAML stream to its
Java equivalent and then to the Clojure equivalent representation to
get the benefits of immutability.

As for Ruby the YAML support is already there and we use it
transparently on the messages
circulating on the bus.

The data conversion layer from Java to Clojure data types is around
250 lines (with comments)
but it also deals with the specific message formats we exchange on the
bus.
The generic part of this module that really focuses on the basic Java
versus Clojure data types is under 80 lines
and we know we can do a better job at it.
It handles Maps, Vectors, Lists, ... anything that has an equivalent
representation in all three languages.

Later this spring we will modify the convert/decoder to deal directly
with the Clojure data types.

As far as interacting with Java data types from Clojure, we did not
experiment any problems.
Clojure uses Java strings for its String data type and since we deal
primarily with strings, it simplified
things a lot.

We use numeric types but we are not relying on heavy mathematical
algorithms yet interacting with Java.
We did not experiment problems in this area but it's been less covered
because of the
nature of our product.

Beware that you may have to gives hints sometimes when calling a Java
member function with
numeric arguments to match it's signature but that's about the worse
problem we dealt with.

We tend to create semi-complex Java objects to hide low level stuff
and move away from Clojure
most of the basic Java stuff. It's represents less code at the top in
the Clojure layer and once the
Java objects are done we rarely reopen them.

Java is where assembly language used to sit in the 80s/90s, at the
bottom layer.
It's a matter of finding where to draw the line between Clojure and
Java low-level objects.

Luc
From: André Thieme
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <gnrhm8$8on$1@news.motzarella.org>
Kenneth Tilton schrieb:

> Do you have any sense of how pure Java types react to Clojure?

Can you be more specific?
Often you can pass Clojure objects into Java code which was written
years before Clojure existed. And you can operate on Java objects with
Clojure constructs. If someone made his own implementation of an
ArrayList or whatever, which Rich Hickey does not even know about, then
Clojures first/rest/map/reduce/filter/etc can work on it.
But in any case, basically every Java class comes with getters/setters,
which allow you to get things in and out of mysterious objects.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Rob Warnock
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <Lv2dnQhCwO0w0zzUnZ2dnUVZ_vWdnZ2d@speakeasy.net>
Andr� Thieme  <······························@justmail.de> wrote:
+---------------
| Kenneth Tilton schrieb:
| > Do you have any sense of how pure Java types react to Clojure?
| 
| Can you be more specific?
| Often you can pass Clojure objects into Java code which was written
| years before Clojure existed. And you can operate on Java objects with
| Clojure constructs. ...
+---------------

No, no, no, not *that* meaning of "type"!!  ;-}
Think more of the French phrase "un type".
Or perhaps "les types de Java" or something...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <49a152af$0$5906$607ed4bc@cv.net>
Andr� Thieme wrote:
> Kenneth Tilton schrieb:
> 
>> Do you have any sense of how pure Java types react to Clojure?
> 
> Can you be more specific?

"pure Java types (of programmers) not already amenable to a Lispy language"

> Often you can pass Clojure objects into Java code which was written
> years before Clojure existed. And you can operate on Java objects with
> Clojure constructs. If someone made his own implementation of an
> ArrayList or whatever, which Rich Hickey does not even know about, then
> Clojures first/rest/map/reduce/filter/etc can work on it.
> But in any case, basically every Java class comes with getters/setters,
> which allow you to get things in and out of mysterious objects.
> 
> 
> Andr�
From: Kaz Kylheku
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <20090301013058.678@gmail.com>
On 2009-02-22, Luc <············@softaddicts.ca> wrote:
> We need a viable accessible alternative to the average Java
> programmer. 

Couldn't have said it better. 
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <49a0d965$0$5904$607ed4bc@cv.net>
Luc wrote:
> On Feb 13, 2:07 pm, Scott Burson <········@gmail.com> wrote:
>> On Feb 10, 7:10 am, Kenneth Tilton <·········@gmail.com> wrote:
>>
>>> What is your Clojure Status?
> 
> In production since beginning of January. No problems, great
> stability. It never failed us since then.
> We use a combinations of Spring beans and Clojure code.

..google..google.. OK, a Java lib. So Clojure got picked up so fast cuz 
your basic requirement was doing Java and anything that made that easier 
got a quick look? Suggesting the Early Adopter niche for Clojure is 
Lispers stuck doing Java?

Feel free to convert my answers into questions and respond diffeerently.

> 
> Currently there are changes being implemented that will force us to
> change some function names
> but we are just waiting for the dust to settle and are confident the
> transition will be smooth.
> 
> Like anything new open source software you have to be careful to
> monitor what's undergoing changes.
> Once we put our hands on a version between these changes it's been
> very resilient.
> 
> We upgraded the runtime three times up to now and it's been a breeze.
> 
> Our application does message routing stuff and it's been an area where
> Clojure allowed us to
> get the code out very fast compared to other alternatives.

Did ABCL or AllegroCL get considered? Or am I wrong, is this also about 
some of the ways Clojure is different than CL?


> 
> So overall it's obviously a positive gain...
> 
> Of course our need for the mod function may not be as high as other
> folks :))))

No mod?!!! How do you print out a diagnostic every thousandth iteration 
without it?!

kt
From: Thomas F. Burdick
Subject: Re: Road to Clojure Survey 2.0
Date: 
Message-ID: <92761d2c-2ed9-4663-8d74-bd70fcc09e0e@x38g2000yqj.googlegroups.com>
On 22 fév, 05:49, Kenneth Tilton <·········@gmail.com> wrote:
> Luc wrote:
> > On Feb 13, 2:07 pm, Scott Burson <········@gmail.com> wrote:
> >> On Feb 10, 7:10 am, Kenneth Tilton <·········@gmail.com> wrote:
>
> >>> What is your Clojure Status?
>
> > In production since beginning of January. No problems, great
> > stability. It never failed us since then.
> > We use a combinations of Spring beans and Clojure code.
>
> ..google..google.. OK, a Java lib. So Clojure got picked up so fast cuz
> your basic requirement was doing Java and anything that made that easier
> got a quick look? Suggesting the Early Adopter niche for Clojure is
> Lispers stuck doing Java?
>
> Feel free to convert my answers into questions and respond diffeerently.
>
>
>
>
>
> > Currently there are changes being implemented that will force us to
> > change some function names
> > but we are just waiting for the dust to settle and are confident the
> > transition will be smooth.
>
> > Like anything new open source software you have to be careful to
> > monitor what's undergoing changes.
> > Once we put our hands on a version between these changes it's been
> > very resilient.
>
> > We upgraded the runtime three times up to now and it's been a breeze.
>
> > Our application does message routing stuff and it's been an area where
> > Clojure allowed us to
> > get the code out very fast compared to other alternatives.
>
> Did ABCL or AllegroCL get considered? Or am I wrong, is this also about
> some of the ways Clojure is different than CL?
>
>
>
> > So overall it's obviously a positive gain...
>
> > Of course our need for the mod function may not be as high as other
> > folks :))))
>
> No mod?!!! How do you print out a diagnostic every thousandth iteration
> without it?!

Probably by printing out such a message every 65536 iterations.
From: Dimiter "malkia" Stanev
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gmsi7k$mtu$1@malkia.motzarella.org>
Kenneth Tilton wrote:
> In 25 words or less, why is Clojure better than Common Lisp?
> 
> In 100 words or less, why is Clojure better than Common Lisp?
> 
> Have you switched to Clojure? If so, from what?
> 
> 

I'm syncing to the daily builds of clojure, and doing some minor 
benchmarks. I'm trying hard to reach the speed of Common Lisp or Java 
(I'm running Clojure with the -server option).

Overall, the speed ain't bad, it's about 10x faster than perl, python, 
ruby, but x10-x20 slower than most of the Common Lisp Compilers (SBCL, 
CMUCL, LispWorks, ACL).

I'm using Lisp for heavy calculations, so I can't really use it, until I 
learn to optimize it better.

My base benchmark was the pnpoly.lisp code (point-in-poly).

Other things that I'm missing from Common Lisp are some form of 
"apropos" and some way of disassembling the functions - I'm doing this 
regurarly with Common Lisp in order to learn the peculiarities of the 
various implementations, and gather knowledge of best practices myself 
(off course there are papers by Fateman, and others about single and 
double floating points).

Another strange peculiarity is the tagging - sometimes you have to do 
(#^Float number), sometimes (number (float 10.0)) - it seems not 
consistent, but granted this is not where the language is shining.

I think it's not the language right now for my needs, but my become, as 
soon as I start explore web development more and more.

The JAR file is rather small, compared to the ABCL (not fair comparison, 
I know different things - but still to give you perspective).

It definitely looks useful, and can teach you how to write even more 
functional code (still trying to prevent myself from imperative thinking).
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gmt6rt$9hq$1@news.motzarella.org>
Dimiter "malkia" Stanev schrieb:
> Kenneth Tilton wrote:
>> In 25 words or less, why is Clojure better than Common Lisp?
>>
>> In 100 words or less, why is Clojure better than Common Lisp?
>>
>> Have you switched to Clojure? If so, from what?
>>
>>
> 
> I'm syncing to the daily builds of clojure, and doing some minor 
> benchmarks. I'm trying hard to reach the speed of Common Lisp or Java 
> (I'm running Clojure with the -server option).
> 
> Overall, the speed ain't bad, it's about 10x faster than perl, python, 
> ruby, but x10-x20 slower than most of the Common Lisp Compilers (SBCL, 
> CMUCL, LispWorks, ACL).
> 
> I'm using Lisp for heavy calculations, so I can't really use it, until I 
> learn to optimize it better.

In general one can suggest to give type hints to speed up things.
For a little test function that Rainer Joswig gave here in c.l.l some
weeks ago I got from x15 more runtime than sbcl to half the runtime of
sbcl with a few type hints.
But sometimes those won�t help. Currently the bignum lib from Java seems
to be pretty slow.
For Java 7 some drastic improvements are visible on the horizon:
http://markmail.org/message/7conncsespvrlazn

Another general suggestion is to run things in parallel.
This makes of course only sense if your algorithms are parallelizable.

If they are not, and if you are using Clojure datastructures (such as
sets, vectors, hashmaps, ...) instead of Javas it can also be in some
cases a disadvantage. The Clojure versions simply have to do more work
under the hood. These datastructures are not only threadsafe, but also
concurrency ready, which is even more expensive.



> Other things that I'm missing from Common Lisp are some form of 
> "apropos"

So find-doc did not give you satisfying results?
It can also take a regex...


> and some way of disassembling the functions

There are many Java tools that can support you.
Did you try jad to decompile .class files into .java files?
(in that sense Java is the Assembler for the JVM :))
But you can also use bytecode viewer.


> Another strange peculiarity is the tagging - sometimes you have to do 
> (#^Float number), sometimes (number (float 10.0)) - it seems not 
> consistent, but granted this is not where the language is shining.

As you can see, float is just an ordinary function, but does implicitly
give a type hint:
http://code.google.com/p/clojure/source/browse/trunk/src/clj/clojure/core.clj#1813

And btw, (number (float 10.0)) produces an error, as the function number
does not exist. Did you mean number? maybe?
Type hints can be given very consistent with the reader macro #^
as in #^TYPE


> I think it's not the language right now for my needs, but my become, as 
> soon as I start explore web development more and more.

I hope you did not base this on the one result of your poly test case.
Although you know of course much better your needs. If that benchmark is
what you are basically doing all the time, then it�s very understandable.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Dimiter "malkia" Stanev
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gmtaqd$j15$1@malkia.motzarella.org>
[snipped a lot of useful information - keeping it for later to read]

> I hope you did not base this on the one result of your poly test case.
> Although you know of course much better your needs. If that benchmark is
> what you are basically doing all the time, then it�s very understandable.
> 
> 
> Andr�

Thanks Andre!

No I'm not going away from it - rather I'm staying - i like the 
interactivity of it, the funny thing about it running on JVM (for good 
or bad, I can get this thing to run on almost any platform, because it 
uses JVM).

Also Rich Hickey seems to know his stuff, and only following his 
creation, is enough to grasp powerful ideas, even if I may not use his 
language at the end professionally.

Definitely I'm staying, and I'm going to dabble into it even more...

For example ARC did not leave me with that impression - to me arc 
sounded like Common Lisp in Rap Lyrics/Slogan... And fact is Paul Graham 
is still my favourite lisp person (I've read his stuff). Maybe I'm 
missing something from ARC too - but that's another topic.
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gn2e3r$32r$1@news.motzarella.org>
Kenneth Tilton schrieb:
> In 25 words or less, why is Clojure better than Common Lisp?
> In 100 words or less, why is Clojure better than Common Lisp?

The word �better� is nothing objective, so people can disagree on what I
personally rate as better.
My list of things that I like in Clojure better than CL
(in no particular order):

1. It basically supports one major paradigm/style of programming,
    the functional one. CL too does support it, but CL also supports
    other styles, and it is even very idiomatic to do imperative
    programming in CL.
    People will disagree if offering a smaller number of programming
    style is better or not, but I like it better. It means that most
    developers will come up with more comparable/compatible solutions.
    Whatever one may think about the Java programming language, it�s a
    fact that it offers a very large set of libraries. This is due to
    the limits which are built in into the language. There is basically
    one way (few ways) to do it, instead of many ways, as in CL.
    So, I prefer to have one major style in Clojure. It happens to be
    the one I preffered since many years in CL too, the functional one.

2. Concurrency ready. I see basically 3 or 4 languages out of the
    many hundreds in use, that are seriously capable of doing concurrent
    programming: Clojure, Erlang, Haskell, and also going there, F#.
    While it is not impossible to do it in other languages, Clojure does
    make it really easy. It�s in some sense the argument that was in
    favour of CL in the past 15-20 years: �Yeah, mathematically speaking
    it is possible in other languages too. In principle one can solve any
    problem in Assembler. It�s just that it is much easier in Lisp, as it
    comes with powerful abstractions�.
    Clojure has gone the evolutionary step into the right direction (in
    my opinion), by providing standard tools for concurrency. Other langs
    like CL or Python can also do functional programming. But the problem
    is that they also offer an alternative way. As long that exists the
    devs have to program by agreement, and they need to be very strict.
    Currently not many languages have a good implementation of a STM with
    Multiversion Concurrency Control. I think for F# one is currently
    being developed. But this really should come with the lang itself,
    as this would be an integral part. If this is an addon lib, then
    other implementations may arise, which can (no doubt) also have ad-
    vantages, but brings back incompatibility.

3. Modernized syntax. It makes totally sense to me (you might disagree
    of course) to have some basic syntax support for the most common
    operations. The CL committee had the same idea in mind and intro-
    duced  '  #'  #+  #-  `  ,  ,@  which, again, makes very much sense
    to me. To make access to datastructures other than lists easier,
    Clojure went a step further, and provides reader macros for vectors
    (which can replace lists to a great part), hashmaps and sets, and
    of course strings (and regular expressions).
    I now hate it so much when I go back to CL that everything is so
    chatty. It does not buy me anything that I have to bloat up my code
    for typical tasks.
    Clojures datastructures are fully integrated into the macro system.

4. Lazyness. In many places Clojure is very lazy :)
    This is great. Not only does that improve performance greatly, no, it
    also allows new idioms and a more elegant programming style. It�s
    well integrated.

5. It runs on the JVM. Today many languages do run in a VM (like CL,
    Python, C#, ...). Why develop your own when you can have the most
    mature one?
    Chosing the JVM brings also tons of advantages:

    a) Operating system does not matter so much anymore. CLs are
       available for most plattforms too, though this does not always
       help. No recompilation needed. I can switch back between the OSes
       and continue coding. The devs of the same team have the choice of
       their OS. The employer would not have to force us anymore to use
       something we don�t like. The plattform in the end is always the
       JVM.

    b) Giant lib. Want a server for RESTful applications? Integration
       with SAP? The JVM can not do magic, but it really haves very
       much to offer, library wise.

    c) Will help to create much more Lisp jobs.
       I personally left two times my home city to get a Lisp job. One
       time I even left my country for it. As Java is the most popular
       programming language it is more likely to find interesting pro-
       jects in cities of my choice. Of course I don�t want to do Java
       programming, but there will always be Java companies (probably
       the not too big ones) that will accept you in their team as a
       Clojure developer. True, it potentially can bring in some diffi-
       culties if you are the only one who can read/write Clojure code.
       But some companies will weight that against the 2x - 20x boost in
       productivity that Lisp can bring over Java. Clojure brings me into
       the position that I suddenly can negotiate something with the
       company.


So, maybe a bit more than 100 words, but here you go.
The points that I listed will not be the ones that everyone else will
also find �better�. I however do.


> Have you switched to Clojure? If so, from what?

Yes, switched from CL to Clojure.
And if it is not necessary, I would not want to go back.
But sure, if Clojure is no option then CL would always be my next
choice.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Mark H.
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <e3f611a2-df15-4552-8d1e-46c14ae78442@q30g2000prq.googlegroups.com>
On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
> In 25 words or less, why is Clojure better than Common Lisp?

Seqs partake of some of the awesomeness of SERIES, but are easier to
use and more native to functional programming.

> In 100 words or less, why is Clojure better than Common Lisp?

As a hobbyist and a student of programming languages, I enjoy using a
language that's new and changing all the time.  I like that Rich
Hickey is actively involved in his language, intelligent, open-minded,
well-read, understands the balance between ideals and practicality,
and is not afraid to make big changes.  I also think that functional
programming will eventually be proven more scalable for programmers
and easier to parallelize, so I'd like to practice using it now with a
Lisp, regardless of whether Clojure itself solves any practical
parallelization problems.

> Have you switched to Clojure? If so, from what?

I don't "switch to" a language, I try it out and determine for what
tasks it's suited.  I use a lot of different languages in my work (C,
Fortran 9x, Python, Matlab, CL, Clojure) and enjoy many of them for
various reasons.

mfh
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <5fce2485-b8bf-491b-88f0-553813a4334d@w24g2000prd.googlegroups.com>
On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>
> > In 25 words or less, why is Clojure better than Common Lisp?
>
> Seqs partake of some of the awesomeness of SERIES, but are easier to
> use and more native to functional programming.

One more time, I can't resist... ;-}

http://common-lisp.net/project/fset/

-- Scott
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnl1k9$gvh$1@news.motzarella.org>
Scott Burson schrieb:
> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>>
>>> In 25 words or less, why is Clojure better than Common Lisp?
>> Seqs partake of some of the awesomeness of SERIES, but are easier to
>> use and more native to functional programming.
> 
> One more time, I can't resist... ;-}
> 
> http://common-lisp.net/project/fset/

Yes, not bad.
But I doubt someone could use this after having used Clojure.
It misses the nice reader macros.
It does not plug in into CL. For example one has to use image
instead of mapcar.
What about REST, LENGTH working on fsets?
There is a do-map, do-seq, do-set, ... instead of just one
thing to do them all.
Examples such as
(isetq m6 (with-default (map ('a (set 1)) ('b (set 2))) (set)))
#{| (A #{ 1 }) (B #{ 2 }) |}/#{ }
(isetq m7 (with-default (map ('b (set "x")) ('c (set "y"))) (set)))
#{| (B #{ "x "}) (C #{" y" }) |}/#{ }
look unreadable and cryptic to me.

Performance wise.. not sure. Rich Hickey spent a good bit of time
to make the concurrency ready Clojure data structures pretty fast.
Most importantly: Fset lacks a STM and MVCC.

But Fset has Bags while Clojure doesn�t.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Russell McManus
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <87d4ddvvgq.fsf@thelonious.cl-user.org>
Andr� Thieme <······························@justmail.de> writes:

> It misses the nice reader macros.

Those could be added very easily, of course.  But you knew that.

-russ
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <27ebc747-5931-479e-824c-d48c0f3888b0@p23g2000prp.googlegroups.com>
On Feb 20, 10:01 am, Russell McManus <···············@yahoo.com>
wrote:
> André Thieme <······························@justmail.de> writes:
> > It misses the nice reader macros.
>
> Those could be added very easily, of course.  But you knew that.

They're in there already.  But I don't use them.  Ordinary Lisp syntax
looks cleaner to me.

-- Scott
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <707p7lFn248bU2@mid.individual.net>
Andr� Thieme wrote:
> Scott Burson schrieb:
>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>>>
>>>> In 25 words or less, why is Clojure better than Common Lisp?
>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
>>> use and more native to functional programming.
>>
>> One more time, I can't resist... ;-}
>>
>> http://common-lisp.net/project/fset/
> 
> Yes, not bad.
> But I doubt someone could use this after having used Clojure.
> It misses the nice reader macros.
> It does not plug in into CL. For example one has to use image
> instead of mapcar.

That's an empty statement. Clojure also doesn't "plug in" into Java.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <97bc1c36-9ea9-4390-a749-66c9d4d01d6f@o11g2000yql.googlegroups.com>
On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
> André Thieme wrote:
> > Scott Burson schrieb:
> >> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> >>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>
> >>>> In 25 words or less, why is Clojure better than Common Lisp?
> >>> Seqs partake of some of the awesomeness of SERIES, but are easier to
> >>> use and more native to functional programming.
>
> >> One more time, I can't resist... ;-}
>
> >>http://common-lisp.net/project/fset/
>
> > Yes, not bad.
> > But I doubt someone could use this after having used Clojure.
> > It misses the nice reader macros.
> > It does not plug in into CL. For example one has to use image
> > instead of mapcar.
>
> That's an empty statement. Clojure also doesn't "plug in" into Java.
>

It's not an empty statement, it's one whose point keeps getting missed/
avoided.

FSet is very nice, but it has to redefine many of the core Lisp
algorithms:

http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/index.html

Why? Because the core algorithms in the COMMON-LISP package do not
extend to new user-defined types like the ones defined by FSet's
author, and more important, neither do existing algorithms defined in
terms of the CL core. That's what is meant by "It does not plug in
into CL". The analogy is not between Clojure plugging into Java but
between new user-defined data types plugging into Clojure's core
algorithms - they can. So such rewriting of algorithms is not
necessary. Old/core algorithms work with new data structures and new
algorithms work with old data structures.

This is not a small nicety, but a critical feature of a language that
purports to be extensible, IMO.

Rich
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <3f4e183f-a955-477c-8e37-d71de7343277@k19g2000yqg.googlegroups.com>
On Feb 20, 6:05 pm, Rich Hickey <··········@gmail.com> wrote:
> It's not an empty statement, it's one whose point keeps getting missed/
> avoided.
>
> FSet is very nice, but it has to redefine many of the core Lisp
> algorithms:
>
> http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>
> Why? Because the core algorithms in the COMMON-LISP package do not
> extend to new user-defined types like the ones defined by FSet's
> author, and more important, neither do existing algorithms defined in
> terms of the CL core. That's what is meant by "It does not plug in
> into CL". The analogy is not between Clojure plugging into Java but
> between new user-defined data types plugging into Clojure's core
> algorithms - they can. So such rewriting of algorithms is not
> necessary. Old/core algorithms work with new data structures and new
> algorithms work with old data structures.

AFAIK, CL is about extensibility, rapid prototyping, metaprogramming
-- those are it's main virtues, by which it stands out. To some extend
you're right, that CL doesn't extend absolutely seamlessly in all
directions, that you might want. It's not perfect. Thought there are
ways around those limitations, which is clearly demonstrated by FSet,
IMO: i.e. it manages to be just a language library, while introducing
a completely different data handling semantics. Yes you should change
you algorithms to use it, but you hardly can demand, that everything
remains unchanged in the face of such a paradigm shift.

AFAIR, the main virtues of Clojure, that you've advertised, are
concurrency support and JVM integration. Now you say, that Clojure is
more extensible, than CL (don't you?). Perhaps that turns out true.
For example, I was quite impressed with your thoughts on abstraction
through interfaces, expressed in the "Clojure for Lisp Hackers" Talk.
But I as well thought the same as Pascal, that as soon as there will
be efforts to extend the language into other directions, you didn't
think of, there may appear the same or even bigger problems, than the
ones we see in CL (which are in practice not so big after all, IMO).

What about this theoretical example? Say, I'd like to implement OCC
(optimistic concurrency control) with some custom conflict resolution
algorithm instead of (or as an alternative to) MVCC in Clojure. Would
it 'plug in' easily? (And this task, I think, can compare from the POV
of the language extensibility capacity with the task of implementing
FSet data types instead of the standard CL data types...)

Best regards,
Vsevolod
From: Tobias C. Rittweiler
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <87ab8hjcd5.fsf@freebits.de>
Rich Hickey <...> writes:

> ... Because the core algorithms in the COMMON-LISP package do not
> extend to new user-defined types like the ones defined by FSet's
> author, and more important, neither do existing algorithms defined in
> terms of the CL core. That's what is meant by "It does not plug in
> into CL". ...
>
> This is not a small nicety, but a critical feature of a language that
> purports to be extensible, IMO.

In case of Common Lisp, you can, however, do the following:

  - define a package GENERIC-CL where all your wished core functions are
    defined as generic functions; for built-in classes, it invokes the
    function from the CL package. Unfortunately, the default case has to
    be reimplemented, of course. (PJB did already do this partially. 
    Parts from SACLA can be used for the reimplementation.)

  - rename the CL package to CLOLD. [*]

  - rename GENERIC-CL to CL.

  - recompile your libraries.

It's annoying. It's not smooth. Perhaps kludgy. But it's possible.

  -T.

[*] SBCL signals a package lock violation on this one. I shortly browsed
    through the CLHS but couldn't find where it prohibits such renaming.
From: Pascal J. Bourguignon
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <87ocwxf3kn.fsf@galatea.local>
"Tobias C. Rittweiler" <···@freebits.de.invalid> writes:
> [*] SBCL signals a package lock violation on this one. I shortly browsed
>     through the CLHS but couldn't find where it prohibits such renaming.

Indeed, but it's nice from an implementation to introduce the notion
of package locks, and to have the CL and other system package be
locked by default.

As you can see in budden's thread, it would make a nice CDR to have
implementations standardize on this point.

-- 
__Pascal Bourguignon__
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <708ivvFmndnuU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
>> Andr� Thieme wrote:
>>> Scott Burson schrieb:
>>>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
>>>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>>>>>> In 25 words or less, why is Clojure better than Common Lisp?
>>>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
>>>>> use and more native to functional programming.
>>>> One more time, I can't resist... ;-}
>>>> http://common-lisp.net/project/fset/
>>> Yes, not bad.
>>> But I doubt someone could use this after having used Clojure.
>>> It misses the nice reader macros.
>>> It does not plug in into CL. For example one has to use image
>>> instead of mapcar.
>> That's an empty statement. Clojure also doesn't "plug in" into Java.
> 
> It's not an empty statement, it's one whose point keeps getting missed/
> avoided.

It's a totally empty statement. And I definitely get your point you're 
trying to make, but you are missing a different point here.

> FSet is very nice, but it has to redefine many of the core Lisp
> algorithms:
> 
> http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/index.html
> 
> Why? Because the core algorithms in the COMMON-LISP package do not
> extend to new user-defined types like the ones defined by FSet's
> author, and more important, neither do existing algorithms defined in
> terms of the CL core. That's what is meant by "It does not plug in
> into CL". The analogy is not between Clojure plugging into Java but
> between new user-defined data types plugging into Clojure's core
> algorithms - they can. So such rewriting of algorithms is not
> necessary. Old/core algorithms work with new data structures and new
> algorithms work with old data structures.
> 
> This is not a small nicety, but a critical feature of a language that
> purports to be extensible, IMO.

FSet relates to Common Lisp in exactly the same way as Clojure relates 
to Java. You decided to use Java as the "back end" for implementing 
Clojure (or more precisely the JVM, but I will use that interchangeably 
here in this context), while Scott Burson decided to use Common Lisp as 
the "back end" for implementing FSet. The only real difference here is 
that FSet has the advantage that CL macros and functions can be directly 
used to implement it, while for Clojure you had to implement your own 
scanner/parser/compiler on top of Java.

Criticizing FSet that algorithms implemented on top of core Common Lisp 
cannot smoothly be reused with FSet data structures is exactly at the 
same level as criticizing Clojure that existing Java algorithms cannot 
smoothly be reused with Clojure data structures. The only reason why you 
seem to confuse this is that Common Lisp syntax and FSet syntax look 
(and are) exactly the same, while in the case of Java vs. Clojure, there 
is a sharp and clear border between implementation language and 
implemented language.

It's a fundamental problem of language extensions in general: Different 
language extensions do not compose for free, and there is no remedy 
against that in the general case. You will get exactly the same problems 
as soon as people start to build their own language extensions on top of 
Clojure. Say, one person implements a dataflow extension for Clojure, 
another implements a logic language for Clojure, then you won't be able 
to just throw them together and expect to be able to use them in 
conjunction either. Clojure would be as little to blame in this regard 
as Common Lisp is to blame that FSet doesn't smoothly work in 
conjunction with other algorithms and extensions.

Yes, you can prepare for certain extensions to become easier to plug in, 
and you seem to have done a pretty good job with Clojure for the core 
collections. But at the same time, you have thrown the baby out with the 
bathwater - no existing Lisp and Scheme libraries will just work out of 
the box with Clojure either, a lot of stuff has to be rebuilt from 
scratch. Again, you had what seems to be good reasons, so I have no 
gripes with that. But please keep the comparison fair.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Vend
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <7d835fda-9d3c-4107-b63f-813e3de3b8e5@o36g2000yqh.googlegroups.com>
On 20 Feb, 21:43, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
> >> André Thieme wrote:
> >>> Scott Burson schrieb:
> >>>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> >>>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
> >>>>>> In 25 words or less, why is Clojure better than Common Lisp?
> >>>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
> >>>>> use and more native to functional programming.
> >>>> One more time, I can't resist... ;-}
> >>>>http://common-lisp.net/project/fset/
> >>> Yes, not bad.
> >>> But I doubt someone could use this after having used Clojure.
> >>> It misses the nice reader macros.
> >>> It does not plug in into CL. For example one has to use image
> >>> instead of mapcar.
> >> That's an empty statement. Clojure also doesn't "plug in" into Java.
>
> > It's not an empty statement, it's one whose point keeps getting missed/
> > avoided.
>
> It's a totally empty statement. And I definitely get your point you're
> trying to make, but you are missing a different point here.
>
>
>
> > FSet is very nice, but it has to redefine many of the core Lisp
> > algorithms:
>
> >http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>
> > Why? Because the core algorithms in the COMMON-LISP package do not
> > extend to new user-defined types like the ones defined by FSet's
> > author, and more important, neither do existing algorithms defined in
> > terms of the CL core. That's what is meant by "It does not plug in
> > into CL". The analogy is not between Clojure plugging into Java but
> > between new user-defined data types plugging into Clojure's core
> > algorithms - they can. So such rewriting of algorithms is not
> > necessary. Old/core algorithms work with new data structures and new
> > algorithms work with old data structures.
>
> > This is not a small nicety, but a critical feature of a language that
> > purports to be extensible, IMO.
>
> FSet relates to Common Lisp in exactly the same way as Clojure relates
> to Java. You decided to use Java as the "back end" for implementing
> Clojure (or more precisely the JVM, but I will use that interchangeably
> here in this context), while Scott Burson decided to use Common Lisp as
> the "back end" for implementing FSet. The only real difference here is
> that FSet has the advantage that CL macros and functions can be directly
> used to implement it, while for Clojure you had to implement your own
> scanner/parser/compiler on top of Java.
>
> Criticizing FSet that algorithms implemented on top of core Common Lisp
> cannot smoothly be reused with FSet data structures is exactly at the
> same level as criticizing Clojure that existing Java algorithms cannot
> smoothly be reused with Clojure data structures. The only reason why you
> seem to confuse this is that Common Lisp syntax and FSet syntax look
> (and are) exactly the same, while in the case of Java vs. Clojure, there
> is a sharp and clear border between implementation language and
> implemented language.

FSet is a library, not a language.
If I understand correctly, native immutable collections are just one
feature of Clojure, and it integrates well with other features
(polymorphic collection manipulation and concurrency control).

> It's a fundamental problem of language extensions in general: Different
> language extensions do not compose for free, and there is no remedy
> against that in the general case. You will get exactly the same problems
> as soon as people start to build their own language extensions on top of
> Clojure. Say, one person implements a dataflow extension for Clojure,
> another implements a logic language for Clojure, then you won't be able
> to just throw them together and expect to be able to use them in
> conjunction either. Clojure would be as little to blame in this regard
> as Common Lisp is to blame that FSet doesn't smoothly work in
> conjunction with other algorithms and extensions.
>
> Yes, you can prepare for certain extensions to become easier to plug in,
> and you seem to have done a pretty good job with Clojure for the core
> collections. But at the same time, you have thrown the baby out with the
> bathwater - no existing Lisp and Scheme libraries will just work out of
> the box with Clojure either, a lot of stuff has to be rebuilt from
> scratch. Again, you had what seems to be good reasons, so I have no
> gripes with that. But please keep the comparison fair.
>
> Pascal
>
> --
> ELS'09:http://www.european-lisp-symposium.org/
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <499f43b8$0$5908$607ed4bc@cv.net>
Vend wrote:
> On 20 Feb, 21:43, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Andr� Thieme wrote:
>>>>> Scott Burson schrieb:
>>>>>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
>>>>>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>>>>>>>> In 25 words or less, why is Clojure better than Common Lisp?
>>>>>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
>>>>>>> use and more native to functional programming.
>>>>>> One more time, I can't resist... ;-}
>>>>>> http://common-lisp.net/project/fset/
>>>>> Yes, not bad.
>>>>> But I doubt someone could use this after having used Clojure.
>>>>> It misses the nice reader macros.
>>>>> It does not plug in into CL. For example one has to use image
>>>>> instead of mapcar.
>>>> That's an empty statement. Clojure also doesn't "plug in" into Java.
>>> It's not an empty statement, it's one whose point keeps getting missed/
>>> avoided.
>> It's a totally empty statement. And I definitely get your point you're
>> trying to make, but you are missing a different point here.
>>
>>
>>
>>> FSet is very nice, but it has to redefine many of the core Lisp
>>> algorithms:
>>> http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>>> Why? Because the core algorithms in the COMMON-LISP package do not
>>> extend to new user-defined types like the ones defined by FSet's
>>> author, and more important, neither do existing algorithms defined in
>>> terms of the CL core. That's what is meant by "It does not plug in
>>> into CL". The analogy is not between Clojure plugging into Java but
>>> between new user-defined data types plugging into Clojure's core
>>> algorithms - they can. So such rewriting of algorithms is not
>>> necessary. Old/core algorithms work with new data structures and new
>>> algorithms work with old data structures.
>>> This is not a small nicety, but a critical feature of a language that
>>> purports to be extensible, IMO.
>> FSet relates to Common Lisp in exactly the same way as Clojure relates
>> to Java. You decided to use Java as the "back end" for implementing
>> Clojure (or more precisely the JVM, but I will use that interchangeably
>> here in this context), while Scott Burson decided to use Common Lisp as
>> the "back end" for implementing FSet. The only real difference here is
>> that FSet has the advantage that CL macros and functions can be directly
>> used to implement it, while for Clojure you had to implement your own
>> scanner/parser/compiler on top of Java.
>>
>> Criticizing FSet that algorithms implemented on top of core Common Lisp
>> cannot smoothly be reused with FSet data structures is exactly at the
>> same level as criticizing Clojure that existing Java algorithms cannot
>> smoothly be reused with Clojure data structures. The only reason why you
>> seem to confuse this is that Common Lisp syntax and FSet syntax look
>> (and are) exactly the same, while in the case of Java vs. Clojure, there
>> is a sharp and clear border between implementation language and
>> implemented language.
> 
> FSet is a library, not a language.
> If I understand correctly, native immutable collections are just one
> feature of Clojure, and it integrates well with other features
> (polymorphic collection manipulation and concurrency control).

Right. The question is whether Clojure collections work seamlessly with 
Clojure. And it do. The underlying Java implementation don't enter into 
it any more than does the machine language into which CL gets compiled, 
cuz Clojure ain't Java, it just has easy access to it.

OTOH, Tilton's Law of Programming Language Advancement says "Make New 
Data Structures, Not New Languages", and FSet does that.*

Methinks that the choice comes down to whether one needs these 
functional doobries all the way down or whether one would prefer to keep 
CL and use the doobries where vital.

kt

* But there are reasons than functional doobries for Clojure's 
existence. So... k
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <708si6Fn2vrdU1@mid.individual.net>
Vend wrote:
> On 20 Feb, 21:43, Pascal Costanza <····@p-cos.net> wrote:
>> Criticizing FSet that algorithms implemented on top of core Common Lisp
>> cannot smoothly be reused with FSet data structures is exactly at the
>> same level as criticizing Clojure that existing Java algorithms cannot
>> smoothly be reused with Clojure data structures. The only reason why you
>> seem to confuse this is that Common Lisp syntax and FSet syntax look
>> (and are) exactly the same, while in the case of Java vs. Clojure, there
>> is a sharp and clear border between implementation language and
>> implemented language.
> 
> FSet is a library, not a language.
> If I understand correctly, native immutable collections are just one
> feature of Clojure, and it integrates well with other features
> (polymorphic collection manipulation and concurrency control).

I picked FSet as a mere example. Whether you treat FSet as a library or 
as a language is largely up to you. You have the choice of treating FSet 
as the main building block for having flexible collections and ignore 
all the other collection-like datatypes in Common Lisp. In that case, 
you treat FSet (or rather Common Lisp-- + FSet) as your new language, 
and you won't have to deal with the limitations of the underlying Common 
Lips data structures anymore.

You could do the same with cl-containers. You could also do the same 
with other language extensions. For example, you could decide to ignore 
defun, and use only defmethod. Or you could decide to ignore defgeneric 
and use only define-layered-function for even more extensibility. You 
could decide to choose QI as your main language and not use the rest of 
Common Lisp anymore. You could restrict yourself to the subset that is 
defined by ACL2 and get the added benefit that you can prove interesting 
properties of your algorithms. You can choose to ignore portability, 
pick one particular CL implementation (say, Clozure Common Lisp), ignore 
all the others and treat the implementation of your choice as a 
single-implementation language (for example, in order to stop worrying 
about being able to use only lowest common denominators for, say, 
multithreading). And so on, and so on.

I sometimes get the impression that people forget too easily that all 
these options exist. You don't necessarily have to start from scratch 
and build a completely new Lisp dialect just because you don't like some 
particular aspects of Common Lisp (or Scheme, or whatever).


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Helmut Eller
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <m2iqn4w3fw.fsf@gmail.com>
* Vend [2009-02-20 22:26+0100] writes:

> FSet is a library, not a language.
> If I understand correctly, native immutable collections are just one
> feature of Clojure, and it integrates well with other features
> (polymorphic collection manipulation and concurrency control).

I'm confused by this whole discussion.

Aren't Clojure's collection classes just a library and the Clojure
compiler/language treats them just like any other Java class?  Is there
a reason why those classes could not be used in normal Java programs?

I also don't understand how those collections can improve concurrency
control beyond ordinary Java libraries.  It seems to me that those
classes fall in the same category as the java.util.concurrency package.
Useful for sure, but claiming that those classes "ensure clean, correct,
multithreaded designs" seems a bit far fetched.  Especially, since "Java
interop" has high priority and hence Clojure has to live with the
existing designs of Java frameworks and can't change those
after-the-fact.

Helmut.
From: Vend
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <11696013-1368-450f-9582-199f88fb7d17@x9g2000yqk.googlegroups.com>
On 21 Feb, 10:21, Helmut Eller <············@gmail.com> wrote:
> * Vend [2009-02-20 22:26+0100] writes:
>
> > FSet is a library, not a language.
> > If I understand correctly, native immutable collections are just one
> > feature of Clojure, and it integrates well with other features
> > (polymorphic collection manipulation and concurrency control).
>
> I'm confused by this whole discussion.
>
> Aren't Clojure's collection classes just a library and the Clojure
> compiler/language treats them just like any other Java class?  Is there
> a reason why those classes could not be used in normal Java programs?

I think so.

> I also don't understand how those collections can improve concurrency
> control beyond ordinary Java libraries.

Clojure concurrency model relies on creating lots of local copies of
shared structures.
This can be done efficiently with immutable structures, since you just
need to copy a pointer.

>  It seems to me that those
> classes fall in the same category as the java.util.concurrency package.
> Useful for sure, but claiming that those classes "ensure clean, correct,
> multithreaded designs" seems a bit far fetched.  Especially, since "Java
> interop" has high priority and hence Clojure has to live with the
> existing designs of Java frameworks and can't change those
> after-the-fact.
>
> Helmut.
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <4710193e-29c5-4bbb-883e-5045eff19ccc@t11g2000yqg.googlegroups.com>
On Feb 21, 4:21 am, Helmut Eller <············@gmail.com> wrote:
> * Vend [2009-02-20 22:26+0100] writes:
>
> > FSet is a library, not a language.
> > If I understand correctly, native immutable collections are just one
> > feature of Clojure, and it integrates well with other features
> > (polymorphic collection manipulation and concurrency control).
>
> I'm confused by this whole discussion.
>
> Aren't Clojure's collection classes just a library and the Clojure
> compiler/language treats them just like any other Java class?

Yes.

> Is there
> a reason why those classes could not be used in normal Java programs?
>

None at all.

> I also don't understand how those collections can improve concurrency
> control beyond ordinary Java libraries.  It seems to me that those
> classes fall in the same category as the java.util.concurrency package.
> Useful for sure, but claiming that those classes "ensure clean, correct,
> multithreaded designs" seems a bit far fetched.  Especially, since "Java
> interop" has high priority and hence Clojure has to live with the
> existing designs of Java frameworks and can't change those
> after-the-fact.
>

The claim applies only to the use of Clojure's data structures and
other facilities - i.e. Clojure gives you the tools to write correct
programs easily. Obviously Clojure has no magic that transforms all
the Java crud into thread-safe designs.

As far as the difference between Clojure's collections and those of
java.util.concurrent - they serve different purposes and both can be
used productively in Clojure programs. j.u.c collections are thread-
safely mutable without user locking. They serve as extremely efficient
caches, for example. But they have a limited API, centered around
atomic activity, e.g. it is not possible, in the face of concurrent
activity, to determine if 2 items are in a j.u.c collection, nor if
one item is in two j.u.c collections, since those actions are not
atomic and there is no way to make them so.

Clojure's collections are immutable, and emphasize programming with
values. It is easy in Clojure to determine if 2 items occur in a
Clojure collection, as it can't change. Determining if an item is in
two collections is possible with Clojure's STM and transactions.

Rich
From: Helmut Eller
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <m2vdr3rbqw.fsf@gmail.com>
* Rich Hickey [2009-02-21 15:42+0100] writes:

> Clojure's collections are immutable, and emphasize programming with
> values. It is easy in Clojure to determine if 2 items occur in a
> Clojure collection, as it can't change. Determining if an item is in
> two collections is possible with Clojure's STM and transactions.

Thank you for your answers.  Exactly what I wanted to know.

Helmut.
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70a8hmFnhhavU1@mid.individual.net>
Helmut Eller wrote:
> * Vend [2009-02-20 22:26+0100] writes:
> 
>> FSet is a library, not a language.
>> If I understand correctly, native immutable collections are just one
>> feature of Clojure, and it integrates well with other features
>> (polymorphic collection manipulation and concurrency control).
> 
> I'm confused by this whole discussion.
> 
> Aren't Clojure's collection classes just a library and the Clojure
> compiler/language treats them just like any other Java class?  Is there
> a reason why those classes could not be used in normal Java programs?

They can be used in Java, but you have to adapt your programming style. 
Existing Java code will not just automagically work with them in the 
general case.

> I also don't understand how those collections can improve concurrency
> control beyond ordinary Java libraries.  It seems to me that those
> classes fall in the same category as the java.util.concurrency package.
> Useful for sure, but claiming that those classes "ensure clean, correct,
> multithreaded designs" seems a bit far fetched.  Especially, since "Java
> interop" has high priority and hence Clojure has to live with the
> existing designs of Java frameworks and can't change those
> after-the-fact.
> 
> Helmut.


-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <edc875a5-2ade-4199-b987-0b4f314fc4af@j1g2000yqi.googlegroups.com>
On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
> Helmut Eller wrote:
> > * Vend [2009-02-20 22:26+0100] writes:
>
> >> FSet is a library, not a language.
> >> If I understand correctly, native immutable collections are just one
> >> feature of Clojure, and it integrates well with other features
> >> (polymorphic collection manipulation and concurrency control).
>
> > I'm confused by this whole discussion.
>
> > Aren't Clojure's collection classes just a library and the Clojure
> > compiler/language treats them just like any other Java class?  Is there
> > a reason why those classes could not be used in normal Java programs?
>
> They can be used in Java, but you have to adapt your programming style.
> Existing Java code will not just automagically work with them in the
> general case.
>

This is FUD - please stop spreading it.

Rich
From: ·····@franz.com
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <d66ba80c-d61a-4060-aaa1-4d5f46d053ad@p2g2000prf.googlegroups.com>
On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>
>
>
> > Helmut Eller wrote:
> > > * Vend [2009-02-20 22:26+0100] writes:
>
> > >> FSet is a library, not a language.
> > >> If I understand correctly, native immutable collections are just one
> > >> feature of Clojure, and it integrates well with other features
> > >> (polymorphic collection manipulation and concurrency control).
>
> > > I'm confused by this whole discussion.
>
> > > Aren't Clojure's collection classes just a library and the Clojure
> > > compiler/language treats them just like any other Java class?  Is there
> > > a reason why those classes could not be used in normal Java programs?
>
> > They can be used in Java, but you have to adapt your programming style.
> > Existing Java code will not just automagically work with them in the
> > general case.
>
> This is FUD - please stop spreading it.

Pascal is not likely to wave his own flag, but I don't think you
realize whom you are talking to.  Pascal was a Java programmer long
before he switched to Common Lisp, and his first writings on Common
Lisp (http://p-cos.net/lisp/guide.html) provide some of his
background.  However, even if you look up his credentials and are not
impressed, at least realize what you yourself are doing; you are
posting in a Lisp newsgroup arguing with someone who has switched his
major emphasis from Java to Lisp, and so cries of FUD are going to
fall on deaf ears and numb them to other things you have to say.

Duane
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <9256e642-8806-423c-acbf-b50928b9d8c8@v13g2000yqm.googlegroups.com>
On Feb 21, 1:16 pm, ·····@franz.com wrote:
> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>
>
>
> > On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>
> > > Helmut Eller wrote:
> > > > * Vend [2009-02-20 22:26+0100] writes:
>
> > > >> FSet is a library, not a language.
> > > >> If I understand correctly, native immutable collections are just one
> > > >> feature of Clojure, and it integrates well with other features
> > > >> (polymorphic collection manipulation and concurrency control).
>
> > > > I'm confused by this whole discussion.
>
> > > > Aren't Clojure's collection classes just a library and the Clojure
> > > > compiler/language treats them just like any other Java class?  Is there
> > > > a reason why those classes could not be used in normal Java programs?
>
> > > They can be used in Java, but you have to adapt your programming style.
> > > Existing Java code will not just automagically work with them in the
> > > general case.
>
> > This is FUD - please stop spreading it.
>
> Pascal is not likely to wave his own flag, but I don't think you
> realize whom you are talking to.  Pascal was a Java programmer long
> before he switched to Common Lisp, and his first writings on Common
> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> background.  However, even if you look up his credentials and are not
> impressed, at least realize what you yourself are doing; you are
> posting in a Lisp newsgroup arguing with someone who has switched his
> major emphasis from Java to Lisp, and so cries of FUD are going to
> fall on deaf ears and numb them to other things you have to say.


I do know Pascal. We've met several times and had some great
discussions. I respect both him and his work. I know Pascal's opinions
are well regarded here, all the more reason for them to be accurate. I
too came to Lisp from C++/Java/C#, and greatly value the areas in
which it is superior. But his statement above is simply wrong. It is
not a matter of qualifications or opinion. If you have existing Java
code that takes a collection and does not mutate it you can pass a
Clojure collection and it will work without change or adaptation, i.e.
"automagically". There is a large body of Java code for which this is
true, and people are leveraging that capability every day.

Clojure has been out for over a year and I have never come here to
evangelize it. Now it is being discussed by others, and some
inaccurate things have been said. I'm just trying to keep the
discussion accurate, and have no aspirations of convincing anyone here
of anything.

Rich
From: ·····@franz.com
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <56830bb6-b5d2-47fc-a12c-20dd89ef838e@i38g2000yqd.googlegroups.com>
On Feb 21, 11:32 am, Rich Hickey <··········@gmail.com> wrote:
> On Feb 21, 1:16 pm, ·····@franz.com wrote:
>
>
>
> > On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>
> > > On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>
> > > > Helmut Eller wrote:
> > > > > * Vend [2009-02-20 22:26+0100] writes:
>
> > > > >> FSet is a library, not a language.
> > > > >> If I understand correctly, native immutable collections are just one
> > > > >> feature of Clojure, and it integrates well with other features
> > > > >> (polymorphic collection manipulation and concurrency control).
>
> > > > > I'm confused by this whole discussion.
>
> > > > > Aren't Clojure's collection classes just a library and the Clojure
> > > > > compiler/language treats them just like any other Java class?  Is there
> > > > > a reason why those classes could not be used in normal Java programs?
>
> > > > They can be used in Java, but you have to adapt your programming style.
> > > > Existing Java code will not just automagically work with them in the
> > > > general case.
>
> > > This is FUD - please stop spreading it.
>
> > Pascal is not likely to wave his own flag, but I don't think you
> > realize whom you are talking to.  Pascal was a Java programmer long
> > before he switched to Common Lisp, and his first writings on Common
> > Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> > background.  However, even if you look up his credentials and are not
> > impressed, at least realize what you yourself are doing; you are
> > posting in a Lisp newsgroup arguing with someone who has switched his
> > major emphasis from Java to Lisp, and so cries of FUD are going to
> > fall on deaf ears and numb them to other things you have to say.
>
> I do know Pascal. We've met several times and had some great
> discussions. I respect both him and his work. I know Pascal's opinions
> are well regarded here, all the more reason for them to be accurate. I
> too came to Lisp from C++/Java/C#, and greatly value the areas in
> which it is superior. But his statement above is simply wrong. It is
> not a matter of qualifications or opinion. If you have existing Java
> code that takes a collection and does not mutate it you can pass a
> Clojure collection and it will work without change or adaptation, i.e.
> "automagically". There is a large body of Java code for which this is
> true, and people are leveraging that capability every day.
>
> Clojure has been out for over a year and I have never come here to
> evangelize it. Now it is being discussed by others, and some
> inaccurate things have been said. I'm just trying to keep the
> discussion accurate, and have no aspirations of convincing anyone here
> of anything.

That's fine.  Have your discussion.  I'm following along with
interest, but when I hear words like FUD, which usually come out of
frustrated efforts to indeed convince someone of something, something
clicks off in me, and I go into a different mode than listening to a
spirited discussion between peers.  And especially when the word is
used several times (I recall at least two, though I'm not going to
look them up) I sense a frustration that detracts from your
argumentation.  Take a short break.  Gather your thoughts.  Take a
different approach.  On the other hand, if you have no aspirations of
convincing anyone here, why do you continue? (rhetorical question, of
course)...

Duane
From: Tamas K Papp
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70bvqfF2cjmU1@mid.individual.net>
On Sat, 21 Feb 2009 18:08:47 -0800, duane wrote:

> On the other hand, if
> you have no aspirations of convincing anyone here, why do you continue?

http://xkcd.com/386/

Tamas
From: William James
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnpmi30bmt@enews5.newsguy.com>
Rich Hickey wrote:

> I'm just trying to keep the
> discussion accurate, and have no aspirations of convincing anyone here
> of anything.

You are a realist.  You realize that logical argument won't
convince a man to change his religion.
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70b48jF2sjoU2@mid.individual.net>
Rich Hickey wrote:
> On Feb 21, 1:16 pm, ·····@franz.com wrote:
>> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>>
>>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Helmut Eller wrote:
>>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>>> FSet is a library, not a language.
>>>>>> If I understand correctly, native immutable collections are just one
>>>>>> feature of Clojure, and it integrates well with other features
>>>>>> (polymorphic collection manipulation and concurrency control).
>>>>> I'm confused by this whole discussion.
>>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>>> compiler/language treats them just like any other Java class?  Is there
>>>>> a reason why those classes could not be used in normal Java programs?
>>>> They can be used in Java, but you have to adapt your programming style.
>>>> Existing Java code will not just automagically work with them in the
>>>> general case.
>>> This is FUD - please stop spreading it.
>> Pascal is not likely to wave his own flag, but I don't think you
>> realize whom you are talking to.  Pascal was a Java programmer long
>> before he switched to Common Lisp, and his first writings on Common
>> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
>> background.  However, even if you look up his credentials and are not
>> impressed, at least realize what you yourself are doing; you are
>> posting in a Lisp newsgroup arguing with someone who has switched his
>> major emphasis from Java to Lisp, and so cries of FUD are going to
>> fall on deaf ears and numb them to other things you have to say.
> 
> I do know Pascal. We've met several times and had some great
> discussions. I respect both him and his work. I know Pascal's opinions
> are well regarded here, all the more reason for them to be accurate. I
> too came to Lisp from C++/Java/C#, and greatly value the areas in
> which it is superior. But his statement above is simply wrong. It is
> not a matter of qualifications or opinion. If you have existing Java
> code that takes a collection and does not mutate it you can pass a
> Clojure collection and it will work without change or adaptation, i.e.
> "automagically".

Two statements have been made, a qualified and an unqualified one. The 
unqualified one was "Clojure's collections work seamlessly with Java 
code" and the qualified one was "Clojure's collections work seamlessly 
with Java code that doesn't mutate them." The first statement is wrong, 
the second statement is correct.

> There is a large body of Java code for which this is
> true, and people are leveraging that capability every day.

This may be true, but it doesn't mean that you can afford not to check 
whether some arbitrary Java code is compatible with Clojure collections.

> Clojure has been out for over a year and I have never come here to
> evangelize it. Now it is being discussed by others, and some
> inaccurate things have been said. I'm just trying to keep the
> discussion accurate, and have no aspirations of convincing anyone here
> of anything.

I agree that the discussion should be accurate.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <1a94e943-c522-41bf-803e-00314079e0bf@w34g2000yqm.googlegroups.com>
On Feb 21, 2:50 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 21, 1:16 pm, ·····@franz.com wrote:
> >> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>
> >>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
> >>>> Helmut Eller wrote:
> >>>>> * Vend [2009-02-20 22:26+0100] writes:
> >>>>>> FSet is a library, not a language.
> >>>>>> If I understand correctly, native immutable collections are just one
> >>>>>> feature of Clojure, and it integrates well with other features
> >>>>>> (polymorphic collection manipulation and concurrency control).
> >>>>> I'm confused by this whole discussion.
> >>>>> Aren't Clojure's collection classes just a library and the Clojure
> >>>>> compiler/language treats them just like any other Java class?  Is there
> >>>>> a reason why those classes could not be used in normal Java programs?
> >>>> They can be used in Java, but you have to adapt your programming style.
> >>>> Existing Java code will not just automagically work with them in the
> >>>> general case.
> >>> This is FUD - please stop spreading it.
> >> Pascal is not likely to wave his own flag, but I don't think you
> >> realize whom you are talking to.  Pascal was a Java programmer long
> >> before he switched to Common Lisp, and his first writings on Common
> >> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> >> background.  However, even if you look up his credentials and are not
> >> impressed, at least realize what you yourself are doing; you are
> >> posting in a Lisp newsgroup arguing with someone who has switched his
> >> major emphasis from Java to Lisp, and so cries of FUD are going to
> >> fall on deaf ears and numb them to other things you have to say.
>
> > I do know Pascal. We've met several times and had some great
> > discussions. I respect both him and his work. I know Pascal's opinions
> > are well regarded here, all the more reason for them to be accurate. I
> > too came to Lisp from C++/Java/C#, and greatly value the areas in
> > which it is superior. But his statement above is simply wrong. It is
> > not a matter of qualifications or opinion. If you have existing Java
> > code that takes a collection and does not mutate it you can pass a
> > Clojure collection and it will work without change or adaptation, i.e.
> > "automagically".
>
> Two statements have been made, a qualified and an unqualified one. The
> unqualified one was "Clojure's collections work seamlessly with Java
> code" and the qualified one was "Clojure's collections work seamlessly
> with Java code that doesn't mutate them." The first statement is wrong,
> the second statement is correct.
>

Not true. The qualifier wasn't for the seamlessness, but for the
utility.

> > There is a large body of Java code for which this is
> > true, and people are leveraging that capability every day.
>
> This may be true, but it doesn't mean that you can afford not to check
> whether some arbitrary Java code is compatible with Clojure collections.
>

Absolutely not. A Clojure collection will work with existing Java code
in precisely the same way as an immutable Java collection, which is
already a legal and possible thing, you can create them, i.e. with
java.util.Collections.unmodifiableList/Map/Set etc. That is, existing
Java code, with whatever policy it has chosen for handling immutable
collections (which has nothing to do with Clojure), will work the same
way, unchanged, with Clojure collections. Other aspects of seamless
that come into play are the lack of copying, lack of adapter or
wrapper classes, direct support for the interfaces, testability via
instanceof, hashCode and equality semantics etc. I think it's seamless
for any reasonable definition of seamless.

Rich
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70bbe3F60moU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 21, 2:50 pm, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 21, 1:16 pm, ·····@franz.com wrote:
>>>> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>>>>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>>>>> Helmut Eller wrote:
>>>>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>>>>> FSet is a library, not a language.
>>>>>>>> If I understand correctly, native immutable collections are just one
>>>>>>>> feature of Clojure, and it integrates well with other features
>>>>>>>> (polymorphic collection manipulation and concurrency control).
>>>>>>> I'm confused by this whole discussion.
>>>>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>>>>> compiler/language treats them just like any other Java class?  Is there
>>>>>>> a reason why those classes could not be used in normal Java programs?
>>>>>> They can be used in Java, but you have to adapt your programming style.
>>>>>> Existing Java code will not just automagically work with them in the
>>>>>> general case.
>>>>> This is FUD - please stop spreading it.
>>>> Pascal is not likely to wave his own flag, but I don't think you
>>>> realize whom you are talking to.  Pascal was a Java programmer long
>>>> before he switched to Common Lisp, and his first writings on Common
>>>> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
>>>> background.  However, even if you look up his credentials and are not
>>>> impressed, at least realize what you yourself are doing; you are
>>>> posting in a Lisp newsgroup arguing with someone who has switched his
>>>> major emphasis from Java to Lisp, and so cries of FUD are going to
>>>> fall on deaf ears and numb them to other things you have to say.
>>> I do know Pascal. We've met several times and had some great
>>> discussions. I respect both him and his work. I know Pascal's opinions
>>> are well regarded here, all the more reason for them to be accurate. I
>>> too came to Lisp from C++/Java/C#, and greatly value the areas in
>>> which it is superior. But his statement above is simply wrong. It is
>>> not a matter of qualifications or opinion. If you have existing Java
>>> code that takes a collection and does not mutate it you can pass a
>>> Clojure collection and it will work without change or adaptation, i.e.
>>> "automagically".
>> Two statements have been made, a qualified and an unqualified one. The
>> unqualified one was "Clojure's collections work seamlessly with Java
>> code" and the qualified one was "Clojure's collections work seamlessly
>> with Java code that doesn't mutate them." The first statement is wrong,
>> the second statement is correct.
> 
> Not true. The qualifier wasn't for the seamlessness, but for the
> utility.

I made the qualified statement. I guess I know better what the qualifier 
was for.

>>> There is a large body of Java code for which this is
>>> true, and people are leveraging that capability every day.
>> This may be true, but it doesn't mean that you can afford not to check
>> whether some arbitrary Java code is compatible with Clojure collections.
> 
> Absolutely not.

Do I speak Spanish, or what?!?

import clojure.lang.*;
import java.util.*;

public class Test {

   public static void main(String[] args) {
     Cons cons = new Cons(1, new Cons(2, new Cons(3, null)));
     Collections.addAll(cons,4);
     System.out.println(cons);
   }
}


java -classpath clojure.jar Test
Exception in thread "main" java.lang.UnsupportedOperationException
	at clojure.lang.ASeq.add(ASeq.java:109)
	at java.util.Collections.addAll(Collections.java:3515)
	at Test.main(Test.java:8)



Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <45a81ca4-9bf1-49c8-95a3-bf7a3302fa4e@a12g2000yqm.googlegroups.com>
On Feb 21, 4:53 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 21, 2:50 pm, Pascal Costanza <····@p-cos.net> wrote:
> >> Rich Hickey wrote:
> >>> On Feb 21, 1:16 pm, ·····@franz.com wrote:
> >>>> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
> >>>>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
> >>>>>> Helmut Eller wrote:
> >>>>>>> * Vend [2009-02-20 22:26+0100] writes:
> >>>>>>>> FSet is a library, not a language.
> >>>>>>>> If I understand correctly, native immutable collections are just one
> >>>>>>>> feature of Clojure, and it integrates well with other features
> >>>>>>>> (polymorphic collection manipulation and concurrency control).
> >>>>>>> I'm confused by this whole discussion.
> >>>>>>> Aren't Clojure's collection classes just a library and the Clojure
> >>>>>>> compiler/language treats them just like any other Java class?  Is there
> >>>>>>> a reason why those classes could not be used in normal Java programs?
> >>>>>> They can be used in Java, but you have to adapt your programming style.
> >>>>>> Existing Java code will not just automagically work with them in the
> >>>>>> general case.
> >>>>> This is FUD - please stop spreading it.
> >>>> Pascal is not likely to wave his own flag, but I don't think you
> >>>> realize whom you are talking to.  Pascal was a Java programmer long
> >>>> before he switched to Common Lisp, and his first writings on Common
> >>>> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> >>>> background.  However, even if you look up his credentials and are not
> >>>> impressed, at least realize what you yourself are doing; you are
> >>>> posting in a Lisp newsgroup arguing with someone who has switched his
> >>>> major emphasis from Java to Lisp, and so cries of FUD are going to
> >>>> fall on deaf ears and numb them to other things you have to say.
> >>> I do know Pascal. We've met several times and had some great
> >>> discussions. I respect both him and his work. I know Pascal's opinions
> >>> are well regarded here, all the more reason for them to be accurate. I
> >>> too came to Lisp from C++/Java/C#, and greatly value the areas in
> >>> which it is superior. But his statement above is simply wrong. It is
> >>> not a matter of qualifications or opinion. If you have existing Java
> >>> code that takes a collection and does not mutate it you can pass a
> >>> Clojure collection and it will work without change or adaptation, i.e.
> >>> "automagically".
> >> Two statements have been made, a qualified and an unqualified one. The
> >> unqualified one was "Clojure's collections work seamlessly with Java
> >> code" and the qualified one was "Clojure's collections work seamlessly
> >> with Java code that doesn't mutate them." The first statement is wrong,
> >> the second statement is correct.
>
> > Not true. The qualifier wasn't for the seamlessness, but for the
> > utility.
>
> I made the qualified statement. I guess I know better what the qualifier
> was for.
>
> >>> There is a large body of Java code for which this is
> >>> true, and people are leveraging that capability every day.
> >> This may be true, but it doesn't mean that you can afford not to check
> >> whether some arbitrary Java code is compatible with Clojure collections.
>
> > Absolutely not.
>
> Do I speak Spanish, or what?!?
>

We are talking about this (English) statement of yours:

"Existing Java code will not just automagically work with them in the
general case."

To which I replied (and you've elided, and ignored):

"A Clojure collection will work with existing Java code
in precisely the same way as an immutable Java collection, which is
already a legal and possible thing, you can create them, i.e. with
java.util.Collections.unmodifiableList/Map/Set etc. That is, existing
Java code, with whatever policy it has chosen for handling immutable
collections (which has nothing to do with Clojure), will work the same
way, unchanged, with Clojure collections."

Your example has nothing to do with the issue ("existing Java code").
It is an inane example of someone writing new code creating an
immutable collection and trying to add something to it.

I'm done - the last word is yours.

Rich

> import clojure.lang.*;
> import java.util.*;
>
> public class Test {
>
>    public static void main(String[] args) {
>      Cons cons = new Cons(1, new Cons(2, new Cons(3, null)));
>      Collections.addAll(cons,4);
>      System.out.println(cons);
>    }
>
> }
>
> java -classpath clojure.jar Test
> Exception in thread "main" java.lang.UnsupportedOperationException
>         at clojure.lang.ASeq.add(ASeq.java:109)
>         at java.util.Collections.addAll(Collections.java:3515)
>         at Test.main(Test.java:8)
>
> Pascal
>
> --
> ELS'09:http://www.european-lisp-symposium.org/
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/
From: William James
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnpvj306hc@enews4.newsguy.com>
Rich Hickey wrote:

> On Feb 21, 4:53 pm, Pascal Costanza <····@p-cos.net> wrote:
> 
...
> Your example has nothing to do with the issue ("existing Java code").
> It is an inane example of someone writing new code creating an
> immutable collection and trying to add something to it.

Costanza believes that lying for the Commode Lord (CL) is a
virtuous act.  He has unshakeable religious faith.

faith, n.  Belief without evidence in what is told by one who
speaks without knowledge, of things without parallel.
From: Javier
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnvjva$a6a$1@aioe.org>
William James escribi�:
> Rich Hickey wrote:
> 
>> On Feb 21, 4:53 pm, Pascal Costanza <····@p-cos.net> wrote:
>>
> ...
>> Your example has nothing to do with the issue ("existing Java code").
>> It is an inane example of someone writing new code creating an
>> immutable collection and trying to add something to it.
> 
> Costanza believes that lying for the Commode Lord (CL) is a
> virtuous act.  He has unshakeable religious faith.
> 
> faith, n.  Belief without evidence in what is told by one who
> speaks without knowledge, of things without parallel.

Oh yes, but Costanza is (most of the time) a good person. There is no
need to attack him. He is probably one of those rare persons here which
is not hostile nor violent, which is something really remarkable.
From: John Thingstad
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <op.upuhy8h5ut4oq5@pandora.alfanett.no>
P� Tue, 24 Feb 2009 02:55:01 +0100, skrev Javier <·······@gmail.com>:

> William James escribi�:
>> Rich Hickey wrote:
>>
>>> On Feb 21, 4:53 pm, Pascal Costanza <····@p-cos.net> wrote:
>>>
>> ...
>>> Your example has nothing to do with the issue ("existing Java code").
>>> It is an inane example of someone writing new code creating an
>>> immutable collection and trying to add something to it.
>>
>> Costanza believes that lying for the Commode Lord (CL) is a
>> virtuous act.  He has unshakeable religious faith.
>>
>> faith, n.  Belief without evidence in what is told by one who
>> speaks without knowledge, of things without parallel.
>
> Oh yes, but Costanza is (most of the time) a good person. There is no
> need to attack him. He is probably one of those rare persons here which
> is not hostile nor violent, which is something really remarkable.

At least he is not just a RUde BYstander.

--------------
John Thingstad
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70bdhiF7g25U2@mid.individual.net>
Rich Hickey wrote:

> Your example has nothing to do with the issue ("existing Java code").
> It is an inane example of someone writing new code creating an
> immutable collection and trying to add something to it.

It's funny. I expected that response.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnq0hk$vhm$1@news.motzarella.org>
Pascal Costanza schrieb:
> Rich Hickey wrote:
> 
>> Your example has nothing to do with the issue ("existing Java code").
>> It is an inane example of someone writing new code creating an
>> immutable collection and trying to add something to it.
> 
> It's funny. I expected that response.

Could you please let me know what you expect the next Lotto
numbers to be? ;)
No really, your example was a bit... alien.

Clojure uses the JVM Strings, the same that also Java can use.
Why not an example of how Clojure does not work with existing data
structures like this:

(+ 14 "6") ==>
java.lang.ClassCastException: java.lang.String cannot be cast to 
java.lang.Number


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: AndyF
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <f2b5176c-0e56-4e16-9c79-3f754c7b5b54@j35g2000yqh.googlegroups.com>
On Feb 21, 2:29 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > Your example has nothing to do with the issue ("existing Java code").
> > It is an inane example of someone writing new code creating an
> > immutable collection and trying to add something to it.
>
> It's funny. I expected that response.


Pascal, sorry to belabor this discussion if you're done with it, but
there is something I don't understand, and I'd like to, because I
think I'd learn something.

Rich says that existing Java code will work with Clojure collections
as well as that existing Java code will work with unmutable Java
collections, seamlessly (e.g. without copying data, without unweildy
conversion APIs, etc.)  AFAIK, that is true.

It seems you don't disagree with that statement, but that the
statement on which you two disagree is this one of yours: "it doesn't
mean that you can afford not to check whether some arbitrary Java code
is compatible with Clojure collections."

which it seems means the following (I'm not trying to put words into
your mouth -- I'm restating what you said in my own words, and if I'm
misstating, please correct me):

"You cannot afford not to check whether some arbitrary Java code is
compatible with immutable collections, before using said Java code
with said immutable collections."

Is your point that it is not safe to develop a system that might under
some conditions throw a java.lang.UnsupportedOperationException,
because the Java code that uses a collection might modify it in
situations that are difficult to hit during testing, and difficult to
find when reviewing that Java code?

That the Java collection libraries are broken because such
incompatibilities of Java-code-using-collections and immutable-
collections-as-input cannot be caught at compile time, and it is
wishful thinking to rely upon catching such incompatibilities during
testing before deploying the code?

If that is your point, then is there any way a tool could be developed
to walk Java source code and/or Java .jar files that can determine
that the code can never invoke a mutation operation on a Java
collection, and that would satisfy your concerns?

Thanks,
Andy Fingerhut
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70e2drF1n667U1@mid.individual.net>
AndyF wrote:
> On Feb 21, 2:29 pm, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> Your example has nothing to do with the issue ("existing Java code").
>>> It is an inane example of someone writing new code creating an
>>> immutable collection and trying to add something to it.
>> It's funny. I expected that response.
> 
> 
> Pascal, sorry to belabor this discussion if you're done with it, but
> there is something I don't understand, and I'd like to, because I
> think I'd learn something.
> 
> Rich says that existing Java code will work with Clojure collections
> as well as that existing Java code will work with unmutable Java
> collections, seamlessly (e.g. without copying data, without unweildy
> conversion APIs, etc.)  AFAIK, that is true.
> 
> It seems you don't disagree with that statement, but that the
> statement on which you two disagree is this one of yours: "it doesn't
> mean that you can afford not to check whether some arbitrary Java code
> is compatible with Clojure collections."
> 
> which it seems means the following (I'm not trying to put words into
> your mouth -- I'm restating what you said in my own words, and if I'm
> misstating, please correct me):
> 
> "You cannot afford not to check whether some arbitrary Java code is
> compatible with immutable collections, before using said Java code
> with said immutable collections."
> 
> Is your point that it is not safe to develop a system that might under
> some conditions throw a java.lang.UnsupportedOperationException,
> because the Java code that uses a collection might modify it in
> situations that are difficult to hit during testing, and difficult to
> find when reviewing that Java code?
> 
> That the Java collection libraries are broken because such
> incompatibilities of Java-code-using-collections and immutable-
> collections-as-input cannot be caught at compile time, and it is
> wishful thinking to rely upon catching such incompatibilities during
> testing before deploying the code?
> 
> If that is your point, then is there any way a tool could be developed
> to walk Java source code and/or Java .jar files that can determine
> that the code can never invoke a mutation operation on a Java
> collection, and that would satisfy your concerns?

Such a tool can probably be developed. But it wasn't quite what I had in 
mind.

The Java Collection API, as I remember it, was very hard to use without 
mutation. For example, initializing a collection was only possible by 
way of creating an empty collection and then adding elements to it.

Maybe that improved.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Scott
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <2d907622-7b0a-4df4-8144-2a1e4be875f9@x10g2000yqk.googlegroups.com>
On Feb 22, 3:37 pm, Pascal Costanza <····@p-cos.net> wrote:
>
> The Java Collection API, as I remember it, was very hard to use without
> mutation. For example, initializing a collection was only possible by
> way of creating an empty collection and then adding elements to it.
>

Your Lisp page says you worked with Java up until 2002.  Java version
1.4 came out that year, but java version 1.3 had been out since two
years earlier.

Looking at the Java 1.3 documentation for the java.util.Collection
interface it says,

  """ All general-purpose Collection implementation classes (which
typically implement Collection indirectly through one of its
subinterfaces) should provide two "standard" constructors: a void (no
arguments) constructor, which creates an empty collection, and a
constructor with a single argument of type Collection, which creates a
new collection with the same elements as its argument. In effect, the
latter constructor allows the user to copy any collection, producing
an equivalent collection of the desired implementation type. There is
no way to enforce this convention (as interfaces cannot contain
constructors) but all of the general-purpose Collection
implementations in the SDK comply. """

> Maybe that improved.

It looks like it had already improved as of 2000.


(If I wasn't already in your killfile, I suspect this might get me
there... :-)
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70fjjfF41q9jU1@mid.individual.net>
Scott wrote:
> On Feb 22, 3:37 pm, Pascal Costanza <····@p-cos.net> wrote:
>> The Java Collection API, as I remember it, was very hard to use without
>> mutation. For example, initializing a collection was only possible by
>> way of creating an empty collection and then adding elements to it.
> 
> Your Lisp page says you worked with Java up until 2002.  Java version
> 1.4 came out that year, but java version 1.3 had been out since two
> years earlier.
> 
> Looking at the Java 1.3 documentation for the java.util.Collection
> interface it says,
> 
>   """ All general-purpose Collection implementation classes (which
> typically implement Collection indirectly through one of its
> subinterfaces) should provide two "standard" constructors: a void (no
> arguments) constructor, which creates an empty collection, and a
> constructor with a single argument of type Collection, which creates a
> new collection with the same elements as its argument. In effect, the
> latter constructor allows the user to copy any collection, producing
> an equivalent collection of the desired implementation type. There is
> no way to enforce this convention (as interfaces cannot contain
> constructors) but all of the general-purpose Collection
> implementations in the SDK comply. """

So where does this other collection come from?

>> Maybe that improved.
> 
> It looks like it had already improved as of 2000.

No, you're actually pointing at the heart of the problem: Maybe that's 
where my impression comes from, the default collections provided by Java 
don't have a constructor that allows you to just enumerate the elements 
(at least not back then). So the only way to create a fresh collection, 
it seems, is to create an empty one and then to mutate it to actually 
contain elements.

> (If I wasn't already in your killfile, I suspect this might get me
> there... :-)

You're trying to have a sane discussion. So why should I add you to my 
killfile?


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Scott
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <f701b417-b67e-4275-9a5f-8cfb5ce10d42@q18g2000vbn.googlegroups.com>
On Feb 23, 5:37 am, Pascal Costanza <····@p-cos.net> wrote:
> Scott wrote:
> > On Feb 22, 3:37 pm, Pascal Costanza <····@p-cos.net> wrote:
> >> The Java Collection API, as I remember it, was very hard to use without
> >> mutation. For example, initializing a collection was only possible by
> >> way of creating an empty collection and then adding elements to it.
>
> > It looks like it had already improved as of 2000.
>
> No, you're actually pointing at the heart of the problem: Maybe that's
> where my impression comes from, the default collections provided by Java
> don't have a constructor that allows you to just enumerate the elements
> (at least not back then). So the only way to create a fresh collection,
> it seems, is to create an empty one and then to mutate it to actually
> contain elements.
>

I dug a little deeper.  It looks like all of this Collections stuff
was introduced in Java 1.2 which was released near the end of 1998.  I
couldn't find the Java 1.2 docs on Sun's main site anymore, but I
found the following links from Google:

    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/ArrayList.html
    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/LinkedList.html
    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/Vector.html
    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/HashMap.html
    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/TreeMap.html

Each of these takes a Collection or one of it's derived interfaces,
such as List or Map, in one of it's constructors.  That's not
exhaustive, but it supports the piece of text that I quoted previously
from the Collection interface documentation page which said, "There is
no way to enforce this convention (as interfaces cannot contain
constructors) but all of the general-purpose Collection
implementations in the JDK comply."

    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/index.html

I think this shows that you can create a java.util.ArrayList (or
whatever) directly from one of Clojure's classes that implement the
List (or corresponding) interface.  The ArrayList constructor will
initialize itself with all of the objects in the Clojure collection.
You do not have to create an empty one first, and (since you've made a
mutable copy) you're free to add or remove more after that.

The java.util.Collection page also specifies that all of the mutating
operations for the Collection interface are optional operations, and
apparently the expectation is that these methods should throw
exceptions when they choose not to add/remove an item.  The details
are in the descriptions for each method.

Over in the java.util.Collections class, there are a bunch of static
methods that operate on the Collection interfaces.  So it looks like
Clojure's collection classes which implement the Collection interfaces
would work with any of these operations that don't require mutation.
I think this would include things like binarySearch(), min(), max(),
etc...

The static methods in the Collections class that would require
mutation, such as fill() and shuffle(), specify that an
UnsuportedOperationException can be thrown if the argument (one of
Clojure's instances in this case) doesn't support the needed mutating
operations.

I think this shows that Clojure's immutable collection classes can be
used with any of those Java algorithms and get reasonable behavior.
At least I think it's reasonable for them to throw an exception when
someone tries to pass an immutable class to a mutating function.  At
the very least, they can't trivially break the contract on the
interface.

I briefly used Java around 1997 and abandoned it since it didn't meet
my needs.  Briefly, sometime around 2004, I wrote a Java library for a
co-worker and had him critique my code.  I was using an ArrayList in a
few places, and I was passing them to other functions I wrote which
were declared to take the ArrayList type as an argument.  In our mini
code review, he said that I should be using a List for argument type.
I accepted his suggestion, and it seems to me now that this means
Clojure's objects would work just fine with my library that had never
anticipated the existence of Clojure.

I don't think this particular co-worker is all that prescient, so this
makes me suspect that using the Collection interfaces is fairly
standard practice over in the Java world.  If so, I would expect there
to be lots of libraries that work with Clojure's collections.

>
> > (If I wasn't already in your killfile, I suspect this might get me
> > there... :-)
>
> You're trying to have a sane discussion. So why should I add you to my
> killfile?
>

Sorry about that.  I was just being obnoxious and letting you know
that I was "calling you out" on this one...  Hopefully you didn't take
my jibe too seriously.

Cheers,
    -Scott
From: Alessio Stalla
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <a94c095a-d84e-4fe8-ad1a-7ab991c0cccb@v18g2000vbb.googlegroups.com>
On Feb 23, 5:22 pm, Scott <·······@gmail.com> wrote:
> I dug a little deeper.  It looks like all of this Collections stuff
> was introduced in Java 1.2 which was released near the end of 1998.  I
> couldn't find the Java 1.2 docs on Sun's main site anymore, but I
> found the following links from Google:
>
>    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/ArrayLis...
>    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/LinkedLi...
>    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/Vector.html
>    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/HashMap....
>    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/java/util/TreeMap....
>
> Each of these takes a Collection or one of it's derived interfaces,
> such as List or Map, in one of it's constructors.  That's not
> exhaustive, but it supports the piece of text that I quoted previously
> from the Collection interface documentation page which said, "There is
> no way to enforce this convention (as interfaces cannot contain
> constructors) but all of the general-purpose Collection
> implementations in the JDK comply."
>
>    http://www.cs.mun.ca/~michael/java/jdk1.2-docs/api/index.html
>
> I think this shows that you can create a java.util.ArrayList (or
> whatever) directly from one of Clojure's classes that implement the
> List (or corresponding) interface.  The ArrayList constructor will
> initialize itself with all of the objects in the Clojure collection.
> You do not have to create an empty one first, and (since you've made a
> mutable copy) you're free to add or remove more after that.
>
> The java.util.Collection page also specifies that all of the mutating
> operations for the Collection interface are optional operations, and
> apparently the expectation is that these methods should throw
> exceptions when they choose not to add/remove an item.  The details
> are in the descriptions for each method.
>
> Over in the java.util.Collections class, there are a bunch of static
> methods that operate on the Collection interfaces.  So it looks like
> Clojure's collection classes which implement the Collection interfaces
> would work with any of these operations that don't require mutation.
> I think this would include things like binarySearch(), min(), max(),
> etc...
>
> The static methods in the Collections class that would require
> mutation, such as fill() and shuffle(), specify that an
> UnsuportedOperationException can be thrown if the argument (one of
> Clojure's instances in this case) doesn't support the needed mutating
> operations.
>
> I think this shows that Clojure's immutable collection classes can be
> used with any of those Java algorithms and get reasonable behavior.
> At least I think it's reasonable for them to throw an exception when
> someone tries to pass an immutable class to a mutating function.  At
> the very least, they can't trivially break the contract on the
> interface.
>
> I briefly used Java around 1997 and abandoned it since it didn't meet
> my needs.  Briefly, sometime around 2004, I wrote a Java library for a
> co-worker and had him critique my code.  I was using an ArrayList in a
> few places, and I was passing them to other functions I wrote which
> were declared to take the ArrayList type as an argument.  In our mini
> code review, he said that I should be using a List for argument type.
> I accepted his suggestion, and it seems to me now that this means
> Clojure's objects would work just fine with my library that had never
> anticipated the existence of Clojure.
>
> I don't think this particular co-worker is all that prescient, so this
> makes me suspect that using the Collection interfaces is fairly
> standard practice over in the Java world.  If so, I would expect there
> to be lots of libraries that work with Clojure's collections.
>

Sorry for stepping into this discussion from nowhere, but I'd like to
point out that, although the general contract for Java collections
requires providing an initializing constructor taking another
Collection as a parameter, AFAIK such a constructor is generally
implemented using the addAll() method (see for example
http://kickjava.com/src/java/util/ArrayList.java.htm), so Pascal's
statement (that some widely used operations on Java collections
require mutation) is not wrong in principle. OTOH I suspect that
Clojure's collections will provide that very same constructor
implemented using non-mutating operations.
Also, while it's true that mutating operations are "optional", in
practice common use of collections in Java involves mutating them.
Immutable collections are not idiomatic (they're not idiomatic in
Common Lisp either, for that matter, even if in general Common Lisp
favours a more "functional" use of sequences/collections).

So, as always truth lays in the middle :) since Clojure's collections
*can* be used like regular Java collections, *provided* that their
user is aware they're not mutable. E.g. Collections.sort(...) won't
work on Clojure's immutable collections. But it must be said imho that
although the use of interfaces favours easy exchange of
implementations, such exchange must always be done with a grain of
salt - different implementations generally *do* different things, or
there would be no point for them to be different. That is, before
using Clojure's collections in my Java application, I would evaluate
their characteristics, pros and cons, and decide whether they would be
suitable or not. For some people (Rich Hickey) this still means
"seamless integration", for others (Pascal) it doesn't, and I'm not
saying anyone of them is "right" or "wrong"; just that the basic step
of evaluating a datastructure before using it is necessary, whether
the datastructure is "seamlessly integrated" with the rest of the
program or not.

That said, having Clojure's collections follow the Java Collections
interfaces is certainly a Good Thing, even if one admits they're not
"seamlessly integrated" with the collections framework. Working in
Java with ABCL's Lisp lists, for example, is quite painful since you
have to directly use Conses, which is not as natural as in Lisp
(mainly because you don't have any syntax support for them).

Alessio
From: Scott
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <03e064d8-4272-4f44-ab18-d44056557594@s20g2000yqh.googlegroups.com>
On Feb 23, 9:53 am, Alessio Stalla <·············@gmail.com> wrote:
>
> Sorry for stepping into this discussion from nowhere,

That's how we all got here.  :-)


> but I'd like to point out that, although the general contract
> for Java collections requires providing an initializing
> constructor taking another Collection as a parameter, AFAIK
> such a constructor is generally implemented using the addAll()
> method (see for example
>  http://kickjava.com/src/java/util/ArrayList.java.htm
> ), so Pascal's statement (that some widely used operations
> on Java collections require mutation) is not wrong in principle.

I don't think Pascal was complaining about the internal implementation
details of the constructors.  I think he was saying that the
interfaces required him to create an empty object and then add all the
items directly.  Please see the text I quoted, or Pascal's original
messages, if you disagree with me.


> OTOH I suspect that
> Clojure's collections will provide that very same constructor
> implemented using non-mutating operations.

Someone's got to build it up piece by piece somewhere, but that's an
implementation detail, not an interface one.


> Collections.sort(...) won't work on Clojure's immutable collections.

It should throw an UnsupportedOperationException - exactly as it is
documented to do in this case.


> Also, while it's true that mutating operations are "optional", in
> practice common use of collections in Java involves mutating them.
> Immutable collections are not idiomatic (they're not idiomatic in
> Common Lisp either, for that matter, even if in general Common Lisp
> favours a more "functional" use of sequences/collections).

Without some pretty ugly hackery, algorithms can't mutate a collection
instance that doesn't want to be mutated.  Even though common Java
idiom is to implement mutable objects, the JDK Collection interfaces
and algorithms explicitly allow immutable ones, and the JVM will
enforce that immutability to a degree beyond most other programming
environments.


> So, as always truth lays in the middle :)

I'm not sure if you're just trying to keep the peace, but I don't
think it lies that close to center in this case.  Pascal's a smart
guy, but I think he misremembered a few things.  Maybe he's recalling
JDK 1.1 - that was before the Collection interfaces were defined.  The
Java implementers possibly introduced the Collection APIs to deal with
exactly the sorts of problems that Pascal was unhappy about.


> That said, having Clojure's collections follow the Java
> Collections interfaces is certainly a Good Thing, even
> if one admits they're not "seamlessly integrated" with
> the collections framework.

"Seamlessly" is a pretty subjective word.  However, given the
constraints, I'm not sure how you'd go about making it any more
seamless than it is.


Cheers,
    -Scott
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70b275F2bcvU1@mid.individual.net>
·····@franz.com wrote:
> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>
>>
>>
>>> Helmut Eller wrote:
>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>> FSet is a library, not a language.
>>>>> If I understand correctly, native immutable collections are just one
>>>>> feature of Clojure, and it integrates well with other features
>>>>> (polymorphic collection manipulation and concurrency control).
>>>> I'm confused by this whole discussion.
>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>> compiler/language treats them just like any other Java class?  Is there
>>>> a reason why those classes could not be used in normal Java programs?
>>> They can be used in Java, but you have to adapt your programming style.
>>> Existing Java code will not just automagically work with them in the
>>> general case.
>> This is FUD - please stop spreading it.
> 
> Pascal is not likely to wave his own flag, but I don't think you
> realize whom you are talking to.  Pascal was a Java programmer long
> before he switched to Common Lisp, and his first writings on Common
> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> background.  However, even if you look up his credentials and are not
> impressed, at least realize what you yourself are doing; you are
> posting in a Lisp newsgroup arguing with someone who has switched his
> major emphasis from Java to Lisp, and so cries of FUD are going to
> fall on deaf ears and numb them to other things you have to say.

I hope not. ;)


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a0a7be$0$20283$607ed4bc@cv.net>
·····@franz.com wrote:
> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>
>>
>>
>>> Helmut Eller wrote:
>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>> FSet is a library, not a language.
>>>>> If I understand correctly, native immutable collections are just one
>>>>> feature of Clojure, and it integrates well with other features
>>>>> (polymorphic collection manipulation and concurrency control).
>>>> I'm confused by this whole discussion.
>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>> compiler/language treats them just like any other Java class?  Is there
>>>> a reason why those classes could not be used in normal Java programs?
>>> They can be used in Java, but you have to adapt your programming style.
>>> Existing Java code will not just automagically work with them in the
>>> general case.
>> This is FUD - please stop spreading it.
> 
> Pascal is not likely to wave his own flag, but I don't think you
> realize whom you are talking to.  Pascal was a Java programmer long
> before he switched to Common Lisp, and his first writings on Common
> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> background.  However, even if you look up his credentials and are not
> impressed, at least realize what you yourself are doing; you are
> posting in a Lisp newsgroup arguing with someone who has switched his
> major emphasis from Java to Lisp, and so cries of FUD are going to
> fall on deaf ears and numb them to other things you have to say.

Unless Rich is right on the facts. And anyone who thinks FSet is to CL 
as Clojure is to Java cannot be all that perfect.

Shall we return to the issues and stop waving about our degrees?

hth,kt BA, MEd
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnpnvi$371$1@news.motzarella.org>
·····@franz.com schrieb:
> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>
>>
>>
>>> Helmut Eller wrote:
>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>> FSet is a library, not a language.
>>>>> If I understand correctly, native immutable collections are just one
>>>>> feature of Clojure, and it integrates well with other features
>>>>> (polymorphic collection manipulation and concurrency control).
>>>> I'm confused by this whole discussion.
>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>> compiler/language treats them just like any other Java class?  Is there
>>>> a reason why those classes could not be used in normal Java programs?
>>> They can be used in Java, but you have to adapt your programming style.
>>> Existing Java code will not just automagically work with them in the
>>> general case.
>> This is FUD - please stop spreading it.
> 
> Pascal is not likely to wave his own flag, but I don't think you
> realize whom you are talking to.  Pascal was a Java programmer long
> before he switched to Common Lisp, and his first writings on Common
> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
> background.  However, even if you look up his credentials and are not
> impressed, at least realize what you yourself are doing; you are
> posting in a Lisp newsgroup arguing with someone who has switched his
> major emphasis from Java to Lisp, and so cries of FUD are going to
> fall on deaf ears and numb them to other things you have to say.

I think it makes more sense to look at the actual facts instead of
argumenting about authorities.
For this discussion it does not matter so much who Pascal is, and how
famous he is in c.l.l and if he came from Java, a long time ago.

I have the strong impression that Pascal did not spend very much time
here coding in Clojure. Same is probably true for most people who let
us know about their criticism.
It was often suggested here that Jon Harrop should do some CL coding
before explaining others what CL is like, and so on.
If someone used Clojure for some few months, wrote some small progs in
it, then I would be interested in her opinion about what sucks about it,
and what is possible or not.

Of course Clojure can also not do magic. But it still feels much more
integrated than anything in CL. I say this after doing 6 years CL, with
some years of this time spent with working for CL companies.

Please let�s go away from the authority argument and come instead to a
peaceful and rational discussion. If you learned Clojure and wrote some
code I would like to hear about your opinions.

And btw, I surely hope that I can soon read Pascal Costanza's Highly
Opinionated Guide to Clojure :)

Peace.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70b7ouF4cf7U1@mid.individual.net>
Andr� Thieme wrote:
> ·····@franz.com schrieb:
>> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>>
>>>
>>>
>>>> Helmut Eller wrote:
>>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>>> FSet is a library, not a language.
>>>>>> If I understand correctly, native immutable collections are just one
>>>>>> feature of Clojure, and it integrates well with other features
>>>>>> (polymorphic collection manipulation and concurrency control).
>>>>> I'm confused by this whole discussion.
>>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>>> compiler/language treats them just like any other Java class?  Is 
>>>>> there
>>>>> a reason why those classes could not be used in normal Java programs?
>>>> They can be used in Java, but you have to adapt your programming style.
>>>> Existing Java code will not just automagically work with them in the
>>>> general case.
>>> This is FUD - please stop spreading it.
>>
>> Pascal is not likely to wave his own flag, but I don't think you
>> realize whom you are talking to.  Pascal was a Java programmer long
>> before he switched to Common Lisp, and his first writings on Common
>> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
>> background.  However, even if you look up his credentials and are not
>> impressed, at least realize what you yourself are doing; you are
>> posting in a Lisp newsgroup arguing with someone who has switched his
>> major emphasis from Java to Lisp, and so cries of FUD are going to
>> fall on deaf ears and numb them to other things you have to say.
> 
> I think it makes more sense to look at the actual facts instead of
> argumenting about authorities.
> For this discussion it does not matter so much who Pascal is, and how
> famous he is in c.l.l and if he came from Java, a long time ago.
> 
> I have the strong impression that Pascal did not spend very much time
> here coding in Clojure. Same is probably true for most people who let
> us know about their criticism.
> It was often suggested here that Jon Harrop should do some CL coding
> before explaining others what CL is like, and so on.

I'm not trying to tell anybody what Clojure is like.

> If someone used Clojure for some few months, wrote some small progs in
> it, then I would be interested in her opinion about what sucks about it,
> and what is possible or not.
> 
> Of course Clojure can also not do magic. But it still feels much more
> integrated than anything in CL. I say this after doing 6 years CL, with
> some years of this time spent with working for CL companies.

Whether arbitrary existing Java code will automagically work with 
Clojure collections or not does not depend on how great or not it is to 
program in Clojure itself. It's a very simple consequence of the fact 
that Java collections in general support mutability and that Java code 
in general may depend on such mutability, and that Clojure collections 
are not mutable.

> Please let�s go away from the authority argument and come instead to a
> peaceful and rational discussion. If you learned Clojure and wrote some
> code I would like to hear about your opinions.

It seems that you have the impression that I criticize Clojure much more 
than I actually do. Otherwise you wouldn't be so defensive.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnptpi$205$1@news.motzarella.org>
Pascal Costanza schrieb:
> Andr� Thieme wrote:
>> ·····@franz.com schrieb:
>>> On Feb 21, 6:43 am, Rich Hickey <··········@gmail.com> wrote:
>>>> On Feb 21, 6:57 am, Pascal Costanza <····@p-cos.net> wrote:
>>>>
>>>>
>>>>
>>>>> Helmut Eller wrote:
>>>>>> * Vend [2009-02-20 22:26+0100] writes:
>>>>>>> FSet is a library, not a language.
>>>>>>> If I understand correctly, native immutable collections are just one
>>>>>>> feature of Clojure, and it integrates well with other features
>>>>>>> (polymorphic collection manipulation and concurrency control).
>>>>>> I'm confused by this whole discussion.
>>>>>> Aren't Clojure's collection classes just a library and the Clojure
>>>>>> compiler/language treats them just like any other Java class?  Is 
>>>>>> there
>>>>>> a reason why those classes could not be used in normal Java programs?
>>>>> They can be used in Java, but you have to adapt your programming 
>>>>> style.
>>>>> Existing Java code will not just automagically work with them in the
>>>>> general case.
>>>> This is FUD - please stop spreading it.
>>>
>>> Pascal is not likely to wave his own flag, but I don't think you
>>> realize whom you are talking to.  Pascal was a Java programmer long
>>> before he switched to Common Lisp, and his first writings on Common
>>> Lisp (http://p-cos.net/lisp/guide.html) provide some of his
>>> background.  However, even if you look up his credentials and are not
>>> impressed, at least realize what you yourself are doing; you are
>>> posting in a Lisp newsgroup arguing with someone who has switched his
>>> major emphasis from Java to Lisp, and so cries of FUD are going to
>>> fall on deaf ears and numb them to other things you have to say.
>>
>> I think it makes more sense to look at the actual facts instead of
>> argumenting about authorities.
>> For this discussion it does not matter so much who Pascal is, and how
>> famous he is in c.l.l and if he came from Java, a long time ago.
>>
>> I have the strong impression that Pascal did not spend very much time
>> here coding in Clojure. Same is probably true for most people who let
>> us know about their criticism.
>> It was often suggested here that Jon Harrop should do some CL coding
>> before explaining others what CL is like, and so on.
> 
> I'm not trying to tell anybody what Clojure is like.

Sorry, now as I reread it, it sounds as if I wanted to explicitly point
out that _you_ are doing it. I was thinking about others.

But still, you made some assumptions about Clojure which don�t tend into
the right direction. Maybe you will find some time in the future to play
with it a little bit.
Language theory is one of your very strong sides, and even without
having used Clojure you already can understand several aspects about it.
However, I think that actually using it can further improve that knowledge.


>> Please let�s go away from the authority argument and come instead to a
>> peaceful and rational discussion. If you learned Clojure and wrote some
>> code I would like to hear about your opinions.
> 
> It seems that you have the impression that I criticize Clojure much more 
> than I actually do. Otherwise you wouldn't be so defensive.

Nah, that�s a little misunderstanding.
I know that you are very rational, and I didn�t communicate that some
weeks ago I thought: �Pascal is really great. He has a rational approach
to all this, and does not seem as religious as others here do�.
Nearly these were my words (thoughts). I don�t know though after which
of your postings this was.
It is just that I don�t think it will bring us forward that you are one
of the few world famous lispers.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70bdpcF7g25U3@mid.individual.net>
Andr� Thieme wrote:

> But still, you made some assumptions about Clojure which don�t tend into
> the right direction. Maybe you will find some time in the future to play
> with it a little bit.

That's unlikely, because Clojure doesn't match my current interests. But 
I can easily imagine using it. It looks like very decent and usable 
design, very well thought-out. It's probably fun using it, and if I had 
enough spare time, I would probably do it.

> Language theory is one of your very strong sides, and even without
> having used Clojure you already can understand several aspects about it.
> However, I think that actually using it can further improve that knowledge.

Sure. That's always true.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Helmut Eller
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <m263j4vukp.fsf@gmail.com>
* Pascal Costanza [2009-02-21 12:57+0100] writes:

>> Aren't Clojure's collection classes just a library and the Clojure
>> compiler/language treats them just like any other Java class?  Is there
>> a reason why those classes could not be used in normal Java programs?
>
> They can be used in Java, but you have to adapt your programming
> style. Existing Java code will not just automagically work with them
> in the general case.

So is the "concurrency magic" of Clojure in the libraries or in the
compiler/language?  I had the impression it is in the libraries, but I
may be wrong.

Helmut.
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <42fcb2fb-d777-4c8a-a825-1a6a4d327fc4@w34g2000yqm.googlegroups.com>
On Feb 21, 7:32 am, Helmut Eller <············@gmail.com> wrote:
> * Pascal Costanza [2009-02-21 12:57+0100] writes:
>
> >> Aren't Clojure's collection classes just a library and the Clojure
> >> compiler/language treats them just like any other Java class?  Is there
> >> a reason why those classes could not be used in normal Java programs?
>
> > They can be used in Java, but you have to adapt your programming
> > style. Existing Java code will not just automagically work with them
> > in the general case.
>
> So is the "concurrency magic" of Clojure in the libraries or in the
> compiler/language?  I had the impression it is in the libraries, but I
> may be wrong.
>

It's in the libraries.

Rich
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnotsb$i6f$1@news.motzarella.org>
Helmut Eller schrieb:
> * Pascal Costanza [2009-02-21 12:57+0100] writes:
> 
>>> Aren't Clojure's collection classes just a library and the Clojure
>>> compiler/language treats them just like any other Java class?  Is there
>>> a reason why those classes could not be used in normal Java programs?
>> They can be used in Java, but you have to adapt your programming
>> style. Existing Java code will not just automagically work with them
>> in the general case.
> 
> So is the "concurrency magic" of Clojure in the libraries or in the
> compiler/language?  I had the impression it is in the libraries, but I
> may be wrong.

Have you already seen some of the Clojure movies?
Try  http://blip.tv/file/812787

Also you can have a look at http://clojure.org/ and read some of the
documents. If you have Java installed it is easy to try the examples
via copy&paste.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnos05$1bb$1@news.motzarella.org>
Helmut Eller schrieb:

> I also don't understand how those collections can improve concurrency
> control beyond ordinary Java libraries.

Java offers low level building material.
That is used along with a STM (with MVCC) and immutable data structures.
When you have data that can not change then of course any number of
threads can use them concurrently without producing inconsistencies.
Immutability is the default in Clojure. Typically a Clojure programmer
will know how to do most things without changing state.
A workmate of mine now started to use it as well. At some point, when he
wanted to make use of one of the mutable constructs offered by the
implementation, I had a short look with him over his code, and we were
able to remove them.
*Of course* all CL/Java programs could be written in the same style.
But this has to happen by convention and could easily be circumvented,
by introducing a setf here or an infc there.
Clojure makes it difficult. For example, if you want to change several
pieces of data outside of a transaction you will get an error. Refs can
only be changed in a (dosync ...) block.

At least until today it is not typical CL/Java style to write programs
in such a way. One could make the change and program the Clojure way in
CL also. Although I see no point in doing so if one wants program in
that style. I would suggest doing it in Clojure.
As well one can sit down a few days and write up an imperative lib for
Clojure, with setf, push, incf and friends and do CL style coding in
Clojure. Possible yes, but why? There already is CL waiting for me if I
want to do that.


 > It seems to me that those
> classes fall in the same category as the java.util.concurrency package.
> Useful for sure, but claiming that those classes "ensure clean, correct,
> multithreaded designs" seems a bit far fetched.

Concurrency is a hard problem. This video is well worth to be watched:
http://rubyconf2008.confreaks.com/what-all-rubyist-should-know-about-threads.html

Yes, it is about a Ruby guy, but what he says applies to 99% of all
programming languages. Outstanding exceptions would be Clojure, Haskell
and Erlang.
Those langs also allow us to make tons of mistakes and they can not do
magic. The hard concurrency problem does not go away. But they do a good
job in making it easier.
Immutability by default, a STM (or similar mechanism) and some
corresponding abstractings/tools in the language make it possible, and
often even trivial.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Helmut Eller
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <m2ocwv7vd2.fsf@gmail.com>
* Andr� Thieme [2009-02-21 13:27+0100] writes:

> Helmut Eller schrieb:
>
>> I also don't understand how those collections can improve concurrency
>> control beyond ordinary Java libraries.
>
> Java offers low level building material.
> That is used along with a STM (with MVCC) and immutable data structures.
> When you have data that can not change then of course any number of
> threads can use them concurrently without producing inconsistencies.
> Immutability is the default in Clojure. Typically a Clojure programmer
> will know how to do most things without changing state.

But if you can't always choose the data structures you'd like.  If you
use Java frameworks you have to use whatever is used by those libraries.
And AFAICT, Clojure tries to use Java libraries whenever possible.

> A workmate of mine now started to use it as well. At some point, when he
> wanted to make use of one of the mutable constructs offered by the
> implementation, I had a short look with him over his code, and we were
> able to remove them.
> *Of course* all CL/Java programs could be written in the same style.
> But this has to happen by convention and could easily be circumvented,
> by introducing a setf here or an infc there.

How is that different in Clojure?  Using Clojure's data-structures
exclusively is just another form of convention.  It is not enforced,
right?

> Clojure makes it difficult. For example, if you want to change several
> pieces of data outside of a transaction you will get an error. Refs
> can only be changed in a (dosync ...) block. At least until today it
> is not typical CL/Java style to write programs in such a way. One
> could make the change and program the Clojure way in CL also. Although
> I see no point in doing so if one wants program in that style. I would
> suggest doing it in Clojure.  As well one can sit down a few days and
> write up an imperative lib for Clojure, with setf, push, incf and
> friends and do CL style coding in Clojure. Possible yes, but why?
> There already is CL waiting for me if I want to do that.
>
>> It seems to me that those
>> classes fall in the same category as the java.util.concurrency package.
>> Useful for sure, but claiming that those classes "ensure clean, correct,
>> multithreaded designs" seems a bit far fetched.
>
> Concurrency is a hard problem.

Of course it is.  And therefore those statements like "ensure correct
multithreaded designs" are almost certainly wrong.

> This video is well worth to be watched:
> http://rubyconf2008.confreaks.com/what-all-rubyist-should-know-about-threads.html

Thanks, for the link.  Have to watch it later.

> Yes, it is about a Ruby guy, but what he says applies to 99% of all
> programming languages. Outstanding exceptions would be Clojure, Haskell
> and Erlang.
> Those langs also allow us to make tons of mistakes and they can not do
> magic. The hard concurrency problem does not go away. But they do a good
> job in making it easier.
> Immutability by default, a STM (or similar mechanism) and some
> corresponding abstractings/tools in the language make it possible, and
> often even trivial.

Well, Erlang and Haskell live in their own isolated worlds and don't
claim to have "seamless integration with Java".  I doubt that it's
possible to have easy Java interop and easy concurrency at the same
time.  It's bit like saying that you can freely call C++ functions and
that there will be no segfaults.

Helmut.
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnp3g0$brl$1@news.motzarella.org>
Helmut Eller schrieb:
> * Andr� Thieme [2009-02-21 13:27+0100] writes:
> 
>> Helmut Eller schrieb:
>>
>>> I also don't understand how those collections can improve concurrency
>>> control beyond ordinary Java libraries.
>> Java offers low level building material.
>> That is used along with a STM (with MVCC) and immutable data structures.
>> When you have data that can not change then of course any number of
>> threads can use them concurrently without producing inconsistencies.
>> Immutability is the default in Clojure. Typically a Clojure programmer
>> will know how to do most things without changing state.
> 
> But if you can't always choose the data structures you'd like.

Right, also I can�t always chose the hardware. Maybe it will be a single
core machine, and all my concurrency code will be useless.


> If you
> use Java frameworks you have to use whatever is used by those libraries.

If I rely on a Java framework for, say, webdevelopment, then I auto-
matically rely on it being working/threadsafe/correct.

Practically all of your program logic will be done in Clojure itself.
The existing libs for the JVM (mostly written in Java) are used for
communicating with the world. For side effects.
I want to print something on the screen, I want to download data from
the internet, I wish to delete a file or open a connection to the DB.
In whatever of the languages that exist today we do this, we need to
make sure to not open files multiple times, forget to close them, not
to delete accidently the harddisk, etc. Side effects can potentially be
dangerous.
When I use an XML-RPC server, written in Java, then I rely on it being
already multithreaded. It is possible in Java as well, as Java offers
all the mechanisms. It�s the problem of the authors to write such a
server in a threadsafe way. I am glad that for example the Apache XML-
RPC Server can handle requests concurrently, and with their client I
can have lots of Clojure agents sending away requests concurrently.
It works great.
When I use buggy libs for doing the side effects in my Clojure apps,
then yes, I will have a problem.
Anyway, depending on the domain my program can be 98% using Clojure
code, and only 2% using Java libs, for communication with the hardware
and the user.
Often I can put those things into their own threads as well.
If I want to write log files, then on one core the logger can run.
It will read data out of a shared log queue into which other threads
write their logging data, all happening concurrently, because the reads
and writes happen without locks in my code in the Clojure side.
Btw, there are of course already Java libs that do all this automatically,
tested for thousands of man hours, so I would not even have to do that
myself. It was just an example.


> And AFAICT, Clojure tries to use Java libraries whenever possible.

Maybe you should actually *try* Clojure first before coming to that
opinion? ;)


>> A workmate of mine now started to use it as well. At some point, when he
>> wanted to make use of one of the mutable constructs offered by the
>> implementation, I had a short look with him over his code, and we were
>> able to remove them.
>> *Of course* all CL/Java programs could be written in the same style.
>> But this has to happen by convention and could easily be circumvented,
>> by introducing a setf here or an infc there.
> 
> How is that different in Clojure?  Using Clojure's data-structures
> exclusively is just another form of convention.  It is not enforced,
> right?

It is not enforced, one can use the JVMs (note I didn�t say �Javas�)
ArrayLists, Files, Dates, etc.
The thing is: using Clojure datastructures is extremly easy.
Instead of doing
(def x (new java.util.Hashtable 3))
(.put x :a 10)
(.put x :b 20)
(.put x :c 30)
...
(println (map inc (.values x)))

or even
(def y (new java.util.Hashtable 3))
(doseq [[k v] [[:a 10] [:b 20] [:c 30]]]
   (.put y k v))
...
(println (map inc (.values x))

we would prefer:
(def z {:a 10, :b 20, :c 30})
(println (map inc (vals z))

Now imagine how I would have used the JVMs Vectors instead of the
Clojure ones. I could not have used destructuring, and saying
[[:a 10] [:b 20] [:c 30]] would be painful. So variant 1 seems to be
more realistic.

Because it is so easy to use lists in CL people use them quite often
at points where a Vector or Hashtable would make more sense.
For example Lisp expert Peter Seibel wrote this chapter:
http://www.gigamonkeys.com/book/practical-a-simple-database.html
He used plists. If he had written this chapter for Clojure then I bet
he would have used a hashmap.
Yes, I know, it was for introductory purposes, and he did not want to
confront the ingenuous newbi with the complicated CL hashtables.

We have also to differentiate between conventions that we need to make
with our workmates, and those that are used worldwide by anyone who
uses the language, because it is a case of writing idiomatic code.


>> This video is well worth to be watched:
>> http://rubyconf2008.confreaks.com/what-all-rubyist-should-know-about-threads.html
> 
> Thanks, for the link.  Have to watch it later.

It�s a nice vid, I just watched 20 minutes of it again.
(47 minutes for the full vid)


>> Yes, it is about a Ruby guy, but what he says applies to 99% of all
>> programming languages. Outstanding exceptions would be Clojure, Haskell
>> and Erlang.
>> Those langs also allow us to make tons of mistakes and they can not do
>> magic. The hard concurrency problem does not go away. But they do a good
>> job in making it easier.
>> Immutability by default, a STM (or similar mechanism) and some
>> corresponding abstractings/tools in the language make it possible, and
>> often even trivial.
> 
> Well, Erlang and Haskell live in their own isolated worlds and don't
> claim to have "seamless integration with Java".  I doubt that it's
> possible to have easy Java interop and easy concurrency at the same
> time.

Please Helmut, don�t see my question too critical, but: on how much
experience with Clojure programming do you rely on when doubting it?


> It's bit like saying that you can freely call C++ functions and
> that there will be no segfaults.

But only a bit :)


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Helmut Eller
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <m24oynsqop.fsf@gmail.com>
* Andr� Thieme [2009-02-21 15:35+0100] writes:

>> Well, Erlang and Haskell live in their own isolated worlds and don't
>> claim to have "seamless integration with Java".  I doubt that it's
>> possible to have easy Java interop and easy concurrency at the same
>> time.
>
> Please Helmut, don�t see my question too critical, but: on how much
> experience with Clojure programming do you rely on when doubting it?

I only read the webpage and the Clojure SLIME backend.

The SLIME backend is a concurrent server and AFAICT it doesn't use
Clojure's concurrency features but imitates the message passing system
that we used for the real SLIME.  To me, the part that emulates message
passing doesn't look any simpler that plain old locking.  I had hoped
that it would use JDI to see something more interesting but it
implements no debugger and no inspector beyond Java's reflection.  I
didn't understand all the Clojure idioms and certainly not the reader
macros, but I know damn well what a SLIME backend has to do.

Despite that, my doubt is a general observation not limited to Clojure.

Helmut.
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70at0bF1qa6U1@mid.individual.net>
Andr� Thieme wrote:

> At least until today it is not typical CL/Java style to write programs
> in such a way.

There is no typical CL style. ACL2 and QI are as much first-class 
citizens of the CL space as other libraries and extensions, for example.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnpn7n$qr2$1@news.motzarella.org>
Pascal Costanza schrieb:
> Andr� Thieme wrote:
> 
>> At least until today it is not typical CL/Java style to write programs
>> in such a way.
> 
> There is no typical CL style. ACL2 and QI are as much first-class 
> citizens of the CL space as other libraries and extensions, for example.

One could maybe define that the typical style is the average out of all
CL programs.
Btw, often people in c.l.l (maybe not you!) suggested other users not to
write C/Java/Whatever in CL, but do it the CL way.
It is typical that CL programs don�t try hard to avoid setf/push/decf/...
So, that is part of the typical CL style.

Btw, I find it strange that you talked about FSet as if it were a
language of its own, but call Qi a CL lib. I have more the impression
that Mark Tarver sees Qi as a unique language which happens to be
implemented on some CL VMs. So, like Clojure it can interface with all
the libs of the VM it runs on. Tarver realized that it makes sense to
leverage the advantages of targetting his language in an already
existant VM instead of writing his own. Although some readers of c.l.l
think that Lisp runs better in its own VM (which is not the case for Qi,
so those people must think that Qi does not run very well (I disagree)),
it brought several advantages. Same was true for Clojure. Rich did not
have to waste his time to implement a GC. Instead he simply uses one of
the best GCs around, the one in the JVM.
Maybe (hopefully) Mark will decide to implement Qi on the JVM. Perhaps
doing so in Clojure.

Anyway, back to the style issue. I think that even if it is hard or
practically not possible to write down what the typical style is, or
the small set of the most typical styles, I see there is such a thing.
When you look at programs by beginners, you can immediately give tips
how they should reorganize their code. Many Lispers could do this.
Yes, there are maybe 2, 3 or even 5 suggestions coming, but the set
will be limited (and even be very small). If that is the case then there
seems to be an agreement on how to solve tasks.
This is what I can understand under �style�.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70b7feF48eoU1@mid.individual.net>
Andr� Thieme wrote:
> Pascal Costanza schrieb:
>> Andr� Thieme wrote:
>>
>>> At least until today it is not typical CL/Java style to write programs
>>> in such a way.
>>
>> There is no typical CL style. ACL2 and QI are as much first-class 
>> citizens of the CL space as other libraries and extensions, for example.
> 
> One could maybe define that the typical style is the average out of all
> CL programs.

That concept only exists in your mind. It is quite common to build your 
own domain-specific language in Common Lisp, and then solve your problem 
in that language. It is a very typical approach in Lisp to think and 
program in terms of domain concepts, and try to avoid to express the 
solutions in terms of the constructs that CL happens to provide.

> Btw, often people in c.l.l (maybe not you!) suggested other users not to
> write C/Java/Whatever in CL, but do it the CL way.
> It is typical that CL programs don�t try hard to avoid setf/push/decf/...

Speak for yourself.

> So, that is part of the typical CL style.

To paraphrase Joe Marshall, the only thing I know for sure about most 
programs is that I haven't seen them.

> Btw, I find it strange that you talked about FSet as if it were a
> language of its own, but call Qi a CL lib.

I said "libraries _and_ extensions". A strong point of Lisp in general 
is that the distinction between libraries and language extensions blurs.

> I have more the impression
> that Mark Tarver sees Qi as a unique language which happens to be
> implemented on some CL VMs. So, like Clojure it can interface with all
> the libs of the VM it runs on. Tarver realized that it makes sense to
> leverage the advantages of targetting his language in an already
> existant VM instead of writing his own. Although some readers of c.l.l
> think that Lisp runs better in its own VM (which is not the case for Qi,
> so those people must think that Qi does not run very well (I disagree)),
> it brought several advantages. Same was true for Clojure. Rich did not
> have to waste his time to implement a GC. Instead he simply uses one of
> the best GCs around, the one in the JVM.

Er, yes. So? I never disputed this.



Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Jeffrey Straszheim
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <e87495ba-154c-4316-9125-8950135de34e@j1g2000yqi.googlegroups.com>
Just as a point of fact, the Clojure data structures implement the
java Collection interface, and can be used fairly seamlessly within
Java, at least for any Java code that respects immutability.


On Feb 20, 3:43 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
> >> André Thieme wrote:
> >>> Scott Burson schrieb:
> >>>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> >>>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
> >>>>>> In 25 words or less, why is Clojure better than Common Lisp?
> >>>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
> >>>>> use and more native to functional programming.
> >>>> One more time, I can't resist... ;-}
> >>>>http://common-lisp.net/project/fset/
> >>> Yes, not bad.
> >>> But I doubt someone could use this after having used Clojure.
> >>> It misses the nice reader macros.
> >>> It does not plug in into CL. For example one has to use image
> >>> instead of mapcar.
> >> That's an empty statement. Clojure also doesn't "plug in" into Java.
>
> > It's not an empty statement, it's one whose point keeps getting missed/
> > avoided.
>
> It's a totally empty statement. And I definitely get your point you're
> trying to make, but you are missing a different point here.
>
>
>
> > FSet is very nice, but it has to redefine many of the core Lisp
> > algorithms:
>
> >http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>
> > Why? Because the core algorithms in the COMMON-LISP package do not
> > extend to new user-defined types like the ones defined by FSet's
> > author, and more important, neither do existing algorithms defined in
> > terms of the CL core. That's what is meant by "It does not plug in
> > into CL". The analogy is not between Clojure plugging into Java but
> > between new user-defined data types plugging into Clojure's core
> > algorithms - they can. So such rewriting of algorithms is not
> > necessary. Old/core algorithms work with new data structures and new
> > algorithms work with old data structures.
>
> > This is not a small nicety, but a critical feature of a language that
> > purports to be extensible, IMO.
>
> FSet relates to Common Lisp in exactly the same way as Clojure relates
> to Java. You decided to use Java as the "back end" for implementing
> Clojure (or more precisely the JVM, but I will use that interchangeably
> here in this context), while Scott Burson decided to use Common Lisp as
> the "back end" for implementing FSet. The only real difference here is
> that FSet has the advantage that CL macros and functions can be directly
> used to implement it, while for Clojure you had to implement your own
> scanner/parser/compiler on top of Java.
>
> Criticizing FSet that algorithms implemented on top of core Common Lisp
> cannot smoothly be reused with FSet data structures is exactly at the
> same level as criticizing Clojure that existing Java algorithms cannot
> smoothly be reused with Clojure data structures. The only reason why you
> seem to confuse this is that Common Lisp syntax and FSet syntax look
> (and are) exactly the same, while in the case of Java vs. Clojure, there
> is a sharp and clear border between implementation language and
> implemented language.
>
> It's a fundamental problem of language extensions in general: Different
> language extensions do not compose for free, and there is no remedy
> against that in the general case. You will get exactly the same problems
> as soon as people start to build their own language extensions on top of
> Clojure. Say, one person implements a dataflow extension for Clojure,
> another implements a logic language for Clojure, then you won't be able
> to just throw them together and expect to be able to use them in
> conjunction either. Clojure would be as little to blame in this regard
> as Common Lisp is to blame that FSet doesn't smoothly work in
> conjunction with other algorithms and extensions.
>
> Yes, you can prepare for certain extensions to become easier to plug in,
> and you seem to have done a pretty good job with Clojure for the core
> collections. But at the same time, you have thrown the baby out with the
> bathwater - no existing Lisp and Scheme libraries will just work out of
> the box with Clojure either, a lot of stuff has to be rebuilt from
> scratch. Again, you had what seems to be good reasons, so I have no
> gripes with that. But please keep the comparison fair.
>
> Pascal
>
> --
> ELS'09:http://www.european-lisp-symposium.org/
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70a8m0FnhhavU2@mid.individual.net>
Jeffrey Straszheim wrote:
> Just as a point of fact, the Clojure data structures implement the
> java Collection interface, and can be used fairly seamlessly within
> Java, at least for any Java code that respects immutability.

I remember Java collections relying a lot on mutation. Really a lot. 
Rich Hickey told me that Java collections work well when using them in a 
functional style (so without mutation). I find it hard to believe that, 
unless they changed the API a lot since I last checked it in more detail 
(which is a couple of years ago).


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <96308046-116a-4135-a999-6ccad25dbd2c@t11g2000yqg.googlegroups.com>
On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
> Jeffrey Straszheim wrote:
> > Just as a point of fact, the Clojure data structures implement the
> > java Collection interface, and can be used fairly seamlessly within
> > Java, at least for any Java code that respects immutability.
>
> I remember Java collections relying a lot on mutation. Really a lot.
> Rich Hickey told me that Java collections work well when using them in a
> functional style (so without mutation). I find it hard to believe that,
> unless they changed the API a lot since I last checked it in more detail
> (which is a couple of years ago).
>

You really must stop the FUD. The Java collection class library is a
pretty nice design. One of the things they definitely thought about
was immutability. All of the collections are defined in terms of
interfaces, allowing for extensions. And the interface specifications
are careful to make all mutating operations optional, with a well
defined protocol for implementing immutable versions.

All of Clojure's collections implement the immutable portion of the
corresponding Java interface - they implement (Java's) Iterable,
Collection, List, Set, Map, etc, and appear as such to Java programs
without conversion or copying.

There is a ton of Java code that consumes collections without mutating
them, and all of that code works transparently with Clojure's data
structures.

And it is easy to extend other Java interfaces in Clojure iteself. The
team working on enclojure, the Clojure plugin for Netbeans (a Java
IDE, written in Java), has written a large portion of the plugin in
Clojure, this in spite of the fact that the entire extensibility API
of Netbeans is specified in terms on Java interfaces and other Java-
based contracts. They routinely pass Clojure data structures directly
to Netbeans.

Rich
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a0678e$0$5911$607ed4bc@cv.net>
Rich Hickey wrote:
> On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
>> Jeffrey Straszheim wrote:
>>> Just as a point of fact, the Clojure data structures implement the
>>> java Collection interface, and can be used fairly seamlessly within
>>> Java, at least for any Java code that respects immutability.
>> I remember Java collections relying a lot on mutation. Really a lot.
>> Rich Hickey told me that Java collections work well when using them in a
>> functional style (so without mutation). I find it hard to believe that,
>> unless they changed the API a lot since I last checked it in more detail
>> (which is a couple of years ago).
>>
> 
> You really must stop the FUD.

No, this is perfect. Now we get to learn solid information about Clojure 
from The Man Himself, all in the fun context of a modest flamewar. It's 
like when trolls set on CL and then have to listen to reams of solid 
advantages thereof.

Witness what came next:

> The Java collection class library is a
> pretty nice design. One of the things they definitely thought about
> was immutability. All of the collections are defined in terms of
> interfaces, allowing for extensions. And the interface specifications
> are careful to make all mutating operations optional, with a well
> defined protocol for implementing immutable versions.
> 
> All of Clojure's collections implement the immutable portion of the
> corresponding Java interface - they implement (Java's) Iterable,
> Collection, List, Set, Map, etc, and appear as such to Java programs
> without conversion or copying.
> 
> There is a ton of Java code that consumes collections without mutating
> them, and all of that code works transparently with Clojure's data
> structures.
> 
> And it is easy to extend other Java interfaces in Clojure iteself. The
> team working on enclojure, the Clojure plugin for Netbeans (a Java
> IDE, written in Java), has written a large portion of the plugin in
> Clojure, this in spite of the fact that the entire extensibility API
> of Netbeans is specified in terms on Java interfaces and other Java-
> based contracts. They routinely pass Clojure data structures directly
> to Netbeans.
> 

The lurkers win big time. And you get to talk up Clojure without being 
accused of spamming.

my2k
From: William James
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnppqd0eu2@enews5.newsguy.com>
Kenneth Tilton wrote:

> The lurkers win big time. And you get to talk up Clojure without
> being accused of spamming.

... says the boy who started the thread with this in mind.
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a0a734$0$20288$607ed4bc@cv.net>
William James wrote:
> Kenneth Tilton wrote:
> 
>> The lurkers win big time. And you get to talk up Clojure without
>> being accused of spamming.
> 
> ... says the boy who started the thread with this in mind.

I thought you were going to say "From the Master of (Cells) Spam)...". I 
would have bought that.

So now I am shilling for Clojure? Does this mean I am no longer shilling 
for qooxdoo? And Franz? Whew! There's a load off.


kt
From: Scott
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <833ab965-40a2-4827-bc8f-ebf92f4663ac@h20g2000yqn.googlegroups.com>
On Feb 21, 6:15 pm, Kenneth Tilton <·········@gmail.com> wrote:
> William James wrote:
>
> > ... says the boy who started the thread with this in mind.
>
> I thought you were going to say "From the Master of (Cells) Spam)...". I
> would have bought that.
>
> So now I am shilling for Clojure? Does this mean I am no longer shilling
> for qooxdoo? And Franz? Whew! There's a load off.
>

After you came crawling back from the village of Arc, and especially
considering you're spending a lot of time in the sprawling suburbs of
JavaScript, it seems safe to conclude that you're still searching for
something you haven't found in Common Lisp.

Oh crap, I was almost intended to complete that metaphor with the
commune of Common Lisp...
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a0c655$0$5901$607ed4bc@cv.net>
Scott wrote:
> On Feb 21, 6:15 pm, Kenneth Tilton <·········@gmail.com> wrote:
>> William James wrote:
>>
>>> ... says the boy who started the thread with this in mind.
>> I thought you were going to say "From the Master of (Cells) Spam)...". I
>> would have bought that.
>>
>> So now I am shilling for Clojure? Does this mean I am no longer shilling
>> for qooxdoo? And Franz? Whew! There's a load off.
>>
> 
> After you came crawling back from the village of Arc, 

I am pretty sure it was head first slide. My plan was to infect the 
world with Cells via Arc when that took off. Oops.

> and especially
> considering you're spending a lot of time in the sprawling suburbs of
> JavaScript, it seems safe to conclude that you're still searching for
> something you haven't found in Common Lisp.

Since the goal* of my current project is to let me write almost zero JS 
so I can use CL+Cells to program qooxdoo...oops, did I just demolish 
your theory?

kzo

* I was going to say the goal was also cells infection, but OpenLaszlo 
kinda beat me to that in re web app programming. k
From: Stuart Sierra
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <144dcb92-506f-497d-b640-7d0f88af6ba8@v19g2000yqn.googlegroups.com>
On Feb 21, 10:28 pm, Kenneth Tilton wrote:
> My plan was to infect the world with Cells
> via Arc when that took off. Oops.

There have been at least four Cells-like things demonstrated on the
Clojure mailing list.  I wrote two of them.  Everyone's waiting for
the perfect Clojure-Cells.  Why don't you dive in and show us how it's
done, Kenny!

Oh, and speaking as the author of several Clojure libraries, I love
it.  It has replaced Common Lisp, Java, and Ruby for me, both at home
and at work.  The more I learn about it the better it gets.

-Stuart Sierra
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a0d71f$0$5898$607ed4bc@cv.net>
Stuart Sierra wrote:
> On Feb 21, 10:28 pm, Kenneth Tilton wrote:
>> My plan was to infect the world with Cells
>> via Arc when that took off. Oops.
> 
> There have been at least four Cells-like things demonstrated on the
> Clojure mailing list.  I wrote two of them.

The paradigm is inevitable, eh? I suspended the Spam Campaign when I 
realized frickin everyone was doing it (inevitable does that to people). 
Even qooxdoo has someone adding primitive dataflow to qx for a masters 
thesis.

>  Everyone's waiting for
> the perfect Clojure-Cells.  Why don't you dive in and show us how it's
> done, Kenny!

You know I'd love to, but I have a kingdom to rule, a war to start, a 
wife to murder -- I'm swamped!

Deep in the Cells Manifesto you'll find a map to the buried treasure: 
five/six attributes defining what I grandiosely christened Integrity. 
That's how it's done.

> 
> Oh, and speaking as the author of several Clojure libraries, I love
> it.  It has replaced Common Lisp, Java, and Ruby for me, both at home
> and at work.  The more I learn about it the better it gets.

Aha! A True Roadie! You should hit a Lisp-NYC drinkfest soon and regale 
us with your Clojjery. Mebbe P&G II will be open by March's meet=up.

kt
From: Scott
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <eea8f6f2-e374-4d55-bc44-d961f79ef5a0@l16g2000yqo.googlegroups.com>
On Feb 21, 8:28 pm, Kenneth Tilton <·········@gmail.com> wrote:
>
> > it seems safe to conclude that you're still searching for
> > something you haven't found in Common Lisp.
>
> Since the goal* of my current project is to let me write almost zero JS
> so I can use CL+Cells to program qooxdoo...oops, did I just demolish
> your theory?
>

Damnit.  I'm wrong again.  Ok, you're still a shill.
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a0e120$0$20285$607ed4bc@cv.net>
Scott wrote:
> On Feb 21, 8:28 pm, Kenneth Tilton <·········@gmail.com> wrote:
>>> it seems safe to conclude that you're still searching for
>>> something you haven't found in Common Lisp.
>> Since the goal* of my current project is to let me write almost zero JS
>> so I can use CL+Cells to program qooxdoo...oops, did I just demolish
>> your theory?
>>
> 
> Damnit.  I'm wrong again.  Ok, you're still a shill.
> 

OK. What for this time? I shill so many I forget.

kt
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70asg7F1nooU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
>> Jeffrey Straszheim wrote:
>>> Just as a point of fact, the Clojure data structures implement the
>>> java Collection interface, and can be used fairly seamlessly within
>>> Java, at least for any Java code that respects immutability.
>> I remember Java collections relying a lot on mutation. Really a lot.
>> Rich Hickey told me that Java collections work well when using them in a
>> functional style (so without mutation). I find it hard to believe that,
>> unless they changed the API a lot since I last checked it in more detail
>> (which is a couple of years ago).
>>
> 
> You really must stop the FUD. The Java collection class library is a
> pretty nice design. 

When I hear you talking about the Java Collection API, I get the 
impression we are talking about two very different things. So I just 
made a quick double-check on the Java Collection API (as of 5.0), and it 
is indeed the same one that I remember from some time ago, and it seems 
that nothing substantial has changed since then.

We are talking about the collections as defined in java.util.*, right? 
The ones where many interfaces define methods for mutating collections, 
right? Where the distinction between mutable and immutable collection is 
made by throwing OperationNotSupportedException, right? Where, if you 
follow the recommended practice to use abstract interface types for 
declaring variables instead of concrete class types, you have no real 
indication whether you will get mutable or immutable collections, right?

I am sorry, but I really have to disagree with you here. The Java 
Collection API sucks. Big time. I know, I had to use it. For real. 
Seriously.

If you mean something in java.util.concurrent.*, then I cannot comment 
on that, because I haven't used it. Maybe we really misunderstand each 
other because we are talking about different things here.


Pascal

> One of the things they definitely thought about
> was immutability. All of the collections are defined in terms of
> interfaces, allowing for extensions. And the interface specifications
> are careful to make all mutating operations optional, with a well
> defined protocol for implementing immutable versions.
> 
> All of Clojure's collections implement the immutable portion of the
> corresponding Java interface - they implement (Java's) Iterable,
> Collection, List, Set, Map, etc, and appear as such to Java programs
> without conversion or copying.
> 
> There is a ton of Java code that consumes collections without mutating
> them, and all of that code works transparently with Clojure's data
> structures.
> 
> And it is easy to extend other Java interfaces in Clojure iteself. The
> team working on enclojure, the Clojure plugin for Netbeans (a Java
> IDE, written in Java), has written a large portion of the plugin in
> Clojure, this in spite of the fact that the entire extensibility API
> of Netbeans is specified in terms on Java interfaces and other Java-
> based contracts. They routinely pass Clojure data structures directly
> to Netbeans.
> 
> Rich


-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <2eeb637f-387d-4671-bc72-b935ae6e17cc@k19g2000yqg.googlegroups.com>
On Feb 21, 12:38 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
> >> Jeffrey Straszheim wrote:
> >>> Just as a point of fact, the Clojure data structures implement the
> >>> java Collection interface, and can be used fairly seamlessly within
> >>> Java, at least for any Java code that respects immutability.
> >> I remember Java collections relying a lot on mutation. Really a lot.
> >> Rich Hickey told me that Java collections work well when using them in a
> >> functional style (so without mutation). I find it hard to believe that,
> >> unless they changed the API a lot since I last checked it in more detail
> >> (which is a couple of years ago).
>
> > You really must stop the FUD. The Java collection class library is a
> > pretty nice design.
>
> When I hear you talking about the Java Collection API, I get the
> impression we are talking about two very different things. So I just
> made a quick double-check on the Java Collection API (as of 5.0), and it
> is indeed the same one that I remember from some time ago, and it seems
> that nothing substantial has changed since then.
>
> We are talking about the collections as defined in java.util.*, right?
> The ones where many interfaces define methods for mutating collections,
> right? Where the distinction between mutable and immutable collection is
> made by throwing OperationNotSupportedException, right? Where, if you
> follow the recommended practice to use abstract interface types for
> declaring variables instead of concrete class types, you have no real
> indication whether you will get mutable or immutable collections, right?
>

> I am sorry, but I really have to disagree with you here. The Java
> Collection API sucks. Big time. I know, I had to use it. For real.
> Seriously.
>

Have we really degraded to "xxxx sucks"? I hope not. At least Java has
a collections API with extensible abstractions. And a final designator
to indicate immutability with some enforcement and optimization.
You're throwing stones at the world that don't even make it out of the
ditch that you are in.

Yes, that's the API. And yes, I'd prefer, in a statically typed
language, that there was a read-only layer in the hierarchy. It's a
real-world design decision that reflects a real-world tradeoff, a
simplified set of abstractions vs. a multiplying number of
collections. I don't know if you've worked with fully-factored
collection class hierarchies (I have, IBM's Open Class collection
classes come to mind), but the hierarchies can quickly become
unwieldy.

That said, in practice, it's a non-issue. No real code says "if
immutable do this, else do that". If you need to change the
collection, the one passed had better be mutable. If you are not
changing the collection, you don't care if it's mutable or not
(concurrency aside). The majority of code falls into the latter
category and uses Clojure collections just fine.

Rich

> If you mean something in java.util.concurrent.*, then I cannot comment
> on that, because I haven't used it. Maybe we really misunderstand each
> other because we are talking about different things here.
>


> Pascal
>
>
>
> > One of the things they definitely thought about
> > was immutability. All of the collections are defined in terms of
> > interfaces, allowing for extensions. And the interface specifications
> > are careful to make all mutating operations optional, with a well
> > defined protocol for implementing immutable versions.
>
> > All of Clojure's collections implement the immutable portion of the
> > corresponding Java interface - they implement (Java's) Iterable,
> > Collection, List, Set, Map, etc, and appear as such to Java programs
> > without conversion or copying.
>
> > There is a ton of Java code that consumes collections without mutating
> > them, and all of that code works transparently with Clojure's data
> > structures.
>
> > And it is easy to extend other Java interfaces in Clojure iteself. The
> > team working on enclojure, the Clojure plugin for Netbeans (a Java
> > IDE, written in Java), has written a large portion of the plugin in
> > Clojure, this in spite of the fact that the entire extensibility API
> > of Netbeans is specified in terms on Java interfaces and other Java-
> > based contracts. They routinely pass Clojure data structures directly
> > to Netbeans.
>
> > Rich
>
> --
> ELS'09:http://www.european-lisp-symposium.org/
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70b3ufF2sjoU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 21, 12:38 pm, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Jeffrey Straszheim wrote:
>>>>> Just as a point of fact, the Clojure data structures implement the
>>>>> java Collection interface, and can be used fairly seamlessly within
>>>>> Java, at least for any Java code that respects immutability.
>>>> I remember Java collections relying a lot on mutation. Really a lot.
>>>> Rich Hickey told me that Java collections work well when using them in a
>>>> functional style (so without mutation). I find it hard to believe that,
>>>> unless they changed the API a lot since I last checked it in more detail
>>>> (which is a couple of years ago).
>>> You really must stop the FUD. The Java collection class library is a
>>> pretty nice design.
>> When I hear you talking about the Java Collection API, I get the
>> impression we are talking about two very different things. So I just
>> made a quick double-check on the Java Collection API (as of 5.0), and it
>> is indeed the same one that I remember from some time ago, and it seems
>> that nothing substantial has changed since then.
>>
>> We are talking about the collections as defined in java.util.*, right?
>> The ones where many interfaces define methods for mutating collections,
>> right? Where the distinction between mutable and immutable collection is
>> made by throwing OperationNotSupportedException, right? Where, if you
>> follow the recommended practice to use abstract interface types for
>> declaring variables instead of concrete class types, you have no real
>> indication whether you will get mutable or immutable collections, right?
>>
> 
>> I am sorry, but I really have to disagree with you here. The Java
>> Collection API sucks. Big time. I know, I had to use it. For real.
>> Seriously.
> 
> Have we really degraded to "xxxx sucks"? I hope not. At least Java has
> a collections API with extensible abstractions. And a final designator
> to indicate immutability with some enforcement and optimization.
> You're throwing stones at the world that don't even make it out of the
> ditch that you are in.

Java's Collection API was mostly a design based on political criteria 
rather than anything else. It was the best Sun could come up with that 
was still compatible with the screwy design of Java's 1.0 API. 
Alternative better designs were already in use, but Sun overruled 
community wishes and forced the Collection API down everybody's throats. 
That's the history.

See http://www.javaworld.com/javaworld/jw-01-1999/jw-01-jglvscoll.html 
and http://java.sun.com/j2se/1.5.0/docs/guide/collections/designfaq.html 
for some background information.

"Real world." - Yeah, sure...


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70d0cmFh56bU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 21, 12:38 pm, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Jeffrey Straszheim wrote:
>>>>> Just as a point of fact, the Clojure data structures implement the
>>>>> java Collection interface, and can be used fairly seamlessly within
>>>>> Java, at least for any Java code that respects immutability.
>>>> I remember Java collections relying a lot on mutation. Really a lot.
>>>> Rich Hickey told me that Java collections work well when using them in a
>>>> functional style (so without mutation). I find it hard to believe that,
>>>> unless they changed the API a lot since I last checked it in more detail
>>>> (which is a couple of years ago).
>>> You really must stop the FUD. The Java collection class library is a
>>> pretty nice design.
>> When I hear you talking about the Java Collection API, I get the
>> impression we are talking about two very different things. So I just
>> made a quick double-check on the Java Collection API (as of 5.0), and it
>> is indeed the same one that I remember from some time ago, and it seems
>> that nothing substantial has changed since then.

[...]
> That said, in practice, it's a non-issue. No real code says "if
> immutable do this, else do that". If you need to change the
> collection, the one passed had better be mutable. If you are not
> changing the collection, you don't care if it's mutable or not
> (concurrency aside). The majority of code falls into the latter
> category and uses Clojure collections just fine.

Rich, I know you're a smart guy, but what you say is strongly different 
from my experience with Java collections.

The only reasonably explanation I can come up with is that, maybe, 
programming practice in Java has evolved in the last few years since I 
stopped working with Java on a day-to-day basis, in such a way that the 
"bad parts" of Java collections are just ignored or circumvented in 
practice. That could indeed be the case and seems to make sense to me. 
(Every language that exists for a considerable amount of time has its 
warts, and practitioners of each language know how to deal with them.)


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <71e060b4-8bd2-4f93-98a7-85ebbf83e173@v19g2000yqn.googlegroups.com>
On Feb 22, 7:56 am, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 21, 12:38 pm, Pascal Costanza <····@p-cos.net> wrote:
> >> Rich Hickey wrote:
> >>> On Feb 21, 7:00 am, Pascal Costanza <····@p-cos.net> wrote:
> >>>> Jeffrey Straszheim wrote:
> >>>>> Just as a point of fact, the Clojure data structures implement the
> >>>>> java Collection interface, and can be used fairly seamlessly within
> >>>>> Java, at least for any Java code that respects immutability.
> >>>> I remember Java collections relying a lot on mutation. Really a lot.
> >>>> Rich Hickey told me that Java collections work well when using them in a
> >>>> functional style (so without mutation). I find it hard to believe that,
> >>>> unless they changed the API a lot since I last checked it in more detail
> >>>> (which is a couple of years ago).
> >>> You really must stop the FUD. The Java collection class library is a
> >>> pretty nice design.
> >> When I hear you talking about the Java Collection API, I get the
> >> impression we are talking about two very different things. So I just
> >> made a quick double-check on the Java Collection API (as of 5.0), and it
> >> is indeed the same one that I remember from some time ago, and it seems
> >> that nothing substantial has changed since then.
>
> [...]
>
> > That said, in practice, it's a non-issue. No real code says "if
> > immutable do this, else do that". If you need to change the
> > collection, the one passed had better be mutable. If you are not
> > changing the collection, you don't care if it's mutable or not
> > (concurrency aside). The majority of code falls into the latter
> > category and uses Clojure collections just fine.
>
> Rich, I know you're a smart guy, but what you say is strongly different
> from my experience with Java collections.
>
> The only reasonably explanation I can come up with is that, maybe,
> programming practice in Java has evolved in the last few years since I
> stopped working with Java on a day-to-day basis, in such a way that the
> "bad parts" of Java collections are just ignored or circumvented in
> practice. That could indeed be the case and seems to make sense to me.
> (Every language that exists for a considerable amount of time has its
> warts, and practitioners of each language know how to deal with them.)
>

Ok, I'll try once more, but I must say, while it's easy to just throw
stones and say things like:

"I remember Java collections relying a lot on mutation. Really a
lot."

and:

"The Java Collection API sucks. Big time. I know, I had to use it. For
real. Seriously."

it's a bit facile coming from a CL fan, where hashtables "rely a lot
on mutation", the language itself has almost no facilities for
specifying [im]mutability, and the collections API is inextensible. I
really wish you would tone down the rhetoric. [I know, guffaws from
the stands :)]

First, I want to make it clear I'm no Java apologist - I wrote Clojure
so I don't have to write in Java/C# anymore. I like Lisp, and Common
Lisp especially, but am unwilling to ignore the rest of the world and
other good ideas.

Nor am I claiming Java's collection classes are the ultimate - there's
plenty about them I don't like, starting with: Maps are not
Collections. But your references just confirm my point - JGL had 151
classes vs java.util's 13 - there is a real tradeoff associated with
full factoring. I've used a lot of collection class libraries
professionally - Open Class, STL, RogueWave, JGL, MFC, java.util,
System.Collections, CL's, Python's and others, and written a few
myself. I am certain I didn't agree with every decision made in any of
them. I am partial to generic algorithms + data structures (just look
at Clojure), but without first-class functions, it's kind of gross and
cumbersome.

I've used enough collection libraries to know there's no way to solve
this problem and please everyone, and also that only a few things
matter to most developers: the big-O characteristics of insert/lookup
and the insertion/iteration order. More important to me is that there
is some extensible factoring of the core abstractions - sequential vs
associative, random access, etc. Mutability is not that important a
thing to characterize via types IMO - having worked with Open Class, a
library that ruthlessly type-factored everything, including the
mutability/comparability of both the collections and the contents, I
know it has a complexity cost. It is also frequently done wrong
(mutables deriving from immutables), ruining the ability to detect a
truly immutable thing. And in a dynamic language you're back to
runtime checks anyway.

In java.util, I see something simple, pragmatic, extensible and
generally consistent, but of course imperfect. One (real) metric for
me was the fact that initially Clojure's collections did not fully
participate in java.util's hierarchy. Retrofitting them to do so was
easy, and required very few tweaks to equality and hashcode
generation, the semantics of which were clearly defined in the
documentation. That kind of transparent extension to a radically
different (immutable/functional) implementation is an indicator of
good design, IMO.

One of the neat things about Clojure is that it brings generic
algorithms + data structures home in a big way, not only to its own
data structures but also to Java's collections. It ends up if you have
first-class functions and a decent extensible functional cursor
interface, you need little from collections other than these cursors.
Clojure supports the definition of functions like those of CL's cons
and sequence library, as well as algorithms from ML/Haskell, in such a
way that they work with just about everything - Clojure and Java
collections, Strings, arrays, functional generators, etc. If it proves
anything, it's that there was never a technical reason stopping anyone
from implementing stand-alone algorithms on top of the java.util
collection API (or most of the others), except convention and perhaps
the awkwardness of the languages themselves not having first-class
functions.

Rich
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70e2m5F1n667U2@mid.individual.net>
Rich Hickey wrote:

> Ok, I'll try once more

Thanks a lot for being patient and taking your time to do this. This is 
very helpful.

Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <bcb0d22c-e807-40af-9dc8-9018da812c35@v19g2000yqn.googlegroups.com>
On Feb 20, 3:43 pm, Pascal Costanza <····@p-cos.net> wrote:
> Rich Hickey wrote:
> > On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
> >> André Thieme wrote:
> >>> Scott Burson schrieb:
> >>>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> >>>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
> >>>>>> In 25 words or less, why is Clojure better than Common Lisp?
> >>>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
> >>>>> use and more native to functional programming.
> >>>> One more time, I can't resist... ;-}
> >>>>http://common-lisp.net/project/fset/
> >>> Yes, not bad.
> >>> But I doubt someone could use this after having used Clojure.
> >>> It misses the nice reader macros.
> >>> It does not plug in into CL. For example one has to use image
> >>> instead of mapcar.
> >> That's an empty statement. Clojure also doesn't "plug in" into Java.
>
> > It's not an empty statement, it's one whose point keeps getting missed/
> > avoided.
>
> It's a totally empty statement. And I definitely get your point you're
> trying to make, but you are missing a different point here.
>
>
>
> > FSet is very nice, but it has to redefine many of the core Lisp
> > algorithms:
>
> >http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>
> > Why? Because the core algorithms in the COMMON-LISP package do not
> > extend to new user-defined types like the ones defined by FSet's
> > author, and more important, neither do existing algorithms defined in
> > terms of the CL core. That's what is meant by "It does not plug in
> > into CL". The analogy is not between Clojure plugging into Java but
> > between new user-defined data types plugging into Clojure's core
> > algorithms - they can. So such rewriting of algorithms is not
> > necessary. Old/core algorithms work with new data structures and new
> > algorithms work with old data structures.
>
> > This is not a small nicety, but a critical feature of a language that
> > purports to be extensible, IMO.
>
> FSet relates to Common Lisp in exactly the same way as Clojure relates
> to Java.

That's completely skewed. Here are the correlated stacks:

C/ASM -> Common Lisp -> CL Libraries (like FSet)

Java -> Clojure -> Clojure libraries

> You decided to use Java as the "back end" for implementing
> Clojure (or more precisely the JVM, but I will use that interchangeably
> here in this context), while Scott Burson decided to use Common Lisp as
> the "back end" for implementing FSet. The only real difference here is
> that FSet has the advantage that CL macros and functions can be directly
> used to implement it, while for Clojure you had to implement your own
> scanner/parser/compiler on top of Java.
>

If you are seriously going to line up Clojure and FSet, that's hardly
the only real difference.

> Criticizing FSet that algorithms implemented on top of core Common Lisp
> cannot smoothly be reused with FSet data structures is exactly at the
> same level as criticizing Clojure that existing Java algorithms cannot
> smoothly be reused with Clojure data structures.

First off, I'm not criticizing FSet in any way, nor CL. I am just
trying to talk about what is, drawing a distinction between the
extensibility of Common Lisp's core algorithms (and, consequently,
other algorithms written atop them), and Clojure's core algorithms.
FSet has no choice but to do what it does.

Second, you are completely wrong as to whether existing Java
algorithms can work with Clojure data structures - of course they can.

> The only reason why you
> seem to confuse this is that Common Lisp syntax and FSet syntax look
> (and are) exactly the same, while in the case of Java vs. Clojure, there
> is a sharp and clear border between implementation language and
> implemented language.
>

If you want to look at every Common Lisp library as a new language,
then the problem just moves there - programs written in these
"languages" have no common basis for polymorphic interoperability. If
every "language" has redefined mapcar/image in terms of their own GFs,
then every data structure author has to build a bridge to each library
(er, language), and every algorithm author has to pick a "language" or
reimplement in each "language". To the extent a language is not just a
way for a single person to communicate with a computer, but a way also
for people to communicate with each other, a plethora of distinct
languages for expressing the same core ideas is a definite
disadvantage.

And the "sharp and clear border" is just FUD - I think until you know
a lot more about Clojure and Java you should refrain from making
statements about them. You can transparently consume/extend Clojure
from Java and consume/extend Java from Clojure.

> It's a fundamental problem of language extensions in general: Different
> language extensions do not compose for free, and there is no remedy
> against that in the general case.

So, because there is no solution in the general case, Clojure's
specific solution doesn't provide any benefit?

> You will get exactly the same problems
> as soon as people start to build their own language extensions on top of
> Clojure. Say, one person implements a dataflow extension for Clojure,
> another implements a logic language for Clojure, then you won't be able
> to just throw them together and expect to be able to use them in
> conjunction either.

You'll soon be proven wrong about that.

> Clojure would be as little to blame in this regard
> as Common Lisp is to blame that FSet doesn't smoothly work in
> conjunction with other algorithms and extensions.
>

Clojure's job is to make sure they don't have to reinvent the
facilities Clojure provides, and, to the extent they each
independently participate in Clojure's extension mechanisms, they can
work together without specific bridges to each other.

> Yes, you can prepare for certain extensions to become easier to plug in,
> and you seem to have done a pretty good job with Clojure for the core
> collections. But at the same time, you have thrown the baby out with the
> bathwater - no existing Lisp and Scheme libraries will just work out of
> the box with Clojure either, a lot of stuff has to be rebuilt from
> scratch. Again, you had what seems to be good reasons, so I have no
> gripes with that. But please keep the comparison fair.
>

And all the great libraries written to the CL core algorithms will
have to be rewritten to work with FSet collections (barring some
shadowing hack, which can only work with one FSet-like library at a
time).

The stuff that Clojure rebuilt from scratch needed to be rebuilt from
scratch in order to provide the facilities that Clojure provides, and
my desire in this discussion is to highlight one area in which that
was the case - lack of extensibility of core algorithms.

You can dance around it all you like, but there are distinct benefits
to implementing in a language with a high-performance (albeit basic)
polymorphic dispatch system, benefits that can be exposed in the
implemented language if so designed. That's how Clojure works. It does
*not* require you to write Java in order to leverage the polymorphism
obtained from having been implemented in Java. I encourage those with
open minds to discover for themselves what it feels like to work with
a polymorphic core library.

To the extent the OP's statement is borne of his experience of the
difference, it is not empty.

Rich
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70au1jF1shfU1@mid.individual.net>
Rich Hickey wrote:
> On Feb 20, 3:43 pm, Pascal Costanza <····@p-cos.net> wrote:
>> Rich Hickey wrote:
>>> On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
>>>> Andr� Thieme wrote:
>>>>> Scott Burson schrieb:
>>>>>> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
>>>>>>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>>>>>>>> In 25 words or less, why is Clojure better than Common Lisp?
>>>>>>> Seqs partake of some of the awesomeness of SERIES, but are easier to
>>>>>>> use and more native to functional programming.
>>>>>> One more time, I can't resist... ;-}
>>>>>> http://common-lisp.net/project/fset/
>>>>> Yes, not bad.
>>>>> But I doubt someone could use this after having used Clojure.
>>>>> It misses the nice reader macros.
>>>>> It does not plug in into CL. For example one has to use image
>>>>> instead of mapcar.
>>>> That's an empty statement. Clojure also doesn't "plug in" into Java.
>>> It's not an empty statement, it's one whose point keeps getting missed/
>>> avoided.
>> It's a totally empty statement. And I definitely get your point you're
>> trying to make, but you are missing a different point here.
>>
>>> FSet is very nice, but it has to redefine many of the core Lisp
>>> algorithms:
>>> http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>>> Why? Because the core algorithms in the COMMON-LISP package do not
>>> extend to new user-defined types like the ones defined by FSet's
>>> author, and more important, neither do existing algorithms defined in
>>> terms of the CL core. That's what is meant by "It does not plug in
>>> into CL". The analogy is not between Clojure plugging into Java but
>>> between new user-defined data types plugging into Clojure's core
>>> algorithms - they can. So such rewriting of algorithms is not
>>> necessary. Old/core algorithms work with new data structures and new
>>> algorithms work with old data structures.
>>> This is not a small nicety, but a critical feature of a language that
>>> purports to be extensible, IMO.
>> FSet relates to Common Lisp in exactly the same way as Clojure relates
>> to Java.
> 
> That's completely skewed. Here are the correlated stacks:
> 
> C/ASM -> Common Lisp -> CL Libraries (like FSet)
> 
> Java -> Clojure -> Clojure libraries

Er, on top of what do you think Java is implemented?!?

>> You decided to use Java as the "back end" for implementing
>> Clojure (or more precisely the JVM, but I will use that interchangeably
>> here in this context), while Scott Burson decided to use Common Lisp as
>> the "back end" for implementing FSet. The only real difference here is
>> that FSet has the advantage that CL macros and functions can be directly
>> used to implement it, while for Clojure you had to implement your own
>> scanner/parser/compiler on top of Java.
> 
> If you are seriously going to line up Clojure and FSet, that's hardly
> the only real difference.

Sorry, I should have been more precise: Of course, I am only comparing 
Clojure's collections with FSet.

>> Criticizing FSet that algorithms implemented on top of core Common Lisp
>> cannot smoothly be reused with FSet data structures is exactly at the
>> same level as criticizing Clojure that existing Java algorithms cannot
>> smoothly be reused with Clojure data structures.
> 
> First off, I'm not criticizing FSet in any way, nor CL. I am just
> trying to talk about what is, drawing a distinction between the
> extensibility of Common Lisp's core algorithms (and, consequently,
> other algorithms written atop them), and Clojure's core algorithms.
> FSet has no choice but to do what it does.
> 
> Second, you are completely wrong as to whether existing Java
> algorithms can work with Clojure data structures - of course they can.

...only to the extent that they don't use the unsupported operations of 
the Java Collection API. That's why I said that "different language 
extensions do not compose for free, and there is no remedy against that 
_in the general case_." In the specific cases, where Java algorithms 
don't mutate collections, Clojure collections will, of course, work. But 
you have to ensure that, it doesn't just come for free.

>> The only reason why you
>> seem to confuse this is that Common Lisp syntax and FSet syntax look
>> (and are) exactly the same, while in the case of Java vs. Clojure, there
>> is a sharp and clear border between implementation language and
>> implemented language.
> 
> If you want to look at every Common Lisp library as a new language,
> then the problem just moves there - programs written in these
> "languages" have no common basis for polymorphic interoperability. If
> every "language" has redefined mapcar/image in terms of their own GFs,
> then every data structure author has to build a bridge to each library
> (er, language), and every algorithm author has to pick a "language" or
> reimplement in each "language". To the extent a language is not just a
> way for a single person to communicate with a computer, but a way also
> for people to communicate with each other, a plethora of distinct
> languages for expressing the same core ideas is a definite
> disadvantage.

Sure. And as soon as Clojure grows beyond a certain size, you will 
definitely get similar problems. Trust me. ;)

> And the "sharp and clear border" is just FUD - I think until you know
> a lot more about Clojure and Java you should refrain from making
> statements about them. You can transparently consume/extend Clojure
> from Java and consume/extend Java from Clojure.

I know enough about Java to be able to judge what the interoperability 
problems between language extensions on top of Java are. Been there, 
done that, don't want to go there ever again.

>> It's a fundamental problem of language extensions in general: Different
>> language extensions do not compose for free, and there is no remedy
>> against that in the general case.
> 
> So, because there is no solution in the general case, Clojure's
> specific solution doesn't provide any benefit?

I never said so. You're reading that into my statements (and I'm sorry 
if it's too easy to misunderstand me, but that's probably rather because 
of the inherent complexity of the topic.)

To be explicit about this: If CL had a better collection API at its 
core, like that of Clojure or of Dylan, for example, things would be 
better off. Sure.

But that doesn't keep us from implementing nicer APIs on top of CL and 
continuing from there. And this is neither fundamentally worse nor 
better than dropping CL altogether and using a different, non-Lisp 
language for such extensions. There are simply different trade offs.

>> You will get exactly the same problems
>> as soon as people start to build their own language extensions on top of
>> Clojure. Say, one person implements a dataflow extension for Clojure,
>> another implements a logic language for Clojure, then you won't be able
>> to just throw them together and expect to be able to use them in
>> conjunction either.
> 
> You'll soon be proven wrong about that.

That's what you think. ;)

> To the extent the OP's statement is borne of his experience of the
> difference, it is not empty.

I stand by my claim that it's an empty statement.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnpq89$r88$1@news.motzarella.org>
Pascal Costanza schrieb:
> Rich Hickey wrote:


>> C/ASM -> Common Lisp -> CL Libraries (like FSet)
>>
>> Java -> Clojure -> Clojure libraries
> 
> Er, on top of what do you think Java is implemented?!?

It doesn�t matter that the Java VM works on top of the underlying system.
Your comparison that �FSet relates to Common Lisp in exactly the same 
way as Clojure relates to Java.� is far away from making sense.
Note especially the �exactly� in there.


>> If you are seriously going to line up Clojure and FSet, that's hardly
>> the only real difference.
> 
> Sorry, I should have been more precise: Of course, I am only comparing 
> Clojure's collections with FSet.

Ah okay, that makes more sense.


> Sure. And as soon as Clojure grows beyond a certain size, you will 
> definitely get similar problems. Trust me. ;)

It is not so easy to simply trust you on this specific thing.
Someone else could come in and ask for trusting her instead. She could
say: �Even when Clojure grows beyond a certain size, you will not get
similar problems. Trust me :)�.


>> And the "sharp and clear border" is just FUD - I think until you know
>> a lot more about Clojure and Java you should refrain from making
>> statements about them. You can transparently consume/extend Clojure
>> from Java and consume/extend Java from Clojure.
> 
> I know enough about Java to be able to judge what the interoperability 
> problems between language extensions on top of Java are. Been there, 
> done that, don't want to go there ever again.

How can you decide to never go there again?
That sounds a little bit religious and closed minded.
Another option would be to stay open minded and see the outcomes of
the evolutionary processes that are in progress.

Clojure will most likely not be the last language ever designed, which
will solve all our problems.
Rich says that Clojure is not the silver bullet.
Maybe in 10-15 years he will design a new language, more fit to the
environment we will be in by then.


> To be explicit about this: If CL had a better collection API at its 
> core, like that of Clojure or of Dylan, for example, things would be 
> better off. Sure.

What you just said makes much more sense.
It takes away this intensity out of your emptyness statement.
Not just black & white, but also gray zones.
Clojure maybe will have some of the problems that you already see coming
today. But at least from what I can see today, it feels much more
integrated. As someone who did not use Clojure yet you could of course
not make the same experience.


> But that doesn't keep us from implementing nicer APIs on top of CL and 
> continuing from there.

Yes, only that this is the typical strawman argument that I can read
here since centuries ago.
We could do it, we could implement A, B and C.
We can do it for CL or for Assembler, and all other languages also could
improve in several ways.
But as I see the situation Clojure offers A-W today, and people are
already working on X and Y. I can look back deeply into the archives
of c.l.l and see these statements over and over again.
Some newbie who never touched Lisp comes in and explains us why it
�sucks�. We tell him: �No no, only because A, B and C are currently
not supported, we could implement them anytime.�.

I completely understand that it is true, but I also see the old ballast
shipping with Lisp, and all code written with that in mind. It would be
like Clojure running on existing CL VMs.
This would bring several advantages and disadvantages.
In my opinion the advantages of the JVM (or .NET) far outweight those
of existing CLs.



 > And this is neither fundamentally worse nor
> better than dropping CL altogether and using a different, non-Lisp 
> language for such extensions. There are simply different trade offs.

Ack.


  >> To the extent the OP's statement is borne of his experience of the
>> difference, it is not empty.
> 
> I stand by my claim that it's an empty statement.

I would value it as soon it would be based on facts and your experience
on writing Clojure code.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70bdanF7g25U1@mid.individual.net>
Andr� Thieme wrote:
> Pascal Costanza schrieb:
>> Sure. And as soon as Clojure grows beyond a certain size, you will 
>> definitely get similar problems. Trust me. ;)
> 
> It is not so easy to simply trust you on this specific thing.
> Someone else could come in and ask for trusting her instead. She could
> say: �Even when Clojure grows beyond a certain size, you will not get
> similar problems. Trust me :)�.

I put the smiley there for a reason.

Language extensions do not compose in general. That's a general problem 
that no amount of language design can solve. You can only find ways to 
better manage it.

That's why the CLOS MOP requires you to declare compatibility of 
metaclasses, that's why in Haskell you can only compose monads by way of 
monad transformers, that's why R6RS Scheme integrates a macro tower in 
its module system, etc., etc.

For Clojure, there are only two options: It either dies soon, or it will 
be successful in the long run and has to deal with it in one way or the 
other as well. There is no way around this.

>>> And the "sharp and clear border" is just FUD - I think until you know
>>> a lot more about Clojure and Java you should refrain from making
>>> statements about them. You can transparently consume/extend Clojure
>>> from Java and consume/extend Java from Clojure.
>>
>> I know enough about Java to be able to judge what the interoperability 
>> problems between language extensions on top of Java are. Been there, 
>> done that, don't want to go there ever again.
> 
> How can you decide to never go there again?

Because I know what I'm talking about.

> That sounds a little bit religious and closed minded.

I studied the Java language and its implementation for seven years, more 
or less from day one, and know it inside out. I am fully aware of its 
strengths and weaknesses. I know which parts of the overall approach of 
that platform hurt. And they hurt a lot. I am also occasionally 
following the progress of the Java platform, and there seem to be no 
serious efforts to overcome its weaknesses.

> Another option would be to stay open minded and see the outcomes of
> the evolutionary processes that are in progress.

The disadvantages of the Java platform outweigh its advantages by far. 
Your open mindedness seems to make you blind for that. Maybe you should 
be more open minded towards a more balanced view of things.

> In my opinion the advantages of the JVM (or .NET) far outweight those
> of existing CLs.

No, they don't. You just fell into the trap to believe that Java's 
acceptance in industry somehow buys you something. Which it does, but 
only to a certain extent.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnq3ei$1jf$1@news.motzarella.org>
Pascal Costanza schrieb:
> Andr� Thieme wrote:

>> How can you decide to never go there again?
> 
> Because I know what I'm talking about.

For the state today I can understand it.
It�s possible though (even if unlikely) that in the future things
change to change your mind. Or that someone brings in new arguments
which you haven�t heard of yet and which make sense.


>> That sounds a little bit religious and closed minded.
> 
> I studied the Java language and its implementation for seven years, more 
> or less from day one, and know it inside out. I am fully aware of its 
> strengths and weaknesses. I know which parts of the overall approach of 
> that platform hurt. And they hurt a lot. I am also occasionally 
> following the progress of the Java platform, and there seem to be no 
> serious efforts to overcome its weaknesses.

>> Another option would be to stay open minded and see the outcomes of
>> the evolutionary processes that are in progress.
> 
> The disadvantages of the Java platform outweigh its advantages by far. 
> Your open mindedness seems to make you blind for that. Maybe you should 
> be more open minded towards a more balanced view of things.
> 
>> In my opinion the advantages of the JVM (or .NET) far outweight those
>> of existing CLs.
> 
> No, they don't. You just fell into the trap to believe that Java's 
> acceptance in industry somehow buys you something. Which it does, but 
> only to a certain extent.

Could you please give a list of the disadvantages for chosing the JVM?
Here some advantages that come to my mind right now:
+ A huge number of libs are available. Libs are what boosts productivity
   more than anything else. Your language may have macros, CLOS and such,
   but your productivity can still be hundreds of times greater if you do
   basic and just use a reusable component. It�s nice when you can build
   a car (in Clojure you can too, independent of the VM it runs on), but
   let�s face that we all just buy an existant one.
   CLers told this story about the 5-20 times higher productivity since
   decades. It was true in the early 90ies. And even today it can be true
   for specific problems. But in general I don�t buy this anymore.

+ Much more independend from the hardware it runs on. In a few years
   people will want to run more and more apps on their mobile phones,
   which will soon (some years) be as powerful as PCs were 3 years ago.

+ Less often recompilation is needed, or OS specific versions.

+ Team members can much more likely use the OS of their choice.
   Currently our CL product runs on Windows only (Lispworks Pro).
   All devs use Windows. When we ported all our code to Clojure, then
   the devs are free to decide if they wish to develop under Linux,
   OSX or Windows. Even during the process of porting they can do it.
   We just won�t allow mobile phones for development right now ;)

+ Greater set of tools. In c.l.l we basically suggest everyone to use
   Emacs+Slime. I use this currently for Clojure development as well,
   but I try NetBeans+Enclojure more and more often.
   When Clojure gains more popularity I can imagine that plugins for
   IDEA and Eclipse will show up. There are several different kinds
   of tools to monitor the JVM.  A profiler developed for clisp does
   not necessarily work together with Allegro CL.

+ The JVM has a nice performance. Although Rich has not put anywhere
   near as many man-hours into Clojures performance, it already looks
   pretty good. Java code typically easily outperforms the best CLs
   of today. They are far from having done for improving the performance
   of the JVM. Current work is being done to get it even better.
   I did not see any problems with speed yet. Some few micro benchmarks
   that I�ve done outperformed most CLs, and several times SBCL. Even
   for code which was much shorter in Clojure as the CL equivalent. It
   seems to me that HotSpot can already work pretty well with what the
   Clojure compiler spits out. If more is done for type inference then
   most Clojure apps will say �Good bye� to CL, performance wise.
   Although this can be already the case today, if we take Clojures
   concurrency capabilities into play (but this is not a pro JVM
   argument).

+ Easier and higher level low-level optimizations. When the profiler
   tells us where the bottleneck is we can rewrite tiny parts of the
   application in Java code. Java is much more high level than C, and
   it is trivial to integrate code written in Java into Clojure apps.
   No strange FFIs are needed for that.

+ Way better chances to get a Lisp job.
   I had to change the city I live in two times to get a CL job. One
   time I even left Germany. Java companies however are present in
   basically every city. 80 times.
   Some smaller of those will accept a Clojure programmer. They will
   trade that other devs in that company can�t understand the sources
   for an increase in productivity. This btw does not contradict my
   statement in a different post, where I doubted the 5x-20x boost in
   productivity that Lisp brings. If it were Lisp vs Java only on the
   language expressivity level, then these numbers may be reality.
   Because Clojure has the same access to all libs that Java also has,
   those libs will not be an advantage for Java. Note: I don�t say that
   all Java companies will or should accept Clojure programmers. But
   I know for sure that some will do. That means that it is now realistic
   that thousands and thousands of Lispers can get a job where they
   can use their favourite programming language: Clojure.

+ Better documentation. The ones from Edi Weitz are great. Franz has
   really good material online for their libs. When I worked in my
   previous CL company (with Allegro Enterprise) I always enjoyed to
   read their well written docs.
   But that�s not the standard. For stuff that runs on the JVM I find
   vastly more and better documented software.

+ Greater coverage of clients. If you are a Linux guy and wrote this
   cool app with SBCL you can�t sell it as easily to a Microsoft
   customer. One can buy a commercial CL and port some parts... but
   this adds to your costs. And if that customer likes to run it on
   Android then...


These are 10 of the advantages that the JVM has and which came to my
mind right now.
I am curious to see the list of disadvantages, which, according to
you �outweigh its advantages by far� (scrolling up in this posting
brings up exactly what you wrote).
Can you list some? I am seriously interested in knowing it.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70cvssF8d3uU1@mid.individual.net>
Andr� Thieme wrote:
> Pascal Costanza schrieb:
>> Andr� Thieme wrote:
> 
>>> How can you decide to never go there again?
>>
>> Because I know what I'm talking about.
> 
> For the state today I can understand it.
> It�s possible though (even if unlikely) that in the future things
> change to change your mind.

Sure. That's true for any language or platform.

> Or that someone brings in new arguments
> which you haven�t heard of yet and which make sense.

I'm not hearing anything new.

> Could you please give a list of the disadvantages for chosing the JVM?
> Here some advantages that come to my mind right now:
> + A huge number of libs are available.

You don't need a "huge number" of libs. You need good libs.

>   Libs are what boosts productivity more than anything else.

Not for the kinds of things I am interested in. I am several orders of 
magnitude more productive with Lisp than with Java for the kinds of 
things I am interested in. It all depends on context.

>   Your language may have macros, CLOS and such,
>   but your productivity can still be hundreds of times greater if you do
>   basic and just use a reusable component. It�s nice when you can build
>   a car (in Clojure you can too, independent of the VM it runs on), but
>   let�s face that we all just buy an existant one.
>   CLers told this story about the 5-20 times higher productivity since
>   decades. It was true in the early 90ies. And even today it can be true
>   for specific problems. But in general I don�t buy this anymore.

That's one point of view.

> + Much more independend from the hardware it runs on. In a few years
>   people will want to run more and more apps on their mobile phones,
>   which will soon (some years) be as powerful as PCs were 3 years ago.

This can also be a disadvantage, for example if you want to make most 
out of the hardware resources at hand.

> + Less often recompilation is needed, or OS specific versions.

That's a myth, only true for vertical applications. But in reality, you 
need to recompile for each platform because of fine-grained adaptations, 
which are always necessary.

> + Team members can much more likely use the OS of their choice.
>   Currently our CL product runs on Windows only (Lispworks Pro).
>   All devs use Windows. When we ported all our code to Clojure, then
>   the devs are free to decide if they wish to develop under Linux,
>   OSX or Windows. Even during the process of porting they can do it.
>   We just won�t allow mobile phones for development right now ;)

Huh?!? That's true for CL as well, of course!

> + Greater set of tools. In c.l.l we basically suggest everyone to use
>   Emacs+Slime. I use this currently for Clojure development as well,
>   but I try NetBeans+Enclojure more and more often.
>   When Clojure gains more popularity I can imagine that plugins for
>   IDEA and Eclipse will show up. There are several different kinds
>   of tools to monitor the JVM.  A profiler developed for clisp does
>   not necessarily work together with Allegro CL.

Neither does a profiler for Sun's JVM work with the Kaffe Virtual 
Machine, for example.

> + The JVM has a nice performance. Although Rich has not put anywhere
>   near as many man-hours into Clojures performance, it already looks
>   pretty good. Java code typically easily outperforms the best CLs
>   of today. They are far from having done for improving the performance
>   of the JVM. Current work is being done to get it even better.
>   I did not see any problems with speed yet. Some few micro benchmarks
>   that I�ve done outperformed most CLs, and several times SBCL. Even
>   for code which was much shorter in Clojure as the CL equivalent. It
>   seems to me that HotSpot can already work pretty well with what the
>   Clojure compiler spits out. If more is done for type inference then
>   most Clojure apps will say �Good bye� to CL, performance wise.
>   Although this can be already the case today, if we take Clojures
>   concurrency capabilities into play (but this is not a pro JVM
>   argument).

The HotSpot JVM is an amazing piece of technology. It beats the crap out 
of other kinds of optimization models. And it is indeed the case that 
more improvements are still possible.

However, this only improves micro efficiency. If you take the whole 
picture into account, it is the case that Java programs are typically 
bloated and slow. The reason is that some of the underlying design 
choices are quite bad, and that many of the standard libraries are quite 
bad.

For example, reflection and metaprogramming capabilities are very 
restricted in Java. However, it is very common that, as soon as you grow 
your programs, you want to have some domain-specific means to express 
your solutions. Because of the limitations with regard to 
metaprogramming, Java solutions tend to end up in using a combination of 
design patterns and/or XML processing to achieve the same results. But 
note that XML processing is essentially building an interpreter, which 
at this level is inherently slower than using, for example, a DSL based 
on macros.

The JVM (not only Java) is restricted to single dispatch and single 
inheritance. This leads to ugly workarounds like using visitor patterns 
and observer patterns all over the place, which again has an impact on 
code size and overall performance.

Constructors are not overridable in Java. This leads to ugly workarounds 
like using factories, or factories of factories, or "dependency 
injection", or configuration via XML files (again), which all are messy 
ways of introducing some form of configuration management into the picture.

Primitive datatypes are not first-class citizens. The way out in recent 
Java versions was to introduce automatic boxing and unboxing, which 
leads to a situation where primitive datatypes may be repeatedly boxed 
and unboxed over and over again, another factor that impacts performance.

The first Java core API (and actually also the first public version of 
the Java language) was implemented in a rush, and some of the bad design 
decisions in the beginning are still hurting, because of "backwards 
compatibility" (which is sometimes used as a reason to block progress in 
some regards -- see genric types and type erasure --, but sometimes 
deliberately broken in other regards -- see the annotation system --).

These are some of the reasons why environments like Eclipse or NetBeans 
use up much more resources and are much slower than environments like 
LispWorks or (for better comparability) VisualWorks or Squeak.

You may object that Clojure provides a clean slate and allows you to do 
better in some regards. However, by basing Clojure on top of the JVM, 
you essentially buy into the whole eco system. (Remember? You want to 
use all those huge amounts of existing libraries, right?)

> + Easier and higher level low-level optimizations. When the profiler
>   tells us where the bottleneck is we can rewrite tiny parts of the
>   application in Java code. Java is much more high level than C, and
>   it is trivial to integrate code written in Java into Clojure apps.
>   No strange FFIs are needed for that.

They are typically also not needed for Common Lisp (or other Lisp dialects).

> + Way better chances to get a Lisp job.
>   I had to change the city I live in two times to get a CL job. One
>   time I even left Germany. Java companies however are present in
>   basically every city. 80 times.
>   Some smaller of those will accept a Clojure programmer. They will
>   trade that other devs in that company can�t understand the sources
>   for an increase in productivity. This btw does not contradict my
>   statement in a different post, where I doubted the 5x-20x boost in
>   productivity that Lisp brings. If it were Lisp vs Java only on the
>   language expressivity level, then these numbers may be reality.
>   Because Clojure has the same access to all libs that Java also has,
>   those libs will not be an advantage for Java. Note: I don�t say that
>   all Java companies will or should accept Clojure programmers. But
>   I know for sure that some will do. That means that it is now realistic
>   that thousands and thousands of Lispers can get a job where they
>   can use their favourite programming language: Clojure.

Unfortunately, that's not true. Many (most?) companies that require Java 
do not require it because it's such a "damn good" language, which it 
isn't, but only because it is an industry-accepted standard. Clojure is 
not an industry-accepted standard, so you will get the same 
acceptability problems as with any other "non-standard" language.

> + Better documentation. The ones from Edi Weitz are great. Franz has
>   really good material online for their libs. When I worked in my
>   previous CL company (with Allegro Enterprise) I always enjoyed to
>   read their well written docs.
>   But that�s not the standard. For stuff that runs on the JVM I find
>   vastly more and better documented software.

...which is much harder to use because of the poor abstraction 
capabilities of the Java language.

> + Greater coverage of clients. If you are a Linux guy and wrote this
>   cool app with SBCL you can�t sell it as easily to a Microsoft
>   customer. One can buy a commercial CL and port some parts... but
>   this adds to your costs. And if that customer likes to run it on
>   Android then...

It's also not that easy with Java, except for vertical applications.

> These are 10 of the advantages that the JVM has and which came to my
> mind right now.
> I am curious to see the list of disadvantages, which, according to
> you �outweigh its advantages by far� (scrolling up in this posting
> brings up exactly what you wrote).
> Can you list some? I am seriously interested in knowing it.

I have listed some above. I could go on, but I find this boring.

Java has (had) some very good points in favor: It made a different 
optimization model (JIT and HotSpot) acceptable in practice; it made 
garbage collection acceptable in practice (possibly the most important 
step forward); and it made certain forms of reflection and 
metaprogramming acceptable in practice (but to a lesser extent).

Java is currently still relevant in industry, yes. But it's legacy 
technology, which is starting to fall apart. It's too complex and too 
bloated, and needs to be replaced with something better.

http://java.sys-con.com/node/331264


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: wlr
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <06d84f02-3368-4066-b844-acaf531efeea@h16g2000yqj.googlegroups.com>
On Feb 22, 7:48 am, Pascal Costanza <····@p-cos.net> wrote:
> For example, reflection and metaprogramming capabilities are very
> restricted in Java. However, it is very common that, as soon as you grow
> your programs, you want to have some domain-specific means to express
> your solutions. Because of the limitations with regard to
> metaprogramming, Java solutions tend to end up in using a combination of
> design patterns and/or XML processing to achieve the same results. But
> note that XML processing is essentially building an interpreter, which
> at this level is inherently slower than using, for example, a DSL based
> on macros.

This bit could be changing.

For example, (the soon-to-be-dead-tree-available) Programming Clojure
[1] has a running example of creating Lancet, a pure Clojure
dependency-based build system (DSL), which also permits access to Ant
tasks.

Just one quote from Programming Clojure:
"Lancet also provides direct access to Ant’s most important feature:
its
large, tested library of targets. Lancet can call ant tasks such as
tstamp,
mkdir, and javac directly as Clojure functions."

No XML.

[1] http://www.pragprog.com/titles/shcloj/programming-clojure
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnrrjh$5qc$1@news.motzarella.org>
Pascal Costanza schrieb:
> Andr� Thieme wrote:

> You don't need a "huge number" of libs. You need good libs.

In the CL world I find a tiny number of good libs.
In that regard CL has (for things I do) no chance against that what
Java/Clojure offers.


>>   Libs are what boosts productivity more than anything else.
> 
> Not for the kinds of things I am interested in. I am several orders of 
> magnitude more productive with Lisp than with Java for the kinds of 
> things I am interested in. It all depends on context.

Yes, I agree.
If you talk about the core language CL vs Java, then it is easy for me
to believe that your productivity with CL is better.
Again, depending on what you do this experience could be worse with
Clojure (if you are doing mostly OOP), or better (if you want to do
functional programming).


>> + Much more independend from the hardware it runs on. In a few years
>>   people will want to run more and more apps on their mobile phones,
>>   which will soon (some years) be as powerful as PCs were 3 years ago.
> 
> This can also be a disadvantage, for example if you want to make most 
> out of the hardware resources at hand.

Yes, so this is one disadvantage of chosing the JVM as the target
plattform for Clojure.
But would a CL VM have been better for that? I don�t think so.
So, if the comparison is: Clojure for a CL VM vs the JVM, then I can not
count this as a disadvantage.


>> + Less often recompilation is needed, or OS specific versions.
> 
> That's a myth, only true for vertical applications. But in reality, you 
> need to recompile for each platform because of fine-grained adaptations, 
> which are always necessary.

As we can see I said �Less often� recompilation is needed.
When an application reaches a certain level of complexity recompilation
and fine-grained adoptions may be needed.
I still see this point as an advantage. Enough non-complex programs need
no recompilation. For CL however it is likely that even the most trivial
programs require it.


>> + Team members can much more likely use the OS of their choice.
>>   Currently our CL product runs on Windows only (Lispworks Pro).
>>   All devs use Windows. When we ported all our code to Clojure, then
>>   the devs are free to decide if they wish to develop under Linux,
>>   OSX or Windows. Even during the process of porting they can do it.
>>   We just won�t allow mobile phones for development right now ;)
> 
> Huh?!? That's true for CL as well, of course!

No, we are not so free in choice. If our CL were SBCL for example, then
it would not make sense to try it under Windows. Not for serious 
development.
Lispworks or Allegro would be possible, if we were ready to buy these
specific licenses. Again another cost factor which is not good for
startups.
And if you say �true for CL� in such a general way, then one could think
that some team members could use Corman CL, others use clisp on OSX
while the next works with CMUCL under Ubuntu.


>> + Greater set of tools. In c.l.l we basically suggest everyone to use
>>   Emacs+Slime. I use this currently for Clojure development as well,
>>   but I try NetBeans+Enclojure more and more often.
>>   When Clojure gains more popularity I can imagine that plugins for
>>   IDEA and Eclipse will show up. There are several different kinds
>>   of tools to monitor the JVM.  A profiler developed for clisp does
>>   not necessarily work together with Allegro CL.
> 
> Neither does a profiler for Sun's JVM work with the Kaffe Virtual 
> Machine, for example.

Yes, and nobody uses Kaffe.
No, I don�t mean this literally, but basically all installations are
either the official Sun JRE/JDK or OpenJDK.
The CL world is way more splitted up. Each CL needs their own profiler,
and they are not compatible with each other.


> For example, reflection and metaprogramming capabilities are very 
> restricted in Java. However, it is very common that, as soon as you grow 
> your programs, you want to have some domain-specific means to express 
> your solutions. Because of the limitations with regard to 
> metaprogramming, Java solutions tend to end up in using a combination of 
> design patterns and/or XML processing to achieve the same results. But 
> note that XML processing is essentially building an interpreter, which 
> at this level is inherently slower than using, for example, a DSL based 
> on macros.

This may all be true for Java. But that still does not make the JVM a
worse target for Clojure.


> The JVM (not only Java) is restricted to single dispatch and single 
> inheritance. This leads to ugly workarounds like using visitor patterns 
> and observer patterns all over the place, which again has an impact on 
> code size and overall performance.

Also not interesting for a functional programming language, which leads
OOP behind, that now had 20 years to prove that it is the superior model
to write applications in. It�s nice for writing GUI frameworks.
We will now see if functional programming can do better. I think so, but
I am also curious to see what really will happen.


> You may object that Clojure provides a clean slate and allows you to do 
> better in some regards. However, by basing Clojure on top of the JVM, 
> you essentially buy into the whole eco system. (Remember? You want to 
> use all those huge amounts of existing libraries, right?)

Okay, so this is the first real disadvantage: it�s possible that the lib
I want to use is doing stupid things under the hood and that will also
slow down my application.
Though I still think it is better to have a not so performant lib than
having no lib at all :)


>> + Easier and higher level low-level optimizations. When the profiler
>>   tells us where the bottleneck is we can rewrite tiny parts of the
>>   application in Java code. Java is much more high level than C, and
>>   it is trivial to integrate code written in Java into Clojure apps.
>>   No strange FFIs are needed for that.
> 
> They are typically also not needed for Common Lisp (or other Lisp 
> dialects).

Still no argument against the VM.
Lisps run often fast enough. This is true for CLs and also for Clojure.


>> + Way better chances to get a Lisp job.
>>   I had to change the city I live in two times to get a CL job. One
>>   time I even left Germany. Java companies however are present in
>>   basically every city. 80 times.
>>   Some smaller of those will accept a Clojure programmer. They will
>>   trade that other devs in that company can�t understand the sources
>>   for an increase in productivity. This btw does not contradict my
>>   statement in a different post, where I doubted the 5x-20x boost in
>>   productivity that Lisp brings. If it were Lisp vs Java only on the
>>   language expressivity level, then these numbers may be reality.
>>   Because Clojure has the same access to all libs that Java also has,
>>   those libs will not be an advantage for Java. Note: I don�t say that
>>   all Java companies will or should accept Clojure programmers. But
>>   I know for sure that some will do. That means that it is now realistic
>>   that thousands and thousands of Lispers can get a job where they
>>   can use their favourite programming language: Clojure.
> 
> Unfortunately, that's not true. Many (most?) companies that require Java 
> do not require it because it's such a "damn good" language, which it 
> isn't, but only because it is an industry-accepted standard. Clojure is 
> not an industry-accepted standard, so you will get the same 
> acceptability problems as with any other "non-standard" language.

No, I must disagree. I know for sure such cases.
I restricted what I said to smaller companies. Some start ups, or
companies that only have 1-4 programmers will listen to you.
Of course, you can not walk in to Oracle, promise them 2x higher
productivity and next day get your Clojure job.
But when it is about smaller teams you can talk with them, you can
negotiate something. Some will listen. A tiny fraction out of a huge
number still has some value.
But telling them that you want to program in CL instead closes the
doors immediately.
Only because you did not experience such a situation (which is not
strange because you did not even work with Clojure, let alone trying
to get a Clojure job), you can not say that my statement is not true.


>> + Better documentation. The ones from Edi Weitz are great. Franz has
>>   really good material online for their libs. When I worked in my
>>   previous CL company (with Allegro Enterprise) I always enjoyed to
>>   read their well written docs.
>>   But that�s not the standard. For stuff that runs on the JVM I find
>>   vastly more and better documented software.
> 
> ...which is much harder to use because of the poor abstraction 
> capabilities of the Java language.

Uh, I probably did not work with the software that you tried.
Can you please list 3-5 libs that you used, and that suffered from the
abstraction capabilities of the Java language, and which are way easier
to use in CL?
And btw, I was talking about the documentation.
I just tried some random libs from cliki. I just clicked on some of the
links and checked what I can find.
Under http://www.cliki.net/RIPEMD-160 I clicked on 
http://kopkillah.com/software/
Okay, 403 error.
Tried http://www.cliki.net/CXML and did not find it obvious where the
documentation is.
I tried UncommenXML at http://alpha.onshored.com/lisp-software/
No webserver running there.
XMLisp at http://www.agentsheets.com/lisp/XMLisp/ lists some code. That
is the documentation. At least Alexander seems to be actively working
on this, last update from December 2008. I don�t know how many users
this lib has. Maybe 12.
http://code.google.com/p/cl-smugmug/ had its last updates some time in
2007. Let�s be nice and call this software stable. No downloads offered.
No wiki, no updates, nothing.



>> + Greater coverage of clients. If you are a Linux guy and wrote this
>>   cool app with SBCL you can�t sell it as easily to a Microsoft
>>   customer. One can buy a commercial CL and port some parts... but
>>   this adds to your costs. And if that customer likes to run it on
>>   Android then...
> 
> It's also not that easy with Java, except for vertical applications.

I did not say complete coverage. It�s greater.
Another advantage.



>> These are 10 of the advantages that the JVM has and which came to my
>> mind right now.
>> I am curious to see the list of disadvantages, which, according to
>> you �outweigh its advantages by far� (scrolling up in this posting
>> brings up exactly what you wrote).
>> Can you list some? I am seriously interested in knowing it.
> 
> I have listed some above. I could go on, but I find this boring.

You listed mostly what you don�t like about Java.
I did not find the list I hoped for. I really thought I could learn
about some disadvantages here, and I would like to know them.
You brought up one valid point: some libs can slow down my application,
because the authors made it slow.
Against that I put that today the JVM outperforms easily all CLs for
most applications. And great improvements are currently being worked
on.
In the CL world maybe 20 people world wide are trying to improve CLs
performance. Perhaps 2 at Lispworks, maybe 3 guys at Franz. Sam works
on clisp I guess, Corman Lisp is dead. Don�t know how many devs OpenMCL
has (I think now called Clozure CL). SBCL probably has the biggest
number of devs, but all doing it as a hobby.
Sun puts some more money in. CL has not the slightest chance in that
regard, not with that amount of manpower and money.
All the decades did not help. Java catched up within just a few years
and now outperforms CL.


> Java has (had) some very good points in favor: It made a different 
> optimization model (JIT and HotSpot) acceptable in practice; it made 
> garbage collection acceptable in practice (possibly the most important 
> step forward); and it made certain forms of reflection and 
> metaprogramming acceptable in practice (but to a lesser extent).

Hmm I see. Well, that is probably interesting for people interested in
language theory and history.


> Java is currently still relevant in industry, yes. But it's legacy 
> technology, which is starting to fall apart. It's too complex and too 
> bloated, and needs to be replaced with something better.
> 
> http://java.sys-con.com/node/331264

Yes, evolution is happening. If the JVM is not fit enough in todays
environment others will eat its ressources. But still possible that
the JVM got enough momentum to survive another 10-40 years.
We will see.
What I found interesting in that article was:
"So Java has been around for 10 years and applets are not the primary 
way that we interact with the web. I think the main reason for this is 
the installation problem, another area of Java that wasn�t well 
thought-out. In fact, why do we like AJAX?

It�s clearly not because JavaScript is so easy to work with � JavaScript 
cross-platform problems are the reason people have avoided it in the 
past. AJAX is popular because we know that the necessary software for 
the client side is already installed. "
                    ^^^^^^^^^^^^^^^^^
Sounds very true for me.
It is easier when a system already includes batteries.
All these arguments that CL in principle could implement all Clojure
goodies falls into that category. It would not help. People don�t want
to have complex installations. Clojure ships with all the nice stuff
already today. Greatly tested, accepted, documented. It was the next
logical step for Lisp.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70dbo3Fne6kU1@mid.individual.net>
Andr� Thieme wrote:
> Pascal Costanza schrieb:
>> Andr� Thieme wrote:

>>> Libs are what boosts productivity more than anything else.
>>
>> Not for the kinds of things I am interested in. I am several orders of 
>> magnitude more productive with Lisp than with Java for the kinds of 
>> things I am interested in. It all depends on context.
> 
> Yes, I agree.
> If you talk about the core language CL vs Java, then it is easy for me
> to believe that your productivity with CL is better.
> Again, depending on what you do this experience could be worse with
> Clojure (if you are doing mostly OOP), or better (if you want to do
> functional programming).
> 
>>> + Much more independend from the hardware it runs on. In a few years
>>>   people will want to run more and more apps on their mobile phones,
>>>   which will soon (some years) be as powerful as PCs were 3 years ago.
>>
>> This can also be a disadvantage, for example if you want to make most 
>> out of the hardware resources at hand.
> 
> Yes, so this is one disadvantage of chosing the JVM as the target
> plattform for Clojure.
> But would a CL VM have been better for that? 

Yes.

>>> + Less often recompilation is needed, or OS specific versions.
>>
>> That's a myth, only true for vertical applications. But in reality, 
>> you need to recompile for each platform because of fine-grained 
>> adaptations, which are always necessary.
> 
> As we can see I said �Less often� recompilation is needed.
> When an application reaches a certain level of complexity recompilation
> and fine-grained adoptions may be needed.
> I still see this point as an advantage. Enough non-complex programs need
> no recompilation. For CL however it is likely that even the most trivial
> programs require it.

In CL, explicitly triggering the compiler is sometimes not even 
necessary. If I invoke an (asdf:oos 'asdf:load-op :some-program), I 
don't care whether it needs to be compiled or not. In Java-land, it's 
absolutely necessary to compile libs. Which is another one of those 
silly design choices, because the bytecode isn't that much different 
from the source code.

>>> + Team members can much more likely use the OS of their choice.
>>>   Currently our CL product runs on Windows only (Lispworks Pro).
>>>   All devs use Windows. When we ported all our code to Clojure, then
>>>   the devs are free to decide if they wish to develop under Linux,
>>>   OSX or Windows. Even during the process of porting they can do it.
>>>   We just won�t allow mobile phones for development right now ;)
>>
>> Huh?!? That's true for CL as well, of course!
> 
> No, we are not so free in choice. If our CL were SBCL for example, then
> it would not make sense to try it under Windows. Not for serious 
> development.

Well, don't use SBCL then?!?

> Lispworks or Allegro would be possible, if we were ready to buy these
> specific licenses. Again another cost factor which is not good for
> startups.

If a startup cannot afford a commercial license, then they have much 
more serious trouble than this. Seriously. This is an empty argument.

> And if you say �true for CL� in such a general way, then one could think
> that some team members could use Corman CL, others use clisp on OSX
> while the next works with CMUCL under Ubuntu.

There is also Clozure Common Lisp for Windows, for example.

We have more choice, not less!

>>> + Greater set of tools. In c.l.l we basically suggest everyone to use
>>>   Emacs+Slime. I use this currently for Clojure development as well,
>>>   but I try NetBeans+Enclojure more and more often.
>>>   When Clojure gains more popularity I can imagine that plugins for
>>>   IDEA and Eclipse will show up. There are several different kinds
>>>   of tools to monitor the JVM.  A profiler developed for clisp does
>>>   not necessarily work together with Allegro CL.
>>
>> Neither does a profiler for Sun's JVM work with the Kaffe Virtual 
>> Machine, for example.
> 
> Yes, and nobody uses Kaffe.
> No, I don�t mean this literally, but basically all installations are
> either the official Sun JRE/JDK or OpenJDK.
> The CL world is way more splitted up. Each CL needs their own profiler,
> and they are not compatible with each other.

Depending on your application domain, you have the same problem with 
Java. A typical problem in the Java world, for example, is that you have 
to address different incompatible versions of Java itself (1.3 vs. 1.4 
vs. 5.0 vs. 6.0). This can be a real pain.

You're seeing Java far too positively than it is!

>> For example, reflection and metaprogramming capabilities are very 
>> restricted in Java. However, it is very common that, as soon as you 
>> grow your programs, you want to have some domain-specific means to 
>> express your solutions. Because of the limitations with regard to 
>> metaprogramming, Java solutions tend to end up in using a combination 
>> of design patterns and/or XML processing to achieve the same results. 
>> But note that XML processing is essentially building an interpreter, 
>> which at this level is inherently slower than using, for example, a 
>> DSL based on macros.
> 
> This may all be true for Java. But that still does not make the JVM a
> worse target for Clojure.

...but it has to live in the same eco system.

>> The JVM (not only Java) is restricted to single dispatch and single 
>> inheritance. This leads to ugly workarounds like using visitor 
>> patterns and observer patterns all over the place, which again has an 
>> impact on code size and overall performance.
> 
> Also not interesting for a functional programming language, which leads
> OOP behind, that now had 20 years to prove that it is the superior model
> to write applications in. It�s nice for writing GUI frameworks.
> We will now see if functional programming can do better. I think so, but
> I am also curious to see what really will happen.

The limitations of the JVM class file model have an impact on the 
languages built on top of the JVM. Sure, Clojure hides that for you, but 
it does have an impact.

>> You may object that Clojure provides a clean slate and allows you to 
>> do better in some regards. However, by basing Clojure on top of the 
>> JVM, you essentially buy into the whole eco system. (Remember? You 
>> want to use all those huge amounts of existing libraries, right?)
> 
> Okay, so this is the first real disadvantage: it�s possible that the lib
> I want to use is doing stupid things under the hood and that will also
> slow down my application.
> Though I still think it is better to have a not so performant lib than
> having no lib at all :)

Again, you're making the assumption that the situation with regard to 
libraries in Common Lisp is much worse than it actually is.

People who program in Common Lisp (and Scheme) can get their job done. 
Seriously.

>>> + Easier and higher level low-level optimizations. When the profiler
>>>   tells us where the bottleneck is we can rewrite tiny parts of the
>>>   application in Java code. Java is much more high level than C, and
>>>   it is trivial to integrate code written in Java into Clojure apps.
>>>   No strange FFIs are needed for that.
>>
>> They are typically also not needed for Common Lisp (or other Lisp 
>> dialects).
> 
> Still no argument against the VM.
> Lisps run often fast enough. This is true for CLs and also for Clojure.

...but the need to have to switch down to the level of Java can 
potentially be disruptive.

>>> + Way better chances to get a Lisp job.
>>>   I had to change the city I live in two times to get a CL job. One
>>>   time I even left Germany. Java companies however are present in
>>>   basically every city. 80 times.
>>>   Some smaller of those will accept a Clojure programmer. They will
>>>   trade that other devs in that company can�t understand the sources
>>>   for an increase in productivity. This btw does not contradict my
>>>   statement in a different post, where I doubted the 5x-20x boost in
>>>   productivity that Lisp brings. If it were Lisp vs Java only on the
>>>   language expressivity level, then these numbers may be reality.
>>>   Because Clojure has the same access to all libs that Java also has,
>>>   those libs will not be an advantage for Java. Note: I don�t say that
>>>   all Java companies will or should accept Clojure programmers. But
>>>   I know for sure that some will do. That means that it is now realistic
>>>   that thousands and thousands of Lispers can get a job where they
>>>   can use their favourite programming language: Clojure.
>>
>> Unfortunately, that's not true. Many (most?) companies that require 
>> Java do not require it because it's such a "damn good" language, which 
>> it isn't, but only because it is an industry-accepted standard. 
>> Clojure is not an industry-accepted standard, so you will get the same 
>> acceptability problems as with any other "non-standard" language.
> 
> No, I must disagree. I know for sure such cases.
> I restricted what I said to smaller companies. Some start ups, or
> companies that only have 1-4 programmers will listen to you.
> Of course, you can not walk in to Oracle, promise them 2x higher
> productivity and next day get your Clojure job.
> But when it is about smaller teams you can talk with them, you can
> negotiate something. Some will listen. A tiny fraction out of a huge
> number still has some value.
> But telling them that you want to program in CL instead closes the
> doors immediately.
> Only because you did not experience such a situation (which is not
> strange because you did not even work with Clojure, let alone trying
> to get a Clojure job), you can not say that my statement is not true.

You're describing a very special kind of situation. I doubt that this 
generalizes well.

If you can negotiate with reasonable people, then it should only depend 
on the concrete problem at hand to choose the best tool for the job. If 
the people are not reasonable, then not.

>>> + Better documentation. The ones from Edi Weitz are great. Franz has
>>>   really good material online for their libs. When I worked in my
>>>   previous CL company (with Allegro Enterprise) I always enjoyed to
>>>   read their well written docs.
>>>   But that�s not the standard. For stuff that runs on the JVM I find
>>>   vastly more and better documented software.
>>
>> ...which is much harder to use because of the poor abstraction 
>> capabilities of the Java language.
> 
> Uh, I probably did not work with the software that you tried.
> Can you please list 3-5 libs that you used, and that suffered from the
> abstraction capabilities of the Java language, and which are way easier
> to use in CL?

Almost anything.

> And btw, I was talking about the documentation.

Sure. What is harder to use needs more documentation.

>>> + Greater coverage of clients. If you are a Linux guy and wrote this
>>>   cool app with SBCL you can�t sell it as easily to a Microsoft
>>>   customer. One can buy a commercial CL and port some parts... but
>>>   this adds to your costs. And if that customer likes to run it on
>>>   Android then...
>>
>> It's also not that easy with Java, except for vertical applications.
> 
> I did not say complete coverage. It�s greater.

I doubt that it's that much "greater".

>>> These are 10 of the advantages that the JVM has and which came to my
>>> mind right now.
>>> I am curious to see the list of disadvantages, which, according to
>>> you �outweigh its advantages by far� (scrolling up in this posting
>>> brings up exactly what you wrote).
>>> Can you list some? I am seriously interested in knowing it.
>>
>> I have listed some above. I could go on, but I find this boring.
> 
> You listed mostly what you don�t like about Java.
> I did not find the list I hoped for. I really thought I could learn
> about some disadvantages here, and I would like to know them.

Then maybe I'm the wrong person to talk to.

Have fun with Java. You seem to be willing to suffer. ;)




Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: ·····@franz.com
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <27af94e2-5b14-4b0c-905a-41494763af34@h5g2000yqh.googlegroups.com>
On Feb 22, 8:10 am, Pascal Costanza <····@p-cos.net> wrote:
> André Thieme wrote:

> Lispworks or Allegro would be possible, if we were ready to buy these
> > specific licenses. Again another cost factor which is not good for
> > startups.
>
> If a startup cannot afford a commercial license, then they have much
> more serious trouble than this. Seriously. This is an empty argument.

It is also an empty argument because it assumes that the commercial
vendors are not willing to work with a startup company to help to make
them successful.  That assumption is false.

Duane
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gns0iv$afv$1@news.motzarella.org>
·····@franz.com schrieb:
> On Feb 22, 8:10 am, Pascal Costanza <····@p-cos.net> wrote:
>> Andr� Thieme wrote:
> 
>> Lispworks or Allegro would be possible, if we were ready to buy these
>>> specific licenses. Again another cost factor which is not good for
>>> startups.
>> If a startup cannot afford a commercial license, then they have much
>> more serious trouble than this. Seriously. This is an empty argument.
> 
> It is also an empty argument because it assumes that the commercial
> vendors are not willing to work with a startup company to help to make
> them successful.  That assumption is false.

Duane, you made the false assumption about me making an assumption.
I know that Franz is supportive to negotiate with start ups.
Even I was in contact with Franz when I was thinking about getting a
license.
But still, not everyone can afford it.
And when a company gets more out of Clojure, then why pay thousands and
thousands for the basic software alone, and then even royalties?
If a company wants to offer competative prices they need to think very
well if they can afford ACL.
The company itself of course does not have to pay the royalties.
A company has no costs. No taxes, no salaries, no electricity, no rent,
no software, etc.
Everything, even the last cent, is forwarded to the customers. They
are the ones who need to pay for it.
And making a product 5% more expensive to forward that money to Franz
is not always an interesting option.
My previous CL company is happy with Allegro, and I was it too.
It�s very good software. And the support of Franz is also very
responsive, thanks.
I understand that Franz needs the pricing model that currently exists
and I respect that descision. But still, ACL will not always make a
final product cheaper. The opposit can easily be the case.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gns062$4ng$1@news.motzarella.org>
Pascal Costanza schrieb:
> Andr� Thieme wrote:

>> But would a CL VM have been better for that? 
> 
> Yes.

It is a bit alien to read that, after I listed 10 advantages of the JVM
over CL, out of which you could not successfuly explain why it is not
true. The list of arguments that speak against the JVM and favour a CL
included one valid point. And now after that your conclusion is yes.
If this isn�t religious then I don�t know what is...


> In CL, explicitly triggering the compiler is sometimes not even 
> necessary. If I invoke an (asdf:oos 'asdf:load-op :some-program), I 
> don't care whether it needs to be compiled or not.

When I load-file something in Clojure I also don�t care very much.


>>>> + Team members can much more likely use the OS of their choice.
>>>>   Currently our CL product runs on Windows only (Lispworks Pro).
>>>>   All devs use Windows. When we ported all our code to Clojure, then
>>>>   the devs are free to decide if they wish to develop under Linux,
>>>>   OSX or Windows. Even during the process of porting they can do it.
>>>>   We just won�t allow mobile phones for development right now ;)
>>>
>>> Huh?!? That's true for CL as well, of course!
>>
>> No, we are not so free in choice. If our CL were SBCL for example, then
>> it would not make sense to try it under Windows. Not for serious 
>> development.
> 
> Well, don't use SBCL then?!?

Yeah, free choice. Don�t use X or Y. Maybe Z.
But hey, my friend, you are free in choice ;)


>> Lispworks or Allegro would be possible, if we were ready to buy these
>> specific licenses. Again another cost factor which is not good for
>> startups.
> 
> If a startup cannot afford a commercial license, then they have much 
> more serious trouble than this. Seriously. This is an empty argument.

You are very fast of accusing others bringing empty arguments.
This is not typical for you. Usually you have arguments and don�t need
to rely on rhethoric tricks.
Also what you say is the religious nonsense and brain-washing stuff that
I can read here since years. Are you now also a financial expert who
understands perfectly what startups have money for and what not?
Why not let them decide if they have enough money?


> Depending on your application domain, you have the same problem with 
> Java. A typical problem in the Java world, for example, is that you have 
> to address different incompatible versions of Java itself (1.3 vs. 1.4 
> vs. 5.0 vs. 6.0). This can be a real pain.

Okay, that sounds like an argument against the JVM.
But how would it help here if Clojure were done in CL?
Will .fasls compiled with SBCL 0.9.x run fine on 0.9.x+4 ?
Unfortunately this is also not always true. So, another strawman
argument against the JVM.
The counter is still at 10:1 for the JVM.


> You're seeing Java far too positively than it is!

Aah, will now the arguments follow?
And btw, I don�t care much about Java. I care about Lisp.
If Clojure would live on .NET then fine, I would use it there.
The advantages/disadvantages are then a bit different.


> The limitations of the JVM class file model have an impact on the 
> languages built on top of the JVM. Sure, Clojure hides that for you, but 
> it does have an impact.

As nice as Rich is, I really don�t care how many problems he had to
write the Java part of Clojure.
I want a usable clojure.jar that let�s me be productive. Rich delivers
exactly that, in an excellent way.
Yeah, I feel a bit with him if he had a bit trouble to express some
problem in Java. Not nice. But still, it is/was his problem, and not
mine.


>> Okay, so this is the first real disadvantage: it�s possible that the lib
>> I want to use is doing stupid things under the hood and that will also
>> slow down my application.
>> Though I still think it is better to have a not so performant lib than
>> having no lib at all :)
> 
> Again, you're making the assumption that the situation with regard to 
> libraries in Common Lisp is much worse than it actually is.

No.


> People who program in Common Lisp (and Scheme) can get their job done. 
> Seriously.

Yes. Same is true for VisualBasic programmers, and for PHP guys.
So, nobody who can already program and gets his job done should look at CL.
This is the blub argument. Paul Graham explained that people who sit in
a blub can not look up the ladder of the continuum.


>>>> + Easier and higher level low-level optimizations. When the profiler
>>>>   tells us where the bottleneck is we can rewrite tiny parts of the
>>>>   application in Java code. Java is much more high level than C, and
>>>>   it is trivial to integrate code written in Java into Clojure apps.
>>>>   No strange FFIs are needed for that.
>>>
>>> They are typically also not needed for Common Lisp (or other Lisp 
>>> dialects).
>>
>> Still no argument against the VM.
>> Lisps run often fast enough. This is true for CLs and also for Clojure.
> 
> ...but the need to have to switch down to the level of Java can 
> potentially be disruptive.

Yes.
If Clojure would run on clisp and one would need to go back to C, can
this then at least potentially also disruptive?


>> No, I must disagree. I know for sure such cases.
>> I restricted what I said to smaller companies. Some start ups, or
>> companies that only have 1-4 programmers will listen to you.
>> Of course, you can not walk in to Oracle, promise them 2x higher
>> productivity and next day get your Clojure job.
>> But when it is about smaller teams you can talk with them, you can
>> negotiate something. Some will listen. A tiny fraction out of a huge
>> number still has some value.
>> But telling them that you want to program in CL instead closes the
>> doors immediately.
>> Only because you did not experience such a situation (which is not
>> strange because you did not even work with Clojure, let alone trying
>> to get a Clojure job), you can not say that my statement is not true.
> 
> You're describing a very special kind of situation. I doubt that this 
> generalizes well.

The article that you linked in your previous posting says:
�Sun is directly supporting the development of JRuby for hybrid
  Java/JRuby programming.�

It seems that Sun sees advantages of mixed environments.


>>>> + Better documentation. The ones from Edi Weitz are great. Franz has
>>>>   really good material online for their libs. When I worked in my
>>>>   previous CL company (with Allegro Enterprise) I always enjoyed to
>>>>   read their well written docs.
>>>>   But that�s not the standard. For stuff that runs on the JVM I find
>>>>   vastly more and better documented software.
>>>
>>> ...which is much harder to use because of the poor abstraction 
>>> capabilities of the Java language.
>>
>> Uh, I probably did not work with the software that you tried.
>> Can you please list 3-5 libs that you used, and that suffered from the
>> abstraction capabilities of the Java language, and which are way easier
>> to use in CL?
> 
> Almost anything.

No, you are wrong.


>> And btw, I was talking about the documentation.
> 
> Sure. What is harder to use needs more documentation.

This makes Allegro CL the hardest to use CL.


> Have fun with Java.

Oh, it�s a little misunderstanding maybe. I don�t want to do Java, but Lisp.


 > You seem to be willing to suffer. ;)

No *lol*
I already have mostly quit using CL ;)


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70djduF1172bU1@mid.individual.net>
Andr� Thieme wrote:
> Pascal Costanza schrieb:
>> Andr� Thieme wrote:
> 
>>> But would a CL VM have been better for that? 
>>
>> Yes.
> 
> It is a bit alien to read that, after I listed 10 advantages of the JVM
> over CL, out of which you could not successfuly explain why it is not
> true. 

It doesn't matter whether I can explain their truth or not. They are 
either true, or they are not. Personally, I think they are naive at best.

> The list of arguments that speak against the JVM and favour a CL
> included one valid point. And now after that your conclusion is yes.
> If this isn�t religious then I don�t know what is...

You will see, my friend.

>>> Lispworks or Allegro would be possible, if we were ready to buy these
>>> specific licenses. Again another cost factor which is not good for
>>> startups.
>>
>> If a startup cannot afford a commercial license, then they have much 
>> more serious trouble than this. Seriously. This is an empty argument.
> 
> You are very fast of accusing others bringing empty arguments.
> This is not typical for you. Usually you have arguments and don�t need
> to rely on rhethoric tricks.

I'm just bored by this particular part of the discussion. I had my share 
of Java experience. My time is too valuable to waste more on it.

> Also what you say is the religious nonsense and brain-washing stuff that
> I can read here since years. Are you now also a financial expert who
> understands perfectly what startups have money for and what not?
> Why not let them decide if they have enough money?

Startups at least need to buy a few computers. A commercial CL license 
is roughly in the same range. If you don't even have the money for 
computers, what kind of startup are you talking about? Cleaning toilets?

>> Depending on your application domain, you have the same problem with 
>> Java. A typical problem in the Java world, for example, is that you 
>> have to address different incompatible versions of Java itself (1.3 
>> vs. 1.4 vs. 5.0 vs. 6.0). This can be a real pain.
> 
> Okay, that sounds like an argument against the JVM.
> But how would it help here if Clojure were done in CL?
> Will .fasls compiled with SBCL 0.9.x run fine on 0.9.x+4 ?
> Unfortunately this is also not always true. So, another strawman
> argument against the JVM.

It's not about the fasls, it's about incompatibilities in the language 
and the APIs. Porting between Java editions can be a real pain. That's a 
problem you always have with unstable languages.

> The counter is still at 10:1 for the JVM.

And the world is flat, sure.

>> People who program in Common Lisp (and Scheme) can get their job done. 
>> Seriously.
> 
> Yes. Same is true for VisualBasic programmers, and for PHP guys.

Indeed.

> So, nobody who can already program and gets his job done should look at CL.

Everybody should use what suits them best. Seriously, this is not a 
rhetoric trick. I mean it.

> This is the blub argument. Paul Graham explained that people who sit in
> a blub can not look up the ladder of the continuum.

Paul Graham assumes that he sits up the ladder of the continuum. How 
does he know that?

>>>>> + Easier and higher level low-level optimizations. When the profiler
>>>>>   tells us where the bottleneck is we can rewrite tiny parts of the
>>>>>   application in Java code. Java is much more high level than C, and
>>>>>   it is trivial to integrate code written in Java into Clojure apps.
>>>>>   No strange FFIs are needed for that.
>>>>
>>>> They are typically also not needed for Common Lisp (or other Lisp 
>>>> dialects).
>>>
>>> Still no argument against the VM.
>>> Lisps run often fast enough. This is true for CLs and also for Clojure.
>>
>> ...but the need to have to switch down to the level of Java can 
>> potentially be disruptive.
> 
> Yes.
> If Clojure would run on clisp and one would need to go back to C, can
> this then at least potentially also disruptive?

Of course. But you have a lot of options in Common Lisp to optimize your 
code before you have to escape the language and go down to its 
implementation language.

I don't know to what extent this is necessary in Clojure. You brought it 
up that you implement libraries for Clojure in Java.

> The article that you linked in your previous posting says:
> �Sun is directly supporting the development of JRuby for hybrid
>  Java/JRuby programming.�
> 
> It seems that Sun sees advantages of mixed environments.

Sun sees that it loses some potential users if it doesn't jump on the 
dynamic languages bandwagon. To an important extent, this is because of 
the market pressure created by .NET. Sun cared a lot less for languages 
other than Java before. Heck, it didn't even care about evolving Java at 
the language level...

>>>>> + Better documentation. The ones from Edi Weitz are great. Franz has
>>>>>   really good material online for their libs. When I worked in my
>>>>>   previous CL company (with Allegro Enterprise) I always enjoyed to
>>>>>   read their well written docs.
>>>>>   But that�s not the standard. For stuff that runs on the JVM I find
>>>>>   vastly more and better documented software.
>>>>
>>>> ...which is much harder to use because of the poor abstraction 
>>>> capabilities of the Java language.
>>>
>>> Uh, I probably did not work with the software that you tried.
>>> Can you please list 3-5 libs that you used, and that suffered from the
>>> abstraction capabilities of the Java language, and which are way easier
>>> to use in CL?
>>
>> Almost anything.
> 
> No, you are wrong.

You cannot know that.

>> Have fun with Java.
> 
> Oh, it�s a little misunderstanding maybe. I don�t want to do Java, but 
> Lisp.

But you have to deal with Java eco system.

> 
> 
>  > You seem to be willing to suffer. ;)
> 
> No *lol*
> I already have mostly quit using CL ;)

Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."



Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal J. Bourguignon
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <87ab8ee92x.fsf@galatea.local>
André Thieme <······························@justmail.de> writes:
>>> + Less often recompilation is needed, or OS specific versions.
>> That's a myth, only true for vertical applications. But in reality,
>> you need to recompile for each platform because of fine-grained
>> adaptations, which are always necessary.
>
> As we can see I said „Less often” recompilation is needed.
> When an application reaches a certain level of complexity recompilation
> and fine-grained adoptions may be needed.
> I still see this point as an advantage. Enough non-complex programs need
> no recompilation. For CL however it is likely that even the most trivial
> programs require it.

For CL, my most trivial programs (ie. scripts) are run without ever
being compiled (thanks clisp).

In fact, choosing to compile a program is not driven by the complexity
of that program, but on the required processing speed, that is
ultimately, on the size of data it has to process.

-- 
__Pascal Bourguignon__
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <cf9f7853-4dea-4f4d-9d17-6d8fc6292e30@z10g2000prl.googlegroups.com>
On Feb 20, 8:05 am, Rich Hickey <··········@gmail.com> wrote:
> On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
> > André Thieme wrote:
> > > Scott Burson schrieb:
> > >> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> > >>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>
> > >>>> In 25 words or less, why is Clojure better than Common Lisp?
> > >>> Seqs partake of some of the awesomeness of SERIES, but are easier to
> > >>> use and more native to functional programming.
>
> > >> One more time, I can't resist... ;-}
>
> > >>http://common-lisp.net/project/fset/
>
> > > Yes, not bad.
> > > But I doubt someone could use this after having used Clojure.
> > > It misses the nice reader macros.
> > > It does not plug in into CL. For example one has to use image
> > > instead of mapcar.
>
> > That's an empty statement. Clojure also doesn't "plug in" into Java.
>
> It's not an empty statement, it's one whose point keeps getting missed/
> avoided.
>
>
> FSet is very nice, but it has to redefine many of the core Lisp
> algorithms:
>
> http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>
> Why? Because the core algorithms in the COMMON-LISP package do not
> extend to new user-defined types like the ones defined by FSet's
> author, and more important, neither do existing algorithms defined in
> terms of the CL core.

I don't see any point in debating this.  CL is what it is; it's
certainly not perfect.  I'm surprised no one in this conversation has
mentioned Dylan, whose design some of the top CL people (notably David
Moon) participated in and which was explicitly intended to be more
orthogonal and extensible.  I'm sure they would have liked to do some
of the same things in CL if they had had the time to figure out how.

On the other hand, shadowing a bunch of the CL operations and
providing compatibility methods was pretty straightforward -- more so
than I would have expected.  (There's a CL rule I had never noticed
before that turned out to be very handy: a method of a generic
function can take additional keyword parameters beyond those given in
the `defgeneric' form.)  What gave me fits was figuring out how much I
wanted to try to integrate with the existing CL generic sequence
system, which of course uses imperative semantics.  So it was the
imperative/functional divergence that was the most trouble... and I
would have had the same problem in Dylan.  It seems that no matter how
much trouble you go to to make your language extensible, there are
still going to be things people will want to do that don't integrate
cleanly.  (Which is not to say your effort is wasted; if you do a good
job, there will be fewer such things.)

Anyway I didn't mean to fan the flames of a CL-vs.-Clojure argument.
I'm certainly not trying to suggest that FSet provides all the
desirable features of Clojure.  I was just pointing out that it does
exist, in case someone wants to use functional collections in CL.

-- Scott
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <557f1e2b-daf0-4204-a813-34d829b73f29@x38g2000yqj.googlegroups.com>
On Feb 21, 12:45 am, Scott Burson <········@gmail.com> wrote:
> On Feb 20, 8:05 am, Rich Hickey <··········@gmail.com> wrote:
>
>
>
> > On Feb 20, 8:24 am, Pascal Costanza <····@p-cos.net> wrote:
> > > André Thieme wrote:
> > > > Scott Burson schrieb:
> > > >> On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> > > >>> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>
> > > >>>> In 25 words or less, why is Clojure better than Common Lisp?
> > > >>> Seqs partake of some of the awesomeness of SERIES, but are easier to
> > > >>> use and more native to functional programming.
>
> > > >> One more time, I can't resist... ;-}
>
> > > >>http://common-lisp.net/project/fset/
>
> > > > Yes, not bad.
> > > > But I doubt someone could use this after having used Clojure.
> > > > It misses the nice reader macros.
> > > > It does not plug in into CL. For example one has to use image
> > > > instead of mapcar.
>
> > > That's an empty statement. Clojure also doesn't "plug in" into Java.
>
> > It's not an empty statement, it's one whose point keeps getting missed/
> > avoided.
>
> > FSet is very nice, but it has to redefine many of the core Lisp
> > algorithms:
>
> >http://common-lisp.net/project/fset/Site/Tinaa-Doc-1.2/fset-package/i...
>
> > Why? Because the core algorithms in the COMMON-LISP package do not
> > extend to new user-defined types like the ones defined by FSet's
> > author, and more important, neither do existing algorithms defined in
> > terms of the CL core.
>
> I don't see any point in debating this.  CL is what it is; it's
> certainly not perfect.  I'm surprised no one in this conversation has
> mentioned Dylan, whose design some of the top CL people (notably David
> Moon) participated in and which was explicitly intended to be more
> orthogonal and extensible.  I'm sure they would have liked to do some
> of the same things in CL if they had had the time to figure out how.
>
> On the other hand, shadowing a bunch of the CL operations and
> providing compatibility methods was pretty straightforward -- more so
> than I would have expected.  (There's a CL rule I had never noticed
> before that turned out to be very handy: a method of a generic
> function can take additional keyword parameters beyond those given in
> the `defgeneric' form.)  What gave me fits was figuring out how much I
> wanted to try to integrate with the existing CL generic sequence
> system, which of course uses imperative semantics.  So it was the
> imperative/functional divergence that was the most trouble... and I
> would have had the same problem in Dylan.

That's a good point - the imperative vs functional is a clear divide
and you pretty much have to pick one. It's a key reason I didn't build
on Kawa, a nice Scheme implementation for the JVM.

> Anyway I didn't mean to fan the flames of a CL-vs.-Clojure argument.
> I'm certainly not trying to suggest that FSet provides all the
> desirable features of Clojure.  I was just pointing out that it does
> exist, in case someone wants to use functional collections in CL.
>

Agreed, and kudo's on FSet. I'm just trying to put out the FUD fires
and return to peaceful coexistence.

Rich
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <979ee6bf-747c-4f37-b5ca-746a2a19fcb8@q30g2000prq.googlegroups.com>
On Feb 21, 7:07 am, Rich Hickey <··········@gmail.com> wrote:
> Agreed, and kudos on FSet.

Thanks!  And kudos to you on Clojure.  It's a truly innovative design.

-- Scott
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70au3bF1shfU2@mid.individual.net>
Scott Burson wrote:
> On Feb 21, 7:07 am, Rich Hickey <··········@gmail.com> wrote:
>> Agreed, and kudos on FSet.
> 
> Thanks!  And kudos to you on Clojure.  It's a truly innovative design.

Just for the records, I fully agree.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70a8rbFnhhavU3@mid.individual.net>
Scott Burson wrote:

> It seems that no matter how
> much trouble you go to to make your language extensible, there are
> still going to be things people will want to do that don't integrate
> cleanly.

+1

> (Which is not to say your effort is wasted; if you do a good
> job, there will be fewer such things.)

+1


Extensibility needs to be carefully designed, and only works well for 
the cases that are anticipated in the design.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <136ff07a-b528-4a74-a9b9-00672aea3bdd@j10g2000prn.googlegroups.com>
On Feb 19, 5:39 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Scott Burson schrieb:
>
> > On Feb 18, 9:21 am, "Mark H." <············@gmail.com> wrote:
> >> On Feb 9, 11:30 pm, Kenneth Tilton <·········@gmail.com> wrote:
>
> >>> In 25 words or less, why is Clojure better than Common Lisp?
> >> Seqs partake of some of the awesomeness of SERIES, but are easier to
> >> use and more native to functional programming.
>
> > One more time, I can't resist... ;-}
>
> >http://common-lisp.net/project/fset/
>
> Yes, not bad.
> But I doubt someone could use this after having used Clojure.
> It misses the nice reader macros.

There are some, actually.  I don't use them myself, though.

> It does not plug in into CL. For example one has to use image
> instead of mapcar.
> What about REST, LENGTH working on fsets?

I went with `size' over `length' because `size' is the more generic
and mathematical term (does a set really have a "length"? how about a
bag?).  `image' is also a mathematical term, and BTW the image of a
set is another set, which normally won't be in one-to-one
correspondence by rank (position) with the original; it may be smaller
and will be in the order defined by its own elements.  As for `rest'
of a set, that doesn't really make sense anyway; if I provided this
operation I would call it `less-least'.

> There is a do-map, do-seq, do-set, ... instead of just one
> thing to do them all.

Yes.  I suppose there could be just one, though I don't know what it
would be called.  And it's not like `do-set' etc. form a difficult
pattern to remember.  But I wonder if you're thinking that you're
likely to want to write code that operates generically on more than
one kind of collection.  In my experience that is vanishingly rare.

> Examples such as
> (isetq m6 (with-default (map ('a (set 1)) ('b (set 2))) (set)))
> #{| (A #{ 1 }) (B #{ 2 }) |}/#{ }
> (isetq m7 (with-default (map ('b (set "x")) ('c (set "y"))) (set)))
> #{| (B #{ "x" }) (C #{ "y" }) |}/#{ }
> look unreadable and cryptic to me.

Those were intended as advanced examples.  Did you work through all
the examples up to that point?  If you're just skimming the tutorial
without trying the examples yourself, then I would expect these to be
confusing.

> Performance wise.. not sure. Rich Hickey spent a good bit of time
> to make the concurrency ready Clojure data structures pretty fast.

Yes, if I had known about HAMTs when I started FSet I would probably
have used them.  Balanced binary trees may not be quite as good but
they're not bad.  I've resisted the temptation to implement HAMTs and
benchmark them against my trees because I don't have the time to
reimplement FSet using HAMTs anyway.  If someone else wants to do
that, that would be great.  (Be sure to benchmark them first, though,
to be sure it's worth the trouble.)

> Most importantly: Fset lacks a STM and MVCC.

True.  It would be interesting to add them.  But I don't know that I
have much use for them myself, and I have other things to work on.

Although FSet and Clojure obviously have something in common, they
have rather different motivations.  I do a lot of compiler and static
analysis work, and I wanted to make CL a nicer language to write that
kind of code in (and in my own opinion, have succeeded wildly).  Yes,
I think functional collections are useful generally, and I hope they
catch on, and so I've gone to the trouble to document and release
FSet; and I would use it now for almost anything I would write in CL;
but its primary purpose remains to support that particular kind of
code.  Rich is aiming for a very different class of applications.

-- Scott
From: Jan Rychter
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <m2skm6iutb.fsf@tnuctip.rychter.com>
I have been reading this thread with amusement. Shouldn't we CL
programmers know better? 

This group has seen so many discussions about how Common Lisp doesn't
provide anything that can't be implemented in {Java, Python, Ruby, C++,
whatever}. People here responded saying that Turing-equivalence isn't
everything and that it does make a difference whether the language is
expressive or not.

So here comes Clojure. A clean redesign of a Lisp language, throwing
away old religious dogmas and providing a clean slate. Expressive, with
fresh ideas, all on top of a popular platform with thousands of
libraries we can make use of. And what do we do?

We shout about how it's really nothing new because look you can do the
same things with Common Lisp only you have to implement these macros and
shadow those symbols and load in that order and follow these
conventions, and avoid doing this, and always do that, see, it's all
right there...

Have we become Blub programmers? [1]

We should at least keep an open mind. There are and will be better
languages than Common Lisp. Instead of digging trenches and shutting our
eyes we should be on the lookout for new ideas. And when they come, we
don't have to all switch religions. Let's just treat the newcomers with
respect.

Seriously, we should know better.

--J.
[1] http://www.paulgraham.com/avg.html
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <a0557e8c-cc40-40b2-a182-2d2a0e988492@w34g2000yqm.googlegroups.com>
On Feb 22, 1:18 pm, Jan Rychter <····@rychter.com> wrote:
> So here comes Clojure. A clean redesign of a Lisp language, throwing
> away old religious dogmas and providing a clean slate. Expressive, with
> fresh ideas, all on top of a popular platform with thousands of
> libraries we can make use of. And what do we do?
> ...
> We should at least keep an open mind. There are and will be better
> languages than Common Lisp. Instead of digging trenches and shutting our
> eyes we should be on the lookout for new ideas. And when they come, we
> don't have to all switch religions. Let's just treat the newcomers with
> respect.

1. The Java platform.
There's ABCL. Did you ask yourself a question why it can't be used in
the Java world by those hoards of Java programmers, who "are in need
of a better language". Isn't it also a Lisp with Java-interop (like
CLojure)?
My answer is simple: FUD. "Ah, Common Lisp. It's that old language
with a weird syntax and lot's of stupid parenthesis?"
And here comes Clojure -- the same weird syntax and parens, but it's
NEW. The ground is already prepared by Groovy, JRuby and Scala (while
ABCL was developed before they became visible), which show, that there
can be other successful languages on the JVM. And it solves the
concurrency problem (which for many may be, actually, a non-problem).
And note, the Java folks just don't care about and understand many of
the features, that distinguish it from CL: Lisp-1 vs Lisp-2 and not-
interning reader, for example. Yeah, I agree, that they care about the
more generic collections. But look, it even doesn't have classes, but
they seam to be willing to swallow it, because that's where the wave
is going (OOP is sooo old style...).
And now we hear, that Clojure will be a ticket for Lisp to the JVM.
Why? Timing, marketing and design are all involved. Not only design.
IMHO, the most important thing is, that a lot of people like to work
on something new, if it has bright prospects. CL is not that sexy...

2. Other things.
I'm developing a web!!! application with Common Lisp. Do I have any
problems?

Libs? No. Up till now I could find all, that I need, and I have a good
level of control over it. As a Lisp programmer I'd prefer enhancing
and adding features to the Lisp lib (if I miss something), than sort
out the stuff in Java libs (and try to understand their
idiosyncrasies), that often have a completely different design
philosophy.

Collections?
Definitely not. I don't buy the argument, that lispers often use list,
where vector or hash-table is more appropriate. I don't. A good
programmer should use the tool (in this case, one of the basic tools
-- a data structure), that is suited for the task. And other
collection types have a rather good support in CL, although it's not
such fundamental as list's one. It's not a problem for the application
programmers. It's a problem for library programmers to some extend,
but it's not so fundamental, i think.

Concurrency?
I have very few cases, where I meet with it in my app. And for this
cases, at least by now, CL gives me enough tools.
For example I use the same approach as Clojure's vars (globals with
thread-unique values). It's done very easily with defvar and let. And
as a bonus I'm not limited to this usage pattern, I can use them
however I like.

Un-interning reader is a good thing, I agree. In some cases I stumbled
into this limitation of CL. But, first, those cases are rare, and,
second I, personally, don't yet understand the topic to such extend,
that can clearly say, how it should be done in the "right" way. If
there's really the one right way.

Does Clojure provide all that CL does? No!
* CL is good for rapid prototyping. Is it the case with Clojure? I
don't think that it's comparable, because it's limiting you in many
aspects: only functional approach, only lock-free concurrency, no OOP
etc.
* A layered system design through metaprogramming, DSL? I didn't try
Clojure macros in some real-world situations (not in trivial examples,
where Lisp-1 vs Lisp-2 don't come into play), but I'm not sure, that
they can at least match the power of CL ones. Maybe. But I didn't see
any mention of DSL in texts about Clojure. It seems, that Clojure
users perceive macros only as a means for syntactic extension.
* Lisp approach is to provide abstraction and generality. And that's
Lisp's "tragedy of the masses", so to say. Because java programmers
don't want that abstraction. They want a single "right" solution.
Clojure provides MVCC STM. But there can be other approaches to STM.
If Clojure followed the Lisp philosophy here, it would give, first of
all, the basic primitives and a possibility for the programmer to hook
into any layer of abstraction. A Clojure-lisp-for-concurrency would,
for example, provide an STM primitive and a possibility to specify
different algorithms of conflict resolution, MVCC being the default,
for example (that's my unanswered question to Hickey).

So, my conclusion is, that Clojure has a lot of good ideas to learn
from. It's a good special-purpose language. But it lacks the
generality of Common Lisp, so it's not better than CL in all respects.
It's better in some basic and some situational aspects.
And we, CL programmers, should take that into account and try to
improve CL in those directions, we were shown it lags behind. But it's
not a reason to all of a sudden consider it a poor language (it's not
a king of a hill game) and drop it all together. Blub paradox is just
a philosophical exercise and shouldn't be taken overly serious.
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnruqa$gt2$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 22, 1:18 pm, Jan Rychter <····@rychter.com> wrote:
>> So here comes Clojure. A clean redesign of a Lisp language, throwing
>> away old religious dogmas and providing a clean slate. Expressive, with
>> fresh ideas, all on top of a popular platform with thousands of
>> libraries we can make use of. And what do we do?
>> ...
>> We should at least keep an open mind. There are and will be better
>> languages than Common Lisp. Instead of digging trenches and shutting our
>> eyes we should be on the lookout for new ideas. And when they come, we
>> don't have to all switch religions. Let's just treat the newcomers with
>> respect.
> 
> 1. The Java platform.
> There's ABCL. Did you ask yourself a question why it can't be used in
> the Java world by those hoards of Java programmers, who "are in need
> of a better language". Isn't it also a Lisp with Java-interop (like
> CLojure)?

ABCL is nice. It has just not gotten as many man-hours as Rich Hickey
put into Clojure. He is the type of guy who just sits down and hacks
like a machine. If there wouldn�t have been the videos of that guy with
the crazy scientists hair one could think that he is in fact a bot,
working with insane progress on his product.

The nice thing is: all of what he has done is available for ABCL.
So, for all CLs that compile to the JVMs byte code can incorporate his
works easily.


> My answer is simple: FUD. "Ah, Common Lisp. It's that old language
> with a weird syntax and lot's of stupid parenthesis?"

Right.
People look at CL just a few moments, see they don�t like it and
their prejudices are set up.
The unfortunate thing that I can observe today is that some of us CLers
react in the same way to Clojure.
They find a small glitch, such as not yet existant TCO in the JVM and
jump over it, as if this had dramatic implications for developing
software in Clojure. So the �victims� of prejudices in the past (we
CL guys who had to read so much bullshit about it) are now coming out
of their holes, and basically do the same.


> And here comes Clojure -- the same weird syntax and parens, but it's
> NEW. The ground is already prepared by Groovy, JRuby and Scala (while
> ABCL was developed before they became visible), which show, that there
> can be other successful languages on the JVM. And it solves the
> concurrency problem (which for many may be, actually, a non-problem).

Yes, good observation. This is part of the human psychology. Many of us
like new things better.
But let�s be fair. When you actually use Clojure you can find out that
it is indeed the next evolutionary step for Lisp.
It�s also part of human nature that small improvements here and there
are not fully respected/realized, but that instead we care more about
disadvantages.
When I came to Clojure I thought that it is nice that one can do nearly
all CL stuff a bit easier/shorter/more readable.
But that was not such a biiig deal. However... when I now go back to CL
I find myself in a different world. How was it possible that I was
accepting it for all these years? I honestly don�t want to go back. It
is obvious for me that it is a step back.
So yes, Clojure is new and has not �Lisp� in its name. That will attract
several people, who just will look at it *because* it is new.
But for experts like us it can really go beyond that.


> And note, the Java folks just don't care about and understand many of
> the features, that distinguish it from CL: Lisp-1 vs Lisp-2 and not-
> interning reader, for example. Yeah, I agree, that they care about the
> more generic collections. But look, it even doesn't have classes, but
> they seam to be willing to swallow it, because that's where the wave
> is going (OOP is sooo old style...).

I strongly tend to buy that argument about OOP.
It had enough time to prove that this is the right way. IMO it failed.
Since some years I was concentrating on doing functional programming in
CL and have the impression that this is better.
The next years must prove it. We will see how Clojure will perform, how
products incorporate its STM, and such. I have a good feeling, but I
also look forward to see what really will happen.


> 2. Other things.
> I'm developing a web!!! application with Common Lisp. Do I have any
> problems?

No, you don�t have a problem in the sense that you can�t do it.
But I smell the scent of Blub here.
Whatever you come up with, the VisualBasic programmer will tell you
how he can do more or less the same with VB.
What you could do is to try out to write a small webapp in Clojure.
Then you can see much better if you actually miss something.


> Libs? No. Up till now I could find all, that I need

The other day we were trying to find a well tested and mature
server for RESTful services. Putting documentation, test status
and maturity aside, we did not even find a crappy server :(
Maybe you want to create .avi videos on-the-fly from some input
data for your users? What about uploading Excel files?


> Collections?
> Definitely not. I don't buy the argument, that lispers often use list,
> where vector or hash-table is more appropriate. I don't.

When you start to write a new function, how often do you begin with
using lists? When you then later decide to move to hashtables, how
often did your beautiful small program needed a rewrite and got ugly
and bloated?
Would Peter Seibel have used plists in his database example at
http://www.gigamonkeys.com/book/practical-a-simple-database.html
if he had written a Clojure book? I am certain he would have used
Clojures hashmaps.
The Clojure example of that chapter would have been slightly more
complex, because push is not available, but his example would have
been concurrency ready. Hundreads of users of a web app that want to
add entries to the DB can do it in their own thread.
Rewrite his example so that runs concurrently, and compare.


> Concurrency?
> I have very few cases, where I meet with it in my app. And for this
> cases, at least by now, CL gives me enough tools.

Yes. Blub.
More things that could run concurrently in your app would do so if you
had written it in Clojure. Because it is so very easy.


> Does Clojure provide all that CL does? No!

Does CL provide all that Clojure does? No!


> * CL is good for rapid prototyping. Is it the case with Clojure? I
> don't think that it's comparable, because it's limiting you in many
> aspects: only functional approach, only lock-free concurrency, no OOP
> etc.

This is not true.
I say that Clojure is even better at prototyping.
Having no OOP is a *plus*. You won�t have to decide how to write your
prototype. Structs? CLOS? Imperative? Functional?
You will do it in functional style (hopefully) right from the beginning.
It served me very well so far.
And you are not forced to do it only the functional way in Clojure.
You can use the Java oop (from within Clojure, without writing a line
of Java) if you wish. But this is much more complex. Clojure made IMO
the right choice for the default. Functional programming.
You are wrong about the lock-free concurrency. Please, be so kind and
read/write Clojure for a few months, and then make statements of how
it is. Why should anyone here trust your statements, when they contradict
those of users of Clojure?
Btw, if you want you can come up with an imperative lib for Clojure
in one or two days. With setf, push and friends. Then you have
highspeed datastructures that don�t need to fear a comparison with what
CL implementations offer you.


> * A layered system design through metaprogramming, DSL? I didn't try
> Clojure macros in some real-world situations

Good, so what I expect to read in the next sentences of yours is, that
you will say something like: �and therefor I will not talk about it,
but instead learn about it now�.


> (not in trivial examples,
> where Lisp-1 vs Lisp-2 don't come into play), but I'm not sure, that
> they can at least match the power of CL ones.

Ah okay.
Like that guy who seems Lisp code, sees the word �list� in there and
then knows that in Lisp only lists are used. And it has these parens...
Sorry, I am being a bit sarcastic. I don�t doubt that you are a Lisp
expert, but please look into that Clojure dialect before debating its
pros/cons.


> Maybe. But I didn't see
> any mention of DSL in texts about Clojure. It seems, that Clojure
> users perceive macros only as a means for syntactic extension.

Is that last statement only a personal experience that you made from
a quick glimpse into some Clojure texts? Or did you make a
representative study in the psychology department of your university?

One option to explain your observation: Clojure has users that never
did Lisp before, or it has some Lisp experts. We experts don�t talk
very much about DSL and macros all over. Same with the newbies, who
will first have to learn and realize what that means.
If you wrote some Clojure macros let me know what you miss.
To write a macro in Clojure you use defmacro.
It has also the backquote ` but not the , or ,@
Instead it has ~ and ·@ which work like their CL equivalents.
Of course, all the syntactic sugar for vectors, maps and sets works
perfectly in macro.
It will be very rare that you need to do gensym. Because Clojure offers
a nice reader macro for that. Just put a # at the end of the var that
you want to be a gensymmed symbol.
This is very cool. I think you will like it.


> * Lisp approach is to provide abstraction and generality. And that's
> Lisp's "tragedy of the masses", so to say. Because java programmers
> don't want that abstraction. They want a single "right" solution.

The consequence is that code is very compatible. When there is basically
one way to do it, then it is easier for teams to work together. In CL
everyone often ends up with his personal re-invention of the wheel, not
compatible to what others make. Good for lonely wolves and cool hackers.


> Clojure provides MVCC STM. But there can be other approaches to STM.

Yup, but STM is one approach, and it is usable. Today. In Clojure.


> If Clojure followed the Lisp philosophy here, it would give, first of
> all, the basic primitives and a possibility for the programmer to hook
> into any layer of abstraction.

Be happy, Clojure follows the Lisp philosophy. You have your hooks.


> So, my conclusion is, that Clojure has a lot of good ideas to learn
> from.

It is one thing to come to an conclusion about something about which you
have read a little, in 30 minutes, or if you actually used it for some
months.
My conclusion is: CL had some nice ideas. Even revolutionary in the mid
80ies. The world has moved, two decades have passed. CL stayed the same.
The environment however is a different one. A fit language 20 years ago
is not automatically a fit one today. The good things from CL are now
available in Clojure. Good things from Erlang and Haskell are also.
Rich Hickey stands on the shoulders of giants and can see very far.


> It's a good special-purpose language. But it lacks the
> generality of Common Lisp, so it's not better than CL in all respects.

I tend to say the opposit of what you said is the case.
I interpret your behaviour as trying to put lipstick on the pig.
Convincing yourself that you are still following the right way.


> It's better in some basic and some situational aspects.

Interesting to hear that from someone who did not write a single line
in it yet.
Please give it a try. Just 2-3 months, then let�s talk again.
Peace.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <3452fbb4-7f1f-48f1-bbd5-197db187d87d@u38g2000yqe.googlegroups.com>
On Feb 22, 6:34 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> But for experts like us it can really go beyond that.
Thanks for such a description, but, actually, I don't consider myself
an expert.

> I strongly tend to buy that argument about OOP.
> It had enough time to prove that this is the right way. IMO it failed.
> Since some years I was concentrating on doing functional programming in
> CL and have the impression that this is better.
> The next years must prove it. We will see how Clojure will perform, how
> products incorporate its STM, and such. I have a good feeling, but I
> also look forward to see what really will happen.
Lisp (CL) was always about multiple paradigms. I, personally, find it
very productive to combine functional and OO styles, because each one
is well suited for solving different problems.

> No, you don’t have a problem in the sense that you can’t do it.
No I don't have the problem in the sense, that I can do it the way I
like and consider most elegant and simple.

> But I smell the scent of Blub here.
> Whatever you come up with, the VisualBasic programmer will tell you
> how he can do more or less the same with VB.
> What you could do is to try out to write a small webapp in Clojure.
> Then you can see much better if you actually miss something.
Maybe you could tell me now what are the advantages of Clojure over CL
for my case (not considering multiprocessing, which I acknowledge is a
strong point of Clojure). Because I can easily list the advantages of
using CL over VB:
A uniform syntax, extensibility and malleability, macros, support for
functional paradigm, conditional system, full control of the language,
basically, well thought-out design of every language sub-system and so
on and so forth.

I mean, if you talk about Blub, than you have to prove it's so. The
Ruby guy also will say, that "Ruby is an acceptable Lisp", so what.
Moreover, I've written above, that this whole Blub stuff is just pure
speculation. I don't consider myself superior to other programmers,
because I use Lisp, neither I consider CL superior to other
programming languages and systems. I just to point to its strong
sides, which align with my desires in programming: rapid prototyping,
metaprogramming, extensibility, reasonable uniformity.

> > Libs? No. Up till now I could find all, that I need
> The other day we were trying to find a well tested and mature
> server for RESTful services. Putting documentation, test status
> and maturity aside, we did not even find a crappy server :(
What about Hunchentoot?

> Maybe you want to create .avi videos on-the-fly from some input
> data for your users?
Don't know, but if there's no CL lib, it should be possible to use
some external tool. Or I could commission it. In general, specific
problems ask for specific solutions. And they not always can come for
free. There are a lot of specific problems, that don't have a free
java lib already available :)
> What about uploading Excel files?
Some problems are non-problems. Use CSV :)))

> When you start to write a new function, how often do you begin with
> using lists?
Very rarely. I usually try to think first about the problem at hand,
what data-structures it requires, and then start coding. Yet I think
that a good advanced collections library would be very handy in CL.
FSet is a good move in one direction. The other one we need to cover
is all the various kinds of trees.


> Would Peter Seibel have used plists in his database example athttp://www.gigamonkeys.com/book/practical-a-simple-database.html
> if he had written a Clojure book? I am certain he would have used
> Clojures hashmaps.
I didn't think about that. Maybe. Anyway, he covers hash-tables quite
well in the book.

> More things that could run concurrently in your app would do so if you
> had written it in Clojure. Because it is so very easy.
I don't object that Clojure's concurrency model is quite advanced. I
just said, that concurrency doesn't play an important role in my
domain. More specifically, I forgot to mention, that most of the
concurrency-related stuff in managed on the side of RDBMS, that is
quite good at it. If I wanted to write a DBMS, I would definitely
consider Clojure.

> Does CL provide all that Clojure does? No!
I agree, Clojure's concurrency support is way better. What else?

> This is not true.
> I say that Clojure is even better at prototyping.
> Having no OOP is a *plus*. You won’t have to decide how to write your
> prototype. Structs? CLOS? Imperative? Functional?
I completely disagree with this. Each domain has the set of most
suitable and natural tools, that you can use to solve problems in it.
For RAPID prototyping it's extremely important to be able to use any
tool, you consider appropriate. And you suggest what is expressed in
the common aphorism: "You have a hammer and now consider every problem
a nail".

> And you are not forced to do it only the functional way in Clojure.
> You can use the Java oop (from within Clojure, without writing a line
> of Java) if you wish. But this is much more complex.
So who is becoming religious here? ;) Surely you can do it in any
style, I don't object. If you go down to the Assembler level, you can
do it even with jumps. I speak about the language being intended for
that purposes.

> You are wrong about the lock-free concurrency. Please, be so kind and
> read/write Clojure for a few months, and then make statements of how
> it is. Why should anyone here trust your statements, when they contradict
> those of users of Clojure?
First I'd like to mention, that although I don't do any programming in
Clojure, I've followed it from the time when first mentions have
appeared approx. 1 year ago. And from this discussion I've learned
about the locking macro. So yes, surely, it's possible. You can as
well go down to the Java level, right? But you yourself contradict
what you and other Clojure people have said: "lock-free concurrency"
So why should anyone trust your comments now, if you contradict your
own statements?

> One option to explain your observation: Clojure has users that never
> did Lisp before, or it has some Lisp experts. We experts don’t talk
> very much about DSL and macros all over.
Why?

> If you wrote some Clojure macros let me know what you miss.
> To write a macro in Clojure you use defmacro.
> It has also the backquote ` but not the , or ,@
> Instead it has ~ and ·@ which work like their CL equivalents.
Thank you, it's very enlightening. ;)

> It will be very rare that you need to do gensym. Because Clojure offers
> a nice reader macro for that. Just put a # at the end of the var that
> you want to be a gensymmed symbol.
> This is very cool. I think you will like it.
There's a whole chapter on how to do it in "Let over Lambda". And
besides, it shows how to incorporate once-only with it. With working
examples. Those, who need that, can take it and use right away in CL.
Btw, does Clojure have once-only?
Btw, does Clojure have user-defined reader macros, or only
implementation ones?
Overall, as I said I have no real experience with Clojure macros. So I
can't say, weather the problems that people talk about wrt Lisp-1 &
macros will come up in it. But at least there's nothing new here,
comparing to CL macros. So in the best possible case it's just not a
step backwards.
(If I have a possibility to work with them substantially, I'll inform
the Clojure mailing list on my opinions :)

> The consequence is that code is very compatible. When there is basically
> one way to do it, then it is easier for teams to work together. In CL
> everyone often ends up with his personal re-invention of the wheel, not
> compatible to what others make. Good for lonely wolves and cool hackers.
I don't object. Every approach is a set of compromises. And every
programmer and team has to choose.

> > Clojure provides MVCC STM. But there can be other approaches to STM.
> Yup, but STM is one approach, and it is usable. Today. In Clojure.
Yes, but there can be different kinds of STMs. Rich Hickey has chosen
one of them, that he thinks is the most appropriate. It's the usual
approach taken by many BDFLs. It really works to make the language
popular, I don't object. It's just not in the Lisp way, IMO.

> Be happy, Clojure follows the Lisp philosophy. You have your hooks.
Which are?..

> It is one thing to come to an conclusion about something about which you
> have read a little, in 30 minutes, or if you actually used it for some
> months.
I read quite a lot about Clojure, just didn't have the possibility to
use it. You see, I have active projects, I'm working on, I don't have
any suggestions to work on Clojure-related projects and don't have the
time to just take it and hack at it from sheer curiosity or religious
zest.

> My conclusion is: CL had some nice ideas. Even revolutionary in the mid
> 80ies. The world has moved, two decades have passed. CL stayed the same.
> The environment however is a different one. A fit language 20 years ago
> is not automatically a fit one today.
I started using CL in 2006. It was quite fit then :)

> The good things from CL are now available in Clojure.
Some are and some ain't. CLOS & MOP, Conditional system, Multiple-
value returns, Lisp-2 ain't, to name a few. But that's not so
important, as the basic attitude, which in CL is abstraction and
generality, and in Clojure - ??? (I don't say it isn't, some things
hint, that yes, others -- that not. I try to investigate)

> Good things from Erlang and Haskell are also.
Some are and some ain't. (On Erlang: http://clojure.org/state. On
Haskell: go ask a Haskell programmer, is everything he likes about
Haskell present in Clojure?)

> I tend to say the opposit of what you said is the case.
> I interpret your behaviour as trying to put lipstick on the pig.
> Convincing yourself that you are still following the right way.
Sorry, but, IMO, you don't have the facts to support your statement.
You are calling many guys here religious, but yourself defend
everything, connected with Clojure, in the religious way.

> Peace.
I hope, that I wasn't too harsh. Personally, I like Clojure's approach
in many aspects. But what I like in are the things, that don't
contradict the CL ways. Moreover, I don't follow the "all or nothing"
principle, so liking many things about Clojure, doesn't make me
dislike CL all of a sudden, because those features of it I like just
didn't disappear.

Best regards,
Vsevolod
From: Rich Hickey
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <fb3a4322-98ed-446b-b703-e7635240cb19@l39g2000yqn.googlegroups.com>
On Feb 22, 7:42 am, Vsevolod <········@gmail.com> wrote:
> On Feb 22, 1:18 pm, Jan Rychter <····@rychter.com> wrote:
>
> > So here comes Clojure. A clean redesign of a Lisp language, throwing
> > away old religious dogmas and providing a clean slate. Expressive, with
> > fresh ideas, all on top of a popular platform with thousands of
> > libraries we can make use of. And what do we do?
> > ...
> > We should at least keep an open mind. There are and will be better
> > languages than Common Lisp. Instead of digging trenches and shutting our
> > eyes we should be on the lookout for new ideas. And when they come, we
> > don't have to all switch religions. Let's just treat the newcomers with
> > respect.
>
> 1. The Java platform.
> There's ABCL. Did you ask yourself a question why it can't be used in
> the Java world by those hoards of Java programmers, who "are in need
> of a better language". Isn't it also a Lisp with Java-interop (like
> CLojure)?
> My answer is simple: FUD. "Ah, Common Lisp. It's that old language
> with a weird syntax and lot's of stupid parenthesis?"

It's a simple answer, and probably not the correct one.

[...]

> Does Clojure provide all that CL does? No!
> * CL is good for rapid prototyping. Is it the case with Clojure?

Yes.

> I don't think that it's comparable, because it's limiting you in many
> aspects: only functional approach, only lock-free concurrency, no OOP
> etc.

Except that none of these things are true. Clojure fosters functional
programming but has mutable constructs, offers locks in addition to
its lock-free constructs, supports Java-style OO as well as
multimethods and ad hoc hierarchies. Etc.

> * A layered system design through metaprogramming, DSL? I didn't try
> Clojure macros in some real-world situations (not in trivial examples,
> where Lisp-1 vs Lisp-2 don't come into play), but I'm not sure, that
> they can at least match the power of CL ones. Maybe.

Definitely. Clojure has CL-style defmacro, with some additions to ease
the Lisp-1 issues. They are general purpose, full-power-of-the-
language macros.

> But I didn't see
> any mention of DSL in texts about Clojure. It seems, that Clojure
> users perceive macros only as a means for syntactic extension.

There are already Clojure DSLs for:

Parser combinators
Monads
Database access
Database query DSLs
Logic programing
Declarative XML processing
Graphics and UI
CL-style generic functions
Web applications
HTML generation
Hierarchical templating
Several testing DSLs
Build system DSLs
Several Cells-alikes

> * Lisp approach is to provide abstraction and generality. And that's
> Lisp's "tragedy of the masses", so to say. Because java programmers
> don't want that abstraction. They want a single "right" solution.

While it may be convenient to paint Clojure programers as Java
programmers, in fact, many are not familiar with Java at all. People
come to Clojure with various backgrounds: Java, Ruby, Scala, Python,
Haskell/ML, and of course, Scheme and Common Lisp. Most come to
appreciate how abstraction-oriented Clojure is. It is certainly not an
exclusive property of CL or CL'ers.

> Clojure provides MVCC STM. But there can be other approaches to STM.
> If Clojure followed the Lisp philosophy here, it would give, first of
> all, the basic primitives and a possibility for the programmer to hook
> into any layer of abstraction. A Clojure-lisp-for-concurrency would,
> for example, provide an STM primitive and a possibility to specify
> different algorithms of conflict resolution, MVCC being the default,
> for example (that's my unanswered question to Hickey).
>

Designing and implementing an STM is hard, and still an open research
area. It is my feeling that an STM must interact closely with the
language design, so the STM, the reference types, and the persistent
data structures all work together in Clojure to form a solution.
Making parts of an STM plug-and-play is not as easy as you might think
(e.g. MVCC is not a conflict resolution strategy, it still has
conflicts and a resolution strategy). Perhaps I will be able to
provide more customizability in the future, but you have to start
somewhere.

Talking about how a Lisp STM ought to work is easy. Clojure's STM is
just a library, there can be others. Please feel free to write another
one (with MOP-like extensibility) and contribute it. You can probably
get a(nother?) PhD at the same time, if you could make it non-
trivially extensible while guaranteeing correctness.

Rich
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <60393efb-cb98-4971-a682-a19884f7ad04@o11g2000yql.googlegroups.com>
On Feb 22, 10:36 pm, Rich Hickey <··········@gmail.com> wrote:
> Except that none of these things are true. Clojure fosters functional
> programming but has mutable constructs, offers locks in addition to
> its lock-free constructs, supports Java-style OO as well as
> multimethods and ad hoc hierarchies. Etc.
Besides, I would add support of metadata to the list, which seems to
be a very useful feature.
Maybe, you really don't limit the programmer in any way -- I'm not a
Clojure expert. But to be sure, I asked the leading questions about
semaphores and class definition to Andre.

> Parser combinators
> Monads
> Database access
> Database query DSLs
> Logic programing
> Declarative XML processing
> Graphics and UI
> CL-style generic functions
> Web applications
> HTML generation
> Hierarchical templating
> Several testing DSLs
> Build system DSLs
> Several Cells-alikes
That's great. I'll check them with great interest as soon as I'll have
time.

> While it may be convenient to paint Clojure programers as Java
> programmers, in fact, many are not familiar with Java at all.
I talked exactly about the Java programmers, not the Clojure ones.

> Most come to
> appreciate how abstraction-oriented Clojure is. It is certainly not an
> exclusive property of CL or CL'ers.
I agree.

> Designing and implementing an STM is hard, and still an open research
> area. It is my feeling that an STM must interact closely with the
> language design, so the STM, the reference types, and the persistent
> data structures all work together in Clojure to form a solution.
> Making parts of an STM plug-and-play is not as easy as you might think
I didn't say it's easy. And I respect your work. But it seems, that
providing generic STM constructs would have been even better, no? And
I was talking about it in the context of the Lisp way in general. I
think, that MOP was not easy as well, but eventually it appeared in
Lisp, while Java folks just came to something in the lines of "we're
ok with single-dispatch and single-inheritance; everything else is too
hard".

> (e.g. MVCC is not a conflict resolution strategy, it still has
> conflicts and a resolution strategy). Perhaps I will be able to
> provide more customizability in the future, but you have to start
> somewhere.
That's a good approach

> Talking about how a Lisp STM ought to work is easy.
Yes. But there's a saying: "in for a penny, in for a pound". If you
say, that you try to create an "abstraction-oriented" or extensibility-
oriented language, than I think you should be ready to hear such
questions. And not try to take a defensive position.

> Clojure's STM is
> just a library, there can be others. Please feel free to write another
> one (with MOP-like extensibility) and contribute it. You can probably
> get a(nother?) PhD at the same time, if you could make it non-
> trivially extensible while guaranteeing correctness.
I don't have a PhD and don't try to get one. I'm just an application
programmer.

Vsevolod
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <caa82331-e523-4e1a-ba4e-88912d7d8db4@w35g2000yqm.googlegroups.com>
On Feb 22, 10:36 pm, Rich Hickey <··········@gmail.com> wrote:
> There are already Clojure DSLs for: ...
Follow-up on DSLs. I checked some of them: the common Lisp DSL
construction patterns are surely present, it will be interesting to
look at them in more detail. In general, the language seems suitable
for such application. So expecting the Programming Clojure book...
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnsb71$mko$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 22, 6:34 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:

> Maybe you could tell me now what are the advantages of Clojure over CL
> for my case (not considering multiprocessing, which I acknowledge is a
> strong point of Clojure).

I don�t know your case, so I can not make a qualified statement about 
that. A week ago I posted a list of points (in this thread) that I see
as an advantage of Clojure over CL.


> Because I can easily list the advantages of
> using CL over VB:
> A uniform syntax, extensibility and malleability, macros, support for
> functional paradigm, conditional system, full control of the language,
> basically, well thought-out design of every language sub-system and so
> on and so forth.

Uniform syntax is also in Clojure. On top of it, it has some very nice
reader macros. The nice thing is that they are quasi standardized. All
Clojure users use and know them.
It has macros and supports the functional paradigm best, where CL has
the best support for imperative programming. In Clojure there is not
the condition system available, but instead the Java Exception system.
That can be a disadvantage, because CLs system can be used for more than
exception handling.
I however never came across a use of that in practice and also never
used it for that.


>> What about uploading Excel files?
> Some problems are non-problems. Use CSV :)))

Fair enough :)


>> When you start to write a new function, how often do you begin with
>> using lists?
> Very rarely. I usually try to think first about the problem at hand,
> what data-structures it requires, and then start coding. Yet I think
> that a good advanced collections library would be very handy in CL.
> FSet is a good move in one direction. The other one we need to cover
> is all the various kinds of trees.

If you begin very rarely with lists, then it sounds you are doing it
right. In Clojure lists are mostly used for putting programs into them,
but else using vectors.


>> Would Peter Seibel have used plists in his database example athttp://www.gigamonkeys.com/book/practical-a-simple-database.html
>> if he had written a Clojure book? I am certain he would have used
>> Clojures hashmaps.
> I didn't think about that. Maybe. Anyway, he covers hash-tables quite
> well in the book.

Yes. My point though was, that sometimes Lispers tend to use lists
because they are very easy to handle.


>> Does CL provide all that Clojure does? No!
> I agree, Clojure's concurrency support is way better. What else?

As I said, I listed advantages in another posting already.
Short summary of what I personally prefer in Clojure over CL, in no
particular order:
Lisp-1, no oop, no clos, no metaboject protocol (it�s an advantage to
not having oop), great integration of language constructs with each
other, more polymorphism (mapping over lists, vectors, hashmaps,
structured maps, sorted trees, and in general more functions work
with more data structures). A very big thing is the lazyness.
Nice reader macros are worth a lot, for data structures or for example
for gensyms in macros. Advantages from the JVM.

The word �better� is of course nothing objective, and nothing that
can be proven. Other people may think that OOP is really something they
need. But then again, why should it be clos?
Paul Graham writes, that functional programming + macros outperform oop.
He also wrote that he never used clos. I asked him why this is so, and
he wrote me back, that it is because he can *implement* oop.
In Clojure you can (but in my opinion should not) do oop. By using the
Java system, or by coming up with something tailored to the job at hand.


>> This is not true.
>> I say that Clojure is even better at prototyping.
>> Having no OOP is a *plus*. You won�t have to decide how to write your
>> prototype. Structs? CLOS? Imperative? Functional?
> I completely disagree with this. Each domain has the set of most
> suitable and natural tools, that you can use to solve problems in it.
> For RAPID prototyping it's extremely important to be able to use any
> tool, you consider appropriate. And you suggest what is expressed in
> the common aphorism: "You have a hammer and now consider every problem
> a nail".

But what if functional programming in the right environment (Lisp-1,
lazyness, immutable data structures) *is* the toolkit vs. being a
hammer?
I believe so, from personal experience. I gave up oop some years ago,
but I am now curious to see, how it will work out in the next years.
Reality will prove if my idea is right or not.


>> And you are not forced to do it only the functional way in Clojure.
>> You can use the Java oop (from within Clojure, without writing a line
>> of Java) if you wish. But this is much more complex.
> So who is becoming religious here? ;) Surely you can do it in any
> style, I don't object. If you go down to the Assembler level, you can
> do it even with jumps. I speak about the language being intended for
> that purposes.

Sorry, I don�t want to sound religious. Especially the part that you
quoted I even don�t find religious.
I am open to new languages, even non-lisp ones.
Anyway, the intended and easy way is the functional one.


>> You are wrong about the lock-free concurrency. Please, be so kind and
>> read/write Clojure for a few months, and then make statements of how
>> it is. Why should anyone here trust your statements, when they contradict
>> those of users of Clojure?
> First I'd like to mention, that although I don't do any programming in
> Clojure, I've followed it from the time when first mentions have
> appeared approx. 1 year ago. And from this discussion I've learned
> about the locking macro. So yes, surely, it's possible. You can as
> well go down to the Java level, right? But you yourself contradict
> what you and other Clojure people have said: "lock-free concurrency"
> So why should anyone trust your comments now, if you contradict your
> own statements?

I explained that you can use all that stuff, and also locks in Clojure.
You originally said:
�it's limiting you in many aspects: only functional approach, only
lock-free concurrency, no OOP, etc.�
^^^^^^^^^
And I corrected what you said. Also the other things you mentioned are
not correct. You are not really bound to the functional approach, and
you can do it the oop way.

I did not need locks so far in Clojure, although scenarios exist for
which locks are better than what the default offers.
One example could be huge transactions, hammering in multiple threads.
Here it could make sense to not just do the
(dosync ...) but instead (lock :big-transaction (dosync ...))


> Btw, does Clojure have once-only?

Not that I know of.


> Btw, does Clojure have user-defined reader macros, or only
> implementation ones?

It has only the reader macros that ship with Clojure.
Difficult to say if this is an advantage or not. I have asked Rich Hickey
if he will give access to reader macros, and currently he is against this.


>>> Clojure provides MVCC STM. But there can be other approaches to STM.
>> Yup, but STM is one approach, and it is usable. Today. In Clojure.
> Yes, but there can be different kinds of STMs. Rich Hickey has chosen
> one of them, that he thinks is the most appropriate.

Yes. CL is in the same situation with CLOS, the condition system or
the GC (if available).


> It's the usual
> approach taken by many BDFLs. It really works to make the language
> popular, I don't object. It's just not in the Lisp way, IMO.

But is it the lisp way to ship a CL with a GC and an oop system?


>> The good things from CL are now available in Clojure.

> Some are and some ain't. CLOS & MOP, Conditional system, Multiple-
> value returns, Lisp-2 ain't, to name a few. But that's not so
> important, as the basic attitude, which in CL is abstraction and
> generality, and in Clojure - ??? (I don't say it isn't, some things
> hint, that yes, others -- that not. I try to investigate)

Okay, we met the point of taste/opinion here.
I think it is good to *not* have clos, and therewith the need for a MOP.
About multiple-return values: yes, they can be a nice extra, and they
are not available in Clojure. I would see it as a good thing if they
were available.


>> Peace.
> I hope, that I wasn't too harsh.

No, it�s fine.
However, I have this uncertain feeling when you talk about Clojure, that
I usually have when non-lispers tell me how Lisp really is.


> Personally, I like Clojure's approach
> in many aspects. But what I like in are the things, that don't
> contradict the CL ways. Moreover, I don't follow the "all or nothing"
> principle, so liking many things about Clojure, doesn't make me
> dislike CL all of a sudden, because those features of it I like just
> didn't disappear.

Right, CL is still my second favourite language. But half a year it was
number one, and now there is a big distance between 1. and 2.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <f701ba22-6460-46a7-a57d-dab637c630cd@j39g2000yqn.googlegroups.com>
On Feb 22, 10:05 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> If you begin very rarely with lists, then it sounds you are doing it
> right. In Clojure lists are mostly used for putting programs into them,
> but else using vectors.
Actually, I use lists quite often, because this is the best data-
structure performance-wise and usage-wise for sequential access data.
I meant, that I usually begin writing functions after I decide, which
data-structure to use.

> Lisp-1,
I strongly prefer Lisp-2 :)

> no oop, no clos, no metaboject protocol (it’s an advantage to
> not having oop)
This is highly subjective

> great integration of language constructs with each
> other,
In CL as well

> more polymorphism (mapping over lists, vectors, hashmaps,
> structured maps, sorted trees, and in general more functions work
> with more data structures).
Possible

> A very big thing is the lazyness.
Maybe, if it's really lazy to the core. As I see from the lazier1 it's
still work in progress. But, in general, agree.

> Nice reader macros are worth a lot, for data structures or for example
> for gensyms in macros.
But you've said there are no user-defined reader macros. I use reader
macros on CL and can implement all of Clojure ones, if needed. (Just
that I need only a fraction). So it (not having ways to hook into) is
rather a disadvantage, no?

> Advantages from the JVM.
For every advantage you can find a disadvantage. For JIT - boxed
numbers and lack of TCO.
Besides, ABCL works on the JVM.
Btw, I tried to run Clojure on j2me emulator yesterday. No luck.
Didn't have time to try ABCL yet.

> >> And you are not forced to do it only the functional way in Clojure.
> >> You can use the Java oop (from within Clojure, without writing a line
> >> of Java) if you wish. But this is much more complex.
> > So who is becoming religious here? ;) Surely you can do it in any
> > style, I don't object. If you go down to the Assembler level, you can
> > do it even with jumps. I speak about the language being intended for
> > that purposes.
> Sorry, I don’t want to sound religious. Especially the part that you
> quoted I even don’t find religious.
I mean, that you sound like everything in Clojure and the JVM is best
it can be. Maybe, I've pointed to not the most illustrative snippet,
but there are such, especially in your discussion with Pascal
Constanza.
In this case I meant, that if Clojure promotes functional style and
discourages the imperative one, it should be harder to do some
imperative stuff. And you say like "oh, it's easy to implement it in a
library" (and, note, that's exactly, what you criticized CL community
in general for: that we say, that everything can be easily implemented
as a library. Isn't it a double standards approach?)

> I explained that you can use all that stuff, and also locks in Clojure.
> You originally said:
> „it's limiting you in many aspects: only functional approach, only
> lock-free concurrency, no OOP, etc.”
> ^^^^^^^^^
> And I corrected what you said. Also the other things you mentioned are
> not correct. You are not really bound to the functional approach, and
> you can do it the oop way.
Examples: can you use semaphores in Clojure, without going to the Java
level, can you define a custom OOP class in Clojure without going to
the Java level? If not, than, IMO, I was not wrong.

> >>> Clojure provides MVCC STM. But there can be other approaches to STM.
> >> Yup, but STM is one approach, and it is usable. Today. In Clojure.
> > Yes, but there can be different kinds of STMs. Rich Hickey has chosen
> > one of them, that he thinks is the most appropriate.
> Yes. CL is in the same situation with CLOS, the condition system or
> the GC (if available).
With CLOS -- not at all. Because having MOP you can implement a
different OO-system. For example a prototype-based one. The
conditional systems: which possible uses are not covered? GC: yeah, it
would be great to have an interface to the GC to change it's internal
working. Python has some. Maybe some of the implementations provide
it, I didn't inquire.

> > It's the usual
> > approach taken by many BDFLs. It really works to make the language
> > popular, I don't object. It's just not in the Lisp way, IMO.
> But is it the lisp way to ship a CL with a GC and an oop system?
Absolutely, if you have hooks into those systems. I've never needed to
hook in the GC, but for the low-level programmers it might be
necessary, And I would understand, if they complain, that CL lacks
extensibility in this regard.

> Okay, we met the point of taste
To some extent yes. Lisp-1 vs Lisp-2, for example. But in some aspects
I don't agree: to have a full OOP system, that you are free to use or
not use is objectively better, that to have none. It's not a question
of taste.

> No, it’s fine.
> However, I have this uncertain feeling when you talk about Clojure, that
> I usually have when non-lispers tell me how Lisp really is.
Maybe that's true. But I mostly try to respond to the criticism of CL
here, which I consider ungrounded, and try to talk about Clojure wrt
CL only.

Best regards,
Vsevolod
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnsgju$ql2$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 22, 10:05 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
>> If you begin very rarely with lists, then it sounds you are doing it
>> right. In Clojure lists are mostly used for putting programs into them,
>> but else using vectors.
> Actually, I use lists quite often, because this is the best data-
> structure performance-wise and usage-wise for sequential access data.
> I meant, that I usually begin writing functions after I decide, which
> data-structure to use.

Are they performance-wise better than vectors?
Also in sequential data access?


>> Lisp-1,
> I strongly prefer Lisp-2 :)

For CL being a Lisp-n is ok.
But even Kent Pitman agrees that for functional programming Lisp-1 is
the right choice.


>> no oop, no clos, no metaboject protocol (it�s an advantage to
>> not having oop)
> This is highly subjective

Indeed, I agree here.
Just an additional comment: one could argue that if functional
programming will prove that it can improve productivity and main-
tainability and thus reduce cost of software while increasing its
complexity, then it can be called �better�. Depends on the definition
of this �better�.


>> great integration of language constructs with each
>> other,
> In CL as well

Not true. Make your clos class inheriting from lists.
Try         (length (make-hash-table :initial-contents '(:a 10 :b 20))).
In Clojure: (count {:a 10, :b 20}) ==> 2



>> A very big thing is the lazyness.
> Maybe, if it's really lazy to the core. As I see from the lazier1 it's
> still work in progress. But, in general, agree.

Just a few days ago the fully lazy branch was merged into svns trunk.
While in general Clojures core is pretty stable and mostly just gets
extended with new tools/abstractions, there are still some things that
can change until 1.0 is ready.


>> Nice reader macros are worth a lot, for data structures or for example
>> for gensyms in macros.
> But you've said there are no user-defined reader macros. I use reader
> macros on CL and can implement all of Clojure ones, if needed. (Just
> that I need only a fraction). So it (not having ways to hook into) is
> rather a disadvantage, no?

As I said, it can be both.
I asked Rich if we can have them, he is against it.
When thinking in the hacker-mentality, where I am the only guy who is
working on a project I would clearly see it as an advantage of having
reader macros. Although the best ones are already taken ;)
For teams however I tend to say that we may be better off without having
user defined reader macros. I still did not decide fully how I think
about this issue.
Offering this feature brings potential power. But that comes for a
price. And sometimes things are good because they lack something.
For example I buy sometimes nice menues from the german company Frosta.
They have some of the highest quality food available, and Frosta is good
for the things it does not have. Antidegradants. Dyestuffs.
Flavor potentiators. No chemical additives. Ah, and no reader macros *g*

So, I can not give you a yes/no here. I tend to no, with regard to the
success of the language.


>> Advantages from the JVM.
> For every advantage you can find a disadvantage. For JIT - boxed
> numbers and lack of TCO.

True.
I think tagged numbers are the favourite thing of Rich he would like the
JDK team to add. People are working on TCO already.


> Besides, ABCL works on the JVM.
> Btw, I tried to run Clojure on j2me emulator yesterday. No luck.
> Didn't have time to try ABCL yet.

I saw a screenshot of someone trying out Android.
Never tried the ME. I just know that it has ridiculous memory expectations.


> I mean, that you sound like everything in Clojure and the JVM is best
> it can be. Maybe, I've pointed to not the most illustrative snippet,
> but there are such, especially in your discussion with Pascal
> Constanza.

Btw, it�s Costanza.


> In this case I meant, that if Clojure promotes functional style and
> discourages the imperative one, it should be harder to do some
> imperative stuff. And you say like "oh, it's easy to implement it in a
> library" (and, note, that's exactly, what you criticized CL community
> in general for: that we say, that everything can be easily implemented
> as a library. Isn't it a double standards approach?)

Per default most Clojure objects are immutable.
It is one of the easier things to implement a lib for imperative 
programming.
I don�t suggest you to do it. I just want to make sure that Clojure does
not stop you to do it. You sounded as if you think it works this way.
For example in Haskell it is even more difficult to get such a behaviour.
But writing such a lib for Clojure is not a task that will keep you busy
for several weeks. That�s all I wanted to say. And at the same time I
say that I don�t see a need for such a lib. I want most parts of my data
to be immutable. I want to think before I decide to put a ref or an
agent on it.
If someone decides to write such a lib after Clojure is 8 years old,
then that would be as doomed as writing something like Clojure for CL.


>> I explained that you can use all that stuff, and also locks in Clojure.
>> You originally said:
>> �it's limiting you in many aspects: only functional approach, only
>> lock-free concurrency, no OOP, etc.�
>> ^^^^^^^^^
>> And I corrected what you said. Also the other things you mentioned are
>> not correct. You are not really bound to the functional approach, and
>> you can do it the oop way.
> Examples: can you use semaphores in Clojure, without going to the Java
> level, can you define a custom OOP class in Clojure without going to
> the Java level? If not, than, IMO, I was not wrong.

Yes, you can use semaphores without writing Java code.
And yes, you can define a custom OOP class in Clojure without writing
Java.


>>>>> Clojure provides MVCC STM. But there can be other approaches to STM.
>>>> Yup, but STM is one approach, and it is usable. Today. In Clojure.
>>> Yes, but there can be different kinds of STMs. Rich Hickey has chosen
>>> one of them, that he thinks is the most appropriate.
>> Yes. CL is in the same situation with CLOS, the condition system or
>> the GC (if available).
> With CLOS -- not at all. Because having MOP you can implement a
> different OO-system. For example a prototype-based one.

Can one use the MOP also to make defclass accepting LIST as the
superclass?


>>> It's the usual
>>> approach taken by many BDFLs. It really works to make the language
>>> popular, I don't object. It's just not in the Lisp way, IMO.
>> But is it the lisp way to ship a CL with a GC and an oop system?
> Absolutely, if you have hooks into those systems. I've never needed to
> hook in the GC, but for the low-level programmers it might be
> necessary, And I would understand, if they complain, that CL lacks
> extensibility in this regard.

So, if the Lisp that you are using has no hooks into the GC, then it is
not the lisp way, did I understand this correctly?


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <f644d288-8fbb-457a-9798-083c4a835472@t11g2000yqg.googlegroups.com>
On Feb 22, 11:38 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Are they performance-wise better than vectors?
> Also in sequential data access?
http://en.wikipedia.org/wiki/Linked_list

> Not true. Make your clos class inheriting from lists.
> Try         (length (make-hash-table :initial-contents '(:a 10 :b 20))).
> In Clojure: (count {:a 10, :b 20}) ==> 2
Try destructuring on a string in Clojure?
If you treat a couple of basic CL data-structures (list, vector, hash-
table) the same as Clojure treats Java simple types, and wrap it in a
CLOS class you'll get what you want. But, in general I agree, there
are some idiosyncrasies in CL, that better be removed (like this lack
of genericness). I even wrote a rant, mentioning that (it appeared
here a while ago).

> Flavor potentiators. No chemical additives. Ah, and no reader macros *g*
Following this line of thought, I could say, that macros are
hazardous, no?

> > Examples: can you use semaphores in Clojure, without going to the Java
> > level, can you define a custom OOP class in Clojure without going to
> > the Java level? If not, than, IMO, I was not wrong.
>
> Yes, you can use semaphores without writing Java code.
> And yes, you can define a custom OOP class in Clojure without writing
> Java.
I would be glad, if you could provide the code examples.

> Can one use the MOP also to make defclass accepting LIST as the
> superclass?
No. But that doesn't stop you to create an clist wrapper class (note
the Clojure naming convention here ;) and subclass from it. Can you
have a string as a superclass in Java? In Clojure, that allows the use
of OOP?

> So, if the Lisp that you are using has no hooks into the GC, then it is
> not the lisp way, did I understand this correctly?
I think so. And remember I didn't say that CL is perfect.

Vsevolod
From: William James
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnsk0r02hqi@enews4.newsguy.com>
Vsevolod wrote:

> Try destructuring on a string in Clojure?

user=> (let [[a b c] "bar"] c)
\r
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnsjeq$sv8$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 22, 11:38 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
>> Are they performance-wise better than vectors?
>> Also in sequential data access?
> http://en.wikipedia.org/wiki/Linked_list
> 
>> Not true. Make your clos class inheriting from lists.
>> Try         (length (make-hash-table :initial-contents '(:a 10 :b 20))).
>> In Clojure: (count {:a 10, :b 20}) ==> 2
> Try destructuring on a string in Clojure?

Hmm, I am not sure what you mean. Under destructuring I understand:
user> (let [[char1 char2 & rest-chars] "abcdefg"]
         (println char1 char2 rest-chars))
a b (c d e f g)

Btw, the destructuring in Clojure is also a very nice feature that I
completely missed to mention.
One can destructure also lists, vectors and hashmaps and basically all
data structures that Clojure offers.


>> Flavor potentiators. No chemical additives. Ah, and no reader macros *g*
> Following this line of thought, I could say, that macros are
> hazardous, no?

Apropos flavour: what I mentioned in that sentence was flavored with
some bits of irony ;)


>>> Examples: can you use semaphores in Clojure, without going to the Java
>>> level, can you define a custom OOP class in Clojure without going to
>>> the Java level? If not, than, IMO, I was not wrong.
>> Yes, you can use semaphores without writing Java code.
>> And yes, you can define a custom OOP class in Clojure without writing
>> Java.
> I would be glad, if you could provide the code examples.

One example that illustrates a way to extend a Clojure data type can
be found here: http://kotka.de/projects/clojure/lazy-map.html

It took the clojure hashmap and made it lazy.
The values will be evaluated only on their first read.

About Semaphores:
user> (import '(java.util.concurrent Semaphore))
nil
user> (def s (Semaphore. 3))
#'user/s
user> s
#<Semaphore ······························@992fa5[Permits = 3]>

user> (dotimes [i 3] (.acquire s))
nil
user> s
#<Semaphore ······························@992fa5[Permits = 0]>
user> (.acquire s)

Damn, I didn�t want to write that last acquire, but I pressed enter
before I realized what this means.
At the time of this writing my repl thread is still frozen ;)

I never used the Java Semaphores before. To do it, I went to
http://java.sun.com/javase/6/docs/api/java/util/concurrent/Semaphore.html
and looked up what the constructors expect.
I decided to take the first one, which wants the number of permits.
I could have called any of the methods listed in that document.


>> Can one use the MOP also to make defclass accepting LIST as the
>> superclass?
> No. But that doesn't stop you to create an clist wrapper class (note
> the Clojure naming convention here ;) and subclass from it. Can you
> have a string as a superclass in Java? In Clojure, that allows the use
> of OOP?

I am not a Java guy, but I think Strings are final and one can not
inherit from them.


>> So, if the Lisp that you are using has no hooks into the GC, then it is
>> not the lisp way, did I understand this correctly?
> I think so. And remember I didn't say that CL is perfect.

Right. And as long as (connect-with-my-brain-and-do-it) something is
seriously wrong with the language I am using.
But from what is available today Clojure is my definite number 1.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <cd6cb999-6b97-413d-a971-8f9892aa18ef@z1g2000yqn.googlegroups.com>
On Feb 23, 12:26 am, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Hmm, I am not sure what you mean. Under destructuring I understand:
> user> (let [[char1 char2 & rest-chars] "abcdefg"]
>          (println char1 char2 rest-chars))
> a b (c d e f g)
It seems, that my memory have failed me, but I remember from the movie
"Clojure for Lisp Programmers" the mention of such idiosyncrasy
imposed on Clojure by the underlying Java system. Maybe it's not about
strings... All I had to say is, that if you compare the abstraction
possibilities of CL and Clojure in this regard they are the same in
theory, but are limited by some legacy inconsistencies, which in case
of Clojure are JVM problems and in case of CL -- it's own.

> Btw, the destructuring in Clojure is also a very nice feature that I
> completely missed to mention.
> One can destructure also lists, vectors and hashmaps and basically all
> data structures that Clojure offers.
Destructuring works great in CL as well. You can check Paul Graham's
dbind to see the more general implementation, than destructuring-bind.

> One example that illustrates a way to extend a Clojure data type can
> be found here:http://kotka.de/projects/clojure/lazy-map.html
>
> It took the clojure hashmap and made it lazy.
> The values will be evaluated only on their first read.
So there's some OOP in Clojure after all ;)
And it is quite heavily bound to Java, which is no surprise.

> About Semaphores:
> user> (import '(java.util.concurrent Semaphore))
> nil
> user> (def s (Semaphore. 3))
> #'user/s
> user> s
> #<Semaphore ······························@992fa5[Permits = 3]>
>
> user> (dotimes [i 3] (.acquire s))
> nil
> user> s
> #<Semaphore ······························@992fa5[Permits = 0]>
> user> (.acquire s)
Not sure, that this can be called "not go down to the Java level",
but, maybe, in the context of Clojure it's acceptable.

But OK, let's consider it enough proof, that Clojure doesn't limit the
programmer. I'll rephrase: Clojure doesn't provide anything, that's
not considered important by its creator (I don't discover Americas
here, I know. It's the usual BDFL model. And, paraphrasing Kenny,
people want BDFL for programming languages). For that there's Java. I
think, that only practice can show, if Clojure's approach is viable
towards the goal of good support for rapid prototyping. And I don't
have enough experience with Clojure to tell.

> Right. And as long as (connect-with-my-brain-and-do-it) something is
> seriously wrong with the language I am using.
> But from what is available today Clojure is my definite number 1.
We are talking about theory here, so no limits to imagination... :)

Cheers,
Vsevolod
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnsp8n$v8q$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 23, 12:26 am, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
>> Hmm, I am not sure what you mean. Under destructuring I understand:
>> user> (let [[char1 char2 & rest-chars] "abcdefg"]
>>          (println char1 char2 rest-chars))
>> a b (c d e f g)
> It seems, that my memory have failed me, but I remember from the movie
> "Clojure for Lisp Programmers" the mention of such idiosyncrasy
> imposed on Clojure by the underlying Java system. Maybe it's not about
> strings... All I had to say is, that if you compare the abstraction
> possibilities of CL and Clojure in this regard they are the same in
> theory, but are limited by some legacy inconsistencies, which in case
> of Clojure are JVM problems and in case of CL -- it's own.

There may be issues with Strings, I am just not aware of them right now.


>> Btw, the destructuring in Clojure is also a very nice feature that I
>> completely missed to mention.
>> One can destructure also lists, vectors and hashmaps and basically all
>> data structures that Clojure offers.
> Destructuring works great in CL as well. You can check Paul Graham's
> dbind to see the more general implementation, than destructuring-bind.

I have not seen code using it. Such a basic macro would be useful if 95%
or more of all users would use it. Even beginner texts about Clojure
will soon begin to talk about the integrated destructuring.
Maybe it is the case that basically everyone uses it. It�s just my
personal experience that this isn�t the case.


>> One example that illustrates a way to extend a Clojure data type can
>> be found here:http://kotka.de/projects/clojure/lazy-map.html
>>
>> It took the clojure hashmap and made it lazy.
>> The values will be evaluated only on their first read.
> So there's some OOP in Clojure after all ;)
> And it is quite heavily bound to Java, which is no surprise.

If one wants to extend the clojure data types in a usable way, then
one needs to use the machinery of the JVM.
Though no Java was needed here.


>> About Semaphores:
>> user> (import '(java.util.concurrent Semaphore))
>> nil
>> user> (def s (Semaphore. 3))
>> #'user/s
>> user> s
>> #<Semaphore ······························@992fa5[Permits = 3]>
>>
>> user> (dotimes [i 3] (.acquire s))
>> nil
>> user> s
>> #<Semaphore ······························@992fa5[Permits = 0]>
>> user> (.acquire s)
> Not sure, that this can be called "not go down to the Java level",
> but, maybe, in the context of Clojure it's acceptable.

I think it is acceptable. Java is a language that offers no data types.
They are all those of the JVM.
Clojure can call them directly, without any need to go down to the
Java level (= writing Java code).
When you say (length '(1 2 3)) in clisp, then you also don�t go down
to the C level.
It�s just that in Clojure the methods you want to call begin with a dot.


> But OK, let's consider it enough proof, that Clojure doesn't limit the
> programmer. I'll rephrase: Clojure doesn't provide anything, that's
> not considered important by its creator (I don't discover Americas
> here, I know. It's the usual BDFL model. And, paraphrasing Kenny,
> people want BDFL for programming languages). For that there's Java. I
> think, that only practice can show, if Clojure's approach is viable
> towards the goal of good support for rapid prototyping. And I don't
> have enough experience with Clojure to tell.

I agree with that. I have a good feeling in that issue, but my practical
experience with Clojure has no meaning, as it is not representative.
We need to see what happens after some millions LOC have been written in
Clojure, and how these apps will perform.

Btw, another thing that I missed to mention what I like better in
Clojure and what CL does not offer are the Clojure multimethods.
They are more general. The multimethods in CL dispatch on type.
The ones in Clojure dispatch on anything that you want. For example if
we want to dispatch on the count of a collection, then:

user> (defmulti foo count)
#'user/foo
user> (defmethod foo 3 [x] (println x "contains 3 things"))
#<MultiFn ····················@1ef45e0>
user> (defmethod foo 10 [_] (println "A collection of 10 elements."))
#<MultiFn ····················@1ef45e0>
user> (foo "yes")
yes contains 3 things
nil
user> (foo (range 10))
A collection of 10 elements.
nil
user>


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <b94e3461-da99-4673-adbd-d0786d281ee0@w34g2000yqm.googlegroups.com>
On Feb 23, 2:05 am, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Btw, another thing that I missed to mention what I like better in
> Clojure and what CL does not offer are the Clojure multimethods.
> They are more general. The multimethods in CL dispatch on type.
> The ones in Clojure dispatch on anything that you want. For example if
> we want to dispatch on the count of a collection, then:
>
> user> (defmulti foo count)
> #'user/foo
> user> (defmethod foo 3 [x] (println x "contains 3 things"))
> #<MultiFn ····················@1ef45e0>
> user> (defmethod foo 10 [_] (println "A collection of 10 elements."))
> #<MultiFn ····················@1ef45e0>
> user> (foo "yes")
> yes contains 3 things
> nil
> user> (foo (range 10))
> A collection of 10 elements.
> nil
> user>

Even without going down to the MOP level, the same behavior can be
implemented with user-defined method combination in CLOS.
Just for illustration purposes (not production-ready code):

CL-USER> (define-method-combination multi (dispatch-fn)
           ((all *))
           (:arguments &whole args)
           `(or ,@(mapcar (lambda (method)
                            `(when (find (apply ,dispatch-fn ,args)
(method-qualifiers ,method))
                               (call-method ,method)))
                          all)))
; in: LAMBDA NIL
;     'INVALID-METHOD-ERROR
;
; note: deleting unreachable code
;
; compilation unit finished
;   printed 1 note
MULTI
CL-USER> (defmacro defmulti (fun-name dispatch-fn lambda-list)
           `(defgeneric ,fun-name ,lambda-list
              (:method-combination multi ,dispatch-fn)))
DEFMULTI
CL-USER> (defmulti foo #'length (collection))
#<STANDARD-GENERIC-FUNCTION FOO (0)>
CL-USER> (defmethod foo 3 (x) (format t "~a contains 3 things" x))
#<STANDARD-METHOD FOO 3 (T) {B6238A9}>
CL-USER> (defmethod foo 10 (_) (format t "A collection of 10 elements.~
%"))
#<STANDARD-METHOD FOO 10 (T) {B03CBC9}>
CL-USER> (foo "yes")
yes contains 3 things
NIL
CL-USER> (foo (range 10))
A collection of 10 elements.
NIL

Best regards,
Vsevolod
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <24955490-1d3a-4191-a16e-11613d1313b0@e18g2000vbe.googlegroups.com>
And to sum up: support for concurrency-oriented programming in Common
Lisp (http://marijn.haverbeke.nl/pcall/background.html):
* Bordeux-threads: portable low-level concurrency primitives
* some non-portable low-level solutions (like sb-ext:compare-and-swap)
* CL-MUPROC: Erlang style Actor-model implementation
* CL-STM: A generic STM
* PCall: an implementation of a 'live datastructures' approach
* FSet: functional collections
Anything else, not mentioned here?

Vsevolod
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <3b877b46-0713-4062-8f51-ea8b00bf5302@x38g2000yqj.googlegroups.com>
On Feb 23, 6:22 am, Vsevolod <········@gmail.com> wrote:
> And to sum up: support for concurrency-oriented programming in Common
> Lisp (http://marijn.haverbeke.nl/pcall/background.html):
> * Bordeux-threads: portable low-level concurrency primitives

It's "Bordeaux threads" (in case anyone goes looking for it).

> * CL-STM: A generic STM

Oh cool -- I didn't realize anyone had done this.

-- Scott
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70fqjpF4e76jU1@mid.individual.net>
Vsevolod wrote:
> And to sum up: support for concurrency-oriented programming in Common
> Lisp (http://marijn.haverbeke.nl/pcall/background.html):
> * Bordeux-threads: portable low-level concurrency primitives
> * some non-portable low-level solutions (like sb-ext:compare-and-swap)
> * CL-MUPROC: Erlang style Actor-model implementation
> * CL-STM: A generic STM
> * PCall: an implementation of a 'live datastructures' approach
> * FSet: functional collections
> Anything else, not mentioned here?

* The portable-threads part of GBBopen.

* A simulator for *Lisp at 
http://examples.franz.com/category/Application/ParallelProgramming/index.html 
  - (would be interesting to port it to a multicore architecture - I can 
provide some assistance if somebody is seriously interested...).

* If I understand correctly, there will be an announcement for CL-MPI at 
ILC'09.

* A parallelism library for ACL2 at 
http://www.cs.utexas.edu/~ragerdl/parallelism/

There's maybe even more...


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnub1j$j9v$1@news.motzarella.org>
Vsevolod schrieb:
> On Feb 23, 2:05 am, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
>> Btw, another thing that I missed to mention what I like better in
>> Clojure and what CL does not offer are the Clojure multimethods.
>> They are more general. The multimethods in CL dispatch on type.
>> The ones in Clojure dispatch on anything that you want. For example if
>> we want to dispatch on the count of a collection, then:
>>
>> user> (defmulti foo count)
>> #'user/foo
>> user> (defmethod foo 3 [x] (println x "contains 3 things"))
>> #<MultiFn ····················@1ef45e0>
>> user> (defmethod foo 10 [_] (println "A collection of 10 elements."))
>> #<MultiFn ····················@1ef45e0>
>> user> (foo "yes")
>> yes contains 3 things
>> nil
>> user> (foo (range 10))
>> A collection of 10 elements.
>> nil
>> user>
> 
> Even without going down to the MOP level, the same behavior can be
> implemented with user-defined method combination in CLOS.
> Just for illustration purposes (not production-ready code):

But of course you can solve that problem in CL. That is not the point.
I never doubted this. A user of Blub would have answered similar.
That�s what Graham explained. Whatever you throw at a C# coder, he will
find some way to solve it. Admittedly, it is not extremly complex to
get that behaviour in CL. But more complex than in Clojure.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Vsevolod
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <9b72f60f-1327-4090-b437-cb77c517383c@v39g2000yqm.googlegroups.com>
On Feb 23, 4:15 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> But of course you can solve that problem in CL. That is not the point.
> I never doubted this. A user of Blub would have answered similar.
> That’s what Graham explained. Whatever you throw at a C# coder, he will
> find some way to solve it. Admittedly, it is not extremly complex to
> get that behaviour in CL. But more complex than in Clojure.
And how easy it is to get before/after/around methods in Clojure? ;)
From: André Thieme
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnv2bg$i89$1@reader.motzarella.org>
Vsevolod schrieb:
> On Feb 23, 4:15 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:

> And how easy it is to get before/after/around methods in Clojure? ;)

That should be an untypical thing to do in a functional programming
language. A before/after method only adds side effects, and btw, I
don�t really like them, and tried to avoid them where ever possible.
In one of my CL jobs we were doing pretty much oop, and it was easy
to not know of the existance of an after method.

For simple cases it can often be enough to do some function combination.
(defn foos [x] (+ x 10))
(defn bar  [x] (println "Writing x to logfile") x)

(comp bar foos)


For other cases one may want to use a macro:
(defmacro beforize [function-name args & body]
   `(let [fn# @#'~function-name]
      (defn ~function-name ~args
        ·@body
        (apply fn# ~args))))


user> (defmulti hallo first)
#'user/hallo
user> (defmethod hallo 5 [x] (println "The 5 is good:" x))
#<MultiFn ····················@b92956>
user> (defmethod hallo \7 [x] (count x))
#<MultiFn ····················@b92956>
user> (hallo [5 4 3])
The 5 is good: [5 4 3]
nil
user> (hallo "7 is also good")
14
user> (beforize hallo [x] (println "Writting to log:" x))
#'user/hallo
user> (hallo [5 4 3])
Writting to log: [5 4 3]
The 5 is good: [5 4 3]
nil
user> (hallo "7 is also good")
Writting to log: 7 is also good
14
user> (beforize hallo [x] (println "Adding another one."))
#'user/hallo
user> (hallo "7 is also good")
Adding another one.
Writting to log: 7 is also good
14


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: budden
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <cbf864d6-512f-40ad-aed7-9f9a793cdd74@k19g2000yqg.googlegroups.com>
Hi!
 Am I right that "with-local-vars" does allow for mutable lexically-
scoped variables?
Well, I'd better take a punisment, but I don't want to be FP-clear:

user=> (with-local-vars [a 1] (var-set a 2) (var-get a))
2

But this sadomasochism amuses me really :)
I think var-set and var-get are too short names and punishment it too
light :)

It would better be:

var-get-punished-now-for-your-damned-mutable-variable-your-heretic

and

var-set-punishment-now-for-your-damned-mutable-variable-your-heretic
From: William James
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <gnvd6n0eid@enews2.newsguy.com>
budden wrote:

>  Am I right that "with-local-vars" does allow for mutable lexically-
> scoped variables?
> Well, I'd better take a punisment, but I don't want to be FP-clear:
> 
> user=> (with-local-vars [a 1] (var-set a 2) (var-get a))
> 2

user=> (with-local-vars [a 1] (var-set a 2) @a)
2

In Forth, @ is pronounced "fetch".
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70fpliF4beqbU1@mid.individual.net>
Andr� Thieme wrote:
> Vsevolod schrieb:
>> On Feb 23, 2:05 am, Andr� Thieme <address.good.until.
>> ···········@justmail.de> wrote:
>>> Btw, another thing that I missed to mention what I like better in
>>> Clojure and what CL does not offer are the Clojure multimethods.
>>> They are more general. The multimethods in CL dispatch on type.
>>> The ones in Clojure dispatch on anything that you want. For example if
>>> we want to dispatch on the count of a collection, then:
>>>
>>> user> (defmulti foo count)
>>> #'user/foo
>>> user> (defmethod foo 3 [x] (println x "contains 3 things"))
>>> #<MultiFn ····················@1ef45e0>
>>> user> (defmethod foo 10 [_] (println "A collection of 10 elements."))
>>> #<MultiFn ····················@1ef45e0>
>>> user> (foo "yes")
>>> yes contains 3 things
>>> nil
>>> user> (foo (range 10))
>>> A collection of 10 elements.
>>> nil
>>> user>
>>
>> Even without going down to the MOP level, the same behavior can be
>> implemented with user-defined method combination in CLOS.
>> Just for illustration purposes (not production-ready code):
> 
> But of course you can solve that problem in CL. That is not the point.
> I never doubted this. A user of Blub would have answered similar.
> That�s what Graham explained. Whatever you throw at a C# coder, he will
> find some way to solve it.

That's a Turing-equivalence argument. I'm pretty sure that's not what 
Vsevolod had in mind.

> Admittedly, it is not extremly complex to
> get that behaviour in CL.

Exactly.

> But more complex than in Clojure.

Because it's built-in in Clojure.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70fjmuF41q9jU2@mid.individual.net>
Andr� Thieme wrote:

> Btw, another thing that I missed to mention what I like better in
> Clojure and what CL does not offer are the Clojure multimethods.
> They are more general. The multimethods in CL dispatch on type.
> The ones in Clojure dispatch on anything that you want. For example if
> we want to dispatch on the count of a collection, then:
> 
> user> (defmulti foo count)
> #'user/foo
> user> (defmethod foo 3 [x] (println x "contains 3 things"))
> #<MultiFn ····················@1ef45e0>
> user> (defmethod foo 10 [_] (println "A collection of 10 elements."))
> #<MultiFn ····················@1ef45e0>
> user> (foo "yes")
> yes contains 3 things
> nil
> user> (foo (range 10))
> A collection of 10 elements.
> nil
> user>

See http://p-cos.net/documents/filtered-dispatch.pdf



Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Matthew D Swank
Subject: Filtered Dispatch, was Re: Road to Clojure Survey
Date: 
Message-ID: <T_Fol.16025$i42.8134@newsfe17.iad>
On Mon, 23 Feb 2009 13:38:54 +0100, Pascal Costanza wrote:

> See http://p-cos.net/documents/filtered-dispatch.pdf

Is there a publicly available implementation of this. Though not quite 
the same approach, I briefly tried to implement a custom method 
specializer using the MOP, and found it quite painful: though I think 
there are extensions to sbcl's MOP to make this less painful.  I thought 
the paper describing this ended up being a CDR, but I can't seem to find 
it there.

Matt

-- 
Your present plans will be successful.
From: Pascal Costanza
Subject: Re: Filtered Dispatch, was Re: Road to Clojure Survey
Date: 
Message-ID: <70i535F81qifU1@mid.individual.net>
Matthew D Swank wrote:
> On Mon, 23 Feb 2009 13:38:54 +0100, Pascal Costanza wrote:
> 
>> See http://p-cos.net/documents/filtered-dispatch.pdf
> 
> Is there a publicly available implementation of this.

Not yet. I need some time to clean up the code before releasing it. I 
have this on my todo list already for a while. :(

> Though not quite 
> the same approach, I briefly tried to implement a custom method 
> specializer using the MOP, and found it quite painful: though I think 
> there are extensions to sbcl's MOP to make this less painful.

A central problem is make-method-lambda, which is not widely supported 
and is, IMHO, a bad idea.

See http://p-cos.net/documents/make-method-lambda.pdf

> I thought 
> the paper describing this ended up being a CDR, but I can't seem to find 
> it there.

Not sure which paper you are referring to. You probably mean a paper by 
Christophe Rhodes...


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <70e2rlF1n667U3@mid.individual.net>
Andr� Thieme wrote:

>>> Can one use the MOP also to make defclass accepting LIST as the
>>> superclass?
>> No. But that doesn't stop you to create an clist wrapper class (note
>> the Clojure naming convention here ;) and subclass from it. Can you
>> have a string as a superclass in Java? In Clojure, that allows the use
>> of OOP?
> 
> I am not a Java guy, but I think Strings are final and one can not
> inherit from them.

You can also not inherit from int, char, boolean, etc.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Kenneth Tilton
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <49a1637b$0$20293$607ed4bc@cv.net>
Jan Rychter wrote:
> I have been reading this thread with amusement. Shouldn't we CL
> programmers know better? 
> 
> This group has seen so many discussions about how Common Lisp doesn't
> provide anything that can't be implemented in {Java, Python, Ruby, C++,
> whatever}. People here responded saying that Turing-equivalence isn't
> everything and that it does make a difference whether the language is
> expressive or not.
> 
> So here comes Clojure. A clean redesign of a Lisp language, throwing
> away old religious dogmas and providing a clean slate. Expressive, with
> fresh ideas, all on top of a popular platform with thousands of
> libraries we can make use of. And what do we do?
> 
> We shout about how it's really nothing new because look you can do the
> same things with Common Lisp only you have to implement these macros and
> shadow those symbols and load in that order and follow these
> conventions, and avoid doing this, and always do that, see, it's all
> right there...
> 
> Have we become Blub programmers? [1]
> 
> We should at least keep an open mind. There are and will be better
> languages than Common Lisp. Instead of digging trenches and shutting our
> eyes we should be on the lookout for new ideas. And when they come, we
> don't have to all switch religions. Let's just treat the newcomers with
> respect.
> 
> Seriously, we should know better.

Sorry to undercut your entire premise, but I have not noticed any 
anti-Clojure sentiment at all!

There was a minor scuffle over an obscure distinction, but what would 
Usenet be without those?

Anyway, here is my next shill, which I will put in the form of a dry 
technical question: what's the big deal with functional sets? 
Performance? Programmer productivity? Other_______________?

kt
From: Scott Burson
Subject: Re: Road to Clojure Survey
Date: 
Message-ID: <dea6aaf6-98b7-41f3-a9da-e46b0b7b68d1@l39g2000yqn.googlegroups.com>
On Feb 22, 6:38 am, Kenneth Tilton <·········@gmail.com> wrote:
> Anyway, here is my next shill, which I will put in the form of a dry
> technical question: what's the big deal with functional sets?
> Performance? Programmer productivity? Other_______________?

I already wrote an essay on this:

  http://common-lisp.net/project/fset/Site/index.html

-- Scott