Re: Improving Clojure startup time with -Xbootclasspath

2009-11-23 Thread Dmitry Ulanov
Very interesting tip! Also, like vimclojure, you can run nailgun (
http://martiansoftware.com/nailgun/background.html) locally or on your
server via ssh.

On Mon, Nov 23, 2009 at 5:07 AM, Alex Osborne a...@meshy.org wrote:

 We were discussing Clojure startup time (in the context of Leiningen)
 and Phil Hagelberg asked some JRuby people about startup time.  They
 suggested using -Xbootclasspath.

 Check this out:

 % time (echo | java -client -cp clojure.jar clojure.main)
 0.84s user 0.04s system 96% cpu 0.908 total

 % time (echo | java -client -Xbootclasspath/a:clojure.jar clojure.main)
 0.42s user 0.04s system 106% cpu 0.431 total

 For the server VM:

 % time (echo | java -server -cp clojure.jar clojure.main)
 1.07s user 0.06s system 113% cpu 0.995 total

 % time (echo | java -server -Xbootclasspath/a:clojure.jar clojure.main)
 0.56s user 0.06s system 109% cpu 0.562 total

 For reference:

 % java -version
 java version 1.6.0_16
 Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
 Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)

 Apparently on Dan Larkin's PC startup time went from a terrible 5.5s to
 a more bearable 1.9s.

 Looks like it's problematic to put Clojure libs in the bootclasspath
 though.  I get an NPE:

 Caused by: java.lang.NullPointerException
 at clojure.lang.RT.load(RT.java:377)
 at clojure.lang.RT.load(RT.java:371)

 Which is this line from RT.java:
 URL classURL = baseLoader().getResource(classfile);

 (clojure.lang.RT/baseLoader) isn't null, so I'm not sure what the deal
 is with that unless the class loading runs in a different thread where
 it is null or something.  But if you just put the Clojure jar itself in
 -Xbootclasspath and the rest of your libs as normal -cp you still get a
 nice fast start. :-)

 Charles Nutter has a nice list of JVM flags here:

 http://blog.headius.com/2009/01/my-favorite-hotspot-jvm-flags.html

 I don't get much of a benefit out of -XShare on my system but it might
 be worth trying as well.

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

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

Re: AOT'd namespaces lose their metadata

2009-11-23 Thread Lauri Pesonen
2009/11/23 Phil Hagelberg p...@hagelb.org:

 I noticed an odd bug when working on the help command for leiningen. It
 uses docstrings on metadata for help output, but when AOTing the
 project, the docstrings (as well as all other metadata) would be
 lost. Note that this doesn't happen when metadata is added to the
 namespace after the fact as is the case with clojure.core and
 alter-meta!.

 Any idea what might be causing this? I'd like to dig deeper but am
 unsure where to look.

There's a ticket for it

https://www.assembla.com/spaces/clojure/tickets/130-Namespace-metadata-lost-in-AOT-compile

but I don't think anyone's spent any time in trying to fix it.

 thanks,
 Phil

-- 
  ! Lauri

-- 
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: Holding onto your head step functions -- confusion

2009-11-23 Thread Garth Sheldon-Coulson
Scratch this question.

I think I've figured out that the step function in some people's code is
there for aesthetic reasons only. As long as the step function contains the
same code as would otherwise go directly inside the (lazy-seq ... ) there's
no difference.

That is,

(let [step (fn [a b] stuff)]
  (lazy-seq (step a b)))

is the same as

(lazy-seq stuff)

The lazy documentation on the web site had made me think there was something
special about the former, i.e. the compiler was optimizing it in some
special way.

Someone please correct me if I'm still confused.

