Why do transactions block each other?

2011-08-29 Thread Dominikus
My understanding of transactions is that they don't block each other
even when the same refs are involved. Obviously, I'm wrong, see the
following scenario:

user=> (def thread (agent "Thread"))
#'user/thread
user=> (def account (ref 1000))
#'user/account
user=> (send thread
  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
account)
#
user=> (time (dosync (ref-set account 2000)))
"Elapsed time: 6838.605366 msecs"
2000

Trying '(dosync (ref-set account 2000))' while the thread is running
blocks the REPL. Interestingly, the threaded transaction isn't retried
as a effect of changing the ref-value while the threaded-transaction
is still running. My understanding is that the threaded transaction
tries to commit *after* Thread/sleep, realizes a changed value for
account and retries the transaction. (BTW, if 'alter' is replaced by
'commute', the REPL does not block.)

What's really going on behind the scenes? What am I missing?

Cheers,

Dominikus

-- 
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 do transactions block each other?

2011-08-29 Thread Stuart Sierra
Hi Dominikus,

I think what you're seeing here is that transactions are synchronous
from the point of view of the calling thread. Within your REPL thread,
it is guaranteed that the transaction has committed before the
`dosync` block returns. So even if transactions are getting aborted
and retried behind the scenes, the thread that initiated the
transaction still blocks until it is finished. As to which transaction
"wins", I'm not sure what the rule is.

-Stuart Sierra
clojure.com

-- 
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: ClojureScript can't call JavaScript functions relying on `this`

2011-08-29 Thread Chouser
On Sun, Aug 28, 2011 at 9:22 PM, Kevin Lynagh  wrote:
> I am having trouble using ClojureScript to call JavaScript functions
> that exploit prototype injection.
> If I'm reading `defmethod :emit invoke` correctly,
>
>    
> https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L513
>
> ClojureScript always seems to compile f(x) JavaScript calls as
>
>    f.call(null, x)
>
> which trip up any functions that rely on `this` to have certain
> properties.
> I have two questions:
>
> 1) why are function calls compiled to the `f.call(null, ...)` form
> rather than just `f(...)`? Is it to support the Closure Compiler?
>
> 2) What is the appropriate way to use JavaScript functions that rely
> on `this`?
> Is there some way to emit `f.call(f, ...)`, or do I need to use `(js*
> "f(...)")`?
>
> For reference, here is a minimal JavaScript example of the JavaScript
> prototype injection pattern:
>
>    var p_injection = function(){};
>    p_injection.one = function(){ return 1; };
>
>    var MyClass = function(){};
>
>    var x = new MyClass();
>    x.two = function(){  return this.one() + 1; };
>    x.__proto__ = p_injection;
>    x.two(); // 2
>    x.two.call(null); // error, object has no method "one()"

Have you tried calling the method using the interop form?

(. x (two))

--Chouser

-- 
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 do transactions block each other?

2011-08-29 Thread Stefan Kamphausen
Hi,

the commute case can be understood:

user=> (send thread (fn [agt aref] (dosync (commute aref + 100) 
(Thread/sleep 8000) agt)) account)
#
user=> (time (dosync (ref-set account 2000)))
"Elapsed time: 0.369415 msecs"
2000
user=> @account
2000
;; wait a few seconds
user=> @account
2100

So, the transaction run from the agent just recalculates the values at the 
end of the transaction again, based upon the value the ref has then.

See LockingTransaction.java:290:

vals.put(ref, f.fn.applyTo(RT.cons(vals.get(ref), f.args)));

So in this case the ref-set from the REPL thread comes first.

As for the other effect, that the REPL thread blocks until the eight seconds 
from the agent-transaction are finished, we can clearly see that the ref-set 
call is the last comitter, because the ref has the value 2000 afterwards:

user=> (dosync (ref-set account 1000))
1000
user=> (send thread (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 
8000) agt)) account)
#
user=> (time (dosync (ref-set account 2000)))
"Elapsed time: 5241.963286 msecs"
2000
;; again wait a few seconds for good measure
user=> @account
2000

I have to confess, that I don't understand that, yet.   I was first guessing 
it could be related to the history, but the history is still zero:

user=> (.getHistoryCount account)
0

Unless someone else answers this I will try to find some time to dive into 
it this evening (CEST). Adding a few atoms as counters here and there 
usually helps understanding, what is going on under the hooks.

Regards,
Stefan

PS: Starting a thread with a transaction using future seems easier to me, 
e.g.:

(future (dosync (alter account + 100) (Thread/sleep 8000)))

-- 
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 do transactions block each other?

2011-08-29 Thread Meikel Brandmeyer (kotarak)
Hi,

alter obviously has a similar effect as ensure. Exchanging the sleep and the 
alter will allow the repl thread to do its ref-set and the background thread 
will retry.

Don't ask me for the details of why and how...

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: is there a 4Clojure forum anywhere?

2011-08-29 Thread chepprey
@Bob --  recovery group, stop now, --  hehehe.   It certainly is a
great website for when I get bored with the daily grind of enterprise-
Java coding.  I guess I was lucky to get stuck on one problem.

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


[ANN] Clojure 1.3 Beta 2

2011-08-29 Thread Christopher Redinger
Clojure 1.3 Beta 2 is now available at 

http://clojure.org/downloads

