Re: Possible namespace bug

2010-05-26 Thread Brent Millare
Hi Meikel,

Well if #'user/x is the correct behavior, then the repl behavior needs
to be fixed. Either one may be correct but that does not explain the
discrepancy. Also I agree that eval should be avoided, but I found an
extreme case where it was necessary (due to the desired side effect of
starting a new classloader).

Best,
Brent

On May 26, 1:27 am, Meikel Brandmeyer m...@kotka.de wrote:
 Hi,

 On May 26, 12:17 am, Brent Millare brent.mill...@gmail.com wrote:

  ^^ That should read #'bar/x instead of #'user/x

 No. foo/f expands into a macro calling eval on a def. This eval
 is put into a function bar/b. When you call the function the
 namespace in charge is user. So everything is correct.

 Usual disclaimer:
 Don't do non-global def (besides a surrounding scope-limiting
 let). Avoid eval.

 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: Possible namespace bug

2010-05-26 Thread Brent Millare
Ah wait, I may have read that wrong. So what I understand is because I
am calling it from the the -e, it is ran in the user ns. Ok that makes
sense.

On May 26, 2:28 am, Brent Millare brent.mill...@gmail.com wrote:
 Hi Meikel,

 Well if #'user/x is the correct behavior, then the repl behavior needs
 to be fixed. Either one may be correct but that does not explain the
 discrepancy. Also I agree that eval should be avoided, but I found an
 extreme case where it was necessary (due to the desired side effect of
 starting a new classloader).

 Best,
 Brent

 On May 26, 1:27 am, Meikel Brandmeyer m...@kotka.de wrote:

  Hi,

  On May 26, 12:17 am, Brent Millare brent.mill...@gmail.com wrote:

   ^^ That should read #'bar/x instead of #'user/x

  No. foo/f expands into a macro calling eval on a def. This eval
  is put into a function bar/b. When you call the function the
  namespace in charge is user. So everything is correct.

  Usual disclaimer:
  Don't do non-global def (besides a surrounding scope-limiting
  let). Avoid eval.

  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: Possible namespace bug

2010-05-26 Thread Meikel Brandmeyer
Hi,

On May 26, 8:35 am, Brent Millare brent.mill...@gmail.com wrote:

 Ah wait, I may have read that wrong. So what I understand is because I
 am calling it from the the -e, it is ran in the user ns. Ok that makes
 sense.

Exactly! And in the Repl you are still in the bar namespace.
Doing a (in-ns 'user) and then calling bar/b should give the
same effect as for -e invokation.

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 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 AtomicReferenceUnitOfTime timeLineHead =

new AtomicReferenceUnitOfTime(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 ConcurrentLinkedQueueObject keepAliveSet = new
ConcurrentLinkedQueueObject();

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 brent.mill...@gmail.com 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 ydong.pub...@gmail.com 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 peter.r.fos...@gmail.com 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


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 eriksoeh...@googlemail.com wrote:
 On 25 Mai, 08:03, Brent Millare brent.mill...@gmail.com 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


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 stuart.hallo...@gmail.com
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 stuart.hallo...@gmail.com 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 peter.schul...@infidyne.com 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.

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

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

-- 
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 mefo...@gmail.com 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: 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 bsmith.o...@gmail.com wrote:
 On Mon, May 24, 2010 at 05:41, Drew Colthorp dcolth...@gmail.com 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 mefo...@gmail.com 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.comclojure%2bunsubscr...@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 mefo...@gmail.com 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 richhic...@gmail.com 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 fabiokamin...@gmail.com 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 mefo...@gmail.com 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 francoisdev...@gmail.com 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 peter.schul...@infidyne.com
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)
goodmike...@gmail.com 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 peter.schul...@infidyne.com
 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 peter.schul...@infidyne.com
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: 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 lis...@gmail.com 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 mark.engelb...@gmail.com 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 lis...@gmail.com 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