compile and gen-class don't seem to work for me

2008-12-12 Thread ntupel

For the first time I tried to use gen-class (using svn r1156), but
unfortunately compilation fails:

u...@computer /tmp $ mkdir test
u...@computer /tmp $ cd test/
u...@computer /tmp/test $ mkdir -p clojure/examples
u...@computer /tmp/test $ gvim clojure/examples/instance.clj  ;copied
the source from http://clojure.org/compilation into the editor and
saved it [1]
u...@computer /tmp/test $ mkdir classes
u...@computer /tmp/test $ java -cp
.:classes:/opt/clojure/clojure/trunk/clojure.jar clojure.main
Clojure
user=> (compile 'clojure.examples.instance)
java.lang.RuntimeException: java.lang.ClassNotFoundException:
clojure.examples.instance$_init__4 (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.RuntimeException: java.lang.ClassNotFoundException:
clojure.examples.instance$_init__4 (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4147)
at clojure.core$eval__3542.invoke(core.clj:1486)
at clojure.main$repl__5154$fn__5169.invoke(main.clj:100)
at clojure.main$repl__5154.doInvoke(main.clj:96)
at clojure.lang.RestFn.invoke(RestFn.java:426)
at clojure.main$repl_opt__5194.invoke(main.clj:153)
at clojure.main$_main__5218.doInvoke(main.clj:228)
at clojure.lang.RestFn.invoke(RestFn.java:402)
at clojure.lang.AFn.applyToHelper(AFn.java:191)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.main.main(Unknown Source)
Caused by: java.lang.RuntimeException:
java.lang.ClassNotFoundException: clojure.examples.instance$_init__4
at clojure.lang.Compiler$FnExpr.getCompiledClass(Compiler.java:3211)
at clojure.lang.Compiler$FnExpr.emit(Compiler.java:3223)
at clojure.lang.Compiler$DefExpr.emit(Compiler.java:318)
at clojure.lang.Compiler.compile(Compiler.java:4560)
at clojure.lang.RT.compile(RT.java:362)
at clojure.lang.RT.load(RT.java:404)
at clojure.lang.RT.load(RT.java:376)
at clojure.core$load__4555$fn__4557.invoke(core.clj:3427)
at clojure.core$load__4555.doInvoke(core.clj:3426)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at clojure.core$load_one__4518.invoke(core.clj:3271)
at clojure.core$compile__4561$fn__4563.invoke(core.clj:3437)
at clojure.core$compile__4561.invoke(core.clj:3436)
at user$eval__1.invoke(Unknown Source)
at clojure.lang.Compiler.eval(Compiler.java:4136)
... 10 more
Caused by: java.lang.ClassNotFoundException: clojure.examples.instance$_init__4
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:52)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.classForName(RT.java:1504)
at clojure.lang.Compiler$FnExpr.getCompiledClass(Compiler.java:3202)
... 24 more
nil

Did I miss anything?

Many thanks,
nt


---
[1] For reference here is the code from instance.clj

(ns clojure.examples.instance
(:gen-class
 :implements [java.util.Iterator]
 :init init
 :constructors {[String] []}
 :state state))

(defn -init [s]
  [[] (ref {:s s :index 0})])

(defn -hasNext [this]
  (let [{:keys [s index]} @(.state this)]
(< index (count s

(defn -next [this]
  (let [{:keys [s index]} @(.state this)
ch (.charAt s index)]
(dosync (alter (.state this) assoc :index (inc index)))
ch))

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Bug with clojure.set/intersection, clojure.set/difference etc.

2009-01-29 Thread ntupel

If its left argument is nil, "intersection" throws a NPE (Clojure rev. 1235):

user=> (set/intersection nil #{1})
java.lang.NullPointerException (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4186)
at clojure.core$eval__3830.invoke(core.clj:1647)
at clojure.main$repl__5568$fn__5586.invoke(main.clj:148)
at clojure.main$repl__5568.doInvoke(main.clj:145)
at clojure.lang.RestFn.invoke(RestFn.java:426)
at clojure.main$repl_opt__5610.invoke(main.clj:208)
at clojure.main$main__5645$fn__5647.invoke(main.clj:295)
at clojure.main$main__5645.doInvoke(main.clj:289)
at clojure.lang.RestFn.invoke(RestFn.java:402)
at clojure.lang.Var.invoke(Var.java:332)
at clojure.lang.AFn.applyToHelper(AFn.java:172)
at clojure.lang.Var.applyTo(Var.java:453)
at clojure.main.main(main.java:39)
Caused by: java.lang.NullPointerException
at clojure.core$disj__3445.invoke(core.clj:915)
at clojure.core$reduce__3173$fn__3176.invoke(core.clj:549)
at clojure.core$reduce__3173.invoke(core.clj:547)
at clojure.set$difference__5658.invoke(set.clj:19)
at clojure.set$intersection__5661.invoke(set.clj:24)
at user$eval__259.invoke(Unknown Source)
at clojure.lang.Compiler.eval(Compiler.java:4175)
... 12 more
nil
user=> (msg/select-messages msgs nil "OR" nil)
nil
user=> (set/intersection #{} nil)
#{}

The same is true for clojure.set/difference and everything else that
uses clojure.disj with nil for the first parameter.

Cheers,
nt

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Bug: self require -> stack overflow

2008-09-08 Thread ntupel

(ns test
  (:require test))

results in:

clojure.lang.Compiler$CompilerException: test.clj:0: null
at clojure.lang.Compiler.analyzeSeq(Compiler.java:3824)
at clojure.lang.Compiler.analyze(Compiler.java:3657)
at clojure.lang.Compiler.eval(Compiler.java:3848)
at clojure.lang.Compiler.load(Compiler.java:4151)
at clojure.lang.RT.loadResourceScript(RT.java:360)
at clojure.lang.RT.loadResourceScript(RT.java:347)
at clojure.lang.RT.loadResourceScript(RT.java:339)
at clojure.load_resources__1744.doInvoke(boot.clj:3209)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at clojure.load_one__1707.invoke(boot.clj:3058)
at clojure.load_lib__1727.doInvoke(boot.clj:3095)
at clojure.lang.RestFn.applyTo(RestFn.java:147)
at clojure.apply__135.doInvoke(boot.clj:364)
at clojure.lang.RestFn.invoke(RestFn.java:443)
at clojure.load_libs__1731.doInvoke(boot.clj:3121)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.apply__135.doInvoke(boot.clj:364)
at clojure.lang.RestFn.invoke(RestFn.java:443)
at clojure.require__1735.doInvoke(boot.clj:3181)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at test.eval__3068.invoke(test.clj:1)
...
Caused by: java.lang.StackOverflowError
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.lang.ClassLoader.defineClass(ClassLoader.java:465)
at 
clojure.lang.DynamicClassLoader.defineClass(DynamicClassLoader.java:39)
at clojure.lang.Compiler$FnExpr.compile(Compiler.java:2986)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:2773)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:3815)
at clojure.lang.Compiler.analyze(Compiler.java:3657)
at clojure.lang.Compiler.eval(Compiler.java:3848)
at clojure.lang.Compiler.load(Compiler.java:4151)
at clojure.lang.RT.loadResourceScript(RT.java:360)
at clojure.lang.RT.loadResourceScript(RT.java:347)
at clojure.lang.RT.loadResourceScript(RT.java:339)
at clojure.load_resources__1744.doInvoke(boot.clj:3209)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at clojure.load_one__1707.invoke(boot.clj:3058)
at clojure.load_lib__1727.doInvoke(boot.clj:3095)
at clojure.lang.RestFn.applyTo(RestFn.java:147)
at clojure.apply__135.doInvoke(boot.clj:364)
at clojure.lang.RestFn.invoke(RestFn.java:443)
at clojure.load_libs__1731.doInvoke(boot.clj:3121)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.apply__135.doInvoke(boot.clj:364)
at clojure.lang.RestFn.invoke(RestFn.java:443)
at clojure.require__1735.doInvoke(boot.clj:3181)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at test.eval__3068.invoke(test.clj:1)
...



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Bug: self require -> stack overflow

2008-09-08 Thread ntupel

On Mon, 2008-09-08 at 13:15 -0700, Rich Hickey wrote:
> Hmm, don't do that?
> 
> Seriously, how is this a bug in Clojure, and not a bug in your
> program, which resulted in an exception which easily leads you to your
> problem?

Well, first of all this bug in a users program results in undefined
behavior in the Clojure compiler which terminates due to a resource
exhaustion without any particular error message. This should never
happen.

Then, please note that this somewhat contrived example, when extended to
circular requires, e.g. A requires B and B requires A might accidentally
(or by bad design) occur during development. One can argue whether this
should result in an error message or whether the semantics of require
are satisfied if the namespaces are loaded once each. But again, a
StackOverflowError and a "don't do that" can not be the answer.

My 2 Cents.



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Bug: self require -> stack overflow

2008-09-09 Thread ntupel

On Tue, 2008-09-09 at 23:57 +1000, Brett Morgan wrote:
> On Tue, Sep 9, 2008 at 10:31 PM, [EMAIL PROTECTED]
> <[EMAIL PROTECTED]> wrote:
> >
> > On Sep 9, 11:26 am, "Brett Morgan" <[EMAIL PROTECTED]> wrote:
> >> For C, protection against circular dependencies is on the head of the
> >> programmer, in the form of #ifdef guards.
> >
> > There is #import as a GCC extension (also used in Objective-C).
> >
> 
> Which expand out to #ifdef guards, if memory serves.

So what? It just shows you another effective way to tackle the cycle
problem. As a programmer I don't care if I use "include" or "import" or
"require" to load my dependencies. But I do care if I need to make extra
steps to not include stuff twice. I really can not believe that we have
to discuss this age old problem which has been solved so many times
already again and again. This is just plain stupid.


--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Bug: self require -> stack overflow

2008-09-09 Thread ntupel

On Wed, 2008-09-10 at 16:47 +1100, Brett Morgan wrote:
> On Wed, Sep 10, 2008 at 4:38 PM, ntupel <[EMAIL PROTECTED]> wrote:
> >
> > On Tue, 2008-09-09 at 23:57 +1000, Brett Morgan wrote:
> >> On Tue, Sep 9, 2008 at 10:31 PM, [EMAIL PROTECTED]
> >> <[EMAIL PROTECTED]> wrote:
> >> >
> >> > On Sep 9, 11:26 am, "Brett Morgan" <[EMAIL PROTECTED]> wrote:
> >> >> For C, protection against circular dependencies is on the head of the
> >> >> programmer, in the form of #ifdef guards.
> >> >
> >> > There is #import as a GCC extension (also used in Objective-C).
> >> >
> >>
> >> Which expand out to #ifdef guards, if memory serves.
> >
> > So what? It just shows you another effective way to tackle the cycle
> > problem. As a programmer I don't care if I use "include" or "import" or
> > "require" to load my dependencies. But I do care if I need to make extra
> > steps to not include stuff twice. I really can not believe that we have
> > to discuss this age old problem which has been solved so many times
> > already again and again. This is just plain stupid.
> >
> 
> Well, you could code your own include macro to achieve the affect you
> are after. It is an open source project, after all.

I know and in fact I had my own version of require long before
clojure-contrib was started. But I was glad that it was no longer needed
when clojure-contrib.lib was included because something as basic as this
needs to be part of the standard distribution. And now despite of these
promising developments it seems that I must again come up with a
homegrown solution as I can not convince the Clojure community that it
should be part of Clojure itself. I am delighted!



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Bug: self require -> stack overflow

2008-09-09 Thread ntupel

On Tue, 2008-09-09 at 07:26 -0700, Rich Hickey wrote:
> Certainly there are areas where there could be more explicit messages,
> but the detection and reporting of errors has a cost (in time,
> sometimes runtime, effort, code size and complexity) and I don't want
> to incur that cost unless it is solving a real, common problem, not
> just a theoretical one.

Just to make myself clear - I clearly said in my first reply to your
post:

"One can argue whether this should result in an error message or
whether the semantics of require are satisfied if the namespaces
are loaded once each."

So I would be glad if the bug is fixed by silently stopping the load if
the namespace is already found in *loaded-libs*. After all the
infrastructure is in place and all that is needed is recording the lib
before the actual load in *loaded-libs* and if the load fails to remove
it again which slightly complicates load-one and/or load-all but still
it seems to be a small price to pay for correctness.



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



true?

2008-09-30 Thread ntupel

The following looks weird to me:

Clojure
user=> (.contains [1 2 3] 2)
true
user=> (true? (.contains [1 2 3] 2))
false

AFAICS true? is implemented using identical? which tests by reference
equality. Now since Java boolean values are boxed into Booleans we have
not only Boolean.TRUE. Maybe true? (and false?) should be implemented in
terms of equals?



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: true?

2008-09-30 Thread ntupel

On Tue, 2008-09-30 at 17:29 -0400, Stuart Halloway wrote:
> For your specific case you should probably be using contains?, which  
> works for both.

No. contains? is meant for maps, i.e. when applied to vectors it checks
against indexes:

user=> (contains? [1 2 3] 0)
true



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Repl over Socket, Threads & Bindings

2008-10-09 Thread ntupel

The Clojure wikibook has an example implementation of a Repl over a
socket
(http://en.wikibooks.org/wiki/Clojure_Programming#Simple_REPL_on_a_Socket).
I wonder how to solve the problem of showing output if somewhere in
the evaluated expression, a new thread is created that will eventually
print something.

As bindings are not inherited by new threads, how can this be done
without actually changing the expressions that are evaluated?

I know that in March it was briefly discussed, but wouldn't it be useful
to have a binding variant, that causes all threads forked off from
within the expression to inherit the binding values?

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Repl over Socket, Threads & Bindings

2008-10-09 Thread ntupel

The Clojure wikibook has an example implementation of a Repl over a
socket
(http://en.wikibooks.org/wiki/Clojure_Programming#Simple_REPL_on_a_Socket). I 
wonder how to solve the problem of showing output if somewhere in the evaluated 
expression, a new thread is created that will eventually print something. 

As bindings are not inherited by new threads, how can this be done
without actually changing the expressions that are evaluated? 

I know that in March it was briefly discussed, but wouldn't it be useful
to have a binding variant, that causes all threads forked off from
within the expression to inherit the binding values?


--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



NPE with binding [was: Repl over Socket, binding and threads]

2008-10-09 Thread ntupel

On Thu, 2008-10-09 at 02:30 -0700, [EMAIL PROTECTED] wrote:
> As bindings are not inherited by new threads, how can this be done
> without actually changing the expressions that are evaluated?
> 
> I know that in March it was briefly discussed, but wouldn't it be
> useful to have a binding variant, that causes all threads forked off
> from within the expression to inherit the binding values?


After further investigation and experimentation with macros I finally
managed to trigger a NullpointerException:

Clojure
user=> (def x)
#'user/x
user=> (defmacro on-thread [env exp] `(doto (new Thread #(binding ~env (~exp))) 
(start)))
nil
user=> (on-thread [x 12] (prn x))
Thread[Thread-0,5,main]
user=> 12
Exception in thread "Thread-0" java.lang.RuntimeException: 
java.lang.NullPointerException
at clojure.lang.AFn.run(AFn.java:42)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NullPointerException
at user.eval__2393$fn__2396.invoke(Unknown Source)
at clojure.lang.AFn.run(AFn.java:38)
... 1 more
(defmacro no-thread [env exp] `(#(binding ~env (~exp ; without thread for 
better stack trace
nil
user=> (no-thread [x 12] (prn x))
12
java.lang.NullPointerException (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4008)
at clojure.lang.Repl.main(Repl.java:85)
Caused by: java.lang.NullPointerException
at user.eval__2403$fn__2405.invoke(Unknown Source)
at user.eval__2403.invoke(Unknown Source)
at clojure.lang.Compiler.eval(Compiler.java:3997)
... 1 more



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: NPE with binding [was: Repl over Socket, binding and threads]

2008-10-09 Thread ntupel

On Thu, 2008-10-09 at 22:06 +0200, ntupel wrote:
> After further investigation and experimentation with macros I finally
> managed to trigger a NullpointerException:
> 
> user=> (defmacro on-thread [env exp] `(doto (new Thread #(binding ~env 
> (~exp))) (start)))

Ignore me. That's like doing ((prn 42)). If I wanted functions, I'd
better pass in functions. I am now using:

(defmacro on-thread
  ([f]
`(doto (new Thread ~f) (start)))
  ([env f]
`(doto (new Thread #(binding ~env (~f))) (start

which seems to do what I wanted.



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Get thread local bindings

2008-10-10 Thread ntupel

I still try to find a way to make threads inherit thread-local
bindings established via binding in the parent thread. I searched for
a function to get the thread bindings but couldn't find one. Did I
miss anything? So I added getThreadBindings() to Var.java:

diff --git a/trunk/src/jvm/clojure/lang/Var.java
b/trunk/src/jvm/clojure/lang/Var.java
index fcbd746..59825a5 100644
--- a/trunk/src/jvm/clojure/lang/Var.java
+++ b/trunk/src/jvm/clojure/lang/Var.java
@@ -282,6 +282,18 @@ public static void releaseThreadBindings(){
dvals.set(null);
 }

+public static Associative getThreadBindings(){
+   Frame f = dvals.get();
+Associative vars = PersistentHashMap.EMPTY;
+   for(ISeq bs = RT.keys(f.frameBindings); bs != null; bs = bs.rest())
+   {
+   Var v = (Var) bs.first();
+if (v.sym != null)
+   vars = vars.assoc(v.sym, v);
+   }
+   return vars;
+}
+
 final Box getThreadBinding(){
if(count.get() > 0)
{

and with the following two functions I can finally inherit thread
local bindings.

(defn bindings []
  "Return key-value list of thread-local bindings."
  (reduce
(fn [env [n v]] (conj env n (var-get v)))
[]
(clojure.lang.Var/getThreadBindings)))

(defmacro on-thread
  "Apply the given function on another thread,
  optionally with the given bindings."
  ([f]
`(let [env# (bindings)]
   (eval `(on-thread ~env# ~~f
  ([env f]
`(doto (new Thread #(binding ~env (~f))) (start



user=> (def x)
#'user/x
user=> (doto (new Thread #(prn (bindings))) (start))
Thread[Thread-0,5,main]
user=> []
user=> (binding [x 12] (on-thread #(prn x)))
12
Thread[Thread-2,5,]
user=>


Not sure if the on-thread macro is kosher. Anyway, would it be
possible to add something like getThreadBindings to Var.java or point
out the right way to get the thread-local bindings?

Thanks,
nt

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Get thread local bindings

2008-10-11 Thread ntupel

On Fri, 2008-10-10 at 12:46 -0700, Mike Hinchey wrote:
> It's usually advised to avoid eval.

Many thanks Mike. I would like to avoid eval, but I am too stupid.
However I would love to find out how to do it. If you could give me
hunch I would be more than happy.

> See dothread-keeping in 
> http://github.com/jochu/swank-clojure/tree/master/swank/util/concurrent/thread/thread.clj
> And keep-bindings in 
> http://github.com/jochu/swank-clojure/tree/master/swank/util/util.clj

Sweet. The only thing that stops me from using these is that I cannot
provide explicitly the values I want to inherit as this would require
knowledge of bindings deep down in code that shouldn't care.

To elaborate a bit. I have an application running that provides a Repl
for maintenance clients over sockets. I started using the Repl example
from the Clojure wikibook. However in my running application the
expressions evaluated by the Repl trigger forks of new threads which
eventually show a result that should be send back to the Repl user over
the socket. But as the binding to *out* is not known in these forked
threads I will never see anything.

If I would need to explicitly say "keep *out*" I would need to do that
in application code that forks off the thread and this detail should be
of no concern to the application code that also doesn't know about the
Repl.

So I had to get the list of thread bindings which currently is not
exposed in Clojure (and I would be happy if Rich could add that). My
next problem with the Repl is, that eval calls Compiler.eval which might
also push thread bindings if the ClassLoader is not initialized,
effectively hiding the thread bindings established by binding in the
Repl code, which forced me to create a class loader before running eval
in the Repl.

The whole result looks rather messy and I would really like to see
Clojure being changed to provide an easy out of the box way to inherit
thread locals.


Here is the Repl-Code (note the clojure.lang.RT/makeClassLoader call):


(defn repl [nspace in out]
  (clojure.lang.Var/pushThreadBindings {clojure.lang.Compiler/LOADER 
(clojure.lang.RT/makeClassLoader)})
  (binding [clojure/*ns* (or (find-ns nspace) (create-ns nspace))
clojure/*warn-on-reflection* false
clojure/*out* (new OutputStreamWriter out)
clojure/*err* clojure/*out*]
(let [eof (new Object)
  r (new LineNumberingPushbackReader (new InputStreamReader in))]
  (println "Welcome User.")
  (print (ns-name *ns*) "\b=> ")
  (flush)
  (loop [e (read r false eof)]
(when-not (= e eof)
  (try
(prn (eval e))
  (catch Exception e
(.printStackTrace e)))
  (print (ns-name *ns*) "\b=> ")
  (flush)
  (recur (read r false eof))
  (clojure.lang.Var/popThreadBindings))



In the running Repl I will do things like:

app.maintenance=> (client! :connect "localhost" 8000)

which invokes a connect method which forkes off a thread to read from
the connection and print it out. Using on-thread:


(defn bindings []
  (reduce
(fn [env [n v]] (conj env n (var-get v)))
[]
(clojure.lang.Var/getThreadBindings)))

(defmacro on-thread
  ([f]
`(let [env# (bindings)]
   (eval `(on-thread ~env# ~~f
  ([env f]
`(doto (new Thread #(binding ~env (~f))) (start


"bindings" depends on the newly introduced Var.getThreadBindings()
method I posted last time. Again I don't like the eval there but I was
not able to get it working without it.

If I am completely off track here I would be grateful for corrections.
The only requirement I have is that my app code should not need to say
"keep just these bindings".

Thanks for reading this far ;-)



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Proxy Bug?

2008-10-29 Thread ntupel

Consider the following code which attempts to redefine clojure/*out*:


(ns test
  (:refer-clojure))

(def output System/out)

(def output-stream
  (let [buffer (new java.io.ByteArrayOutputStream)]
(proxy [java.io.OutputStream] []
  (flush []
(.append output (.toString buffer "UTF-8"))
(.reset buffer))
  (write [x]
(when (>= (.size buffer) 32)
  (.flush this))
(.write buffer x))
  (write [x off len]
(.write buffer x off len)

(in-ns 'clojure)
(def *out* (new java.io.OutputStreamWriter test/output-stream "UTF-8"))


This works, but according to the the documentation of clojure/proxy it
seems that "If a method fn is not provided for a class method, the
superclass methd will be called." [1] However if I omit the second write
method in the proxy definition, I get the following error:


user=> (load-file "test.clj")
#=(var clojure/*out*)
user=> (prn "hello")
java.lang.IllegalArgumentException: Wrong number of args passed to: fn--2490$fn 
(NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.IllegalArgumentException: Wrong number of args passed to: fn--2490$fn 
(NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4122)
at clojure.lang.Repl.main(Repl.java:91)
Caused by: java.lang.IllegalArgumentException: Wrong number of args passed to: 
fn--2490$fn
at clojure.lang.AFn.throwArity(AFn.java:460)
at clojure.lang.AFn.invoke(AFn.java:75)
at clojure.lang.Proxy__2499.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
at clojure.flush__906.invoke(boot.clj:1658)
at clojure.prn__909.doInvoke(boot.clj:1667)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at user.eval__2503.invoke(Unknown Source)
at clojure.lang.Compiler.eval(Compiler.java:4111)
... 1 more


[1] http://clojure.org/java_interop#toc20



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Proxy Bug?

2008-10-30 Thread ntupel

On Wed, 2008-10-29 at 23:44 -0700, mb wrote:
> But proxy-super to the rescue: You may try the following snippet
> for the write method:

Nice. Never heard of proxy-super before. Would be nice to mention it on
the Java interop page and not only on the API page.

> 
>(write
>  ([x]
>   (when (>= (.size buffer) 32)
> (.flush this))
>   (.write buffer x))
>  ([x off len]
>   (proxy-super write x off len)))
> 
> Since there is a write method, we have to call the super-class'
> method explicitely.

Tried it but it fails with:

java.lang.reflect.InvocationTargetException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4122)
at clojure.lang.Repl.main(Repl.java:91)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:86)
at
clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
at test.fn__2490$fn__2492$fn__2495.invoke(test.clj:18)
at clojure.proxy_call_with_super__2077.invoke(proxy.clj:264)
at test.fn__2490$fn__2492.invoke(test.clj:18)
at clojure.lang.Proxy__2503.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at
sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
at clojure.flush__906.invoke(boot.clj:1658)
at clojure.prn__909.doInvoke(boot.clj:1667)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at user.eval__2507.invoke(Unknown Source)
at clojure.lang.Compiler.eval(Compiler.java:4111)
... 1 more
Caused by: java.lang.AbstractMethodError: java.io.OutputStream.write(I)V
at clojure.lang.Proxy__2503.write(Unknown Source)
at java.io.OutputStream.write(OutputStream.java:99)
at clojure.lang.Proxy__2503.write(Unknown Source)
... 21 more


Interestingly java.io.OutputStream.write(I)V is invoked even though this
should be covered by the proxy write method.

> Hope this helps.

Despite the error it did. 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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Proxy Bug?

2008-10-30 Thread ntupel

On Thu, 2008-10-30 at 01:37 -0700, mb wrote:
> I lookep up the implementation of proxy-super. It replaces the
> method temporarily. So proxy-super basically doesn't work for
> methods with multiple implementations for different arglists,
> since only the actually called method-arglist combination is
> then in effect. I think it throws the Exception because now,
> the first implementation is missing and it is abstract in the
> superclass.

Yes, after I looked into proxy-super I came to the the same conclusion.
I wonder though what can be done about this limitation of the proxy
approach, as according to the documentation of proxy, access to super
can not be proxied. What a pity.



--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Agent errors reporting

2008-11-15 Thread ntupel

Currently agent errors are only reported when the agent is derefenced
or further actions are dispatched to the agent. It would be great if
one can get immediate notification of agent errors maybe through a
callback.

Thanks,
nt

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



seq and vector

2008-11-22 Thread ntupel

In one of my data structures I have a vector as a buffer where things
are appended to. In addition the things in that buffer sometimes get
modified using map or filter. Now as map and filter return sequences I
wonder how to get a vector back efficiently. I need a vector in order
for conj to append and not to prepend as it happens with sequences,
otherwise the order would be screwed. What is the most efficient (and
still idiomatic) way to achieve this?

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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---