The list of changes:

  * clojure.test/*/*-report vars made dynamic for use with external
tools.
  * Calls favor arg vectors :tag over var :tag (CLJ-811)
  * BigInt ops made faster when values are small enough to be treated as 
longs
  * rational? metadata fixed
  * partition and partition-all holds less
  * Bug fixed on transient vectors
  * print-dup and print-method removed for deftypes (CLJ-812)
  * Prevent make-parents NPE, (CLJ-808)
  * Special print support removed for BigIntegers. (CLJ-798)

Please grab it and let us know how it works for you.

Thanks!

--
Chris Redinger
Clojure/core
http://clojure.com

-- 
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: ClojureScript can't call JavaScript functions relying on `this`

2011-08-29 Thread Kevin Lynagh
Chouser,

Yes, that does it---I didn't even think about my use of (apply js/f
args), thanks!

Is there a way to use the interop form with variable-arity JavaScript
functions without using `apply`?
This issue came up with my ClojureScript wrapper for D3; I'm using
this macro

(defmacro shim [name]
  "Define a proxy to native D3 method"
  `(defn ~name [sel# & args#]
 (apply (. sel# ~name) args#)))

to define proxy functions.
If I can't use `apply` because of the `this = null` problem, do I have
to write out a case for each arity?

thanks,
kevin

On Aug 29, 6:24 am, Chouser  wrote:
> On Sun, Aug 28, 2011 at 9:22 PM, Kevin Lynagh  wrote:
> > I am having trouble using ClojureScript to call JavaScript functions
> > that exploit prototype injection.
> > If I'm reading `defmethod :emit invoke` correctly,
>
> >    https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/com...
>
> > ClojureScript always seems to compile f(x) JavaScript calls as
>
> >    f.call(null, x)
>
> > which trip up any functions that rely on `this` to have certain
> > properties.
> > I have two questions:
>
> > 1) why are function calls compiled to the `f.call(null, ...)` form
> > rather than just `f(...)`? Is it to support the Closure Compiler?
>
> > 2) What is the appropriate way to use JavaScript functions that rely
> > on `this`?
> > Is there some way to emit `f.call(f, ...)`, or do I need to use `(js*
> > "f(...)")`?
>
> > For reference, here is a minimal JavaScript example of the JavaScript
> > prototype injection pattern:
>
> >    var p_injection = function(){};
> >    p_injection.one = function(){ return 1; };
>
> >    var MyClass = function(){};
>
> >    var x = new MyClass();
> >    x.two = function(){  return this.one() + 1; };
> >    x.__proto__ = p_injection;
> >    x.two(); // 2
> >    x.two.call(null); // error, object has no method "one()"
>
> Have you tried calling the method using the interop form?
>
> (. x (two))
>
> --Chouser

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


ClojureScript and lein?

2011-08-29 Thread Michael Jaaka
Hello,

I wanted to give a try to ClojureScript but from Windows XP.
Now I was doing all what is written on github but had to remove -server to 
obey "missing jvm.dll" problem (even after coping server path there was 
still a problem about loading some routine) and had to add to ENV Variables 
CLOJURESCRIPT_HOME with "D:/clojurescript/" (note the last /)
Now I'm able to compile hello.cljs to hello.js and put reference to 
test.html but still it doesn't work. I think that there is some problem with 
relative paths.

What I'm using is: JRE (not SDK since have problem with jvm as written 
above), Chrome as Browser and rest newest fetched with boostrap.

My final thought is that running it is a nightmare and you wont gain 
critical mass to get some feedback from community.
So the other thought is why can the lein do the job? Has anyone tried? I'm 
also a Mac user and probably in home all this howto will work, but in 
company where we all are using Windows there is no chance to get it 
working easily.
In case you care how to set ENV Variable from batch on win32 it is:

(defn set-env-variable [ name value]
(console (str "Setting environment variable \"" name "\" to \"" value "\""))
(command "reg add HKCU\\Environment /v" name "/f /t REG_SZ /d" (str "\"" 
value "\"")))

Where command is just a cmd (args are interposed with space) call and 
console is an output to cmd console.


-- 
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 do transactions block each other?

2011-08-29 Thread Stefan Kamphausen
The call to alter already wrote to the Ref, this requires a write-lock on 
the ref (see LockingTransaction.java/doSet).  After that it sleeps a while 
and gets to its commit phase.  The other transactions retries in the 
meantime.  Consider the following code, which introduces some atoms for 
counting the retries

(defn tz []
  (let [rr (ref 10)
a1 (atom 0)
a2 (atom 0)]
(println "Starting future")
(future
 (dosync
  (swap! a1 inc)
  (alter rr + 100)
  (Thread/sleep 8000)))
(println "Sleeping a bit")
(Thread/sleep 1000)
(println "Another dosync")
(time
 (dosync
  (swap! a2 inc)
  (ref-set rr 1)))
[@rr @a1 @a2 (.getHistoryCount rr)]))

user> (tz)
Starting future
Sleeping a bit
Another dosync
"Elapsed time: 7001.554 msecs"
[1 1 71 0]

Note, how the 71 retries nice fit the approximately 7 seconds left and the 
100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in 
LockingTransaction.java/tryWriteLock.

Transactions with significantly different run-times should be avoided, 
although there is some point at which older transactions will get their 
turn.  This could be another explanation of the effect.  Take a look at the 
barge-function in LockingTransaction.java

Hope this helps,
Stefan 

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

get keys from defrecord

2011-08-29 Thread Razvan Rotaru
Hi,

Assuming I have:

(defrecord myrecord [:a :b :c])

is there a way to get the list of keys from the record definition?

Thanks,
Razvan

-- 
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: get keys from defrecord

2011-08-29 Thread Aaron Bedra

user=> (defrecord MyRecord [a b c])
user.MyRecord
user=> (def rec (user.MyRecord. "one" "two" "three"))
#'user/rec
user=> (keys rec)
(:a :b :c)


Cheers,

Aaron Bedra
--
Clojure/core
http://clojure.com

On 08/29/2011 12:54 PM, Razvan Rotaru wrote:

Hi,

Assuming I have:

(defrecord myrecord [:a :b :c])

is there a way to get the list of keys from the record definition?

Thanks,
Razvan



--
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 do transactions block each other?

2011-08-29 Thread Dominikus
Thanks a lot for this detailed analysis and the pointers to the Java
implementation, Stefan! That's excellent and very helpful.

I still wonder, why the first transaction blocks write access. My
overall understanding of the transaction system is that changes to
referenced values remain in-transaction before committing them, a
write-lock shouldn't be needed. I'm surprised, that the second
transaction is the one who has to retry 71 times even though the first
transaction hasn't committed anything yet.

Cheers,

Dominikus

P.S.: Thanks for the idea to use 'future' to spawn a thread!

On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
> The call to alter already wrote to the Ref, this requires a write-lock on
> the ref (see LockingTransaction.java/doSet).  After that it sleeps a while
> and gets to its commit phase.  The other transactions retries in the
> meantime.  Consider the following code, which introduces some atoms for
> counting the retries
>
> (defn tz []
>   (let [rr (ref 10)
>         a1 (atom 0)
>         a2 (atom 0)]
>     (println "Starting future")
>     (future
>      (dosync
>       (swap! a1 inc)
>       (alter rr + 100)
>       (Thread/sleep 8000)))
>     (println "Sleeping a bit")
>     (Thread/sleep 1000)
>     (println "Another dosync")
>     (time
>      (dosync
>       (swap! a2 inc)
>       (ref-set rr 1)))
>     [@rr @a1 @a2 (.getHistoryCount rr)]))
>
> user> (tz)
> Starting future
> Sleeping a bit
> Another dosync
> "Elapsed time: 7001.554 msecs"
> [1 1 71 0]
>
> Note, how the 71 retries nice fit the approximately 7 seconds left and the
> 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
> LockingTransaction.java/tryWriteLock.
>
> Transactions with significantly different run-times should be avoided,
> although there is some point at which older transactions will get their
> turn.  This could be another explanation of the effect.  Take a look at the
> barge-function in LockingTransaction.java
>
> Hope this helps,
> Stefan

-- 
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: get keys from defrecord

2011-08-29 Thread Tassilo Horn
Aaron Bedra  writes:

> user=> (defrecord MyRecord [a b c])
> user.MyRecord
> user=> (def rec (user.MyRecord. "one" "two" "three"))
> #'user/rec
> user=> (keys rec)
> (:a :b :c)

I guess the problem with that is that you need to have an instance of
the record before you can use `keys'.  And to create an instance, at
least you have to know the number of keys.

However, you can inspect the record's constructor using reflection:

  (-> MyRecord .getConstructors first .getParameterTypes)

This gets you an array of the record's parameter types.  It seems, that
the last 2 Object parameters are some internal stuff (metadata?), so the
array length - 2 is the arity.

  (-> MyRecord .getConstructors first .getParameterTypes)
  ==> 5 ;; so the record has 3 keys

If the record doesn't have fields hinted with primitive types, then
that's enough knowledge to create an instance.  If there are primitive
type hints, then the constructor has primitive type parameters you have
to match when calling it.

All in all, it seems there's everything you need to create a function
that creates a dummy instance of arbitrary (unknown) records that you
can query for its keys afterwards.

But maybe there's a better way... :-)

Bye,
Tassilo

> On 08/29/2011 12:54 PM, Razvan Rotaru wrote:
>> Hi,
>>
>> Assuming I have:
>>
>> (defrecord myrecord [:a :b :c])
>>
>> is there a way to get the list of keys from the record definition?
>>
>> Thanks,
>> Razvan
>>

-- 
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 do transactions block each other?

2011-08-29 Thread Stefan Kamphausen
Hm,

while I was just reading the source of the STM implementation in Ref.java 
and LockingTransaction.java two new questions came up for me.

1. Is there any use of the msecs field in the inner TVal in Ref? I don't see 
any and if it's not used anymore, at least two calls to 
System.currentTimeMillis() could be removed (one in Ref, the other in 
LockingTransaction).  As far as I undestand, that call is considered 
expensive.

2. I found this post 
http://dow.ngra.de/2008/10/27/when-systemcurrenttimemillis-is-too-slow/ 
rather interesting to read and I wonder, whether such a thing could be used 
in bargeTimeElapsed() which is only interested in whether an interval has 
passed or not, too.

Could this lead to a performance improvement?

Kind regards,
Stefan

-- 
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: JVM 7 support (invokedynamic)

2011-08-29 Thread Tal Liron
Progress... is slow.

I encouraged other people to try, so the least I can do now is to point you 
at some of the serious challenges.

Right now I have what I think is a nice semi-generic mechanism for 
invokedynamic. It's called the "Linker": it handles finding the target 
method handle, bootstrapping, and what I call "restrapping", which is what 
happens when you guard it with an "ILinkable" (another new interface) and it 
fallbacks when a SwitchPoint is invalidated. There some various MethodHandle 
composing to make sure caller and target are both happy. I hope the "Linker" 
will make is easier to add invokedynamic in Clojure, and possibly in other 
projects.

My real challenge is not there, however, but with adapting Clojure to JVM 7 
more generally. invokedynamic requires V1.7 classes, and for V1.7 the stack 
frame map that was optional in V1.6 is now a requirement. This is overall a 
very good idea for moving the JVM forward (these maps are a huge help for 
HotSpot), but I have no doubt that it will create serious pain for any 
project that generates JVM bytecode and until JVM 7 now could afford to be 
sloppier with stack frames. The V1.7 verifier will simply not let you load 
classes that don't have perfectly aligned maps.

ASM has very nice support for doing the stack frame arithmetic for you, but 
this is still being worked on in ASM 4 (trunk), and is not working in 
Clojure. I'm getting VerifyErrors specifically having to do with the mapping 
of try-catch blocks, and am working on debugging this via close look at 
CheckClassAdapter dumps. It's about as much fun as filling in tax forms. :/

(I've added support for two new defines, -Dclojure.jvm7=true and 
-Dclojure.invokedynamic=true, so each can be turned on separately. To be 
clear, my problems right now are in -Dclojure.jvm7=true and 
-Dclojure.invokedynamic=false.)

I've already patched one tiny part of ASM commons in order to add support 
for invokedynamic, and my work on debugging this may result in a more major 
patch to ASM. Assuming I do manage a fix. :/

So, what can I say? It's the cutting edge, baby. In for a penny, in for a 
pound.

-Tal

-- 
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: get keys from defrecord

2011-08-29 Thread Laurent PETIT
Hi, it could help if you can provide more info on what you're trying to
achieve

2011/8/29 Razvan Rotaru 

> Hi,
>
> Assuming I have:
>
> (defrecord myrecord [:a :b :c])
>
> is there a way to get the list of keys from the record definition?
>
> Thanks,
> Razvan
>
> --
> 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: Why do transactions block each other?

2011-08-29 Thread Laurent PETIT
2011/8/29 Dominikus 

> Thanks a lot for this detailed analysis and the pointers to the Java
> implementation, Stefan! That's excellent and very helpful.
>
> I still wonder, why the first transaction blocks write access. My
> overall understanding of the transaction system is that changes to
> referenced values remain in-transaction before committing them, a
> write-lock shouldn't be needed. I'm surprised, that the second
> transaction is the one who has to retry 71 times even though the first
> transaction hasn't committed anything yet.
>

I must confess this behaviour also challenges my assumptions.

Does this work the same whatever the clojure version used ?


>
> Cheers,
>
> Dominikus
>
> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>
> On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
> > The call to alter already wrote to the Ref, this requires a write-lock on
> > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
> while
> > and gets to its commit phase.  The other transactions retries in the
> > meantime.  Consider the following code, which introduces some atoms for
> > counting the retries
> >
> > (defn tz []
> >   (let [rr (ref 10)
> > a1 (atom 0)
> > a2 (atom 0)]
> > (println "Starting future")
> > (future
> >  (dosync
> >   (swap! a1 inc)
> >   (alter rr + 100)
> >   (Thread/sleep 8000)))
> > (println "Sleeping a bit")
> > (Thread/sleep 1000)
> > (println "Another dosync")
> > (time
> >  (dosync
> >   (swap! a2 inc)
> >   (ref-set rr 1)))
> > [@rr @a1 @a2 (.getHistoryCount rr)]))
> >
> > user> (tz)
> > Starting future
> > Sleeping a bit
> > Another dosync
> > "Elapsed time: 7001.554 msecs"
> > [1 1 71 0]
> >
> > Note, how the 71 retries nice fit the approximately 7 seconds left and
> the
> > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
> > LockingTransaction.java/tryWriteLock.
> >
> > Transactions with significantly different run-times should be avoided,
> > although there is some point at which older transactions will get their
> > turn.  This could be another explanation of the effect.  Take a look at
> the
> > barge-function in LockingTransaction.java
> >
> > Hope this helps,
> > Stefan
>
> --
> 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

Clojurescript Beginner's Question

2011-08-29 Thread atucker
Hi!  I wonder if someone might tell me what I'm doing wrong here.

(ns hello (:require [goog.fx :as fx] [goog.dom :as dom]))

(defn ^:export main []
  (let [kurdt (dom/getElement "kurdt")]
(dom/appendChild (.body (dom/getDocument)) (dom/createDom "h1" 0
(dom/getOuterHtml kurdt)))
(fx/Dragger. kurdt)
(dom/appendChild (.body (dom/getDocument)) (dom/createDom "h1" 0
(dom/getOuterHtml kurdt)

with the HTML:




  
  
  
hello.main();
  



As you can see here 
http://www2.warwick.ac.uk/fac/cross_fac/comcom/dtcsite/people/students2009/tucker/test2,
I am only getting the first output, as if the call to fx/Dragger. is
stopping the script.

Thank you!  Alistair

-- 
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 do transactions block each other?

2011-08-29 Thread Laurent PETIT
Congratulations, you've found a bug in clojure 1.3 beta2, see:

 look with my clojure 1.2.0 version :

;; Clojure 1.2.0
=> (def thread (agent "Thread"))
   (def account (ref 1000))
   (send thread
 (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
 account)
   (time (dosync (ref-set account 2000)))
#'user/thread
#'user/account
#
"Elapsed time: 0.498106 msecs"
2000
=> ;; 10 seconds later :
=> @account
2100


And now with clojure 1.3 beta1 :

;; Clojure 1.3.0-beta1
=> (def thread (agent "Thread"))
   (def account (ref 1000))
   (send thread
 (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
 account)
   (time (dosync (ref-set account 2000)))
   ;; 10 seconds later :
#'user/thread
#'user/account
#
"Elapsed time: 0.270225 msecs"
2000
=> @account
2100

And now with Clojure 1.3-beta2
;; Clojure 1.3.0-beta2
=> (def thread (agent "Thread"))
   (def account (ref 1000))
   (send thread
 (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
 account)
   (time (dosync (ref-set account 2000)))
#'user/thread
#'user/account
#
"Elapsed time: 7957.328798 msecs"
2000
   ;; 10 seconds later :
=> @account
2000
   ;; 10 more seconds later :
=> @account
2000

2011/8/30 Laurent PETIT 

> 2011/8/29 Dominikus 
>
>> Thanks a lot for this detailed analysis and the pointers to the Java
>> implementation, Stefan! That's excellent and very helpful.
>>
>> I still wonder, why the first transaction blocks write access. My
>> overall understanding of the transaction system is that changes to
>> referenced values remain in-transaction before committing them, a
>> write-lock shouldn't be needed. I'm surprised, that the second
>> transaction is the one who has to retry 71 times even though the first
>> transaction hasn't committed anything yet.
>>
>
> I must confess this behaviour also challenges my assumptions.
>
> Does this work the same whatever the clojure version used ?
>
>
>>
>> Cheers,
>>
>> Dominikus
>>
>> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>>
>> On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
>> > The call to alter already wrote to the Ref, this requires a write-lock
>> on
>> > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
>> while
>> > and gets to its commit phase.  The other transactions retries in the
>> > meantime.  Consider the following code, which introduces some atoms for
>> > counting the retries
>> >
>> > (defn tz []
>> >   (let [rr (ref 10)
>> > a1 (atom 0)
>> > a2 (atom 0)]
>> > (println "Starting future")
>> > (future
>> >  (dosync
>> >   (swap! a1 inc)
>> >   (alter rr + 100)
>> >   (Thread/sleep 8000)))
>> > (println "Sleeping a bit")
>> > (Thread/sleep 1000)
>> > (println "Another dosync")
>> > (time
>> >  (dosync
>> >   (swap! a2 inc)
>> >   (ref-set rr 1)))
>> > [@rr @a1 @a2 (.getHistoryCount rr)]))
>> >
>> > user> (tz)
>> > Starting future
>> > Sleeping a bit
>> > Another dosync
>> > "Elapsed time: 7001.554 msecs"
>> > [1 1 71 0]
>> >
>> > Note, how the 71 retries nice fit the approximately 7 seconds left and
>> the
>> > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
>> > LockingTransaction.java/tryWriteLock.
>> >
>> > Transactions with significantly different run-times should be avoided,
>> > although there is some point at which older transactions will get their
>> > turn.  This could be another explanation of the effect.  Take a look at
>> the
>> > barge-function in LockingTransaction.java
>> >
>> > Hope this helps,
>> > Stefan
>>
>> --
>> 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: JVM 7 support (invokedynamic)

2011-08-29 Thread Aaron Bedra
The version of ASM that is bundled in Clojure is very old.  This will
likely cause problems.  You are correct in looking to ASM 4 since it has
started supported the JSR-292 stuff and other Java 7 changes.  I am
planning on doing an extraction, update, and re-packaging of ASM in
Clojure as soon as Programming Clojure hits the printers.  This most
likely won't get started until October though because of conferences.

Cheers,

Aaron Bedra
--
Clojure/core
http://clojure.com

On 08/29/2011 05:53 PM, Tal Liron wrote:
> Progress... is slow.
>
> I encouraged other people to try, so the least I can do now is to
> point you at some of the serious challenges.
>
> Right now I have what I think is a nice semi-generic mechanism for
> invokedynamic. It's called the "Linker": it handles finding the target
> method handle, bootstrapping, and what I call "restrapping", which is
> what happens when you guard it with an "ILinkable" (another new
> interface) and it fallbacks when a SwitchPoint is invalidated. There
> some various MethodHandle composing to make sure caller and target are
> both happy. I hope the "Linker" will make is easier to add
> invokedynamic in Clojure, and possibly in other projects.
>
> My real challenge is not there, however, but with adapting Clojure to
> JVM 7 more generally. invokedynamic requires V1.7 classes, and for
> V1.7 the stack frame map that was optional in V1.6 is now a
> requirement. This is overall a very good idea for moving the JVM
> forward (these maps are a huge help for HotSpot), but I have no doubt
> that it will create serious pain for any project that generates JVM
> bytecode and until JVM 7 now could afford to be sloppier with stack
> frames. The V1.7 verifier will simply not let you load classes that
> don't have perfectly aligned maps.
>
> ASM has very nice support for doing the stack frame arithmetic for
> you, but this is still being worked on in ASM 4 (trunk), and is not
> working in Clojure. I'm getting VerifyErrors specifically having to do
> with the mapping of try-catch blocks, and am working on debugging this
> via close look at CheckClassAdapter dumps. It's about as much fun as
> filling in tax forms. :/
>
> (I've added support for two new defines, -Dclojure.jvm7=true and
> -Dclojure.invokedynamic=true, so each can be turned on separately. To
> be clear, my problems right now are in -Dclojure.jvm7=true and
> -Dclojure.invokedynamic=false.)
>
> I've already patched one tiny part of ASM commons in order to add
> support for invokedynamic, and my work on debugging this may result in
> a more major patch to ASM. Assuming I do manage a fix. :/
>
> So, what can I say? It's the cutting edge, baby. In for a penny, in
> for a pound.
>
> -Tal
> -- 
> 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: Why do transactions block each other?

2011-08-29 Thread Laurent PETIT
ok so now i'm totally confused, since I cannot see why the behaviour is so
different between beta1 and beta 2 ...

2011/8/30 Laurent PETIT 

> Congratulations, you've found a bug in clojure 1.3 beta2, see:
>
>  look with my clojure 1.2.0 version :
>
> ;; Clojure 1.2.0
> => (def thread (agent "Thread"))
>(def account (ref 1000))
>(send thread
>  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
> agt))
>  account)
>(time (dosync (ref-set account 2000)))
> #'user/thread
> #'user/account
> #
> "Elapsed time: 0.498106 msecs"
> 2000
> => ;; 10 seconds later :
> => @account
> 2100
>
>
> And now with clojure 1.3 beta1 :
>
> ;; Clojure 1.3.0-beta1
> => (def thread (agent "Thread"))
>(def account (ref 1000))
>(send thread
>  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
> agt))
>  account)
>(time (dosync (ref-set account 2000)))
>;; 10 seconds later :
> #'user/thread
> #'user/account
> #
> "Elapsed time: 0.270225 msecs"
> 2000
> => @account
> 2100
>
> And now with Clojure 1.3-beta2
> ;; Clojure 1.3.0-beta2
> => (def thread (agent "Thread"))
>(def account (ref 1000))
>(send thread
>  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
> agt))
>  account)
>(time (dosync (ref-set account 2000)))
> #'user/thread
> #'user/account
> #
> "Elapsed time: 7957.328798 msecs"
> 2000
>;; 10 seconds later :
> => @account
> 2000
>;; 10 more seconds later :
> => @account
> 2000
>
> 2011/8/30 Laurent PETIT 
>
>> 2011/8/29 Dominikus 
>>
>>> Thanks a lot for this detailed analysis and the pointers to the Java
>>> implementation, Stefan! That's excellent and very helpful.
>>>
>>> I still wonder, why the first transaction blocks write access. My
>>> overall understanding of the transaction system is that changes to
>>> referenced values remain in-transaction before committing them, a
>>> write-lock shouldn't be needed. I'm surprised, that the second
>>> transaction is the one who has to retry 71 times even though the first
>>> transaction hasn't committed anything yet.
>>>
>>
>> I must confess this behaviour also challenges my assumptions.
>>
>> Does this work the same whatever the clojure version used ?
>>
>>
>>>
>>> Cheers,
>>>
>>> Dominikus
>>>
>>> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>>>
>>> On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
>>> > The call to alter already wrote to the Ref, this requires a write-lock
>>> on
>>> > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
>>> while
>>> > and gets to its commit phase.  The other transactions retries in the
>>> > meantime.  Consider the following code, which introduces some atoms for
>>> > counting the retries
>>> >
>>> > (defn tz []
>>> >   (let [rr (ref 10)
>>> > a1 (atom 0)
>>> > a2 (atom 0)]
>>> > (println "Starting future")
>>> > (future
>>> >  (dosync
>>> >   (swap! a1 inc)
>>> >   (alter rr + 100)
>>> >   (Thread/sleep 8000)))
>>> > (println "Sleeping a bit")
>>> > (Thread/sleep 1000)
>>> > (println "Another dosync")
>>> > (time
>>> >  (dosync
>>> >   (swap! a2 inc)
>>> >   (ref-set rr 1)))
>>> > [@rr @a1 @a2 (.getHistoryCount rr)]))
>>> >
>>> > user> (tz)
>>> > Starting future
>>> > Sleeping a bit
>>> > Another dosync
>>> > "Elapsed time: 7001.554 msecs"
>>> > [1 1 71 0]
>>> >
>>> > Note, how the 71 retries nice fit the approximately 7 seconds left and
>>> the
>>> > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
>>> > LockingTransaction.java/tryWriteLock.
>>> >
>>> > Transactions with significantly different run-times should be avoided,
>>> > although there is some point at which older transactions will get their
>>> > turn.  This could be another explanation of the effect.  Take a look at
>>> the
>>> > barge-function in LockingTransaction.java
>>> >
>>> > Hope this helps,
>>> > Stefan
>>>
>>> --
>>> 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: JVM 7 support (invokedynamic)

2011-08-29 Thread Tal Liron

  
  
On 08/29/2011 06:01 PM, Aaron Bedra wrote:

  The version of ASM that is bundled in Clojure is very old.  This will
likely cause problems.  You are correct in looking to ASM 4 since it has
started supported the JSR-292 stuff and other Java 7 changes.  I am
planning on doing an extraction, update, and re-packaging of ASM in
Clojure as soon as Programming Clojure hits the printers.  This most
likely won't get started until October though because of conferences.


I've already done that for my branch (that was a task in itself!
needed a little monkeypatching to support Clojure's
DynamicClassLoader), so you may want to leave it to me.

My code is in quite a messy state now and I'm embarrassed to make it
public quite yet...

BTW, does somebody have an Eclipse Java code formatter configuration
for Clojure's wacky coding style?

-Tal
  




-- 
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: get keys from defrecord

2011-08-29 Thread Alex Miller
There is no good way to do this in 1.2 other than using the instance
mechanism that Aaron suggests.  I have had this need myself for
several meta-programming type use cases (building specialized record
serializers, universal record constructors, etc).  We wrap defrecord
in our own macros that generate multimethod implementations at record
construction time.

One possible solution is to use Java reflection to grab the fields
directly.  Clojure generates some in the class, but I think they all
start with an _, so you skip those and probably come up with the
correct fields.  However, I presume the names would be mangled and
you'd need to de-mangle them.

I'm not sure if there are any enhancements in the 1.3 record support
for this feature.



On Aug 29, 11:54 am, Razvan Rotaru  wrote:
> Hi,
>
> Assuming I have:
>
> (defrecord myrecord [:a :b :c])
>
> is there a way to get the list of keys from the record definition?
>
> Thanks,
> Razvan

-- 
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: get keys from defrecord

2011-08-29 Thread Lee Spector

On Aug 29, 2011, at 2:57 PM, Tassilo Horn wrote:
> 
> I guess the problem with that is that you need to have an instance of
> the record before you can use `keys'.  And to create an instance, at
> least you have to know the number of keys.
> 
> However, you can inspect the record's constructor using reflection:

Or, if structs will do for your application, then you can do this more simply:

user=> (defstruct mystruct :a :b :c)
#'user/mystruct
user=> (keys (struct-map mystruct))
(:a :b :c)

 -Lee

-- 
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: ClojureScript and lein?

2011-08-29 Thread Eric Lavigne
> I wanted to give a try to ClojureScript but from Windows XP.
> Now I was doing all what is written on github but had to remove -server to
> obey "missing jvm.dll" problem (even after coping server path there was
> still a problem about loading some routine)

After copying the server path, you found another problem about loading
some routine. What was the error message?

> Now I'm able to compile hello.cljs to hello.js and put reference to
> test.html but still it doesn't work. I think that there is some problem with
> relative paths.

Exactly what commands did you use to compile hello.cljs? The getting
started page shows how to do it from both the shell and the REPL, and
I suggest trying both. Did you get any error messages at this point?
If you open hello.js, do you see something that looks like Javascript?

> My final thought is that running it is a nightmare and you wont gain
> critical mass to get some feedback from community.

It is easy to install and use on Linux, and probably on Mac as well. I
was able to install it on Windows 7 using the Windows-Setup
instructions. You may be the first to test those instructions on
Windows XP. Remember that ClojureScript was only released a month ago,
and most of the people contributing to it don't have Windows. That is
why these problems can't be solved without feedback from early
adopters like yourself.

> So the other thought is why can the lein do the job? Has anyone tried?

Someone has created a Leiningen-installable ClojureScript compiler,
including automatic recompilation when your source code changes.
Unfortunately, I haven't been able to make it work on my computer, but
you could still give it a try.

 https://github.com/ibdknox/noir-cljs

> I'm
> also a Mac user and probably in home all this howto will work, but in
> company where we all are using Windows there is no chance to get it
> working easily.

There are people at your workplace who program in Clojure, or who are
willing to try it, but aren't willing to try developing on Linux or
Mac? This surprises me.

The installation issues will be ironed out eventually. It may be
better to use it at home for now, and wait a month or two before
recommending it at work.

Good luck.

-- 
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 do transactions block each other?

2011-08-29 Thread Kevin Downey
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L424
is definitely the line that causes the write lock to be acquired.

I get the same behavior on master(1.3) and 1.2.1:

the first time I run the code on a particular ref it locks for writing
while the first transaction is running, but subsequent runs do not.

1.3

user=> (def x (ref 0))
#'user/x
user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
(dosync (alter x dec
"Elapsed time: 10007.789 msecs"
0
user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
(dosync (alter x dec
"Elapsed time: 0.409 msecs"
-1
user=>

1.2

Clojure 1.2.1
user=> (def x (ref 0))
#'user/x
user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
(dosync (alter x dec
"Elapsed time: 10007.026 msecs"
0
user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
(dosync (alter x dec
"Elapsed time: 0.391 msecs"
-1
user=>


if I had to guess, I'd say that until a ref has some initial number of
history entries (1?) to satisfy readers it falls back to locking, but
I really have no clue

On Mon, Aug 29, 2011 at 4:03 PM, Laurent PETIT  wrote:
> ok so now i'm totally confused, since I cannot see why the behaviour is so
> different between beta1 and beta 2 ...
>
> 2011/8/30 Laurent PETIT 
>>
>> Congratulations, you've found a bug in clojure 1.3 beta2, see:
>>  look with my clojure 1.2.0 version :
>> ;; Clojure 1.2.0
>> => (def thread (agent "Thread"))
>>    (def account (ref 1000))
>>    (send thread
>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>> agt))
>>          account)
>>    (time (dosync (ref-set account 2000)))
>> #'user/thread
>> #'user/account
>> #
>> "Elapsed time: 0.498106 msecs"
>> 2000
>> => ;; 10 seconds later :
>> => @account
>> 2100
>>
>> And now with clojure 1.3 beta1 :
>> ;; Clojure 1.3.0-beta1
>> => (def thread (agent "Thread"))
>>    (def account (ref 1000))
>>    (send thread
>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>> agt))
>>          account)
>>    (time (dosync (ref-set account 2000)))
>>    ;; 10 seconds later :
>> #'user/thread
>> #'user/account
>> #
>> "Elapsed time: 0.270225 msecs"
>> 2000
>> => @account
>> 2100
>> And now with Clojure 1.3-beta2
>> ;; Clojure 1.3.0-beta2
>> => (def thread (agent "Thread"))
>>    (def account (ref 1000))
>>    (send thread
>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>> agt))
>>          account)
>>    (time (dosync (ref-set account 2000)))
>> #'user/thread
>> #'user/account
>> #
>> "Elapsed time: 7957.328798 msecs"
>> 2000
>>    ;; 10 seconds later :
>> => @account
>> 2000
>>    ;; 10 more seconds later :
>> => @account
>> 2000
>> 2011/8/30 Laurent PETIT 
>>>
>>> 2011/8/29 Dominikus 

 Thanks a lot for this detailed analysis and the pointers to the Java
 implementation, Stefan! That's excellent and very helpful.

 I still wonder, why the first transaction blocks write access. My
 overall understanding of the transaction system is that changes to
 referenced values remain in-transaction before committing them, a
 write-lock shouldn't be needed. I'm surprised, that the second
 transaction is the one who has to retry 71 times even though the first
 transaction hasn't committed anything yet.
>>>
>>> I must confess this behaviour also challenges my assumptions.
>>> Does this work the same whatever the clojure version used ?
>>>

 Cheers,

 Dominikus

 P.S.: Thanks for the idea to use 'future' to spawn a thread!

 On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
 > The call to alter already wrote to the Ref, this requires a write-lock
 > on
 > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
 > while
 > and gets to its commit phase.  The other transactions retries in the
 > meantime.  Consider the following code, which introduces some atoms
 > for
 > counting the retries
 >
 > (defn tz []
 >   (let [rr (ref 10)
 >         a1 (atom 0)
 >         a2 (atom 0)]
 >     (println "Starting future")
 >     (future
 >      (dosync
 >       (swap! a1 inc)
 >       (alter rr + 100)
 >       (Thread/sleep 8000)))
 >     (println "Sleeping a bit")
 >     (Thread/sleep 1000)
 >     (println "Another dosync")
 >     (time
 >      (dosync
 >       (swap! a2 inc)
 >       (ref-set rr 1)))
 >     [@rr @a1 @a2 (.getHistoryCount rr)]))
 >
 > user> (tz)
 > Starting future
 > Sleeping a bit
 > Another dosync
 > "Elapsed time: 7001.554 msecs"
 > [1 1 71 0]
 >
 > Note, how the 71 retries nice fit the approximately 7 seconds left and
 > the
 > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
 > LockingTransaction.java/tryWriteLock.
 >
 > Transactions with significantly different run-times should 

Re: Why do transactions block each other?

2011-08-29 Thread Kevin Downey
weird, it actually ping-pongs, every other run of the (time …) the
transaction in the future locks the ref writing so you get

"Elapsed time: 10006.505 msecs"
"Elapsed time: 0.358 msecs"
"Elapsed time: 9038.18 msecs"
"Elapsed time: 0.348 msecs"
"Elapsed time: 26250.854 msecs"

On Mon, Aug 29, 2011 at 6:13 PM, Kevin Downey  wrote:
> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L424
> is definitely the line that causes the write lock to be acquired.
>
> I get the same behavior on master(1.3) and 1.2.1:
>
> the first time I run the code on a particular ref it locks for writing
> while the first transaction is running, but subsequent runs do not.
>
> 1.3
>
> user=> (def x (ref 0))
> #'user/x
> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
> (dosync (alter x dec
> "Elapsed time: 10007.789 msecs"
> 0
> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
> (dosync (alter x dec
> "Elapsed time: 0.409 msecs"
> -1
> user=>
>
> 1.2
>
> Clojure 1.2.1
> user=> (def x (ref 0))
> #'user/x
> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
> (dosync (alter x dec
> "Elapsed time: 10007.026 msecs"
> 0
> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
> (dosync (alter x dec
> "Elapsed time: 0.391 msecs"
> -1
> user=>
>
>
> if I had to guess, I'd say that until a ref has some initial number of
> history entries (1?) to satisfy readers it falls back to locking, but
> I really have no clue
>
> On Mon, Aug 29, 2011 at 4:03 PM, Laurent PETIT  
> wrote:
>> ok so now i'm totally confused, since I cannot see why the behaviour is so
>> different between beta1 and beta 2 ...
>>
>> 2011/8/30 Laurent PETIT 
>>>
>>> Congratulations, you've found a bug in clojure 1.3 beta2, see:
>>>  look with my clojure 1.2.0 version :
>>> ;; Clojure 1.2.0
>>> => (def thread (agent "Thread"))
>>>    (def account (ref 1000))
>>>    (send thread
>>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>>> agt))
>>>          account)
>>>    (time (dosync (ref-set account 2000)))
>>> #'user/thread
>>> #'user/account
>>> #
>>> "Elapsed time: 0.498106 msecs"
>>> 2000
>>> => ;; 10 seconds later :
>>> => @account
>>> 2100
>>>
>>> And now with clojure 1.3 beta1 :
>>> ;; Clojure 1.3.0-beta1
>>> => (def thread (agent "Thread"))
>>>    (def account (ref 1000))
>>>    (send thread
>>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>>> agt))
>>>          account)
>>>    (time (dosync (ref-set account 2000)))
>>>    ;; 10 seconds later :
>>> #'user/thread
>>> #'user/account
>>> #
>>> "Elapsed time: 0.270225 msecs"
>>> 2000
>>> => @account
>>> 2100
>>> And now with Clojure 1.3-beta2
>>> ;; Clojure 1.3.0-beta2
>>> => (def thread (agent "Thread"))
>>>    (def account (ref 1000))
>>>    (send thread
>>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>>> agt))
>>>          account)
>>>    (time (dosync (ref-set account 2000)))
>>> #'user/thread
>>> #'user/account
>>> #
>>> "Elapsed time: 7957.328798 msecs"
>>> 2000
>>>    ;; 10 seconds later :
>>> => @account
>>> 2000
>>>    ;; 10 more seconds later :
>>> => @account
>>> 2000
>>> 2011/8/30 Laurent PETIT 

 2011/8/29 Dominikus 
>
> Thanks a lot for this detailed analysis and the pointers to the Java
> implementation, Stefan! That's excellent and very helpful.
>
> I still wonder, why the first transaction blocks write access. My
> overall understanding of the transaction system is that changes to
> referenced values remain in-transaction before committing them, a
> write-lock shouldn't be needed. I'm surprised, that the second
> transaction is the one who has to retry 71 times even though the first
> transaction hasn't committed anything yet.

 I must confess this behaviour also challenges my assumptions.
 Does this work the same whatever the clojure version used ?

>
> Cheers,
>
> Dominikus
>
> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>
> On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
> > The call to alter already wrote to the Ref, this requires a write-lock
> > on
> > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
> > while
> > and gets to its commit phase.  The other transactions retries in the
> > meantime.  Consider the following code, which introduces some atoms
> > for
> > counting the retries
> >
> > (defn tz []
> >   (let [rr (ref 10)
> >         a1 (atom 0)
> >         a2 (atom 0)]
> >     (println "Starting future")
> >     (future
> >      (dosync
> >       (swap! a1 inc)
> >       (alter rr + 100)
> >       (Thread/sleep 8000)))
> >     (println "Sleeping a bit")
> >     (Thread/sleep 1000)
> >     (println "Another dosync")
> >     (time
> >      (dosync
> >       (swap

Re: get keys from defrecord

2011-08-29 Thread Steve Miner

On Aug 29, 2011, at 8:20 PM, Alex Miller wrote:

> I'm not sure if there are any enhancements in the 1.3 record support
> for this feature.


In 1.3beta2, the record class has a static method getBasis that will give you 
the fields.  I remember Fogus mentioning this on the mailing list.  The design 
notes [1] say "These methods should not be used in Clojure code" as they're 
intended for tool support, but they seem generally useful to me.

user=> (clojure-version)
"1.3.0-beta2"
user=> (defrecord MyRecord [a b])
user.MyRecord
user=> (MyRecord/getBasis)
[a b]


[1] http://dev.clojure.org/display/design/defrecord+improvements


Steve Miner

-- 
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: Clojurescript Beginner's Question

2011-08-29 Thread Eric Lavigne
Firebug says goog.fx.Dragger is not a constructor.

Firebug's error message doesn't match my understanding of the
goog.fx.Dragger documentation, but yes, that line did stop the script.

 http://closure-library.googlecode.com/svn/docs/class_goog_fx_Dragger.html


On Mon, Aug 29, 2011 at 6:50 PM, atucker  wrote:
> Hi!  I wonder if someone might tell me what I'm doing wrong here.
>
> (ns hello (:require [goog.fx :as fx] [goog.dom :as dom]))
>
> (defn ^:export main []
>  (let [kurdt (dom/getElement "kurdt")]
>    (dom/appendChild (.body (dom/getDocument)) (dom/createDom "h1" 0
> (dom/getOuterHtml kurdt)))
>    (fx/Dragger. kurdt)
>    (dom/appendChild (.body (dom/getDocument)) (dom/createDom "h1" 0
> (dom/getOuterHtml kurdt)
>
> with the HTML:
>
> 
> 
> 
>  
>  
>  
>    hello.main();
>  
> 
> 
>
> As you can see here 
> http://www2.warwick.ac.uk/fac/cross_fac/comcom/dtcsite/people/students2009/tucker/test2,
> I am only getting the first output, as if the call to fx/Dragger. is
> stopping the script.
>
> Thank you!  Alistair
>
> --
> 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: Why do transactions block each other?

2011-08-29 Thread Kevin Downey
https://github.com/hiredman/clojure/compare/master...apocrypha-stm#L0L296

I've been playing around with the stm, and I think this change gives
you the behavior that is intuitively expected, someone else will have
to speak for correctness. ant test runs successfully but I don't know
how extensive the stm tests are.

I think the ping ponging arises because both transactions race to
acquire the write lock. Seems odd to me that it would ping pong so
regularly, but it is a concurrent program, so who knows.

Having the first writer lock may be an attempt to ensure that at least
one transaction can complete without retries.

On Mon, Aug 29, 2011 at 6:42 PM, Kevin Downey  wrote:
> weird, it actually ping-pongs, every other run of the (time …) the
> transaction in the future locks the ref writing so you get
>
> "Elapsed time: 10006.505 msecs"
> "Elapsed time: 0.358 msecs"
> "Elapsed time: 9038.18 msecs"
> "Elapsed time: 0.348 msecs"
> "Elapsed time: 26250.854 msecs"
>
> On Mon, Aug 29, 2011 at 6:13 PM, Kevin Downey  wrote:
>> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L424
>> is definitely the line that causes the write lock to be acquired.
>>
>> I get the same behavior on master(1.3) and 1.2.1:
>>
>> the first time I run the code on a particular ref it locks for writing
>> while the first transaction is running, but subsequent runs do not.
>>
>> 1.3
>>
>> user=> (def x (ref 0))
>> #'user/x
>> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
>> (dosync (alter x dec
>> "Elapsed time: 10007.789 msecs"
>> 0
>> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
>> (dosync (alter x dec
>> "Elapsed time: 0.409 msecs"
>> -1
>> user=>
>>
>> 1.2
>>
>> Clojure 1.2.1
>> user=> (def x (ref 0))
>> #'user/x
>> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
>> (dosync (alter x dec
>> "Elapsed time: 10007.026 msecs"
>> 0
>> user=> (time (do (future (dosync (alter x inc) (Thread/sleep 1)))
>> (dosync (alter x dec
>> "Elapsed time: 0.391 msecs"
>> -1
>> user=>
>>
>>
>> if I had to guess, I'd say that until a ref has some initial number of
>> history entries (1?) to satisfy readers it falls back to locking, but
>> I really have no clue
>>
>> On Mon, Aug 29, 2011 at 4:03 PM, Laurent PETIT  
>> wrote:
>>> ok so now i'm totally confused, since I cannot see why the behaviour is so
>>> different between beta1 and beta 2 ...
>>>
>>> 2011/8/30 Laurent PETIT 

 Congratulations, you've found a bug in clojure 1.3 beta2, see:
  look with my clojure 1.2.0 version :
 ;; Clojure 1.2.0
 => (def thread (agent "Thread"))
    (def account (ref 1000))
    (send thread
          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
 agt))
          account)
    (time (dosync (ref-set account 2000)))
 #'user/thread
 #'user/account
 #
 "Elapsed time: 0.498106 msecs"
 2000
 => ;; 10 seconds later :
 => @account
 2100

 And now with clojure 1.3 beta1 :
 ;; Clojure 1.3.0-beta1
 => (def thread (agent "Thread"))
    (def account (ref 1000))
    (send thread
          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
 agt))
          account)
    (time (dosync (ref-set account 2000)))
    ;; 10 seconds later :
 #'user/thread
 #'user/account
 #
 "Elapsed time: 0.270225 msecs"
 2000
 => @account
 2100
 And now with Clojure 1.3-beta2
 ;; Clojure 1.3.0-beta2
 => (def thread (agent "Thread"))
    (def account (ref 1000))
    (send thread
          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
 agt))
          account)
    (time (dosync (ref-set account 2000)))
 #'user/thread
 #'user/account
 #
 "Elapsed time: 7957.328798 msecs"
 2000
    ;; 10 seconds later :
 => @account
 2000
    ;; 10 more seconds later :
 => @account
 2000
 2011/8/30 Laurent PETIT 
>
> 2011/8/29 Dominikus 
>>
>> Thanks a lot for this detailed analysis and the pointers to the Java
>> implementation, Stefan! That's excellent and very helpful.
>>
>> I still wonder, why the first transaction blocks write access. My
>> overall understanding of the transaction system is that changes to
>> referenced values remain in-transaction before committing them, a
>> write-lock shouldn't be needed. I'm surprised, that the second
>> transaction is the one who has to retry 71 times even though the first
>> transaction hasn't committed anything yet.
>
> I must confess this behaviour also challenges my assumptions.
> Does this work the same whatever the clojure version used ?
>
>>
>> Cheers,
>>
>> Dominikus
>>
>> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>>
>> On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:

Re: Clojure 1.3 Beta 2

2011-08-29 Thread Armando Blancas
The change to beta2 isn't working for me:


  org.clojure
  clojure
  1.3.0-beta2


1.3.0-beta1 works fine.

On Aug 29, 7:28 am, Christopher Redinger  wrote:
> Clojure 1.3 Beta 2 is now available at
>
> http://clojure.org/downloads
>
> The list of changes:
>
>   * clojure.test/*/*-report vars made dynamic for use with external
>     tools.
>   * Calls favor arg vectors :tag over var :tag (CLJ-811)
>   * BigInt ops made faster when values are small enough to be treated as
> longs
>   * rational? metadata fixed
>   * partition and partition-all holds less
>   * Bug fixed on transient vectors
>   * print-dup and print-method removed for deftypes (CLJ-812)
>   * Prevent make-parents NPE, (CLJ-808)
>   * Special print support removed for BigIntegers. (CLJ-798)
>
> Please grab it and let us know how it works for you.
>
> Thanks!
>
> --
> Chris Redinger
> Clojure/corehttp://clojure.com

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