On Sun, Nov 22, 2009 at 6:06 PM, Garth Sheldon-Coulson g...@mit.edu wrote:

 Hi All,

 I'll confused about the hold-onto-your-head business when building lazy
 seqs using lazy-seq.

 The lazier documentation on the web site doesn't really clear things up
 for me, though I've read it a few times.

 Under what circumstances must one use a step function, and under what
 circumstances it it acceptable not to?

 If this is covered in depth somewhere other than the lazier page please
 feel free just to send a link.

 As a point of discussion, does the following function have the potential to
 cause memory problems?

 Some notes: *kernel* and *options* are dynamic vars I want the lazy-seq to
 close over. parse-simple-atom is a function for parsing each element
 (atom, **unrelated to Clojure atoms**) of the coll. type is an arg that is
 used in the parsing of each element of the coll.

 (defn parse-expr-coll-to-lazy-seq [coll type]
 (let [kernel  *kernel*
 options *options*]
 (lazy-seq
 (binding [*kernel*  kernel
 *options* options]
 (when-let [s (seq coll)]
 (cons (parse-simple-atom (first s) type)
 (parse-expr-coll-to-lazy-seq (rest s) type)))

 Thanks,
 Garth


-- 
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: leiningen - a Clojure build tool

2009-11-23 Thread Gilbert
Leiningen and Clojar are

LEGEN...

wait for it...

DARY!

Anyways, just wanted to say thanks.

On Nov 19, 1:23 pm, Alex Osborne a...@meshy.org wrote:
 meb wrote:
  Was the name Leiningen inspired by the Esquire short story Leiningen
  vs. Ants?  That would be a brilliantly obscure way to challenge the
  predominance of ant.  Or did you have another reference in mind.

  From the Leiningen README:

 Leiningen! he shouted. You're insane! They're not creatures you can
 fight--they're an elemental--an 'act of God!' Ten miles long, two miles
 wide--ants, nothing but ants! And every single one of them a fiend from
 hell... -- from Leiningen Versus the Ants by Carl Stephenson

 For those who haven't heard of it:

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

 The story seems to be online in various places, like this one:

 http://www.americanliterature.com/Stephenson/SS/LeiningenVersustheAnt...

-- 
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: Datatypes and Protocols - early experience program

2009-11-23 Thread Rich Hickey
On Thu, Nov 19, 2009 at 12:39 PM, Krukow karl.kru...@gmail.com wrote:
 On Nov 19, 12:01 am, samppi rbysam...@gmail.com wrote:
 Question: are the general mechanisms for accessing and setting fields
 their keywords and assoc respectively:
   (deftype Bar [a b c d e])
   (def b (Bar 1 2 3 4 5))
   (:c b)
   (def c (assoc b :e 2))
 Does (:c b) and (assoc b :e 2) take advantage of Bar's field
 information? Is it any faster than using an array map? Are there any
 equivalents to struct maps' accessor functions?

 I've been wondering about this myself. I think you'd often want a
 persistent types in the sense of the persistent datastructure.

 You can use the ability to implement interfaces, specifically
 automatic support for IPersistentMap:

 ser= (deftype Bar [a b] [clojure.lang.IPersistentMap])
 #'user/Bar
 user= (assoc (Bar 1 2) :a 42)
 #:Bar{:a 42, :b 2}
 user=

 I have a question here, though: what is this?

 ser= (assoc (Bar 1 2) :c 42)
 #:Bar{:a 1, :b 2, :c 42}
 user= #:Bar{:a 1, :b 2, :c 42}

 Is it a Bar with field-speed access to :a and :b and map-speed
 access to :c?

Yes.


 Also can I assume that

 (assoc (Bar 1 2) :a 42)
 #:Bar{:a 42, :b 2}

 will share structure with the (Bar 1 2) and still has fast access
 to :a? Is the assoc function using that :a is a field?


Shared structure only kicks in when data structures become large
enough for it to be a performance advantage. That's not the case for
small maps or the fixed fields of a deftype.


 I guess I am just asking if the performance guarantees are those I
 would expect of Clojure (i.e., too fast ;-))


Yup. The fixed field access to deftypes via keyword literal lookup is
the fastest offered by any Clojure data structure.

Rich

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


making rlwrap Clojure friendly

2009-11-23 Thread Sergey Didenko
Hi,

has anybody tried to make rlwrap lexer more Clojure friendly? Just
adding - to the word characters would be a big gain (to enjoy
auto-completion.)

I spent some time looking through rlwrap sources but has not find a
good place to do the changes.

Regards, Sergey.

-- 
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: making rlwrap Clojure friendly

2009-11-23 Thread Sergey Didenko
Probably it can be done with Rlwrap filters, I have not tried it yet.

On Sat, Nov 21, 2009 at 2:30 PM, Sergey Didenko
sergey.dide...@gmail.com wrote:
 Hi,

 has anybody tried to make rlwrap lexer more Clojure friendly? Just
 adding - to the word characters would be a big gain (to enjoy
 auto-completion.)

 I spent some time looking through rlwrap sources but has not find a
 good place to do the changes.

 Regards, Sergey.


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

2009-11-23 Thread Meikel Brandmeyer

Hi,

Am 21.11.2009 um 05:22 schrieb Mark Engelberg:


Which reminds me, every once in a while I see people talking about
this here, and brainstorming up some alternatives to binding that
might interact better with lazy data structures.  Has there been any
real progress on this, or has every proposed solution been equally
problematic?


I wrote up a little blog post on the problem and the possible  
solutions. Feedback welcome.


http://kotka.de/blog/clojure/Taming_the_Bound_Seq.html

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Does a standard function exist that acts like assoc except it applies fns to vals

2009-11-23 Thread Meikel Brandmeyer

Hi,

Am 22.11.2009 um 22:32 schrieb samppi:


(defn vary [coll  keys-and-fns]
 (let [fn-map (apply arrray-map keys-and-fns)
   keys-and-vals (mapcat #((val %) (get coll (key %))) fn-map)]
   (apply assoc-args coll keys-and-vals)))


As Jon said: update-in.

(- coll
  (update-in [:x] fn-x)
  (update-in [:y] fn-y))

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Improving Clojure startup time with -Xbootclasspath

2009-11-23 Thread Meikel Brandmeyer
Hi,

On Nov 23, 9:57 am, Dmitry Ulanov dula...@gmail.com wrote:

 Very interesting tip! Also, like vimclojure, you can run nailgun 
 (http://martiansoftware.com/nailgun/background.html) locally or on your
 server via ssh.

I'd also like to mention clj-server: http://github.com/Neronus/clj-server.

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


initialization of clojure.contrib.logging library

2009-11-23 Thread Alex Ott
Hello all

I have one question about logging library from contrib? How i can configure
it to write data into log files?

P.S. I'm not Java developer, and may be don't know many of java's logging tricks

-- 
With best wishes, Alex Ott, MBA
http://alexott.blogspot.com/http://xtalk.msk.su/~ott/
http://alexott-ru.blogspot.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: Datatypes and Protocols - early experience program

2009-11-23 Thread Krukow


On Nov 20, 5:24 pm, Rich Hickey richhic...@gmail.com wrote:
 Yup. The fixed field access to deftypes via keyword literal lookup is
 the fastest offered by any Clojure data structure.

 Rich

While we are talking performance. Is there a simple way to explain the
performance characteristics of protocols versus interfaces?

/Karl

-- 
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: leiningen - a Clojure build tool

2009-11-23 Thread Krukow


On Nov 18, 8:29 am, Phil Hagelberg p...@hagelb.org wrote:
 I'm pleased to announce the initial release of Leiningen.

 Leiningen is a build tool for Clojure designed to not set your hair on fire.

I really like it so far - particularly the combination of lein and
clojars!

I'm not sure if this is the place for questions and/or bug-reports,
perhaps lein should have its own group?

Anyway, here is my situation. I have a project I want to push to
clojars using lein. The project depends on the newest version of
clojure in the new branch  - i.e. commit
75cd05080f7260c54007d7728fb280ae53b56f63 in 
http://github.com/richhickey/clojure/tree/new

I created a clojar in my group:
[org.clojars.krukow/clojure-1.1.0-alpha-snapshot
75cd05080f7260c54007d7728fb280ae53b56f63]

and for my project which depends on this jar i created a project.clj:

(defproject org.clojars.krukow/circuit-breaker 0.1
:dependencies [[org.clojars.krukow/clojure-1.1.0-alpha-snapshot
 
75cd05080f7260c54007d7728fb280ae53b56f63]])

I ran deps:
krukow:~/Projects/clojure/circuitbreaker$ lein deps
 [copy] Copying 1 file to /Users/krukow/Projects/clojure/
circuitbreaker/lib
krukow:~/Projects/clojure/circuitbreaker$ ls lib/
clojure-1.1.0-alpha-
snapshot-75cd05080f7260c54007d7728fb280ae53b56f63.jar
krukow:~/Projects/clojure/circuitbreaker$

But now all lein commands fail. E.g,

krukow:~/Projects/clojure/circuitbreaker$ lein help
Exception in thread main java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.loadClassForName(RT.java:1516)
at clojure.lang.RT.load(RT.java:389)
at clojure.lang.RT.load(RT.java:371)
...

I suspect it is because I've put another version of clojure on the
classpath.

Any advice on how to do projects that depend on specific versions of
clojure?

/Karl

-- 
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: Datatypes and Protocols - early experience program

2009-11-23 Thread Krukow


On Nov 12, 1:10 pm, Rich Hickey richhic...@gmail.com wrote:
 An early version of the code for a few important new language
 features, datatypes[1] and protocols[2] is now available in the 'new'
 branch[3]. Note also that the build system[4] has builds of the new
 branch, and that the new branch works with current contrib.

 If you have the time and inclination, please try them out. Feedback is
 particularly welcome as they are being refined.

 Thanks,

 Rich

I've had very good experiences so far - I really like the modeling
aspects of this.

Two comments.

First is a bug.
Using newest commit of new: 75cd05080f7260c54007d7728fb280ae53b56f63

Clojure 1.1.0-alpha-SNAPSHOT
user= (deftype Foo [x])
#'user/Foo
user= (defprotocol P (fun [x]))
P
user= (extend ::Foo P {:fun (fn [x] x)})
nil
user= (fun (Foo 42))
#:Foo{:x 42}
user= (def f1 (Foo 42))
#'user/f1
user= f1
#:Foo{:x 42}
user= (def f2 (fun f1))
java.lang.IllegalAccessError (NO_SOURCE_FILE:7)
user=

The error occurs if I try to bind the result of a protocol function to
a var.

Second is a feature request:

Map-based initializers and Default values for deftype.

Example:
user= (deftype TransitionPolicy [fail-count timeout])
#'user/TransitionPolicy
user= (def p (TransitionPolicy {:fail-count 5 :timeout 5000}))

;; I'd like

'user/p
user= p
#:TransitionPolicy{:fail-count 5, :timeout 5000}
user=

Now defaults:
user= (deftype TransitionPolicy [fail-count :def 5 timeout :def
5000])

;;I'd like
#'user/TransitionPolicy
user= (TransitionPolicy :fail-count 5)
#:TransitionPolicy{:fail-count {:fail-count 10}, :timeout 5000}
user= (TransitionPolicy)
#:TransitionPolicy{:fail-count 5, :timeout 5000}

I know I can easily construct functions that realize these maps and
default initializers, but it would be nice to have Out-of-the-box if
it doesn't complicate the design.

Cheers,
/Karl

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

2009-11-23 Thread Chouser
On Sat, Nov 21, 2009 at 4:37 PM, Meikel Brandmeyer m...@kotka.de wrote:
 Hi,

 Am 21.11.2009 um 05:22 schrieb Mark Engelberg:

 Which reminds me, every once in a while I see people talking about
 this here, and brainstorming up some alternatives to binding that
 might interact better with lazy data structures.  Has there been any
 real progress on this, or has every proposed solution been equally
 problematic?

 I wrote up a little blog post on the problem and the possible solutions.
 Feedback welcome.

 http://kotka.de/blog/clojure/Taming_the_Bound_Seq.html

That's excellent Meikel, thanks.  Any reson you didn't use the
with-bindings macro to make your final example a bit simpler?

--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: making rlwrap Clojure friendly

2009-11-23 Thread Chouser
On Sat, Nov 21, 2009 at 7:30 AM, Sergey Didenko
sergey.dide...@gmail.com wrote:
 Hi,

 has anybody tried to make rlwrap lexer more Clojure friendly? Just
 adding - to the word characters would be a big gain (to enjoy
 auto-completion.)

 I spent some time looking through rlwrap sources but has not find a
 good place to do the changes.

The shell script I use to start my Clojure REPLs includes this:

rlwrap --remember --complete-filenames \
   --history-filename ~/.clojure/history \
   --break-chars \\\'(){}[],^%$#@;:| \
   java and its startup args here

I'm sure it's imperfect, but works well enough for me.

--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: Mysterious errors w/ protocols and types

2009-11-23 Thread Krukow


On Nov 23, 7:36 am, samppi rbysam...@gmail.com wrote:
 The following code contains an error, and I cannot figure out what it
 is at all. When I run StateMeta's test once, the statement marked with
 a comment above fails. When I run it again, it succeeds. This has been
 causing very weird bugs in my code. I've replicated the behavior in
 both a script and the REPL. Here's the bugged code:

[snip]

I recommend that you try and find a minimal version of a program that
exhibits the bug. This makes it so much easier to fix quickly. In your
case, it looks like the combination of varargs and protocol functions:

krukow:~/emacs/clojure/clojure$ rlwrap java -cp
clojure-1.1.0-75cd05080f7260c54007d7728fb280ae53b56f63.jar
clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user= (defprotocol P (foo [x  args]))
P
user= (deftype T [x])
#'user/T
user= (extend ::T P {:foo (fn [x  args] args)})
nil
user= (foo (T 42) 1 2 3)
java.lang.IllegalArgumentException: Wrong number of args passed to:
user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
user=

Perhaps varargs isn't supported yet?

/Karl

-- 
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: Improving Clojure startup time with -Xbootclasspath

2009-11-23 Thread Armando Blancas
I added the contrib lib expecting it to fail but it worked, and loaded
(in half the usual time) some code from the user.clj as well:

java -Xbootclasspath/a:clojure\clojure.jar;clojure-contrib\clojure-contrib.jar 
clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=

I had been reading in this paper: 
http://www.tedneward.com/files/Papers/BootClasspath/BootClasspath.pdf
about the case below and how that could explain the NPE, but when I
added the lib to see it, the thing worked.

public class NewObjectLoader {
  public static void main (String args[]) {
NewObject no = new NewObject();
System.out.println(
  no.getClass().getName() +  was loaded by  +
 no.getClass().getClassLoader());
   }
}
Sure enough, the NewObject class is not only found at compile-time and
runtime, but it prints
NewObject was loaded by null, indicating it owes its existence to
the bootstrap ClassLoader.

Running on Vista
java -version
java version 1.6.0_13
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

-- 
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: Performance tuning for a simple SLE solver

2009-11-23 Thread luskwater
I replaced the calls to get-in with a my-get-in macro that compiled
them to nested calls on the map or vector:

  (my-get-in sle [:A 1 2]) =
(((sle :A) 1) 2)

The form (data key) seems to be about 10 to 15 times faster than the
equivalent (get-in data [key]) on my laptop.

It cut the runtime in half or so.  I would think that floating point
operations might be faster, too.

On Oct 9, 6:38 am, andi.xeno...@googlemail.com
andi.xeno...@googlemail.com wrote:
 Hi,

 I'm new to Clojure, and let me first say that I love it! At least I
 love the language, but I have some concerns regarding performance:

 My first try was to implement a Gauß elemination algorithm for solving
 a system of linear equations. Here is the code:

 http://www.xenoage.com/extern/zongblog/matrix.clj

 Solving 1.000.000 SLEs (see last line) took 33.000 ms on my machine,
 while the corresponding algorithm written in Java needed less than 300
 ms.

 Since I am a Java programmer and I have no experience in functional
 programming, I probably have to apologize for the bad code. Anyway, I
 already tried to make it faster using the well-known performance tips
 (like type hints), but they did not really help (ok, 25.000 ms instead
 of 33.000, but it is still too much).

 What are my options?
 - Can you identify problems in my code? I do not mean things that make
 it 10% faster, but at least double as fast.
 - Could you say, that Clojure is not made for such numerical things,
 and I should use Java code for these performance-critical algorithms?
 (would be perfectly ok for me)
 - Should I try it in Clojure, but using a (mutable) Java array instead
 (also ok for me, since this mutable structure is only used locally and
 within a single thread)

 Any ideas? Thanks in advance :-)

 Andi

-- 
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: Mysterious errors w/ protocols and types

2009-11-23 Thread samppi
Variable-length arguments in protocols seem to be supported, but
there's just a weird, stateful behavior. Look what happens when you
call foo first with one argument twice (it fails both times), then two
arguments (it succeeds), then one argument again (it succeeds now
too!). Is this a Clojure bug?

Clojure 1.1.0-alpha-SNAPSHOT
user= (defprotocol P (foo [x  args]))
P
user= (deftype T [x])
#'user/T
user= (extend ::T P {:foo (fn [x  args] args)})
nil
user= (foo (T 42))
java.lang.IllegalArgumentException: Wrong number of args passed to:
user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
user= (foo (T 42))
java.lang.IllegalArgumentException: Wrong number of args passed to:
user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
user= (foo (T 42) 1 2)
(1 2)
user= (foo (T 42))
nil

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

2009-11-23 Thread Sergey Didenko
Hi Paul,

This time I tested it under Linux, following the instructions exactly
and it worked.

Though when I opened the second REPL it failed with a
NullPointerException. I repeated the step and had two REPLs with the
same vars.

For some reason it failed earlier on Windows, I will try to make it work there.

Yes, I can try to help. Feel free to write me.

Actually, I would like to try Clojure + Terracotta as a data layer for
my Java app, so I'm more interested in adapting the changes to the
latest Clojure codebase and tuning Terracotta interaction. I saw
autolocking in config and now thinking how bad that can be.

I will study your google document and the changes to Clojure classes
to understand the TIM better.

P.S. (svn rev. 1335 + the new tim-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


PersistentStructMap Exception

2009-11-23 Thread cearl
Hi,
I'm getting a cast exception on trying to create a simple structure
and wondered if there was something obvious that I'm not doing. The
transcript below shows my version of java. Running on Mac Book Pro,
Snow Leopard 5.6.1


bash-3.2$ java -version
java version 1.6.0_15
Java(TM) SE Runtime Environment (build 1.6.0_15-b03-219)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02-90, mixed mode)
bash-3.2$ java -cp clojure-1.0.0.jar clojure.lang.Repl
Clojure 1.0.0-
user= (defstruct s1 :a :b)
#'user/s1
user= (s1 1 2)
java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def
cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)


Thanks

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


Re: making rlwrap Clojure friendly

2009-11-23 Thread Sergey Didenko
So simple :) Thanks!

On Mon, Nov 23, 2009 at 4:47 PM, Chouser chou...@gmail.com wrote:
 The shell script I use to start my Clojure REPLs includes this:

 rlwrap --remember --complete-filenames \
   --history-filename ~/.clojure/history \
   --break-chars \\\'(){}[],^%$#@;:| \
   java and its startup args here


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

2009-11-23 Thread Meikel Brandmeyer
Hi,

On Nov 23, 3:36 pm, Chouser chou...@gmail.com wrote:

 http://kotka.de/blog/clojure/Taming_the_Bound_Seq.html

 That's excellent Meikel, thanks.  Any reson you didn't use the
 with-bindings macro to make your final example a bit simpler?

Woops. The reason might be the time of day (23 o'clock after getting
up on 5:30 in the morning). I simply forgot about with-bindings. :( I
will update the post tonight. Maybe I'll also show a more detailed
example for bound-fn.

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: Clojure Scoping Rules

2009-11-23 Thread Meikel Brandmeyer
Hi,

On Nov 23, 3:32 pm, nchubrich nicholas.chubr...@gmail.com wrote:
 Meikel, is get-thread-bindings only in a development version of
 Clojure?  I have 1.09.11 and don't see it documented or usable (or in
 the online docs).

I'm not sure what 1.09.11 means, but the following commits added push-/
pop-/get-thread-bindings as wells as with-bindings and bound-fn.

thread-bindings interface: 
http://github.com/richhickey/clojure/commit/110b9c2eb8a128d837e6e620efc7e1c4e33feb82
with-bindings and bound-fn: 
http://github.com/richhickey/clojure/commit/fbacc4a5751fa5c15baa599b5a058cd81b05a247

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: Mysterious errors w/ protocols and types

2009-11-23 Thread Rich Hickey


On Nov 23, 11:36 am, samppi rbysam...@gmail.com wrote:
 Variable-length arguments in protocols seem to be supported, but
 there's just a weird, stateful behavior. Look what happens when you
 call foo first with one argument twice (it fails both times), then two
 arguments (it succeeds), then one argument again (it succeeds now
 too!). Is this a Clojure bug?

 Clojure 1.1.0-alpha-SNAPSHOT
 user= (defprotocol P (foo [x  args]))
 P
 user= (deftype T [x])
 #'user/T
 user= (extend ::T P {:foo (fn [x  args] args)})
 nil
 user= (foo (T 42))
 java.lang.IllegalArgumentException: Wrong number of args passed to:
 user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
 user= (foo (T 42))
 java.lang.IllegalArgumentException: Wrong number of args passed to:
 user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
 user= (foo (T 42) 1 2)
 (1 2)
 user= (foo (T 42))
 nil

Varargs in protocols are not yet supported.

Rich

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


Feedback for a visitor closure generator

2009-11-23 Thread Sean Devlin
Multimethods are a great abstraction in Clojure.  They are great for
adapting a wide variety of inputs to a function.  However, I often
need to decouple the adaptation of data from the function that
operates on the adapted data.  Also, after the work is complete, I
need to adapt the data back to the original format.

As such, I've found the need to create visitor closures in my code.
Along the way I came up with a helper function to generate visitor
closures.  I'd like feedback on the visitor generator.

* Getting Motivated: String functions *

I write the following code a lot to deal with keywords  symbols:

(keyword (some-str-fn (name a-keyword) str-fn-args))
(symbol  (some-str-fn (name a-symbol ) str-fn-args))

Each of these can be abstracted out as
(defn visit-keyword
 [str-fn a-keyword  args]
(keyword
  (apply str-fn (name a-keyword) args)))

(defn visit-symbol
 [str-fn a-symbol  args]
(symbol
  (apply str-fn (name a-symbol ) args)))

So, the code is now called as follows

(visit-keyword str-fn a-keyword args)
(visit-symbol  str-fn a-symbol args)

This is one possible implementation of a visitor patter for symbols,
keywords  strings.

* More Problems: Map Functions *

It's common to filter on values or keys when working with maps.  I've
written a lot of code like this:

;keys
(into {} (some-pred-fn (comp a-pred key) map-fn-args))
;values
(into {} (some-pred-fn (comp a-pred val) map-fn-args))

A first approach would be to write specific helper function for each
case.  However, this can be turned into a visitor as well.

(defn visitor-keys-pred
  [pred-fn pred-arg  args]
(into {}
  (apply pred-fn (#(comp % key) pred-arg)
args)))

(defn visitor-vals-pred
  [pred-fn pred-arg  args]
(into {}
  (apply pred-fn (#(comp % val) pred-arg)
args)))

The definition looks a little funky, but we'll see why in a minute.
For now the functions can be called as follows:

(visitor-keys-pred pred-fn pred-arg args)
(visitor-vals-pred pred-fn pred-arg args)

* Putting it together:  Visitor Closures *

As you can see, a pattern is starting to develop.  Each visitor
function has a similar signature:

[f first-arg  rest-args]

This obviously becomes

[f  args]

Each visitor follows a similar pattern, too.
1.  Apply a visit-fn to get to a common base type
2.  Do work on the base type
3.  Apply a return-fn to get back to the original type.

We can turn this description into a closure generating function:

(defn visitor
  Used to implement visitor patterns. (first (args)) is modified by
the visitor function, and the result is wrapped in a return-fn call.
  [visit-fn return-fn]
  (fn [f  args]
(return-fn
 (apply f
   (visit-fn (first args))
   (rest args)

We now have a new way to define previous visitor functions.  Here's
what they look like using this new helper function:

(def visit-keyword (visitor name keyword))
(def visit-symbol  (visitor name symbol ))

;Works w/ predicate functions
(def visit-keys-pred (visitor #(comp % key) (partial into {}))
(def visit-vals-pred (visitor #(comp % val) (partial into {}))

As you can see, the only thing we described is the visit-fn and return-
fn.  The rest of the behavior is defined by the visitor pattern
itself.

* Second form *

The one catch is that visitor assumes that the dispatched data is the
first argument to f.  Sometimes it is the last argument to f, as in
take  drop.  It is easy enough to define visitor* that works on the
last argument of a function.  The definition is in the link.

http://gist.github.com/241144

* Back to Multimethods *

The power of the individual closures can be amplified when wrapped in
a multimethod.  Consider our String/Symbol/Keyword group.

(defmulti visit-string (fn [ args] (second args))

(defmethod visit-string clojure.lang.Symbol
 [f  args]
 (apply visit-symbol f args))

(defmethod visit-string clojure.lang.Keyword
 [f  args]
 (apply visit-keyword f args))

(defmethod visit-string :default
 [f  args]
 (apply f args))

We now have a visit-string function that can truly visit anything.
Our function calls above become:

(visit-string str-fn a-keyword args)
(visit-string str-fn a-symbol  args)

* Closing questions *

So now that you've how  why this works, I've got some questions for
the group:

* Did I accidentally duplicate functionality in core?
* How can this be more flexible?
* What maintenance problems are there that I don't see?
* Will speed be an issue?
* Is the signature of visitor sensible?  Is the signature of the
generated function sensible?  How could it be better?

Thanks in advance,
Sean

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

Re: Mysterious errors w/ protocols and types

2009-11-23 Thread samppi
I see; then that of course would be the reason. Thanks for the answer.

On Nov 23, 12:24 pm, Rich Hickey richhic...@gmail.com wrote:
 On Nov 23, 11:36 am, samppi rbysam...@gmail.com wrote:





  Variable-length arguments in protocols seem to be supported, but
  there's just a weird, stateful behavior. Look what happens when you
  call foo first with one argument twice (it fails both times), then two
  arguments (it succeeds), then one argument again (it succeeds now
  too!). Is this a Clojure bug?

  Clojure 1.1.0-alpha-SNAPSHOT
  user= (defprotocol P (foo [x  args]))
  P
  user= (deftype T [x])
  #'user/T
  user= (extend ::T P {:foo (fn [x  args] args)})
  nil
  user= (foo (T 42))
  java.lang.IllegalArgumentException: Wrong number of args passed to:
  user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
  user= (foo (T 42))
  java.lang.IllegalArgumentException: Wrong number of args passed to:
  user$eval--12$fn--14$G--1 (NO_SOURCE_FILE:0)
  user= (foo (T 42) 1 2)
  (1 2)
  user= (foo (T 42))
  nil

 Varargs in protocols are not yet supported.

 Rich

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


Re: initialization of clojure.contrib.logging library

2009-11-23 Thread ataggart
The c.c.logging library delegates to an underlying implementation,
thus for any configuration help you'll need to check the documentation
of the actual logging system, e.g., log4j.



On Nov 21, 7:21 am, Alex Ott alex...@gmail.com wrote:
 Hello all

 I have one question about logging library from contrib? How i can configure
 it to write data into log files?

 P.S. I'm not Java developer, and may be don't know many of java's logging 
 tricks

 --
 With best wishes, Alex Ott, MBAhttp://alexott.blogspot.com/       
 http://xtalk.msk.su/~ott/http://alexott-ru.blogspot.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: Monad problems: finding an m-zero

2009-11-23 Thread Konrad Hinsen
On 22 Nov 2009, at 22:06, samppi wrote:

 Yes, I see. I'm going to guess that the parser-m that I give above has
 no possible m-zero, so I think I'll have to rethink how I'm going to
 approach this problem. I probably am going to just define failure in
 another way. (The reason why I can't use nil is because I need to
 store metadata on the object representing failure. I'm sure I'll
 figure something out.) Thanks for your help.

Using another value than nil (e.g. a keyword) is doable:

(state-t (maybe-t identity-m ::failure))

instead of

(state-t maybe-m)

However, it seems to me (after a quick look at your initial message)  
that you want m-zero to be a pair containing a keyword plus a state  
value. That is not possible because m-zero has to be a constant. You  
can't pack additional information on m-zero. Using metadata on m-zero  
looks risky as well (but I didn't think it through to the end) because  
metadata is easily lost in operations that don't expect it to be there.

Konrad.

-- 
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: Monad problems: finding an m-zero

2009-11-23 Thread Konrad Hinsen
On 22 Nov 2009, at 22:10, John Harrop wrote:

 Is there an explanation of monads out there that doesn't require the  
 reader to know Haskell to understand it? One that's generic to any  
 FP-capable language?

Nothing I know of; you need some syntax if only for the examples.  
Moreover, there are some fundamental differences to implementing  
monads in static and dynamically typed languages.

There are two monad tutorials for Clojure programmers:


[http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/
 
 Monad tutorial part 1]

[http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-2/
 
 Monad tutorial part 2]

[http://onclojure.com/2009/03/23/a-monad-tutorial-for-clojure-programmers-part-3/
 
 Monad tutorial part 3]

[http://onclojure.com/2009/04/24/a-monad-tutorial-for-clojure-programmers-part-4/
 
 Monad tutorial part 4]
[http://intensivesystems.net/tutorials/monads_101.html; Monads in  
Clojure part 1]
[http://intensivesystems.net/tutorials/monads_201.html; Monads in  
Clojure part 2]]

Konrad.

-- 
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: Oh, yeah, transients are fast!

2009-11-23 Thread Raoul Duke
i have tried:

1.5
1.6
1.6 -server
the last i did both in repl-in-emacs, and in a repl-in-straightup-shell.

the numbers i get are weird. it does seem like v2 is faster than v,
but never gets stupendously fast (never faster than 500 msec on a dual
core macbook pro 2.2ghz core 2 duo 4gb ram), and v does a strange
thing where i run v2 a bunch then the first time i run v it is like 2x
v2, and then subsequent runs of timing v are like 8x v2. and here i
thought hotspot was supposed to get faster, not slower, over time.

oy veh.

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


Clojure User Survey, preparation for 1.1

2009-11-23 Thread the . stuart . sierra
If you have trouble viewing or submitting this form, you can fill it out  
online:
http://spreadsheets.google.com/viewform?formkey=dFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MA


Clojure User Survey


This user survey will help move Clojure toward an official 1.1 release.


How do you get Clojure? *

Download release
Github
Maven or Ivy


What distribution of Clojure do you use primarily? *

1.0 release
I picked one development snapshot and stuck with it
I use the latest development snapshot
I follow Github master branch
I follow Github new branch


What about chunked sequences? *

I don't know what they are
The help me
They hurt me
I don't notice any difference


Powered by Google Docs Report Abuse - Terms of Service - Additional Terms


-- 
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: Deep deref

2009-11-23 Thread Sergey Didenko
Hi,

Andre, Danny's first approach is about syncing only on the root
object, so that every piece of data is behind one deref:

(def root (ref {:persons [ ... no other refs here... ]))

This approach is simpler to code but can lead to a lot of retried
transactions under heavy concurrent load, as I understand.

What about making all derefs that you need inside one transaction?
There are words somewhere in docs that you need dosync if you perform
a few reads that must be consistent. I think this is what you need.

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

2009-11-23 Thread Meikel Brandmeyer

Chris, Graham,

Am 23.11.2009 um 21:21 schrieb Graham Fawcett:


Very nice. A generalized version might be more useful to your readers:
take an input seq, and return an output seq which is evaluated
stepwise in the binding environment.


Thank you for your good comments. I updated the post with a bound-seq  
helper, which turns any given lazy input sequence into a bound  
sequence. The environment might be chosen manually in the style of  
binding. Or alternatively get-thread-bindings captures the whole  
environment.


http://kotka.de/blog/clojure/Taming_the_Bound_Seq.html

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Deep deref

2009-11-23 Thread Sergey Didenko
BTW I'm also coding the simple persistence for Clojure data
structures. Though I took Prevayler approach (http://prevayler.org),
so I journal function calls that change my root object.

This approach is better than simple snapshotting when your data grows
big, so you can't do the snapshots very often but do not want to lose
a lot of the latest changes.

Making snapshots are easy to implement after this, if data objects
reference each other only one time or through ids. I guess it would be
a simple traversal of the root object.

I plan to make this persistence code public if anyone is interested.
Though I'm not moving very fast, I'm learning Clojure at the same
time.

-- 
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: Deep deref

2009-11-23 Thread Wojciech Kaczmarek
On Mon, Nov 23, 2009 at 22:46, Sergey Didenko sergey.dide...@gmail.com wrote:
 BTW I'm also coding the simple persistence for Clojure data
 structures. Though I took Prevayler approach (http://prevayler.org),
 so I journal function calls that change my root object.

 This approach is better than simple snapshotting when your data grows
 big, so you can't do the snapshots very often but do not want to lose
 a lot of the latest changes.

 Making snapshots are easy to implement after this, if data objects
 reference each other only one time or through ids. I guess it would be
 a simple traversal of the root object.

 I plan to make this persistence code public if anyone is interested.
 Though I'm not moving very fast, I'm learning Clojure at the same
 time.

Yeah it would be cool to look at it.

-- 
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: Deep deref

2009-11-23 Thread John Harrop
On Mon, Nov 23, 2009 at 4:34 PM, Sergey Didenko sergey.dide...@gmail.comwrote:

 Hi,

 Andre, Danny's first approach is about syncing only on the root
 object, so that every piece of data is behind one deref:

 (def root (ref {:persons [ ... no other refs here... ]))

 This approach is simpler to code but can lead to a lot of retried
 transactions under heavy concurrent load, as I understand.

 What about making all derefs that you need inside one transaction?
 There are words somewhere in docs that you need dosync if you perform
 a few reads that must be consistent. I think this is what you need.


I'm starting to think that for some tasks Clojure could use a concept of
row locking with maps.  It would mean having a map-of-refs type that was
integrated with the STM, so multiple updates whose keys didn't collide could
occur concurrently.

It *might* be possible to do this using commute and update-in, with a ref
wrapping the whole map. The tricky thing is you want the update-ins to
commute if the keys are not the same, but not if they are. Perhaps we need a
conditional commute that takes two extra arguments, a value to test and a
binary predicate. Then it could be done with (conditional-commute key = map
update-in [key] val-transform-fn).

The idea here being, in this case, that if two of these were done in
overlapping transactions, the first arguments would be compared using the
second argument. If the result was true one transaction would be retried, if
false the operations would commute. (If the second arguments to the two
conditional-commutes differed the transaction would be retried.)

I think adding conditional commute would require changes to core, however.

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

roll call of production use?

2009-11-23 Thread Raoul Duke
hi,

i'd be interested to hear who has successfully used clojure in
production. i know of some, as some folks have been vocal; any other
interesting-but-so-far-silent uses people'd be willing to fess up
about?

many thanks.

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


Re: roll call of production use?

2009-11-23 Thread David Brown
On Mon, Nov 23, 2009 at 03:00:16PM -0800, Raoul Duke wrote:

i'd be interested to hear who has successfully used clojure in
production. i know of some, as some folks have been vocal; any other
interesting-but-so-far-silent uses people'd be willing to fess up
about?

I've thrown together a small clojure program to present an internal
dashboard of active projects and states and stuff.  Having the JVM was
invaluable, since I could easily make postgreSQL queries as well as
use JGit to walk the history of a git repository.

I've mentioned this before, but http://github.com/d3zd3z/webweight
is a small program I wrote to learn compojure.

One significant part is that I've written an org.davidb.contrib.html
and xml that wrap around the same data structure used by clojure.xml.
It allows for easier construction of html/xml in code:

   (html/table :border 1
 (html/tr
   (html/td :valign top Cell) ..))

I also wrote an html/xml emitter that uses ones from the standard Java
libraries, since the one in clojure.xml doesn't actually generate
valid xml.

The other interesting part of webweight is that the build.xml and the
ivy and files under etc are sufficient to build most Clojure projects.
It's similar to the idea behind Leiningen, but it will also build Java
and native code into the project as well.

The production webpage is internal, and has a lot more data on it, but
I've captured and scrubbed a snapshot
http://www.davidb.org/dashboard/sample.html

I was able to throw the whole thing together in just a couple of days
using Clojure.  I haven't really felt this productive writing code
since using Common Lisp.

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: leiningen - a Clojure build tool

2009-11-23 Thread Alex Osborne
Krukow karl.kru...@gmail.com writes:

 On Nov 18, 8:29 am, Phil Hagelberg p...@hagelb.org wrote:
 I'm pleased to announce the initial release of Leiningen.

 Leiningen is a build tool for Clojure designed to not set your hair on fire.

 I really like it so far - particularly the combination of lein and
 clojars!

 I'm not sure if this is the place for questions and/or bug-reports,
 perhaps lein should have its own group?

We hadn't gotten around to really telling anyone yet, but there is in
fact a Leiningen group:

http://groups.google.com/group/leiningen

There's also a #leiningen channel on irc.freenode.org.

 I suspect it is because I've put another version of clojure on the
 classpath.

 Any advice on how to do projects that depend on specific versions of
 clojure?

I'm afraid that you can't just yet, but we're working on it.  The
problem is compilation currently happens in the same JVM as Leiningen
itself runs.  Compiling in a separate process or classloader is a
planned Lein 1.0 feature and should fix this up.

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

2009-11-23 Thread André Ferreira
Would it be possible to create an implementation of delay and lazy-seq
that didn't use fn to delay evaluation, or atleast captured dynamic
variables?

(delay (+ x 3))  reasonable semantics in current clojure (let [x x]
(delay (+ x 3)))
(delay (fn [y] (+ x y))) semantics should be the same it already is (x
should get it's value from the dynamic binding)
(delay [x (fn [y] (+ x y))]) semantics should be (let [G_N x] (delay
[G_N (fn [y] (+ x y))])), so all captured variables would need
renaming using gensyms.

delay would need it's body macroexpanded code to be able to correctly
capture variables. It would also try to capture local variables, but
that wouldn't change the semantics and would probably be optimized
away by the compiler.
I might have missed some important detail, since dynamic binding and
lazyness have such a peculiar semantics interaction, but it would
yield much more reasoanable execution, wouldn't it?

-- 
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: roll call of production use?

2009-11-23 Thread Wojciech Kaczmarek
On Tue, Nov 24, 2009 at 00:00, Raoul Duke rao...@gmail.com wrote:
 hi,

 i'd be interested to hear who has successfully used clojure in
 production. i know of some, as some folks have been vocal; any other
 interesting-but-so-far-silent uses people'd be willing to fess up
 about?

 many thanks.

I use Clojure for web crawling / scraping of certain services with
storing extracted data in a custom database. I could marry existing
Java libs with an excellent xml/html walking via zippers; and could
test it in REPL which is a pleasure to use. After finishing a
prototype it became a valid production version which Just Works in a
near-zero time. Ah, and I eradicated many bugs early by having set
*warn-of-reflection* - esp. for the code heavily calling Java.

Nothing revolutionary, it was just use of typical web-related
techniques, which are unfortunately still a major pain in the ass on
many programming platforms (and they don't have macros!! ;)

More uses incoming. It will be bulk data load of QDBM and TokyoCabinet
storages, for example.

-- 
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: Monad problems: finding an m-zero

2009-11-23 Thread jim
Konrad,

Glad to see you're still around doing monads in Clojure. :)

Jim

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


Annotations on the new deftype?

2009-11-23 Thread Mark Derricutt
With all the newly added/being worked on defprotocol/deftype features
- I've not seen anyone mention JDK annotations being part of things,
is support for annotations being worked on as part of this?  Would be
a -very- handy addition, esp. as more and more JVM libraries/tools are
looking for them.

Mark



-- 
Pull me down under...

-- 
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: roll call of production use?

2009-11-23 Thread Phlex

 i'd be interested to hear who has successfully used clojure in
 production.

Hello,

1- We have this license server, used to control the use of a 
professional software (this one written using delphi).
This was tested with thousands of simutaneous connections, and has been 
working with no hiccup for 6 months. It uses nio + ssl + a mysql database.

2- An application that connects to telephony switches and gives real 
time call informations to web users. With the whole administration part 
(managing customer, agents and their different price lists, showing 
statistics). It has many users permanently logged in as they need to 
monitor those calls (they are call shops). So they can see the calls 
counting for their (typically 8) booths, and can do various operation on 
the calls (like interrupting a prepaid call for instance). That's a lot 
of polling. We're still in the ramp-up period so we only have a fraction 
of the existing customers using our application yet. This project uses 
compojure + jetty + ssl + a postgres database.

There isn't much to report, everything worked as expected. The jvm 
integration was a big help, providing access to some java third party 
libraries. Also using java, i can develop on windows, and just drop the 
jar on a solaris or linux server, it just works.
The REPL helps a lot too.

I'd like to see support for database connection pooling, and those pesky 
sql underscored column names to end up with dashes on the clojure side. 
Also compojure has somewhat of an attitude. Actually i miss cl-sql and 
hunchentooth, but hey you can't get everything, and what we've got is 
already fantastic.

The language itself is perfect for the job, though i'm looking forward 
to the protocols and deftype extensions. The type metadata trick always 
seems wrong, and including it in a map feels like a hack. Refs, atoms 
and agents helped a lot, as well as the immutable data structures.

There it is, an application programmer's view on clojure !

Sacha De Vos

-- 
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 User Survey, preparation for 1.1

2009-11-23 Thread Bill Allen
Stuart, I think there's another valid option for getting clojure. I got it
by installing the unfortunately titled Emacs Starter Kit from
http://github.com/technomancy/emacs-starter-kit. I has an install clojure
option that does most of the work of installing clojure, clojure-contrib and
setting up slime in a way that gets one going very quickly.

Regards,
Bill

On Mon, Nov 23, 2009 at 4:55 PM, the.stuart.sie...@gmail.com wrote:

 If you have trouble viewing or submitting this form, you can fill it out
 online:

 http://spreadsheets.google.com/viewform?formkey=dFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MA

 Clojure User Survey

 This user survey will help move Clojure toward an official 1.1 release.


  How do you get Clojure? *

- Download release
- Github
- Maven or Ivy


  What distribution of Clojure do you use primarily? *

- 1.0 release
- I picked one development snapshot and stuck with it
- I use the latest development snapshot
- I follow Github master branch
- I follow Github new branch


  What about chunked sequences? *

- I don't know what they are
- The help me
- They hurt me
- I don't notice any difference


Powered by Google Docs http://docs.google.com Report 
 Abusehttp://spreadsheets.google.com/reportabuse?formkey=dFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MAsource=http%253A%252F%252Fspreadsheets.google.com%252Fviewform%253Fformkey%253DdFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MA-
  Terms
 of Service http://www.google.com/accounts/TOS - Additional 
 Termshttp://www.google.com/google-d-s/terms.html

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

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

Re: PersistentStructMap Exception

2009-11-23 Thread songoku

 user= (defstruct s1 :a :b)
 #'user/s1
 user= (s1 1 2)

(struct s1 1 2) or (struct-map s1 :a 1 :b 2)
-- {:a 1, :b 2}

or:
(struct s1 1)
-- {:a 1, :b nil}

(struct-map s1 :b 2)
-- {:a nil, :b 2}

-- 
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: roll call of production use?

2009-11-23 Thread John Harrop
On Mon, Nov 23, 2009 at 8:35 PM, Phlex ph...@telenet.be wrote:


  i'd be interested to hear who has successfully used clojure in
  production.

 Hello,

 1- We have this license server, used to control the use of a
 professional software (this one written using delphi).


What are the ethics of using an open source product like Clojure to
implement DRM restrictions for some other product? Seems there might be
something a bit iffy there -- if not legally, perhaps morally.

-- 
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: roll call of production use?

2009-11-23 Thread Phlex

 1- We have this license server, used to control the use of a
 professional software (this one written using delphi).


 What are the ethics of using an open source product like Clojure to 
 implement DRM restrictions for some other product? Seems there might 
 be something a bit iffy there -- if not legally, perhaps morally.
 -- 

Ah nice to see you've finally adopted a lisp !

This customer's request seemed reasonable, and the project looked like a 
perfect test bed for clojure.
The scope was small, and the requirements well defined. It involved 
multithreading, networking, databases and long up-times.

The ethics are not mine to define. I'm just programmer, and will leave 
this discussion to you philosophers.
Once a consensus will be reached you may drop me a mail.
In the meantime, I'll just go hack at my next evil project.

Sacha De Vos


-- 
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: Datatypes and Protocols - early experience program

2009-11-23 Thread Allen Rohner


On Nov 12, 6:10 am, Rich Hickey richhic...@gmail.com wrote:
 An early version of the code for a few important new language
 features, datatypes[1] and protocols[2] is now available in the 'new'
 branch[3]. Note also that the build system[4] has builds of the new
 branch, and that the new branch works with current contrib.

 If you have the time and inclination, please try them out. Feedback is
 particularly welcome as they are being refined.

 Thanks,

 Rich

 [1]http://www.assembla.com/wiki/show/clojure/Datatypes
 [2]http://www.assembla.com/wiki/show/clojure/Protocols
 [3]http://github.com/richhickey/clojure/tree/new
 [4]http://build.clojure.org/

The first stumbling point I reached is that deftypes provide an
automatic implementation for IPersistentMap, but not IFn. I attempted
to write (instance key), which exploded, but (key instance) works just
fine. My existing code uses (instance key) almost universally. Should
I get used to this, or are there plans to provide a default IFn
implementation?

Allen

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


Re: roll call of production use?

2009-11-23 Thread mbrodersen
I use an internal DSL (Domain Specific Language)  in Clojure to
generate C++ and C# code.

Cheers
Morten

On Nov 24, 10:00 am, Raoul Duke rao...@gmail.com wrote:
 hi,

 i'd be interested to hear who has successfully used clojure in
 production. i know of some, as some folks have been vocal; any other
 interesting-but-so-far-silent uses people'd be willing to fess up
 about?

 many thanks.

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


Re: roll call of production use?

2009-11-23 Thread John Harrop
On Mon, Nov 23, 2009 at 9:47 PM, Richard Newman holyg...@gmail.com wrote:

 1- We have this license server, used to control the use of a
 professional software (this one written using delphi).


 What are the ethics of using an open source product like Clojure to
 implement DRM restrictions for some other product? Seems there might be
 something a bit iffy there -- if not legally, perhaps morally.


 I don't agree. So long as they abide by the Clojure license, everything is
 A-OK… and the Clojure license doesn't impose restrictions on its use for
 this purpose.


Hence my if not legally.


 This use of Clojure is internally consistent, and so I suspect that you're
 simply slightly offended by the idea of someone making money by using
 open-source software. In that case, I'd suggest you look first at Red Hat
 (market cap: $5.09B), and the Linux community's attitude towards them
 (generally positive).


Oh, I have no problem with making money by using open source software, when
it's done in the manner that companies like Red Hat do it. It's the use to
lock down some piece of proprietary software even more than it already is
that seems, at the very least, ironic.

-- 
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: Datatypes and Protocols - early experience program

2009-11-23 Thread Krukow


On Nov 24, 4:55 am, Allen Rohner aroh...@gmail.com wrote:
 The first stumbling point I reached is that deftypes provide an
 automatic implementation for IPersistentMap, but not IFn. I attempted
 to write (instance key), which exploded, but (key instance) works just
 fine. My existing code uses (instance key) almost universally. Should
 I get used to this, or are there plans to provide a default IFn
 implementation?

I agree that it would be nice with an automatic IFn implementation if
you specify the interface. As an alternative, you could use

user (deftype F[x] [clojure.lang.IPersistentMap clojure.lang.IFn]
 (.invoke [k] (k this)))
#'user/F
user ((F 42) :x)
42
user

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

2009-11-23 Thread Mark Engelberg
Meikel's blog post quotes:
running into a lot of such trouble is a sign, that you misuse dynamic
variables. Use them wisely.

I'd like to see examples of what you think is a good, clean,
compelling use of dynamic variables that are properly used wisely.

My own experience is that if the code is simple enough for you to
analyze the use of binding and be sure it is correct, then the code is
also simple enough to have easily written in another way (perhaps
using explicit parameter passing).  On the other hand, if the use of
binding is complex enough to really matter, it is also sufficiently
complex you can't be 100% sure binding will do what you expect.

I even somewhat question the places where Clojure internally uses
bindings.  For example, if you use with-precision to try to control
floating point behavior within a structure that potentially has some
deep laziness (like a tree) that can't easily be forced with a doall,
you're in for a surprise.

I would like to be proven wrong, so I'm serious about wanting to see
good examples of dynamic binding.

-- 
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 User Survey, preparation for 1.1

2009-11-23 Thread David Brown
On Mon, Nov 23, 2009 at 09:55:46PM +, the.stuart.sie...@gmail.com wrote:

Since the form only lets me answer one answer for each, but reality is
much more complicated.

How do you get Clojure? *

Download release
Github
Maven or Ivy

I primarily use the latest development snapshot that I pull down with
Maven/Ivy.

But, I also keep a git workspace and bounce between master and new.

As far as chunked sequences, I started using clojure after they were
already in place, so I don't really have anything to compare it with.

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

2009-11-23 Thread Garth Sheldon-Coulson
Hi Mark,

In Clojuratica I make what I think is good, clean, compelling use of
dynamic vars. I rewrote the code to use dynamic vars after I found that
doing it the other way became unwieldy and inelegant.

To simplify a little, the API consists of just one main function, let's call
it math-evaluate.

Every time the user calls math-evaluate, he or she can specify any of a
number of flags. Just for illustration, let's say two of these flags are
:flag1 and :flag2.

The math-evaluate function parses the flags and places them in a map called
*options* (or options before I was using dynamic vars). It then calls into
the core functions of the code base and returns the result. The core
functions call one another in complex ways. There are scores of core
functions. All of them have need to have access to the options map, if not
for their own consumption then for passing to other core functions.

Without dynamic vars, every single function in my code base would need to
have an options argument. Moreover, every mutual call between these scores
of functions would need to include the options map as an argument. I did it
this way for a while, and it was painful.

Moreover, if in the future I decided that every core function needed access
to *two* of these global-within-the-dynamic-scope vars instead of one, I
would need to edit the signature of every function and edit every mutual
call between the functions.

It turned out that this actually happened: I decided I needed another map to
store a few I/O bindings (it's called *kernel*). Because I was using dynamic
vars, I was able to change just one location in my code---the namespace
where the dynamics are interned---instead of several hundred locations.

The trade-off is the following. When I need to return a function or lazy seq
I need to close over the *options* and *kernel* vars by jumping through the
hoops Meikel has documented. There are only five or six such places in the
code, so I'm more than happy to do this. It feels quite elegant to me,
although I'd like a little more syntactic sugar.

Note that the dynamic vars are solely for my convenience as a programmer,
not part of the API of the software. I shield them from the user, so if the
user tried to bind *options* him- or herself it would have no effect on the
code. Every call to math-evaluate binds the dynamic vars anew on the basis
of the flags passed. My use of dynamics is an implementation detail.

The source is on github. The real-laziness branch is the newest and uses
bound lazy-seqs the most, particularly in clojuratica.base.parse.

Comments on this usage welcome.

Garth

On Tue, Nov 24, 2009 at 1:43 AM, Mark Engelberg mark.engelb...@gmail.comwrote:

 Meikel's blog post quotes:
 running into a lot of such trouble is a sign, that you misuse dynamic
 variables. Use them wisely.

 I'd like to see examples of what you think is a good, clean,
 compelling use of dynamic variables that are properly used wisely.

 My own experience is that if the code is simple enough for you to
 analyze the use of binding and be sure it is correct, then the code is
 also simple enough to have easily written in another way (perhaps
 using explicit parameter passing).  On the other hand, if the use of
 binding is complex enough to really matter, it is also sufficiently
 complex you can't be 100% sure binding will do what you expect.

 I even somewhat question the places where Clojure internally uses
 bindings.  For example, if you use with-precision to try to control
 floating point behavior within a structure that potentially has some
 deep laziness (like a tree) that can't easily be forced with a doall,
 you're in for a surprise.

 I would like to be proven wrong, so I'm serious about wanting to see
 good examples of dynamic binding.

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


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