Re: Why is MVCC history managed manually?

2010-05-26 Thread Peter
Hi Rich,

maybe this is a better way of looking at it.

When you create a transaction, you get a new UnitOfTime object that
has the sequential timestamp in it. The Transaction object keeps a
reference to the UnitOfTime object for the rest of the Transaction
objects life.

private static final AtomicReference timeLineHead =

new AtomicReference(new UnitOfTime(0));

public static UnitOfTime getNewUnitOfTime() {

UnitOfTime current = timeLineHead.get();

final UnitOfTime future = new UnitOfTime(current.time + 1);

while (!timeLineHead.compareAndSet(current, future)) {

current = timeLineHead.get();

future.time = current.time + 1;

}

current.future = future;

return future;

}

UnitOfTime objects are kept in a singly linked list to make a time
line. The sole purpose of this list is to guarantee garbage collection
order. The first UnitOfTime object created will also be the first one
GC'd. Now we have a guaranteed order objects will be GC'd - great for
a Ref history list.

The UnitOfTime object also has a set of objects you want it to keep
alive. This set is only written to, never read. It exists only to tell
the GC what you don't want GC'd too early. (It probably doesn't have
to be concurrent.)

public class UnitOfTime {

public UnitOfTime future;

public long time;

private final ConcurrentLinkedQueue keepAliveSet = new
ConcurrentLinkedQueue();

public void keepAlive(Object obj) { keepAliveSet.add(obj); }

public UnitOfTime(long time) { this.time = time; }

}

So we now have Transaction objects referencing the UnitOfTime they
were created. This holds that UnitOfTime object in memory (and
consequently all later UnitOfTime objects) until the Transaction
object has been forgotten and GC'd.

I think you are using the using the latest time in your commits, so
your commit would getNewUnitOfTime(). So when you update your Refs
with new Values, you put the old value on the Ref's history list, you
also use the commit's UnitOfTime object and do
commitUnitOfTime.keepAlive(prevValue). This then guarantees the value
your replaced on the Ref will live up to the commit's UnitOfTime. Any
transaction starting before the commit is now guaranteed to be able to
find that old Value as the commitUnitOfTime will not GC until alll
previous UnitOfTime objects have GC'd. Which means all previous
Transaction objects have been GC'd.

You will need to keep a history list in Ref, but that history list
used WeakReference instead of a strong reference.

I hope this is a clearer explaination.

-Peter

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


Re: weird repl + classloader behavior

2010-05-26 Thread Erik Söhnel


On 25 Mai, 08:03, Brent Millare  wrote:
> Erik, what you said seems to make sense. So the question now is, since
> a new classloader is started during each eval at the repl, does that
> mean that it is closed after each repl statement? This seems to be the
> case because after requiring a namespace in a previous command at the
> repl, I can no longer reload that namespace with (require
> 'foo :reload). However, because I am holding on to that namespace (as
> I can access anything in that namespace I required), I feel that it
> isn't completely unloaded. The natural follow up question would be,
> does unloading the namespace required earlier then unload the
> classloader? And, how does one test this? How does one obtain the
> hierarchy of classloaders given you don't have references to the
> children.

Don't know for sure, I think the ClassLoader and all classes loaded
with it will be GC'ed if there are no more references to the old
classes and the loader itself. Is there even a way to "close" a
classloader? What do you mean by "can not longer reload that
namespace"?
To inspect objects of a running jvm, you can either use a debugger, or
patch the clojure.lang.DynamicClassLoader code so that it puts
reference into a static Var on each ctor call or such.
The java debug interface alsow allows you to get a list of all classes/
objects currently available in the running vm, see
http://java.sun.com/javase/6/docs/jdk/api/jpda/jdi/index.html
BTW, are you aware that clojure haa aa "add-classpath" (marked as
deprecated) function, wich will be removed in future versions, due to
the problems it introduced wich java-dependencies?

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


Question on bound-fn source

2010-05-26 Thread YD
(defmacro bound-fn
  [& fntail]
  `(bound-fn* (fn ~...@fntail)))

Shouldn't it be: (fn [] ~...@fntail) ?

If you try to use this function by passing more than one function as
arguments to it, you'll get an exception. e.g. (bound-fn f1 f2)

I'm a newbie to clojure and I'm not quite sure if this is a bug.

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


Stockholm Clojure User Group

2010-05-26 Thread Patrik Fredriksson
Hi!

There is now a Clojure user group in Stockholm, Sweden (via
http://twitter.com/peter_hultgren/status/14648902541).

Join us at http://groups.google.com/group/stockholm-clojure-user-group

/Patrik

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


Re: Question on bound-fn source

2010-05-26 Thread Meikel Brandmeyer
Hi,

On May 26, 12:41 pm, YD  wrote:

> (defmacro bound-fn
>   [& fntail]
>   `(bound-fn* (fn ~...@fntail)))
>
> Shouldn't it be: (fn [] ~...@fntail) ?
>
> If you try to use this function by passing more than one function as
> arguments to it, you'll get an exception. e.g. (bound-fn f1 f2)
>
> I'm a newbie to clojure and I'm not quite sure if this is a bug.

It's not a bug. The idea of bound-fn is to *define* a bound
function. So instead of saying (fn [a b c] (do-things)) you
say (bound-fn [a b c] (do-things)).

If you already have a function, which you want to turn into
a bound function use bound-fn*: (bound-fn* f1) (bound-fn* f2).

Sincerely
Meikel

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


Re: Why is MVCC history managed manually?

2010-05-26 Thread Rich Hickey


On May 25, 11:29 am, Peter  wrote:
> Hi Rich,
>
> If you set up your object dependencies correctly then the objects you
> want will stay in memory. Your history list would be a list of
> WeakReference so it could be GC'd.
>
> This is nothing about read tracking, more about setting the correct
> object dependencies so that the GC doesn't remove objects you aren't
> quite finished with yet.
>
> I been writing up a description here. It's a simplified version of
> what I've been playing 
> with.http://creativereality.com.au/notes/concurrency/54-mvcc-stm-gcd-ref-h...
>
> I kept the Transaction objects on the list, but you could consider
> keeping a smaller object with just has a collection in it; associated
> with the transaction.
>
>

I took a look at your notes. I have a few problems with it:

First, and foremost, it creates interaction relationships between
transactions that otherwise have no overlap. You see this in the
memory blowup during overlapping transactions. This rubs against a
design objective in Clojure's STM to absolutely minimize transactional
overlap and interaction.

Second, you do a lot of work in createNewTransaction (get a new
timestamp, modify existing head, make new transaction the head). How
is that made consistent? You really need a lock, and at that point
have moved to a much heavier contention point than in the current
Clojure STM.