Reify creates two objects?

2011-08-29 Thread Jason Wolfe
I came across the following behavior today, and wanted to make sure
it's expected (on 1.2 and 1.3-beta2).
Each time a reify form is executed, two fresh objects seem to be
created; one is immediately thrown away, and the other is returned
from the form:

user=> (defn foo [] (let [x (reify Object (finalize [this] (println
"Finalize" this)))] (println "Create" x) x))
user=> (def x [(foo) (foo)])
Create #
Create #

user=> (System/gc)
Finalize #
Finalize #

user=> (def x nil)
user=> (System/gc)
Finalize #
Finalize #

Thanks,
Jason

-- 
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: ClojureScript Compile errors

2011-08-29 Thread David Nolen
On Wed, Aug 10, 2011 at 7:39 AM, Rich Hickey  wrote:

> :use … :only doesn't have the problems of full :use.
>
> Enhancement ticket and patch for :use … :only welcome. Note it must support
> :use … :only only, i.e. :only is required.
>
> Rich


http://dev.clojure.org/jira/browse/CLJS-65. Hopefully this is an ok
approach. Also couldn't find any tests related to namespace declaration
parsing so I didn't add any.

David

-- 
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: Clojure 1.3 Beta 2

2011-08-29 Thread Armando Blancas
False alarm. Some trouble with the VPN line.