Third, I'm wary of such extensive use of WeakReferences. That may just
be conservatism on my part.

I had considered and implemented similar designs in the early stages
of developing Clojure's STM, and, while they have some appeal, I think
these 3 points will eventually cause pain in practice.

Rich

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


Macro expand time

2010-05-26 Thread Quzanti
Hi,

As a newbie to lisp/clojure one thing I am having real trouble with is
understanding macro expand time (now having discovered the difference
between quote and backquote I was hoping I was on the way to nirvana
but still trip up)

Some newbie questions:

If the macro is run at compile time how can it call functions - or can
it only call functions that you can guarantee will already have been
compiled - so if you have macros calling functions in each other's
namespaces would the compiler have to compile part of one namespace
file, then part of the other, then back to the first?

If there is any error in your file below the macro, will the macro
have been expanded before the compiler discovers this? Or is there a
first pass for syntax before the main compile time. So what exactly is
compile time?

Is there a newbie friendly reference to all this?


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


Re: Macro expand time

2010-05-26 Thread Laurent PETIT
Hi,

2010/5/26 Quzanti 

> Hi,
>
> As a newbie to lisp/clojure one thing I am having real trouble with is
> understanding macro expand time (now having discovered the difference
> between quote and backquote I was hoping I was on the way to nirvana
> but still trip up)
>
> Some newbie questions:
>
> If the macro is run at compile time how can it call functions - or can
> it only call functions that you can guarantee will already have been
> compiled


Yes.


> - so if you have macros calling functions in each other's
> namespaces would the compiler have to compile part of one namespace
> file, then part of the other, then back to the first?
>

No, the compiler will not even be as smart as you describe. It's the (:use)
(:require) (:load) declarations which will have taken place before the macro
is invoked (generally inside an (ns) declaration) that would have made the
required other functions / macros available.


> If there is any error in your file below the macro, will the macro
> have been expanded before the compiler discovers this? Or is there a
> first pass for syntax before the main compile time. So what exactly is
> compile time?
>

The compiler will take each "top level form" one after the other :
  * read one form from the "input stream" (it will then get the famous
"code-as-data"),
  * evaluate it: if the "code-as-data" starts with a list, we face a
function call, so first resolve the function; if it is a real function, then
first evaluate its arguments then pass them to the function; if it is a
macro, then pass the arguments non-evaluated to the macro definition and
substitute the whole macro call with the "code-as-data" returned by the
macro ; if it is a special form, then execute the special form behaviour
('def has a side effect of creating a new var in the current namespace, 'fn
has a side effect of compiling in memory (and on disk if *compile* is true)
the function it defines, etc.

This is certainly not accurate, but hopefully it gives you an overall view
of the mechanisms.

So the "first pass" is  getting just enough information for evaluating the
next "form" in the stream.

HTH,

-- 
Laurent

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

Re: Macro expand time

2010-05-26 Thread Quzanti
Thanks Laurent.

It does give me an overall view, but more importantly it gives me the
impression that there are some subtleties, so I am not feeling so bad
about the fact some of the behaviour hasn't been what I had predicted.

On May 26, 1:55 pm, Laurent PETIT  wrote:
> Hi,
>
> 2010/5/26 Quzanti 
>
> > Hi,
>
> > As a newbie to lisp/clojure one thing I am having real trouble with is
> > understanding macro expand time (now having discovered the difference
> > between quote and backquote I was hoping I was on the way to nirvana
> > but still trip up)
>
> > Some newbie questions:
>
> > If the macro is run at compile time how can it call functions - or can
> > it only call functions that you can guarantee will already have been
> > compiled
>
> Yes.
>
> > - so if you have macros calling functions in each other's
> > namespaces would the compiler have to compile part of one namespace
> > file, then part of the other, then back to the first?
>
> No, the compiler will not even be as smart as you describe. It's the (:use)
> (:require) (:load) declarations which will have taken place before the macro
> is invoked (generally inside an (ns) declaration) that would have made the
> required other functions / macros available.
>
> > If there is any error in your file below the macro, will the macro
> > have been expanded before the compiler discovers this? Or is there a
> > first pass for syntax before the main compile time. So what exactly is
> > compile time?
>
> The compiler will take each "top level form" one after the other :
>   * read one form from the "input stream" (it will then get the famous
> "code-as-data"),
>   * evaluate it: if the "code-as-data" starts with a list, we face a
> function call, so first resolve the function; if it is a real function, then
> first evaluate its arguments then pass them to the function; if it is a
> macro, then pass the arguments non-evaluated to the macro definition and
> substitute the whole macro call with the "code-as-data" returned by the
> macro ; if it is a special form, then execute the special form behaviour
> ('def has a side effect of creating a new var in the current namespace, 'fn
> has a side effect of compiling in memory (and on disk if *compile* is true)
> the function it defines, etc.
>
> This is certainly not accurate, but hopefully it gives you an overall view
> of the mechanisms.
>
> So the "first pass" is  getting just enough information for evaluating the
> next "form" in the stream.
>
> HTH,
>
> --
> Laurent

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


Re: Anyone experienced in using clojure as a "database"

2010-05-26 Thread Andrzej
I'd love to see a persistent "table" type together with some common
primitives (select, join, union) and optimization capabilities.
Currently a "set of maps" does something like that but I have no idea
how to, for example, add an "index" to some particular field and use
it in other operations.

Another thing is tying such a database to some on-disk storage. Is
there any database backend that doesn't internally mutate data? Even
if not, such a data type could still be useful as a read-only view for
other databases.

Andrzej

On Wed, May 26, 2010 at 3:36 AM, Sean Devlin  wrote:
> You might want to look at FleetDB
>
> http://fleetdb.org/
> http://github.com/mmcgrana/fleetdb
>
> On May 25, 2:08 pm, Fabio Kaminski  wrote:
>> Folks,
>>
>> i would like advice,
>> cause since im starting something that will be eventually big data
>> intensive, from scratch
>> and i really like the options already built in in clojure like STM,
>> parallelizing data and concurrency logic implemented on it
>> i think its wonderfully tuned to use as database... and you can achieve
>> different strategies, like graphs or balanced trees for different data
>>
>> my worries are about the efficiency in serializing it and recovering from/to
>> the disk,
>> java VM as a hungry heap VM,
>> (and with immutable strategies, more heap needed)
>>
>> the benefits are control of sharding mechanism's and parallelizing not only
>> in the unit's cores but between nodes of a cluster..
>>
>> anyone using clojure  not just as database middleware(wich is perfect for)
>> but as database backend too?
>>
>> Thanks all,
>>
>> Fabio Kaminski
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with your 
>> first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group 
>> athttp://groups.google.com/group/clojure?hl=en
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


Re: weird repl + classloader behavior

2010-05-26 Thread Brent Millare
Hi Erik,

>From what I understand, to close a classloader, you would need to also
remove all references to it or set the references to it to nil/null.
In the case of an eval in the repl, again I'm assuming we do lose that
reference once we are out of the scope of the eval.

While I said not reloading a namespace, I really meant not being able
to reload a file that was on the new path added by the new
classloader. So for example, if I added a swank-clojure.jar to the
classpath, and I did a (require 'swank.core), then I went out of scope
of the eval, did a (require 'swank.core :reload), I would get an error
saying it doesn't exist.

That JDI seems incredibly powerful, thanks for the tip.

I was aware of add-classpath but I saw that it was deprecated, and I
wanted to overcome its limitations. Unloading the classloader is an
example of something not possible with add-classpath.

On May 26, 4:31 am, Erik Söhnel  wrote:
> On 25 Mai, 08:03, Brent Millare  wrote:
>
> > Erik, what you said seems to make sense. So the question now is, since
> > a new classloader is started during each eval at the repl, does that
> > mean that it is closed after each repl statement? This seems to be the
> > case because after requiring a namespace in a previous command at the
> > repl, I can no longer reload that namespace with (require
> > 'foo :reload). However, because I am holding on to that namespace (as
> > I can access anything in that namespace I required), I feel that it
> > isn't completely unloaded. The natural follow up question would be,
> > does unloading the namespace required earlier then unload the
> > classloader? And, how does one test this? How does one obtain the
> > hierarchy of classloaders given you don't have references to the
> > children.
>
> Don't know for sure, I think the ClassLoader and all classes loaded
> with it will be GC'ed if there are no more references to the old
> classes and the loader itself. Is there even a way to "close" a
> classloader? What do you mean by "can not longer reload that
> namespace"?
> To inspect objects of a running jvm, you can either use a debugger, or
> patch the clojure.lang.DynamicClassLoader code so that it puts
> reference into a static Var on each ctor call or such.
> The java debug interface alsow allows you to get a list of all classes/
> objects currently available in the running vm, 
> seehttp://java.sun.com/javase/6/docs/jdk/api/jpda/jdi/index.html
> BTW, are you aware that clojure haa aa "add-classpath" (marked as
> deprecated) function, wich will be removed in future versions, due to
> the problems it introduced wich java-dependencies?

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


promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Stuart Halloway
If you are a user of clojure.contrib.string, please take a look at the  
proposed promotion to clojure [1]. Feedback welcome! It is my hope  
that this promotion has enough "batteries included" that many libs can  
end their dependency on contrib for string functions.


Cheers,
Stu

[1] https://www.assembla.com/spaces/clojure/tickets/359-promote-contrib-string

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Sean Devlin
Stu,
What happened to *not* promoting string?

http://groups.google.com/group/clojure-dev/browse_thread/thread/e294cd444227

Also, is there an actual patch/diff to review?  I didn't see one in
Assembla.

Sean

On May 26, 11:16 am, Stuart Halloway 
wrote:
> If you are a user of clojure.contrib.string, please take a look at the  
> proposed promotion to clojure [1]. Feedback welcome! It is my hope  
> that this promotion has enough "batteries included" that many libs can  
> end their dependency on contrib for string functions.
>
> Cheers,
> Stu
>
> [1]https://www.assembla.com/spaces/clojure/tickets/359-promote-contrib-s...

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


non-monolithic contrib build, starting with matchure

2010-05-26 Thread Stuart Halloway
Based on the discussion of release granularity that started with the  
proposed move of matchure to contrib [1], we are going to start doing  
granular builds of Clojure. Matchure can be the first: It can be part  
of the full contrib build, but also released as a standalone library  
with its own version numbering.


Drew: If you want to modify the maven build to support this, I wont'  
stop you. :-) But you don't have to -- if you just want to add the  
source code and ping me, I will take care of implementing the build  
bits.


There is an issue for this in the Contrib Assembla [2]. Discussion/ 
suggestions/feedback welcome!


Thanks!
Stu

[1] 
http://groups.google.com/group/clojure/browse_thread/thread/58e32801489ef92f/d3f8b7c230e0330a
[2] 
https://www.assembla.com/spaces/clojure-contrib/tickets/85-build-and-release-sublibraries


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


Re: Question on bound-fn source

2010-05-26 Thread YD
Thank you, now I see the point.

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


Re: Why is MVCC history managed manually?

2010-05-26 Thread Peter
Hi Rich,

>
> First, and foremost, it creates interaction relationships between
> transactions that otherwise have no overlap. You see this in the
> memory blowup during overlapping transactions. This rubs against a
> design objective in Clojure's STM to absolutely minimize transactional
> overlap and interaction.

Fair enough.

>
> Second, you do a lot of work in createNewTransaction (get a new
> timestamp, modify existing head, make new transaction the head). How
> is that made consistent? You really need a lock, and at that point
> have moved to a much heavier contention point than in the current
> Clojure STM.

I don't think that's right. I can do most of it with CAS. I need to
the list pointer afterwards but only 1 thread ever sets it and it's
never read.
Well, it's been running tests an i7 without showing any issues so
far.

>
> Third, I'm wary of such extensive use of WeakReferences. That may just
> be conservatism on my part.

It's a fair point, you have to be careful with WeakReferences, they
have a habit of disappearing between uses.

>
> I had considered and implemented similar designs in the early stages
> of developing Clojure's STM, and, while they have some appeal, I think
> these 3 points will eventually cause pain in practice.

Thanks, I thought you would have considered it but wasn't sure why you
went the direction you did.

I think it just shows how lazy I am in not wanting to write the code
to manage the lists.

I appreciate your response.

Regards,
Peter

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Stuart Halloway

Stu,
What happened to *not* promoting string?


Changed our mind. It helps keep the people with prerelease books  
busy. ;-) Seriously: I did an audit of several third-party libraries,  
and concluded that for some libs, the presence of these string  
functions in core could be the make-or-break difference in needing to  
depend on contrib. Obviously a slippery-slope argument, but it seemed  
worth it.



http://groups.google.com/group/clojure-dev/browse_thread/thread/e294cd444227

Also, is there an actual patch/diff to review?  I didn't see one in
Assembla.


No -- taking time to get feedback. It will be a simple patch though.

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Mark Engelberg
Are these going to be in their own namespace (clojure.string), or in
core?  I hope the former, because many of these names (replace,
reverse, join, split) are too valuable to be dedicated only to
strings.

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Stuart Halloway

Definitely! It will be clojure.string. Ticket updated to reflect this.


Are these going to be in their own namespace (clojure.string), or in
core?  I hope the former, because many of these names (replace,
reverse, join, split) are too valuable to be dedicated only to
strings.

--  
You received this message because you are subscribed to the Google

Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient  
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Sean Devlin
Stu Halloway,
Changes like this are a nuisance as a documentation guy >:|  It makes
Beta seem further away, but it's a tough call and someone has to make
it.  Such is life on the edge.

As far as technical feedback goes, it seems like a VERY useful list to
promote to core.  There are a few things I'd tweak:

I'd like to see a specific proposal for replace & replace-first.
Stuart Sierra put a lot of effort into getting those fns the way they
are in contrib, and we should be careful to not undo any lessons
learned in the process.  Also, this may beg a few questions about new
seq fns existing in core, depending on the implementation.

You also mention making the string argument first in some of these
fns.  I believe Will Smith's catch phrase says it best:  "Aw hell
no".  String fns are like any other seq fn, and they need to be
partial'ed, comp'ed and chained appropriately.  I can't even begin to
count the number of point free string processing routines I have.

Overall, this is exciting.  We're getting close to making "String
Processing Kick Ass in Clojure".
Sean

On May 26, 11:46 am, Stuart Halloway 
wrote:
> > Stu,
> > What happened to *not* promoting string?
>
> Changed our mind. It helps keep the people with prerelease books  
> busy. ;-) Seriously: I did an audit of several third-party libraries,  
> and concluded that for some libs, the presence of these string  
> functions in core could be the make-or-break difference in needing to  
> depend on contrib. Obviously a slippery-slope argument, but it seemed  
> worth it.
>
> >http://groups.google.com/group/clojure-dev/browse_thread/thread/e294c...
>
> > Also, is there an actual patch/diff to review?  I didn't see one in
> > Assembla.
>
> No -- taking time to get feedback. It will be a simple patch though.

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Fogus
> Changed our mind. It helps keep the people with prerelease books  
> busy. ;-)