On Aug 29, 9:06 pm, Armando Blancas  wrote:
> The change to beta2 isn't working for me:
>
>     
>       org.clojure
>       clojure
>       1.3.0-beta2
>     
>
> 1.3.0-beta1 works fine.
>
> On Aug 29, 7:28 am, Christopher Redinger  wrote:
>
>
>
>
>
>
>
> > Clojure 1.3 Beta 2 is now available at
>
> >http://clojure.org/downloads
>
> > The list of changes:
>
> >   * clojure.test/*/*-report vars made dynamic for use with external
> >     tools.
> >   * Calls favor arg vectors :tag over var :tag (CLJ-811)
> >   * BigInt ops made faster when values are small enough to be treated as
> > longs
> >   * rational? metadata fixed
> >   * partition and partition-all holds less
> >   * Bug fixed on transient vectors
> >   * print-dup and print-method removed for deftypes (CLJ-812)
> >   * Prevent make-parents NPE, (CLJ-808)
> >   * Special print support removed for BigIntegers. (CLJ-798)
>
> > Please grab it and let us know how it works for you.
>
> > Thanks!
>
> > --
> > Chris Redinger
> > Clojure/corehttp://clojure.com

-- 
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: Clojure 1.3 Beta 2

2011-08-29 Thread Isaac Gouy
Not surprisingly, some of the benchmarks game programs written for
Clojure 1.2 have problems with 1.3 Beta 2.

My guess is that small changes to the programs will be required to
catch up with the new version, but occasionally program failures have
indicated a bug in new versions of other languages.

Mon 15:17:15 ...OK .binarytrees.clojure-5.clojure [33]
Mon 15:21:02 ...OK .binarytrees.clojure-4.clojure [32]
Mon 15:30:04 ...OK .binarytrees.clojure [31]
Mon 15:37:59 ...OK .binarytrees.clojure-2.clojure [30]
Mon 15:49:27 ...OK .binarytrees.clojure-3.clojure [29]
Mon 15:54:51 ...OK fannkuchredux.clojure-2.clojure [28]
Mon 15:58:54 ...OK .fasta.clojure-2.clojure [27]
Mon 16:00:21 ...OK .fasta.clojure [26]
Mon 16:02:01 .PROGRAM FAILED fasta.clojure-4.clojure [25]
Mon 16:02:04 .PROGRAM FAILED fasta.clojure-3.clojure [24]
Mon 16:02:07 .PROGRAM FAILED fastaredux.clojure-4.clojure [23]
Mon 16:02:10 .PROGRAM FAILED knucleotide.clojure-3.clojure [22]
Mon 16:02:12 ...OK knucleotide.clojure-2.clojure [21]
Mon 16:10:07 ...OK knucleotide.clojure [20]
Mon 16:21:06 ...OK .mandelbrot.clojure [19]
Mon 16:29:08 .PROGRAM FAILED mandelbrot.clojure-3.clojure [18]
Mon 16:29:11 .PROGRAM FAILED mandelbrot.clojure-4.clojure [17]
Mon 16:29:14 ...OK .mandelbrot.clojure-2.clojure [16]
Mon 16:37:06 .PROGRAM FAILED meteor.clojure [15]
Mon 16:37:12 ...TIMED OUT nbody.clojure-2.clojure [14]
Mon 17:47:43 .PROGRAM FAILED pidigits.clojure [13]
Mon 17:47:46 ...OK .regexdna.clojure-3.clojure [12]
Mon 17:52:45 .PROGRAM FAILED regexdna.clojure-2.clojure [11]
Mon 17:52:47 ...PROGRAM FAILED .revcomp.clojure [10]
Mon 17:53:38 ...PROGRAM FAILED .revcomp.clojure-2.clojure [9]
Mon 18:03:45 ...OK .revcomp.clojure-4.clojure [8]
Mon 18:04:31 ...OK .revcomp.clojure-3.clojure [7]
Mon 18:05:07 ...OK .spectralnorm.clojure-5.clojure [6]
Mon 18:09:07 ...OK .spectralnorm.clojure-7.clojure [5]
Mon 18:11:06 ...OK .spectralnorm.clojure-2.clojure [4]
Mon 18:16:31 ...OK .spectralnorm.clojure-6.clojure [3]
Mon 18:18:28 ...TIMED OUT .threadring.clojure [2]
Mon 19:21:30 ...TIMED OUT .threadring.clojure-2.clojure [1]

(Note reverse-complement and reverse-complement  #2 fail because
memory settings were requested to show reduced Clojure memory usage on
the other reverse-complement programs.)

The program source code, with build and run logs can be reached from
the program name links -

http://shootout.alioth.debian.org/u64/measurements.php?lang=clojure

-- 
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 do transactions block each other?

2011-08-29 Thread Laurent PETIT
My tests were false.

Since I sent the code "at once" to the REPL, there was a race condition
between the start of the agent and the dosync for setting the ref's value to
2000 ; this explains the weirdness of my test results (thank you, Mr Murphy,
for having made the tests look like beta2 behaved differently from the
others ...)

So now I see consistent behaviours across 1.2.0, beta1 and beta2.

But I am still perplex and confused by the behaviour ...


2011/8/30 Laurent PETIT 

> ok so now i'm totally confused, since I cannot see why the behaviour is so
> different between beta1 and beta 2 ...
>
>
> 2011/8/30 Laurent PETIT 
>
>> Congratulations, you've found a bug in clojure 1.3 beta2, see:
>>
>>  look with my clojure 1.2.0 version :
>>
>> ;; Clojure 1.2.0
>> => (def thread (agent "Thread"))
>>(def account (ref 1000))
>>(send thread
>>  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>> agt))
>>  account)
>>(time (dosync (ref-set account 2000)))
>> #'user/thread
>> #'user/account
>> #
>> "Elapsed time: 0.498106 msecs"
>> 2000
>> => ;; 10 seconds later :
>> => @account
>> 2100
>>
>>
>> And now with clojure 1.3 beta1 :
>>
>> ;; Clojure 1.3.0-beta1
>> => (def thread (agent "Thread"))
>>(def account (ref 1000))
>>(send thread
>>  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>> agt))
>>  account)
>>(time (dosync (ref-set account 2000)))
>>;; 10 seconds later :
>> #'user/thread
>> #'user/account
>> #
>> "Elapsed time: 0.270225 msecs"
>> 2000
>> => @account
>> 2100
>>
>> And now with Clojure 1.3-beta2
>> ;; Clojure 1.3.0-beta2
>> => (def thread (agent "Thread"))
>>(def account (ref 1000))
>>(send thread
>>  (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>> agt))
>>  account)
>>(time (dosync (ref-set account 2000)))
>> #'user/thread
>> #'user/account
>> #
>> "Elapsed time: 7957.328798 msecs"
>> 2000
>>;; 10 seconds later :
>> => @account
>> 2000
>>;; 10 more seconds later :
>> => @account
>> 2000
>>
>> 2011/8/30 Laurent PETIT 
>>
>>> 2011/8/29 Dominikus 
>>>
 Thanks a lot for this detailed analysis and the pointers to the Java
 implementation, Stefan! That's excellent and very helpful.

 I still wonder, why the first transaction blocks write access. My
 overall understanding of the transaction system is that changes to
 referenced values remain in-transaction before committing them, a
 write-lock shouldn't be needed. I'm surprised, that the second
 transaction is the one who has to retry 71 times even though the first
 transaction hasn't committed anything yet.

>>>
>>> I must confess this behaviour also challenges my assumptions.
>>>
>>> Does this work the same whatever the clojure version used ?
>>>
>>>

 Cheers,

 Dominikus

 P.S.: Thanks for the idea to use 'future' to spawn a thread!

 On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
 > The call to alter already wrote to the Ref, this requires a write-lock
 on
 > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
 while
 > and gets to its commit phase.  The other transactions retries in the
 > meantime.  Consider the following code, which introduces some atoms
 for
 > counting the retries
 >
 > (defn tz []
 >   (let [rr (ref 10)
 > a1 (atom 0)
 > a2 (atom 0)]
 > (println "Starting future")
 > (future
 >  (dosync
 >   (swap! a1 inc)
 >   (alter rr + 100)
 >   (Thread/sleep 8000)))
 > (println "Sleeping a bit")
 > (Thread/sleep 1000)
 > (println "Another dosync")
 > (time
 >  (dosync
 >   (swap! a2 inc)
 >   (ref-set rr 1)))
 > [@rr @a1 @a2 (.getHistoryCount rr)]))
 >
 > user> (tz)
 > Starting future
 > Sleeping a bit
 > Another dosync
 > "Elapsed time: 7001.554 msecs"
 > [1 1 71 0]
 >
 > Note, how the 71 retries nice fit the approximately 7 seconds left and
 the
 > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
 > LockingTransaction.java/tryWriteLock.
 >
 > Transactions with significantly different run-times should be avoided,
 > although there is some point at which older transactions will get
 their
 > turn.  This could be another explanation of the effect.  Take a look
 at the
 > barge-function in LockingTransaction.java
 >
 > Hope this helps,
 > Stefan

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

Re: Why do transactions block each other?

2011-08-29 Thread Kevin Downey
the two threads race to acquire the write lock and the winner runs,
the loser retries. my guess is acquiring the write lock helps avoid
live locks between transactions.

On Mon, Aug 29, 2011 at 10:59 PM, Laurent PETIT  wrote:
> My tests were false.
> Since I sent the code "at once" to the REPL, there was a race condition
> between the start of the agent and the dosync for setting the ref's value to
> 2000 ; this explains the weirdness of my test results (thank you, Mr Murphy,
> for having made the tests look like beta2 behaved differently from the
> others ...)
> So now I see consistent behaviours across 1.2.0, beta1 and beta2.
> But I am still perplex and confused by the behaviour ...
>
> 2011/8/30 Laurent PETIT 
>>
>> ok so now i'm totally confused, since I cannot see why the behaviour is so
>> different between beta1 and beta 2 ...
>>
>> 2011/8/30 Laurent PETIT 
>>>
>>> Congratulations, you've found a bug in clojure 1.3 beta2, see:
>>>  look with my clojure 1.2.0 version :
>>> ;; Clojure 1.2.0
>>> => (def thread (agent "Thread"))
>>>    (def account (ref 1000))
>>>    (send thread
>>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>>> agt))
>>>          account)
>>>    (time (dosync (ref-set account 2000)))
>>> #'user/thread
>>> #'user/account
>>> #
>>> "Elapsed time: 0.498106 msecs"
>>> 2000
>>> => ;; 10 seconds later :
>>> => @account
>>> 2100
>>>
>>> And now with clojure 1.3 beta1 :
>>> ;; Clojure 1.3.0-beta1
>>> => (def thread (agent "Thread"))
>>>    (def account (ref 1000))
>>>    (send thread
>>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>>> agt))
>>>          account)
>>>    (time (dosync (ref-set account 2000)))
>>>    ;; 10 seconds later :
>>> #'user/thread
>>> #'user/account
>>> #
>>> "Elapsed time: 0.270225 msecs"
>>> 2000
>>> => @account
>>> 2100
>>> And now with Clojure 1.3-beta2
>>> ;; Clojure 1.3.0-beta2
>>> => (def thread (agent "Thread"))
>>>    (def account (ref 1000))
>>>    (send thread
>>>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
>>> agt))
>>>          account)
>>>    (time (dosync (ref-set account 2000)))
>>> #'user/thread
>>> #'user/account
>>> #
>>> "Elapsed time: 7957.328798 msecs"
>>> 2000
>>>    ;; 10 seconds later :
>>> => @account
>>> 2000
>>>    ;; 10 more seconds later :
>>> => @account
>>> 2000
>>> 2011/8/30 Laurent PETIT 

 2011/8/29 Dominikus 
>
> Thanks a lot for this detailed analysis and the pointers to the Java
> implementation, Stefan! That's excellent and very helpful.
>
> I still wonder, why the first transaction blocks write access. My
> overall understanding of the transaction system is that changes to
> referenced values remain in-transaction before committing them, a
> write-lock shouldn't be needed. I'm surprised, that the second
> transaction is the one who has to retry 71 times even though the first
> transaction hasn't committed anything yet.

 I must confess this behaviour also challenges my assumptions.
 Does this work the same whatever the clojure version used ?

>
> Cheers,
>
> Dominikus
>
> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>
> On Aug 29, 5:42 pm, Stefan Kamphausen  wrote:
> > The call to alter already wrote to the Ref, this requires a
> > write-lock on
> > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
> > while
> > and gets to its commit phase.  The other transactions retries in the
> > meantime.  Consider the following code, which introduces some atoms
> > for
> > counting the retries
> >
> > (defn tz []
> >   (let [rr (ref 10)
> >         a1 (atom 0)
> >         a2 (atom 0)]
> >     (println "Starting future")
> >     (future
> >      (dosync
> >       (swap! a1 inc)
> >       (alter rr + 100)
> >       (Thread/sleep 8000)))
> >     (println "Sleeping a bit")
> >     (Thread/sleep 1000)
> >     (println "Another dosync")
> >     (time
> >      (dosync
> >       (swap! a2 inc)
> >       (ref-set rr 1)))
> >     [@rr @a1 @a2 (.getHistoryCount rr)]))
> >
> > user> (tz)
> > Starting future
> > Sleeping a bit
> > Another dosync
> > "Elapsed time: 7001.554 msecs"
> > [1 1 71 0]
> >
> > Note, how the 71 retries nice fit the approximately 7 seconds left
> > and the
> > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
> > LockingTransaction.java/tryWriteLock.
> >
> > Transactions with significantly different run-times should be
> > avoided,
> > although there is some point at which older transactions will get
> > their
> > turn.  This could be another explanation of the effect.  Take a look
> > at the
> > barge-function in LockingTransaction.java
> >
> > Hope this helps,
> > Stefan
>
> --
> You received thi