Oh great!  I'm going to have to cancel my appearance on "The View"
because of this.

I have mentioned my gripes in the IRC, but for public view I would
love better names for chomp and chop.  In isolation those names are
meaningless, so I suggest:

chomp => rtrim
(rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the
door open for trim and ltrim functions should the need arise.

chop => less
(less "foo") => "fo"
(less "foo" 2) => "f"

With less becoming

(defn ^String less
  "Cuts n characters from the end of a string returning the resulting
string.  If the
  number of cuts is greater than the string length, then nothing
happens.  When the
  number of cuts is not supplied, then the last character is dropped."
  ([^String s] (less s 1))
  ([^String s n]
 {:pre [(pos? n)]}
 (let [cuts (- (count s) n)]
   (if (neg? cuts)
 s
 (subs s 0 cuts)

(or http://paste.lisp.org/display/100521 if this is flubbed)

:f

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Peter Schuller
> chomp => rtrim
> (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the
> door open for trim and ltrim functions should the need arise.

I like this. And in general I often fine the entire trio useful, and
adopting the ltrim/trim/rtrim naming makes it nice and tidy.

While I recognize the perl (or whatever the original is) precedent
from chomp/chop, there is precedent for trim/left trim/right trim too.
What *would* one call trim/ltrim to make them consistent with chomp?

-- 
/ Peter Schuller

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Brian Carper
On May 26, 8:16 am, Stuart Halloway  wrote:
> If you are a user of clojure.contrib.string, please take a look at the  
> proposed promotion to clojure [1]. Feedback welcome! It is my hope  
> that this promotion has enough "batteries included" that many libs can  
> end their dependency on contrib for string functions.

Great to see these bumped into core.  But are we now going to have
clojure.string, and clojure.contrib.string, with half the string
functions in one and half in the other?  It's going to be confusing to
remember which namespace has which functions (since I often use
functions you aren't promoting here), and now I potentially have to
depend on two libs instead of just one.

split-lines (for example) is something I use constantly.  It's also
something just annoying/error-prone enough that I don't want to write
(split #"\r?\n" s) over and over.  I always trip over core's line-seq
because it takes a reader instead of a string as I'd expect.  It'd be
nice to see that one promoted, if split is being promoted too.

What's the point of promoting upper-case and lower-case?  I thought
Clojure generally avoided thin wrappers around Java methods.  I always
use the Java methods directly, personally.  The comments say it's for
mapping over a list of strings, but (map #(.toUpperCase %) xs) isn't
that much typing.  The only use I see for making these a Clojure
function is to improve error-handling.  (upper-case nil) gives an
unhelpful NPE.

--Brian

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Mike Meyer
On Wed, 26 May 2010 19:47:25 +0200
Peter Schuller  wrote:

> > chomp => rtrim
> > (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the
> > door open for trim and ltrim functions should the need arise.
> 
> I like this. And in general I often fine the entire trio useful, and
> adopting the ltrim/trim/rtrim naming makes it nice and tidy.
> 
> While I recognize the perl (or whatever the original is) precedent
> from chomp/chop, there is precedent for trim/left trim/right trim too.
> What *would* one call trim/ltrim to make them consistent with chomp?

Personally, I like the lstrip/strip/rstrip, but that's just because
I'm used to them.

 http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Peter Schuller
> Personally, I like the lstrip/strip/rstrip, but that's just because
> I'm used to them.

strip is fine too IMO; I'm neutral between *strip and *trim.

-- 
/ Peter Schuller

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Brian Carper
On May 26, 10:29 am, Fogus  wrote:
> I have mentioned my gripes in the IRC, but for public view I would
> love better names for chomp and chop.  In isolation those names are
> meaningless, so I suggest:

Almost every name in a programming language is meaningless in
isolation.  But we don't work in isolation.  Look at "slurp".  I had
to explain that one to a non-programmer colleague the other day.
"chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell-
scripting.

"rtrim" in isolation could mean trim newlines, or trim whitespace, or
trim some specified characters, or trim arbitrary characters.  "less"
is so generic it could mean almost anything.

But this is largely an aesthetic question and I'm not going to lose
sleep if we end up with a word other than "chomp".

--Brian

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Fogus
> "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell-
> scripting.

Believe me I can sympathize with this, but just because they are well-
known to some doesn't mean that they are good names.  On that note,
just because rtrim and less make sense to me... you know the
rest.  :-)

:f

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


question about agent implementation

2010-05-26 Thread Michael Harrison (goodmike)
I'm preparing a presentation about asynchronous concurrency in
Clojure, and I'm planning on talking a bit about how Clojure's
constructs make good, sensible use of Java's concurrency libraries. My
question is about clojure.lang.Agent. In the doRun method, I'm missing
what prevents a race condition in the updating of the agent's state
variable.

This code in doRun seems to be a classic read-and-write operation:

Object oldval = action.agent.state;
Object newval = action.fn.applyTo(
RT.cons(action.agent.state, action.args));
action.agent.setState(newval);

doRun is not synchronized. As far as I can tell, Executors don't
synchronize the execution of runnable objects. What am I missing?

BTW, I have to say, it's really fun to read the Java code in src/jvm/
clojure.

Cheers,
Michael

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Mark Engelberg
If you're developing a trio, like ltrim, trim, rtrim, wouldn't it be
better to call them triml, trim, trimr so that they show up next to
each other in the alphabetized documentation?

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Luc Préfontaine

On Wed, 2010-05-26 at 13:57 -0400, Mike Meyer wrote:

> On Wed, 26 May 2010 19:47:25 +0200
> Peter Schuller  wrote:
> 
> > > chomp => rtrim
> > > (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the
> > > door open for trim and ltrim functions should the need arise.
> > 
> > I like this. And in general I often fine the entire trio useful, and
> > adopting the ltrim/trim/rtrim naming makes it nice and tidy.
> > 
> > While I recognize the perl (or whatever the original is) precedent
> > from chomp/chop, there is precedent for trim/left trim/right trim too.
> > What *would* one call trim/ltrim to make them consistent with chomp?
> 
> Personally, I like the lstrip/strip/rstrip, but that's just because
> I'm used to them.

Why not lpluck, pluck and rpluck then ?
(in French, pluck => effeuiller and the name effeuilleuse is one of the
synonyms for stripteaser :)))

ltrim & co.intents are a bit more precise


Luc :)))

>  -- 
> Mike Meyerhttp://www.mired.org/consulting.html
> Independent Network/Unix/Perforce consultant, email for more information.
> 
> O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
> 

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

Re: question about agent implementation

2010-05-26 Thread Peter Schuller
> question is about clojure.lang.Agent. In the doRun method, I'm missing
> what prevents a race condition in the updating of the agent's state
> variable.

Unless I am misunderstanding the context in which the code runs, I
believe it is correct because doRun() is guaranteed never to run
concurrently (because agents mutate state by function application in a
serialized fashion).

If I understand it correctly (and someone correct me if I'm wrong),
enqueue() is the initial entry point to execution. It will trigger
execution if the agent was not already running and had nothing queued.

doRun() itself keeps itself running until it manages to empty the
queue, at which point a future enqueue() will once again re-start
execution.

-- 
/ Peter Schuller

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


Re: matchure becoming clojure.contrib.match

2010-05-26 Thread Drew Colthorp
Good point Ben. That change was obviously ill-conceived.

On May 25, 7:16 am, B Smith-Mannschott  wrote:
> On Mon, May 24, 2010 at 05:41, Drew Colthorp  wrote:
> > A few weeks ago I announced a pattern matching library called
> >matchure. I'm excited to say it's being merged into clojure.contrib as
> > clojure.contrib.match. I'd like some feedback on ideas for some
> > backward-incompatible changes I'm planning to make before it's
> > actually pushed to clojure.contrib.
>
> > In the discussion below, I'll use "matchure" when I'm speaking of the
> > current behavior, and "clojure.contrib.match" when I'm describing
> > proposed behavior of the library when it's merged in. See
> >http://github.com/dcolthorp/matchure/blob/master/README.mdfor an
> > introduction tomatchureand the existing syntax, though I'll describe
> > the relevant before and after behaviors below.
>
> > Change 1: {:foo #"bar"} becomes {#"bar" :foo}
>
> > Inmatchure, maps test against the values of corresponding keys. I'm
> > going to change this so that the pattern is first and the key
> > second. This makes the behavior closer to let, makes
> > clojure.contrib.match more consistent in that patterns will always be
> > to the left of the matched value, and patterns like {even? :foo} read
> > better. This seems like an easy decision.
>
> This strikes me as an odd change. Did you overlook the fact that map
> keys have to be unique?
>
> {even? :foo,
>  even? :bar}
>
> Might read nicely, but will it work?
>
> // Ben
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Mohammad Khan
This thread has potential to be the longest thread of clojure mailing list!

personally, I like strip or trim than chomp/chop.

On Wed, May 26, 2010 at 2:08 PM, Fogus  wrote:

> > "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell-
> > scripting.
>
> Believe me I can sympathize with this, but just because they are well-
> known to some doesn't mean that they are good names.  On that note,
> just because rtrim and less make sense to me... you know the
> rest.  :-)
>
> :f
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

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

Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Praki Prakash
> personally, I like strip or trim than chomp/chop.
>

+1

Seeing how Clojure dropped/changed many classic Lisp monikers, there
is no reason to use comp/chop which may be familiar to somebody with
Perl/Python but confusing to others.

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


Re: Todo item annotation in Clojure.

2010-05-26 Thread Thomas
Thanks to sids, the project now has lein todo functionality.

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Justin Kramer
I've done Perl coding and I still mix up chomp and chop. The meaning
of trim, ltrim, and rtrim is immediately clear to me.

trim, ltrim, and rtrim could take an optional argument for characters
to strip:

(rtrim foo) ;; strip trailing whitespace
(rtrim foo "\r\n") ;; equivalent to chomp

If clojure.contrib.string/butlast actually mirrored clojure.core/
butlast, it would do the same as chop (c.c.s/butlast requires an extra
arg).

Justin

On May 26, 2:08 pm, Fogus  wrote:
> > "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell-
> > scripting.
>
> Believe me I can sympathize with this, but just because they are well-
> known to some doesn't mean that they are good names.  On that note,
> just because rtrim and less make sense to me... you know the
> rest.  :-)
>
> :f

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


Re: question about agent implementation

2010-05-26 Thread Peter Schuller
> Unless I am misunderstanding the context in which the code runs, I

Which I was. Please ignore my previous post (sorry, think before I
post... think before I post...) and consider me joined in the OP's
question.

-- 
/ Peter Schuller

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


Re: Announcing Clojure/core

2010-05-26 Thread Luke VanderHart
Very cool.

The website doesn't say... how was/is the Clojure/core team selected?
Are they all Relevance employees, or freelance? Do you plan on ever
bringing more people on board? Although I'm not quite as qualified as
some of the others, that's something I'd potentially be very
interested in, particularly since the book Stuart and I wrote is now
out...

-Luke

On May 25, 8:30 am, Rich Hickey  wrote:
> I'm happy to announce Clojure/core, a joint endeavor between myself
> and Relevance, Inc.  Clojure/core is a specialized technical practice
> within Relevance, focused on Clojure. Featuring myself and Stuart
> Halloway as advisors, the team also includes Clojure experts such as
> David Liebke (Incanter), Stuart Sierra (clojure-contrib contributor)
> and Aaron Bedra (an experienced consultant using Clojure).
>
> The practice will be providing mentorship, training and development
> services for those using, or planning to use, Clojure, and sustaining
> Clojure itself.
>
> Not interested in Clojure mentorship, training or dev assistance?
> There's still plenty of good news for the Clojure community in this
> announcement. One of the missions of Clojure/core is the
> sustainability of Clojure. The team will spend 20% of its time on
> Clojure itself. This includes working on enhancements and tickets,
> incorporating patches, helping tend the mailing list etc. This will
> enable our team to get a lot more done than I could ever do myself,
> while enabling me to focus on the fundamental aspects of Clojure. It
> will also broaden the pool of people with intimate knowledge of the
> internals of Clojure.
>
> The availability of services such as this is an important milestone
> for Clojure, as people choosing to adopt Clojure can be assured they
> can get mentorship, training and dev assistance, from experts.
>
> I'm very excited about this effort. The folks at Relevance have never
> failed to impress me with their skills and attitude, and they truly
> get Clojure and care about its sustainability.
>
> Note: clojure.com will now resolve to the Clojure/core site. Come
> check it out!
>
> http://clojure.com
>
> Rich
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: question about agent implementation

2010-05-26 Thread Peter Schuller
>> Unless I am misunderstanding the context in which the code runs, I
>
> Which I was. Please ignore my previous post (sorry, think before I
> post... think before I post...) and consider me joined in the OP's
> question.

And every time this happens I wonder if I should just leave it to
avoid flooding with responses further, or follow-up yet again, risking
the realization that I have to take something back *again*.

I think I was confused the second time and right the first. But to
elaborate on my first post to clarify:

As far as I can tell, execute() is only ever called by enqueue() and
enqueue() will only ever call execute() if the queue was non-empty
when the action was enqueued using the compareAndSet(). Further, if it
*was* empty, it always calls execute().

doRun() itself does a similar compareAndSet() loop and *always*
executes itself if the queue is non-empty.

The resulting behavior is that any CAS loop that ends with the
realization that there was something already there to execute, leads
to said action being executed if needed. In the case of doRun() this
is accomplished by calling execute() itself - since doRun() is the one
already being executed, it knows it is done and that scheduling one
more action will lead not lead to a >1 concurrency level. In the case
of enqueue(), it either does nothing (if there was *already* something
there), or schedules the execution if the enqueue() invocation was
responsible for making the queue non-empty.

In either case, the concurrency level can never go above 1.

(I find this to be a very interesting use-case for immutable data
structures btw... it allows a complex data structure, without them in
and of themselves doing careful lock-less operations to support
concurrency, to be used in combination with simple CAS loops to great
effect.)

-- 
/ Peter Schuller

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


Re: Anyone experienced in using clojure as a "database"

2010-05-26 Thread Luke VanderHart
Clojure is not a great choice for this. It's oriented as a programming
language, not a database. It doesn't have any built-in persistence
mechanisms, and while it has many virtues, it's a little bit of a
memory hog. That isn't really what you want in an in-memory DB.

For anything more than a toy app where you don't want to do the work,
I think you'll be much more pleased with the results if you hook up a
real DB or NoSQL solution.

- Luke

On May 25, 2:08 pm, Fabio Kaminski  wrote:
> Folks,
>
> i would like advice,
> cause since im starting something that will be eventually big data
> intensive, from scratch
> and i really like the options already built in in clojure like STM,
> parallelizing data and concurrency logic implemented on it
> i think its wonderfully tuned to use as database... and you can achieve
> different strategies, like graphs or balanced trees for different data
>
> my worries are about the efficiency in serializing it and recovering from/to
> the disk,
> java VM as a hungry heap VM,
> (and with immutable strategies, more heap needed)
>
> the benefits are control of sharding mechanism's and parallelizing not only
> in the unit's cores but between nodes of a cluster..
>
> anyone using clojure  not just as database middleware(wich is perfect for)
> but as database backend too?
>
> Thanks all,
>
> Fabio Kaminski
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Stuart Halloway

The people have spoken! The trims have it!

Stu


I've done Perl coding and I still mix up chomp and chop. The meaning
of trim, ltrim, and rtrim is immediately clear to me.

trim, ltrim, and rtrim could take an optional argument for characters
to strip:

   (rtrim foo) ;; strip trailing whitespace
   (rtrim foo "\r\n") ;; equivalent to chomp

If clojure.contrib.string/butlast actually mirrored clojure.core/
butlast, it would do the same as chop (c.c.s/butlast requires an extra
arg).

Justin

On May 26, 2:08 pm, Fogus  wrote:

"chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell-
scripting.


Believe me I can sympathize with this, but just because they are  
well-

known to some doesn't mean that they are good names.  On that note,
just because rtrim and less make sense to me... you know the
rest.  :-)

:f


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient  
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Stuart Sierra
On May 26, 12:42 pm, Sean Devlin  wrote:
> I'd like to see a specific proposal for replace & replace-first.
> Stuart Sierra put a lot of effort into getting those fns the way they
> are in contrib, and we should be careful to not undo any lessons
> learned in the process.

Yes, originally replace and replace-first were multimethods.  But
that's too slow for string routines, which tend to be called often.
The type-specific replace-* and replace-first-* functions are
carefully optimized.

-Stuart

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


Some suggestions for transients

2010-05-26 Thread Michael Jaaka
Hi!

I have some suggestions about transients (btw. the http://clojure.org/transients
is not linked from http://clojure.org).

Maybe before you give up reading the whole post I will post as first
the digression:
vars binding and transient are similar, however in the first case we
have thread isolation on reading and writing with reference covering/
hiding ability. Currently operations on transients structures seems to
be badly interfaced in Clojure and below is a deal:


Why do we have to deal with conj! and rest of foo! operations, when
there are much more functions like update-in, assoc-in etc. what about
them? In most my code I fail to use transient because of xyz-in
operations. More over I know that the code is whole executed by one
thread, since I know where the transient structure starts to exist and
when it ends. Tracking such code is easy task to do since most fast
compuations are free of side effects and thread intercommunication.

If the whole talk is about thread isolation (which is great feature),
then the interface should be simplified, in the way like - (transient
x) - attaches thread (which calls transient) reference to my structure
(object), when any other thread tries to modify x then the exception
is thrown. When I do (persistent x), the thread reference is detached
from the structure, so it becomes persistent and others threads can
concurrently modify it.

This would eleminate duplication of functions and allow for single
threaded computations. This would satisfy most computations related
with reduce operation and recurention. So easy to do, so easy to
track, yet not in Clojure ;-(. The (transient x) and (persistent x)
are required since the are explicit declaration of single thread
mutation.

Also it would be nice if such transient structures could be used in
binding clasues, since I have found other adoption - for example
thread is doing computations in a functional way - and with binded
transients I'm gathering statistics (time measurement, bytes counting
etc. in an imperative, side effecting, more like aspect way.)

What are your thoughts?

Thanks,

BTW. What does it mean "don't bash in place" - since for not all
people English is not a native language I suggest to use simpler words
in such formulations.

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


Re: question about agent implementation

2010-05-26 Thread Michael Harrison (goodmike)
Thanks for your post, Peter. I'm tracing the code, and it's
interesting.

The interesting point is definitely the agent's aq member, the
AtomicReference that wraps an ActionQueue.

The aq.compareAndSet call keeps the value of the ActionQueue from
switching out form under us while we attempt to set aq to a new
ActionQueue wrapping a PersistentQueue that contains the agent's
action -- the compareAndSet will be retried if it returns false.

As I read the end of Agent's enqueue method, the action is only told
to execute if the ActionQueue's PersistentQueue was empty before the
compareAndSet and the ActionQueue is free of errors.

I also see where Agent's static doRun method will pop an action off
the agent's queue and execute the action.

Where is Action's execute method called in the event the queue is not
empty?

Michael


On May 26, 4:28 pm, Peter Schuller 
wrote:
> >> Unless I am misunderstanding the context in which the code runs, I
>
> > Which I was. Please ignore my previous post (sorry, think before I
> > post... think before I post...) and consider me joined in the OP's
> > question.
>
> And every time this happens I wonder if I should just leave it to
> avoid flooding with responses further, or follow-up yet again, risking
> the realization that I have to take something back *again*.
>
> I think I was confused the second time and right the first. But to
> elaborate on my first post to clarify:
>
> As far as I can tell, execute() is only ever called by enqueue() and
> enqueue() will only ever call execute() if the queue was non-empty
> when the action was enqueued using the compareAndSet(). Further, if it
> *was* empty, it always calls execute().
>
> doRun() itself does a similar compareAndSet() loop and *always*
> executes itself if the queue is non-empty.
>
> The resulting behavior is that any CAS loop that ends with the
> realization that there was something already there to execute, leads
> to said action being executed if needed. In the case of doRun() this
> is accomplished by calling execute() itself - since doRun() is the one
> already being executed, it knows it is done and that scheduling one
> more action will lead not lead to a >1 concurrency level. In the case
> of enqueue(), it either does nothing (if there was *already* something
> there), or schedules the execution if the enqueue() invocation was
> responsible for making the queue non-empty.
>
> In either case, the concurrency level can never go above 1.
>
> (I find this to be a very interesting use-case for immutable data
> structures btw... it allows a complex data structure, without them in
> and of themselves doing careful lock-less operations to support
> concurrency, to be used in combination with simple CAS loops to great
> effect.)
>
> --
> / Peter Schuller

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


Re: question about agent implementation

2010-05-26 Thread Peter Schuller
> Where is Action's execute method called in the event the queue is not
> empty?

If the agent's queue was non-empty from the perspective of enqueue(),
that means one of the following is true:

(1) A previous enqueue() has already scheduled the execution of an
action, but it has not yet begun running.
(2) doRun() is running but has not yet completed its CAS loop at the end.

In either case, once doRun() runs and reaches its CAS loop, it will
detect that the queue is non-empty and schedule the next action. This
is the:

if(error == null && next.q.count() > 0)
((Action) next.q.peek()).execute();
}

which appears towards the end of doRun(). Next is the atomically
obtained (through CAS looping) queue, after it popped itself.

Another way to look at it might be that the queue can be in two
relevant states at any point in time:

  * empty
  * non-empty

In the non-empty state, doRun() is continuously responsible for
re-scheduling itself. In the empty state, enqueue() is responsible for
scheduling it. Because of the use of CAS loops, the transition from
"empty" to "non-empty" can be atomically detected by enqueue(),
allowing it to determine whether or not it was responsible for such a
state transition, in which case it schedules the action for execution.

-- 
/ Peter Schuller

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


Re: question about agent implementation

2010-05-26 Thread Michael Harrison (goodmike)
OK, chouser gave me the explanation on IRC. It's amazing that we can
pop into #clojure and there's one of the two people who've touched
this file. Thanks, chouser!

The compareAndSet (CAS) that protects the agent's queue from
overlapping updates forces the agent's actions into serial execution.
When enqueue determines the queue has gone from 0 items to 1 item, it
starts a chain of executions: at the end of execute, if another action
can be popped off the queue (CAS again) then it is, and it is
executed. That execution will repeat the attempt to execute the next
action, if any, on the queue.

If the queue was already non-zero in size, there is guaranteed to be
an execution underway that will in time trigger the new action's
execution, so no explicit execute call is needed.

The CAS on the queue, and the placement of calls to execute only in
enqueue and execute itself, force an agent's actions to execute
serially, without any locks.

Sweet!

Cheers,
Michael

On May 26, 5:23 pm, "Michael Harrison (goodmike)"
 wrote:
> Thanks for your post, Peter. I'm tracing the code, and it's
> interesting.
>
> The interesting point is definitely the agent's aq member, the
> AtomicReference that wraps an ActionQueue.
>
> The aq.compareAndSet call keeps the value of the ActionQueue from
> switching out form under us while we attempt to set aq to a new
> ActionQueue wrapping a PersistentQueue that contains the agent's
> action -- the compareAndSet will be retried if it returns false.
>
> As I read the end of Agent's enqueue method, the action is only told
> to execute if the ActionQueue's PersistentQueue was empty before the
> compareAndSet and the ActionQueue is free of errors.
>
> I also see where Agent's static doRun method will pop an action off
> the agent's queue and execute the action.
>
> Where is Action's execute method called in the event the queue is not
> empty?
>
> Michael
>
> On May 26, 4:28 pm, Peter Schuller 
> wrote:
>
> > >> Unless I am misunderstanding the context in which the code runs, I
>
> > > Which I was. Please ignore my previous post (sorry, think before I
> > > post... think before I post...) and consider me joined in the OP's
> > > question.
>
> > And every time this happens I wonder if I should just leave it to
> > avoid flooding with responses further, or follow-up yet again, risking
> > the realization that I have to take something back *again*.
>
> > I think I was confused the second time and right the first. But to
> > elaborate on my first post to clarify:
>
> > As far as I can tell, execute() is only ever called by enqueue() and
> > enqueue() will only ever call execute() if the queue was non-empty
> > when the action was enqueued using the compareAndSet(). Further, if it
> > *was* empty, it always calls execute().
>
> > doRun() itself does a similar compareAndSet() loop and *always*
> > executes itself if the queue is non-empty.
>
> > The resulting behavior is that any CAS loop that ends with the
> > realization that there was something already there to execute, leads
> > to said action being executed if needed. In the case of doRun() this
> > is accomplished by calling execute() itself - since doRun() is the one
> > already being executed, it knows it is done and that scheduling one
> > more action will lead not lead to a >1 concurrency level. In the case
> > of enqueue(), it either does nothing (if there was *already* something
> > there), or schedules the execution if the enqueue() invocation was
> > responsible for making the queue non-empty.
>
> > In either case, the concurrency level can never go above 1.
>
> > (I find this to be a very interesting use-case for immutable data
> > structures btw... it allows a complex data structure, without them in
> > and of themselves doing careful lock-less operations to support
> > concurrency, to be used in combination with simple CAS loops to great
> > effect.)
>
> > --
> > / Peter Schuller
>
>

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


Re: question about agent implementation

2010-05-26 Thread Michael Harrison (goodmike)
Thanks for the explanation, Peter, and for accompanying me on this
journey into the unknown. Your description of enqueue is what chouser
explained to me too.

Someday I have to write some code with a queue named eat so that eat
will pop itself.

Cheers,
Michael


On May 26, 5:54 pm, Peter Schuller 
wrote:
> > Where is Action's execute method called in the event the queue is not
> > empty?
>
> If the agent's queue was non-empty from the perspective of enqueue(),
> that means one of the following is true:
>
> (1) A previous enqueue() has already scheduled the execution of an
> action, but it has not yet begun running.
> (2) doRun() is running but has not yet completed its CAS loop at the end.
>
> In either case, once doRun() runs and reaches its CAS loop, it will
> detect that the queue is non-empty and schedule the next action. This
> is the:
>
>                         if(error == null && next.q.count() > 0)
>                                 ((Action) next.q.peek()).execute();
>                         }
>
> which appears towards the end of doRun(). Next is the atomically
> obtained (through CAS looping) queue, after it popped itself.
>
> Another way to look at it might be that the queue can be in two
> relevant states at any point in time:
>
>   * empty
>   * non-empty
>
> In the non-empty state, doRun() is continuously responsible for
> re-scheduling itself. In the empty state, enqueue() is responsible for
> scheduling it. Because of the use of CAS loops, the transition from
> "empty" to "non-empty" can be atomically detected by enqueue(),
> allowing it to determine whether or not it was responsible for such a
> state transition, in which case it schedules the action for execution.
>
> --
> / Peter Schuller

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


labrepl dependencies

2010-05-26 Thread Harrison Maseko
Hi all,
The instructions on the labrepl git page says to "download missing
dependencies" of the labrepl. For some reason I cannot download them
in NetBeans running on Ubuntu 10.04. Can I also just download them
manually one by one? If so, what, specifically, are the dependencies
that the labrepl requires?
Thanks for your help. If I am using the wrong forum, please advise.

Harrison.

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


Re: API in Clojure for Java folklore

2010-05-26 Thread ka
Hi all,

Inspired by Erik above, I've written a macro: gen-class+javadoc
(http://gist.github.com/415269).

It works quite well for me on Windows XP.  For *nix, I think people
will have to make at least one change - the shell command (at line
57).

What it does -
1. Generates a javadoc for your API made using gen-class.

How to use -
1. Just use gen-class+javadoc macro instead of the gen-class macro.
_No other changes are required by the coder_.

Functioning -
1. It calls gen-class first as usual with the args.
2. Generates a .java file containing the javadoc.
3. Runs the javadoc command and generates docs in the doc/ directory.
4. Deletes the .java file created above.

Few points to note -
1. It is by no means complete.  For eg. it doesn't handle interface
related stuff yet.
2. It uses macroexpand inside a macro, but some people on Clojure#
pointed out that this is not recommended.  I'm very new to macro-foo,
so please let me know of the alternatives.
3. The macro itself contains a lot of side effects, dunno if this is a
very big issue.

Try it out if you expose an API through gen-class.

Any comments / suggestions / critiques are welcome.

- Thanks


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


Re: labrepl dependencies

2010-05-26 Thread Base

Hi Harrison.

Welcome!

I am not familiar with netbeans but reading the labrepl instructions
it appears that dependencies will auto resolve.

Is there an error? Any more info?

On May 26, 5:34 pm, Harrison Maseko  wrote:
> Hi all,
> The instructions on the labrepl git page says to "download missing
> dependencies" of the labrepl. For some reason I cannot download them
> in NetBeans running on Ubuntu 10.04. Can I also just download them
> manually one by one? If so, what, specifically, are the dependencies
> that the labrepl requires?
> Thanks for your help. If I am using the wrong forum, please advise.
>
> Harrison.

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-26 Thread Eric Schulte
Mark Engelberg  writes:

> If you're developing a trio, like ltrim, trim, rtrim, wouldn't it be
> better to call them triml, trim, trimr so that they show up next to
> each other in the alphabetized documentation?

+1 for modifiers at the end

Let's not forget those of us who search for functions using
tab-completion in the repl.

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


Re: labrepl dependencies

2010-05-26 Thread Paul Hobbs
Harrison,

Use leiningen (http://github.com/technomancy/leiningen) and then run
"lein deps" at your command line.
--
Paul Hobbs



On Wed, May 26, 2010 at 11:34 PM, Harrison Maseko  wrote:
> Hi all,
> The instructions on the labrepl git page says to "download missing
> dependencies" of the labrepl. For some reason I cannot download them
> in NetBeans running on Ubuntu 10.04. Can I also just download them
> manually one by one? If so, what, specifically, are the dependencies
> that the labrepl requires?
> Thanks for your help. If I am using the wrong forum, please advise.
>
> Harrison.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


NullPointerException on disj

2010-05-26 Thread Allen Johnson
Hey everyone. I was playing around with the protocols/deftype stuff
and ran into a weird NullPointerException when calling the satisfies?
function. Seems to only happen with a java.lang.Object instance.

Clojure 1.2.0-master-SNAPSHOT
user=> (defprotocol Greeter (greet [this]))
Greeter
user=> (satisfies? Greeter nil)
false
user=> (satisfies? Greeter "")
false
user=> (satisfies? Greeter (Object.))
java.lang.NullPointerException (NO_SOURCE_FILE:0)

Narrowed it down to this function:

;; core_deftype.clj
(defn find-protocol-impl [protocol x]
  (if (instance? (:on-interface protocol) x)
x
(let [c (class x)
  impl #(get (:impls protocol) %)]
  (or (impl c)
  (and c (or (first (remove nil? (map impl (butlast (super-chain c)
 (when-let [t (reduce pref (filter impl (disj
(supers c) Object)))]
   (impl t))
 (impl Object)))

More specifically, here:

(disj (supers c) Object)

Since in this case, `c` is java.lang.Object, supers returns nil which
disj doesn't seem to like. Shouldn't disj handle nil gracefully?

Thanks,
Allen

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