Re: Joy of Clojure example not working

2021-08-14 Thread Chouser
In this case, I think the git repo 

 
has correct code where the book does not; "clang" instead of "gcc":

(defmethod compile-cmd [::osx "gcc"] [m]
  (str "/usr/bin/" (get m :c-compiler)))

...should instead be...

(defmethod compile-cmd [::osx "clang"] [m]   ;; Match the vector exactly
  (str "/usr/bin/" (get m :c-compiler)))

On Tuesday, May 20, 2014 at 11:06:09 PM UTC-4 JD wrote:

> This did it Greg,
>
> Thanks a lot.
>
>
> On Wednesday, May 21, 2014 2:18:08 AM UTC+9, Greg D wrote:
>>
>> Yes, the examples in the book are missing some lines. I think the 
>> following log shows what they were going for:
>>
>> joy.udp=> (remove-method compiler ::osx)
>> joy.udp=> (def unix (into unix {::c-compiler "/usr/bin/gcc"}))
>> joy.udp=> (def osx (into osx {:c-compiler "gcc"}))
>> oy.udp=> osx
>> {:home "/Users", :llvm-compiler "clang", :os :joy.udp/osx, 
>> :joy.udp/prototype {:home "/home", :os :joy.udp/unix, :c-compiler "cc", 
>> :dev "/dev"}, :c-compiler "gcc"}
>> joy.udp=> unix
>> {:home "/home", :joy.udp/c-compiler "/usr/bin/gcc", :os :joy.udp/unix, 
>> :c-compiler "cc", :dev "/dev"}
>> joy.udp=> (compiler osx)
>> "gcc"
>> joy.udp=> (compile-cmd osx)
>> "/usr/bin/gcc"
>>
>> About your question:
>>
>>> Isn't there a core function/macro where I can derive and set hierarchy 
>>> all at once?
>>>
>> Such a function would need to know in advance what hierarchy you want to 
>> construct. If you have a desired pattern of hierarchy that you want to 
>> reuse, you could define a function to create it using "derive" and 
>> optionally "make-hierarchy". 
>>
>>
>> On Monday, May 19, 2014 4:38:00 PM UTC-7, gamma235 wrote:
>>>
>>> I actually just wanna know why I need to use derive so many times. Isn't 
>>> there a core function/macro where I can derive and set hierarchy all at 
>>> once? I'm just looking for a more efficient way. My bad for not stating 
>>> that more clearly in the original post. 
>>>
>>> The real problem though is the last two calls to compile-cmd. I've been 
>>> messing with it for a couple of days so any help there would be well 
>>> appreciated.
>>>
>>> Thanks
>>>
>>> J
>>>
>>>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/f4e8b3e6-f521-4cbc-83e2-859e6016110en%40googlegroups.com.


Re: PSA: A slight tweak to "concat"

2019-07-08 Thread Chouser
I see I introduced the bug while adding support for chunked seqs to
concat. I'm grateful someone has found and fixed my mistake. Thanks,
Alex!

—Chouser

On Sat, Jul 6, 2019 at 7:57 AM Matching Socks  wrote:
>
> There's activity on a ticket in Jira to fix a quirk of "concat" that dates 
> back to a commit by chouser in 2009!
>
> It's subtle because the title of CLJ-2523 is "lazy-cat can cause 
> StackOverflowError with more than 2 arguments", which describes a symptom 
> observed downstream.  The ticket's patch fixes concat.
>
> Looking forward to Clojure 11!

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/CAM%3DV%2BJVunPKBYoENpnTy4%3D87qiZwyC3A%2BDqhz_M9xd-FZrXh%3DA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: order of returned values from keys and vals

2014-02-01 Thread Chouser
There's no substitute for measurement.

(defn maptest [f]
  (let [m (apply hash-map (range 40))]
(time (dotimes [_ 10] (f m)))
(f m)))

(maptest #(zipmap (keys %) (map inc (vals %
; Elapsed time: 1405.890766 msecs
;= {0 2, 32 34, 2 4, 34 36, 4 6, 36 38, 6 8, 38 40, 8 10, 10 12, 12 14, 14
16, 16 18, 18 20, 20 22, 22 24, 24 26, 26 28, 28 30, 30 32}

(maptest #(into {} (map (fn [[k v]] [k (inc v)]) %)))
; Elapsed time: 1433.270362 msecs
;= {0 2, 32 34, 2 4, 34 36, 4 6, 36 38, 6 8, 38 40, 8 10, 10 12, 12 14, 14
16, 16 18, 18 20, 20 22, 22 24, 24 26, 26 28, 28 30, 30 32}

(maptest #(reduce-kv (fn [m k v] (assoc m k (inc v))) {} %))
; Elapsed time: 649.452695 msecs
;= {0 2, 32 34, 2 4, 34 36, 4 6, 36 38, 6 8, 38 40, 8 10, 10 12, 12 14, 14
16, 16 18, 18 20, 20 22, 22 24, 24 26, 26 28, 28 30, 30 32}

These results are fairly robust in relation to each other for other sizes
of smallish maps.

--Chouser


On Sat, Feb 1, 2014 at 10:35 PM, Justin Smith noisesm...@gmail.com wrote:

 Realistically, how many situations are there where running keys and vals
 independently is preferable to running seq once and using the two element
 vectors that returns?

 Usually this way one can avoid walking the whole thing twice.

 (into {} (map (fn [[k v]] [k (inc v)]) {:a 0 :b 1})) is representative of
 the idiom I usually use. As a bonus, into uses transients, which can create
 the resulting structure in fewer cycles / less time.


 On Saturday, February 1, 2014 10:00:33 AM UTC-8, Sam Ritchie wrote:

 Looks like Rich just chimed in with:

 keys order == vals order == seq order 

   Matching Socks
  January 31, 2014 7:31 PM
 Actually, http://dev.clojure.org/jira/browse/CLJ-1302 keys and vals
 consistency not mentioned in docstring was declined, with the comment The
 absence of this property in the docs is correct. You should not rely on
 this.



 On Wednesday, August 11, 2010 6:03:39 PM UTC-4, Chouser wrote:
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@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 unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/groups/opt_out.


 --
 Sam Ritchie (@sritchie)
 Paddleguru Co-Founder
 703.863.8561
 www.paddleguru.com
 Twitter http://twitter.com/paddleguru // 
 Facebookhttp://facebook.com/paddleguru




-- 
--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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: infinite loop print out of cyclic structure at repl

2013-10-01 Thread Chouser
Bah, mutable state! To be cursed in all its forms!

Here is the same content as was at that paste.lisp.org link. I haven't
tested it with recent versions of Clojure or anything:

https://gist.github.com/Chouser/6783292

--Chouser

On Tue, Oct 1, 2013 at 12:44 PM, Patrik Sundberg
patrik.sundb...@gmail.com wrote:
 This paste seems gone - anyone has it available?

 I seem to get bitten by this kind of thing in emacs using nrepl and it
 pretty printing something and it gets into an infinite loop locking up my
 emacs session completely. Running the same from command line i can see same
 behavior (seems related to protocols in my case, but haven't spent much time
 on it(). Either way I'd love to work out a way to avoid the cycles and this
 paste sounds good.


 On Monday, January 18, 2010 10:21:52 PM UTC, Chouser wrote:

  On Jan 18, 4:22 pm, Raoul Duke rao...@gmail.com wrote:
  hi,
 
  hmmm, i wish there were a way (or that it was the default) to tell the
  repl to not continue to loop for ever over things it has already
  printed out when i eval something that is a cyclic thing. anybody
  have a patch, or thought on this?

 On Mon, Jan 18, 2010 at 4:38 PM, Mark Hamstra markh...@gmail.com wrote:
  See *print-length* and *print-level* in the core API.

 Or if you want unlimited depth, but want to avoid printing the
 value of any reference object more than once, you can try this
 little thing I hacked together a while ago:

 http://paste.lisp.org/display/83647

 Note that it has to keep a reference to every IDeref object it
 sees while it's printing, in order to detect duplicates.

 --Chouser
 http://joyofclojure.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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.



-- 
--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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Natively Compiled Clojure

2013-01-21 Thread Chouser
I'm pretty sure clj-native is more recent, faster, better, and more
actively maintained. I ought to update clojure-jna to say all that.


On Mon, Jan 21, 2013 at 2:21 PM, Philip Potter philip.g.pot...@gmail.comwrote:

 you might want to look at clj-native:

 https://github.com/bagucode/clj-native

 It's used, among other things, by overtone to interact with
 libscsynth, the supercollider synthesis library:


 https://github.com/overtone/overtone/blob/master/src/overtone/sc/machinery/server/native.clj

 I don't know how it compares to clojure-jna; clj-native also uses jna
 under the hood.

 Phil

 On 21 January 2013 17:25, octopusgrabbus octopusgrab...@gmail.com wrote:
  I've had no problems. I am just curious.
 
  What triggered this was this morning I saw something on
 stackoverflow.com
  about Clojure's possibly interacting with C code, and the natively
 compiled
  question just popped into my head.
 
 
  On Monday, January 21, 2013 12:19:27 PM UTC-5, tbc++ wrote:
 
  If you haven't found a performance problem, and it's working well for
 your
  needs, why are you interested in making the code run natively. What
  problems have you encountered that pique your intrest in this area?
 
  Timothy
 
 
 
 
  On Mon, Jan 21, 2013 at 9:29 AM, octopusgrabbus octopus...@gmail.com
  wrote:
 
  I use Clojure primarily as a very reliable tool to aid in data
  transformations, that is taking data in one application's database and
  transforming it into the format needed for another applications'
 database.
 
  So, my question is would a natively compiled Clojure make sense or turn
  the language into something that was not intended? In almost all
 instances I
  have not found a problem with Clojure's execution speed so my question
 is
  not about pro or anti Java.
 
  Thanks.
 
  --
  You received this message because you are subscribed to the Google
  Groups Clojure group.
  To post to this group, send email to clo...@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+u...@googlegroups.com
 
  For more options, visit this group at
  http://groups.google.com/group/clojure?hl=en
 
 
 
 
  --
  “One of the main causes of the fall of the Roman Empire was that–lacking
  zero–they had no way to indicate successful termination of their C
  programs.”
  (Robert Firth)
 
  --
  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




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

Call for Presentations: Commercial Users of Functional Programming 2012

2012-02-24 Thread Chouser
The 2012 CUFP call for presentations is out:
http://cufp.org/cufp-2012-call-presentations

The program committee is hoping for better representation from the
Clojure community this year, so if you've got something interesting to
say about Clojure, please submit a proposal!

--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: Empty list type

2011-11-01 Thread Chouser
2011/11/1 Sebastián Galkin paras...@gmail.com:
 On Tuesday, November 1, 2011 9:33:31 PM UTC-2, David Nolen wrote:

 (isa? (type '(:foo :bar)) clojure.lang.IPersistentList) = true
 (isa? (type ()) clojure.lang.IPersistentList) = true
 (isa? (type (list)) clojure.lang.IPersistentList) = true

 oh that's right

There's a larger point here that I think David was making.  It is
important not to rely on the concrete type of anything, but instead to
rely on an interface or protocol that it supports.  Choose the right
abstraction to allow concrete details to be adjusted without breaking
your program.  The EmptyList class is a perfect example of an
implementation detail that we shouldn't rely on.  Nobody promises that
it will be there in the future.  However, Clojure does promise that
'(:foo :bar), () and (list) will all return something for which seq?,
list?, coll?, and sequential? will return true, and that () and (list)
will return something for which empty? will return true.

--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: Idiomatic record construction in 1.3

2011-10-26 Thread Chouser
On Wed, Oct 26, 2011 at 9:24 AM, Alex Miller a...@puredanger.com wrote:
 I need to correct that p2 and m1 should not have parens around
 them sorry about that.  Seemed obvious when I read it again this
 morning.

 The literal reader forms are even trickier in how they treat embedded
 expressions.  They seem to preserve (and not evaluate) the quoted
 forms?

 user= (def p #user.Person[(str a b) c])
 #'user/p
 user= p
 #user.Person{:first (str a b), :last c}    ;; note the embedded
 str here, not ab
 user= (:first p)
 (str a b)           ;; aroo?

 Surely, this is not the intended behavior?

I suspect it is intended.  You certainly wouldn't want those interior
forms evaluated at reader time.  To be more like literal vectors and
maps, eval would have to know how to handle each record type, find the
forms contained in the values, evaluate them, and build a new record
with the results.  Off the top of my head I don't see why this would
be impossible, but it may not be desirable.

--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: Tail Recursion In Erjang

2011-10-21 Thread Chouser
On Fri, Oct 21, 2011 at 10:14 AM, Stuart Sierra
the.stuart.sie...@gmail.com wrote:
 Clojure does tail-call elimination for simple cases with loop/recur. This is
 by far the most common case. Most other tail-recursive situations can be
 represented as lazy sequences, which are another way to handle recursive
 functions without consuming stack space. For the final rare cases (e.g.
 mutually recursive functions) Clojure has `trampoline`, which does something
 similar to (on first glance) Erjang.

I agree, it seems that Erjang is doing a form of trampoline
automatically.  Besides Clojure's solution being manual, another
difference is that Clojure returns the data necessary to execute the
next step while Erjang stores that data in a mutable spot that's used
only by the current thread.

 One nice thing about Clojure's approach is that any function can be invoked
 from Java just like any other method. On a quick read, I can't tell if  the
 Erjang approach requires special handling from Java code.

This is a critical question for Java.  It looks like every Erjang
function provides an .invoke() method than handles any required
trampolining, so calling that from Java should be safe.

 The underlying goal of Clojure's recursion semantics is to always be
 explicit about where compilation strategies will differ. Loop/recur, lazy
 seqs, and trampoline all have different performance characteristics. You
 don't have to guess which method is being used.

This, combined with the fact that together these techniques cover an
overwhelming majority of use cases (and the fact that they're already
done and work) means the cost/benefit of now adding something like
Erjang does may not be so good.

Hm, and besides performance there are implications for stack traces.
Trampolines, either explicit in Clojure or automatic in Erjang, surely
would make Java stack traces harder to understand as information about
intermediate function calls would be completely missing.

Might be an interesting experiment though.

So... is a function call that could be either of two things (a
loop/recur or a trampoline site) simple or complected?

--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: Clojure 1.3 wonky behavior

2011-10-20 Thread Chouser
On Thu, Oct 20, 2011 at 4:31 PM, Chris Perkins chrisperkin...@gmail.com wrote:
 Note: I forgot to preface that with I think... :)  Upon experimenting
 briefly, it turns out I was wrong about how Clojure works (that seems to
 happen a lot with me).  A declare/def defines a var even when it's not
 executed!
 user (defn xxx [] (declare yyy))
 #'user/xxx
 user yyy
 #Unbound Unbound: #'user/yyy
 Well, I learned something today.

But it only interns the Var, it doesn't fully set it up.  Particularly
relevant to the OP's example is that the metadata from the name symbol
is not transferred to the Var (and the changes to the Var based on
:dynamic are not applied) until runtime for the 'def', even though the
Var exists at compile time.

Here's a macro that expands at compile time to the *compile* time
metadata of the var named in its argument:

(defmacro compile-time-meta [x] (meta (resolve x)))

Now observe how it behaves differently than a runtime call to 'meta':

(vector
  (declare ^:dynamic *myvar*)
  (meta #'*myvar*)
  (compile-time-meta #'*myvar*)))

The above returns:

[#'user/*myvar*
 {:ns #Namespace user, :name *myvar*, :dynamic true, :declared true, ...}
 {:ns #Namespace user, :name #Unbound Unbound: #'user/*myvar*}]

First is the Var itself.
Next is the metadata of the Var at runtime, after the entire form has
been compiled and therefore the metadata from the name has been
applied to the Var, including the :dynamic flag.
Finally we see that when our macro was expanded the Var existed but
had minimal metadata.  This was after the declare was compiled but
before any part of the 'vector' form was run.  There is no :dynamic
flag, and anything that depends on that flag at compile time to work
correctly (such as a function that refers the for Var) will fail to
work correctly.

--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: ClojureScript Mobile BOF at the Clojure/conj?

2011-10-18 Thread Chouser
On Tue, Oct 18, 2011 at 12:22 PM, Chas Emerick cemer...@snowtide.com wrote:
 On Oct 18, 11:12 am, Michael Fogus mefo...@gmail.com wrote:
  Anyone from the Clojure/conj org committee

 While I'm not on the organization committee, I will say that
 side-events like this would be spectacular.  The logistics escape me
 at the moment, but perhaps spontaneity is the best approach?

 …or even a little light planning if you really want to get a group
 together.  There are way too many special interests for any single
 body to plan for.  Absolutely nothing is keeping someone from creating
 a google docs spreadsheet, defining some time slots, and dropping
 talks / BOFs / topical hack sessions in, quasi-unconference style.

I love this idea -- google spreadsheet of extra events.

/me waits for someone to post a link.

--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: Recursively convert Java Map to Clojure Map

2011-10-16 Thread Chouser
On Sun, Oct 16, 2011 at 1:51 AM, Baishampayan Ghose b.gh...@gmail.com wrote:
 On Sun, Oct 16, 2011 at 11:16 AM, Jestan Nirojan
 jestanniro...@gmail.com wrote:
 Your solution worked, about 4x~5x improvement.
 Thanks a lot BG.

 Glad that it worked for you, Jestan. Protocols are usually the right
 approach for these kind of tasks.

Why convert at all?  Java maps can be used quite conveniently in Clojure.

If it's because you need the map to be persistent, you might consider
converting each map only when the user attempts to conj or assoc,
rather than doing all the work up front.  Since those aren't (yet!)
protocols, I supposed you'd have to either use a non-standard conj and
assoc, or create a wrapper around the Java Maps.  Of course there are
complications with all three of these solutions, so you'll have to
choose carefully based on your needs.

--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: Partitioning problem

2011-09-23 Thread Chouser
On Fri, Sep 23, 2011 at 7:51 AM, Michael Jaaka
michael.ja...@googlemail.com wrote:
 Hi!

 I have a sequence of natural numbers and I have to partition them into
 more or less equals N groups.
 Partitioning function is just a sum of numbers in a given group.

 My naive solution is to sort numbers descending then take each number
 and put into one of N groups in which sum of its elements with given
 number is the lowest. Here is the code: http://pastebin.com/Nw28FaRK

 So for input [ 1 2 34  54 12 23 5  2 3  1 2 12 11 12 32 67 ] and N = 5
 I get
 ([32 12 5 1 1] [34 12 2 2] [23 12 11 3 2] [54] [67])

 Do you know any better solution?

Seems like a good algorithm.  Here's another implementation:

(defn partition-into [f n coll]
  (map peek
   (reduce
 (fn [buckets x]
   (let [b (first buckets), b2 (conj (b 2) x)]
 (conj (disj buckets b) [(apply f b2) (b 1) b2])))
 (apply sorted-set (for [i (range n)] [0 i []]))
 (reverse (sort coll)

This only computes the sum once each time a partition is added to
(instead of multiple times during the sort), and because it's using a
sorted set only has to compare the sum to log(n) other buckets each
time instead of doing an n*log(n) sort-by.

--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: clojurescript closure problem?

2011-09-22 Thread Chouser
On Thu, Sep 22, 2011 at 8:46 AM, David Nolen dnolen.li...@gmail.com wrote:
 It's a known issue:
 http://dev.clojure.org/jira/browse/CLJS-39

I somehow missed that one and had filed this one as well:

http://dev.clojure.org/jira/browse/CLJS-59

--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: How does clojure class reloading work?

2011-09-22 Thread Chouser
On Thu, Sep 22, 2011 at 2:56 PM, Kevin Downey redc...@gmail.com wrote:
 most likely the compiler is creating a new DynamicClassLoader, it uses
 a var clojure.lang.Compiler/LOADER and pushes and pops class loaders
 from there.

You nailed it.

It looks like each top-level form currently gets its own fresh
DynamicClassLoader.

(do
  (deftype C [])
  (def x1 (C.))
  (deftype C [a])
  (def x2 (C. 42)))

(.getClassLoader (class x1))
;= #DynamicClassLoader clojure.lang.DynamicClassLoader@3e5b38d7

(.getClassLoader (class x2))
;= #DynamicClassLoader clojure.lang.DynamicClassLoader@727f3b8a

Note the numbers after the @s are different -- each got its own
classloader.  This is not exclusive to deftype of course:

(do (def a #()) (def b #()))

(.getClassLoader (class a))
;= #DynamicClassLoader clojure.lang.DynamicClassLoader@638bd7f1

(.getClassLoader (class b))
;= #DynamicClassLoader clojure.lang.DynamicClassLoader@581de498

--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: How does clojure class reloading work?

2011-09-22 Thread Chouser
On Thu, Sep 22, 2011 at 8:52 PM, Phil Hagelberg p...@hagelb.org wrote:
 On Thu, Sep 22, 2011 at 2:19 PM, Chouser chou...@gmail.com wrote:
 It looks like each top-level form currently gets its own fresh
 DynamicClassLoader.

 [...]

 (do (def a #()) (def b #()))

 If you'll pardon a nit-pick, this example is somewhat misleading since
 do forms are special-cased by the compiler so that each form they
 contain is treated as a top-level form.

Yes, you're right.  I shouldn't have used that example without
explaining that.  Thanks for doing it 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: [newbie] filter confusion

2011-09-20 Thread Chouser
On Mon, Sep 19, 2011 at 2:20 PM, qhfgva qhf...@gmail.com wrote:
 I'm working through some puzzle problems to help get up to speed on
 clojure.  Generally I've been able to pound on something for a while
 and get the moment of enlightenment but for some reason this seemingly
 simple item is stumping me.  (FWIW, the puzzle in question is the
 crossing a bridge at night in pairs with one lantern problem).

 Here is The output that is confusing me:

 Using:

 (defn not-seen-already? [states state]
  (not (some #{state} states)))

 user= path
 [{:left [1 2 3], :lamp :left, :right []} {:lamp :right, :left (2
 3), :right (1)}]
 user= next-steps
 ({:lamp :left, :right (), :left (1 2 3)})
 user= next-steps2
 [{:lamp :left, :right [], :left [1 2 3]}]
 user= (filter #(not-seen-already? path %) next-steps)
 ({:lamp :left, :right (), :left (1 2 3)})
 user= (filter #(not-seen-already? path %) next-steps2)
 ()
 user= (filter #(not-seen-already? path %) '({:lamp :left, :right
 (), :left (1 2 3)}))
 ()
 user= (filter #(not-seen-already? path %) [{:lamp :left, :right
 [], :left [1 2 3]}])
 ()

 As you can see above, passing in the variable next-steps and next-
 steps2 above into my expression I get two different results (I was
 expecting the second result).  When I pass the data structures in
 explicitly I get the same result for each.

I can't reproduce your results:

user= (filter #(not-seen-already? path %) next-steps)
()

What does your REPL say if you: (= (first next-steps) (first path))
What version of Clojure are you using?

--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: How to convert general recursion to loop .. recur syntax

2011-09-15 Thread Chouser
On Thu, Sep 15, 2011 at 8:56 AM, Herwig Hochleitner
hhochleit...@gmail.com wrote:
 Hi,

 as you might know, the original version actually does run in fixed
 stack space, thanks to lazy sequences.

You are right!

Without testing it I had thought that the way recursion was used would
cause skl to overflow the stack if the input tree was very deep on its
first elements.

 (defn skl
  [tree]
  (map skl (filter seq? tree)))

But in testing this skl fn I couldn't get it to overflow.  This is
because the tree is not flattened, and so calling 'first' on the top
level of the resulting tree only forces the top-level map, whose first
item remains a lazy seq, neatly avoiding an overflow error.

Good catch, Herwig!

 Consider

 (defn find-in-tree
  ([tree pred?]
    (concat
      (filter pred? tree)
      (mapcat find-in-tree (filter sequential? tree) (repeat pred?)

 which of course is much simpler written as

 (defn find-in-tree
  ([tree pred?] (filter pred? (flatten tree

 all of which are lazy, hence consume constant stack space

Alas, this suffers from exactly the problem that I incorrectly
believed skl suffered from.  It works fine for some trees:

(find-in-tree (reduce list (range 1000)) #(when-not (seq? %) (even? %)))
;= (0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44
46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90
92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126
128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160
162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194
196 198 200 202 204 ...)

But the lazy seqs form a chain so that in order to return the first
element of the result, they seqs must each force the next in the
chain, consuming call stack frames as they go.  Provide a tree deep
enough and it overflows the stack:

(find-in-tree (reduce list (range 1)) #(when-not (seq? %) (even? %)))
; StackOverflowError   clojure.lang.RT.boundedLength (RT.java:1607)


Nevertheless let us now marvel for a moment at the beauty of lazy
seqs, that they can sometimes avoid both premature computation and
stack overflows, even in cases where no amount of
tail-call-optimization would help! And all this while delivering code
so similar to the problem statement and therefore concise, compared to
the long and tortured loop/recur version I posted yesterday.

--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: How to convert general recursion to loop .. recur syntax

2011-09-14 Thread Chouser
On Wed, Sep 14, 2011 at 3:58 PM, octopusgrabbus
octopusgrab...@gmail.com wrote:
 Alan:

 I may have misunderstood what I've read both in books, blogs, and the
 Clojure site, but it seems that writing recursive functions in the loop ..
 recur style is the preferred style. I also remember most of the texts
 currently out on Clojure say use the higher level sequence functions rather
 than recursion. I get it.

 I wanted to do this particular exercise without the aid of Clojure.zip.

I would highly recommend using zip for such things, because otherwise
you have to write code like this:

(defn skl [tree]
  (loop [[self  todo :as src] [tree], dst [()]]
(cond
  (empty? src)   dst
  (not (coll? self)) (recur todo (first dst))
  (empty? self)  (recur todo (conj (first dst) (rest dst)))
  :else  (recur (list* (first self) (rest self) todo) [dst]

Jonathan Claggett helped write that.  I'm not sure there was ever a
moment where we both understood it simultaneously.

It essentially does what zippers do, but holds the data in a
loop/recur frame rather than a data structure.  Any further
explanation is left as an exercise to the reader.

--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: Neighbors function from The Joy of Clojure

2011-09-14 Thread Chouser
On Wed, Sep 14, 2011 at 3:35 PM, Fogus mefo...@gmail.com wrote:
 diagonals as neighbors.  We don't think we take advantage of the
 flexibility anywhere in the book, so perhaps your version would indeed
 be better.

I meant to say I didn't think.  Sorry, didn't mean to put words in
your mouth, Fogus.

 It was used again only briefly in section 11.2 to define the legal
 moves that a king can make in chess, which of course includes
 diagonals.  :-)

Ah, indeed.  Sorry to mislead.

--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: heaps in clojure

2011-09-13 Thread Chouser
On Tue, Sep 13, 2011 at 7:44 AM, Sunil S Nandihalli
sunil.nandiha...@gmail.com wrote:
 Hi Everybody,
  I have a very large, but with finite size, collection. I would like to get
 like first 10 elements in the sorted list . I would use a heap if I were in
 c++ .. is there a inbuilt implementation of this in clojure? .. Is there
 some other way to achieve this? some sort of lazy sort would be perfect. I
 know I need the full collection to start with .. but that is fine.

A seq on a sorted set should be pretty efficient.

(take 3 (sorted-set 8 2 1 4 6 9 7 3))
;= (1 2 3)

--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: Programmer Day

2011-09-13 Thread Chouser
On Tue, Sep 13, 2011 at 12:31 PM, Wilker wilkerlu...@gmail.com wrote:
 (println (apply str (map char [72 97 112 112 121 32 80 114 111 103 114 97
 109 109 101 114 32 68 97 121 33])))

What kind of day is that, anyway?

(let [m map, c comp, p partial, s str]
  (m (c symbol (p apply s) (p m (c char dec int)) s)
 '[ibqqz qsphsbnnfs ebz]))

--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: Misleading Exception due to function name containing -

2011-09-12 Thread Chouser
On Fri, Sep 9, 2011 at 4:47 AM, Christina Conway
ccon...@annadaletech.com wrote:
 A function name contains the characters -
   e.g.  foo-fn
 The function causes an exception.
 However the exception is not reported on the function but on another
 function called before it.
   java.lang.IllegalArgumentException: Wrong number of args (1) passed
 to: datetime$other-fn

 If the  character is removed from the function name
   e.g. foo-fn
 then the same exception is thrown but on the function itself:
   java.lang.IllegalArgumentException: Wrong number of args (1) passed
 to: datetime$foo-fn

 If the - character is removed from the function name
   e.g. foofn
 then the exception is thrown on the function as follows:
   java.lang.IllegalArgumentException: Wrong number of args (1) passed
 to: datetime$foo-GT-fn

 The foo-fn function is compiled to a .class file as:
 foo__GT_fn.class
 The foofn function is compiled to a .class file as:
 foo_GT_fn.class
 The foo-fn function is compiled to a .class file as:
 foo_fn.class

 Has anybody else encountered this with function names containing -.
 Is this a bug?

I was unable to reproduce the problem:

user= (defn foo-fn [] (throw (Exception. bad thing)))
#'user/foo-fn
user= (defn other-fn [] (foo-fn))
#'user/other-fn
user= (other-fn)
Exception bad thing  user/foo-fn (NO_SOURCE_FILE:1)

Perhaps you can post a minimal example that demonstrates the problem.
Also, what version of Clojure are you using?

--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: On Lisp with Clojure

2011-09-09 Thread Chouser
On Fri, Sep 9, 2011 at 8:09 AM, Nicolas bousque...@gmail.com wrote:
 I would rather say difficult than impossible... and maybe not that
 important.

Clojure uses Java method-calling conventions for all method and
function invocation, for tight integration and best performance.

 After all JVM is turring complete. If scheme can do it compiling down
 to machine code, clojure could do it compiling down to JVM bytecode.

Yes, but it would have to use a technique such as trampolines which
would not follow Java calling conventions, with implications for both
interop and HotSpot performance.

--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: java interop not possible in #=(..) reader syntax?

2011-09-09 Thread Chouser
On Fri, Sep 9, 2011 at 7:47 AM, Tassilo Horn tass...@member.fsf.org wrote:
 Hi all,

 I wanted to create some stand-alone example that demonstrates my issue
 from the other thread: Message-ID: 8762l2n391@thinkpad.tsdh.de

 While trying to fiddle something together, I became aware that any code
 inside #=(..) that includes java interop constructs fail.

The #= syntax is intentionally undocumented, which means it's hard to
know what is and is not supported, or how it's supposed to work.  I
don't know if it's possible to call instance methods, but static
methods and constructors work fine using the modern syntax.

 user (new java.util.Date 1 2 3)
 #Date Sun Mar 03 00:00:00 CET 1901
 user #=(new java.util.Date 1 2 3)
 ; Evaluation aborted.
 Can't resolve new

Use #=(java.util.Date. 1 2 3) instead.

 user (.newInstance java.util.Date)
 #Date Fri Sep 09 13:25:09 CEST 2011
 user #=(.newInstance java.util.Date)
 ; Evaluation aborted.
 Can't resolve .newInstance

This is an instance method call.  As I said above, I don't know if
this can be made to work at all in #=()

 Hm, but even without the reader #=(..) syntax, there's some strangeness:

 --8---cut here---start-8---
 user (. java.util.Date newInstance)
 ; Evaluation aborted.
 java.lang.NoSuchFieldException: newInstance
  [Thrown class java.lang.RuntimeException]
 user (. (identity java.util.Date) newInstance)
 Reflection warning, NO_SOURCE_FILE:1 - reference to field newInstance can't 
 be resolved.
 #Date Fri Sep 09 13:46:06 CEST 2011
 --8---cut here---end---8---

 Why do I have to use identity here?

This used to be Clojure FAQ #1, when no other syntax was available.
newInstance is an instance method of the class Class, so these days
the best way to call it is (.newInstance java.util.Date).  If you want
a static method of class Date, do something like (java.util.Date/UTC 1
2 3 4 5 6).  These are modern syntax.

It's generally best not to use the older form (. foo bar) as it can be
ambiguous.  But just so you know what's going on... If Clojure finds
that foo is a class name, it assumes that bar is a static method or
field of class bar.  When if can't find a foo in bar, it gives you the
error above.  By wrapping foo in 'identity' you're making it clear to
the compiler that the first arg to . is an expression not a class
name, so it then looks for an instance method or field.

--Chouser
http://joyofclojure.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: What's wrong with my *print-dup* persistence?

2011-09-09 Thread Chouser
On Thu, Sep 8, 2011 at 5:16 PM, Tassilo Horn tass...@member.fsf.org wrote:
 Hi all,

 I've just read Alan Malloy's excellent clojure persistence article at

  http://amalloy.hubpages.com/hub/Dont-use-XML-JSON-for-Clojure-only-persistence-messaging

 Then I wanted to add a feature for persisting and reloading clojure data
 that also contains vertices and edges of some java graph datastructure.
 In contrast to his java.util.Date example, those cannot be simply
 created but have to be retrieved in the context of the graph that holds
 the vertex or edge in question.

 All vertices and all edges have a numeric and unique id in their graph,
 and a graph itself has a unique graph id (some string).  A vertex can be
 retrieved by id using (vertex mygraph id), and it's likewise for edges
 (edge mygraph id).

 So my plan was to serialize vertices and edges as calls to those
 functions where the graph is looked up in a hash-map that has to be
 bound dynamically when reading the data back.  That's what I came up
 with:

 --8---cut here---start-8---
 (def ^:dynamic
  *serialization-bindings* nil)

 (defmethod print-dup Vertex [v out]
  (.write out
          (str #=
               `(vertex (*serialization-bindings* ~(id (graph v))) ~(id v)

 (defmethod print-dup Edge [e out]
  (.write out
          (str #=
               `(edge (*serialization-bindings* ~(id (graph e))) ~(id e)

 (defn tg-pr [x]
  (binding [*print-dup* true]
    (pr-str x)))
 --8---cut here---end---8---

 Testing that (rg is a memoized fn that returns just some sample graph),
 I get

 == (tg-pr [1 2 3 (vertex (rg) 1) 4])
 [1 2 3 #=(de.uni-koblenz.funtg.core/vertex
           (de.uni-koblenz.funtg.core/*serialization-bindings*
             \c06de1c7-f4ec0906-21cfbc86-28c31aa1\) 1)
        4]

 Looks good, I'd say.  So my reloading function only needs to bind
 *serialization-bindings* to a map from graph id to graph, and it should
 work.

 --8---cut here---start-8---
 (defn tg-read [str  gs]
  (binding [*serialization-bindings* (into {} (map (fn [g] [(id g) g])
                                                   gs))
            *print-dup* true]
    (binding [*print-dup* false]            ;; For debugging...
      (println *serialization-bindings*))
    (read-string str)))
 --8---cut here---end---8---

 However, using that, I get an exception.

 de.uni-koblenz.funtg.test.core (tg-read (tg-pr [1 2 3 (vertex (rg) 1) 4]) 
 (rg))
 {c06de1c7-f4ec0906-21cfbc86-28c31aa1 #RouteMapImpl 
 de.uni_koblenz.jgralabtest.schemas.greqltestschema.impl.std.RouteMapImpl@5203e0c6}
 ; Evaluation aborted.
 No implementation of method: :vertex of protocol: 
 #'de.uni-koblenz.funtg.core/IDOps found for class: clojure.lang.PersistentList

I haven't tried all the above, but I had a couple thoughts that might help:

First, inside #=(), arguments aren't evaluated.  They act as if quoted:

#=(+ 1 (+ 2 4))
; ClassCastException clojure.lang.PersistentList cannot be cast to
java.lang.Number clojure.lang.Numbers.add (Numbers.java:126)

The list (+ 2 4) is passed as a list to the outer +, which fails
because it's expecting a number not a list.  So one alternative would
be:

#=(+ 1 #=(+ 2 4))
;= 7

But please consider another alternative:

(+ 1 (+ 2 4))
;= 7

That is, if you're going to be evaluating a large amount of code while
reading your data back into memory, why not just go ahead and eval it
instead of just reading it?

(read-string #=(+ 1 #=(+ 2 4)))
vs.
(eval (read-string (+ 1 (+ 2 4

--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: not= counterintuitive?

2011-09-03 Thread Chouser
On Sat, Sep 3, 2011 at 10:59 AM, Alex Baranosky
alexander.barano...@gmail.com wrote:
 Sounds like you want a function such as:

 none=

...which could be written as #(not-any? #{1} [1 2 3])

--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: 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 klyn...@gmail.com 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: clojurescript support of ns-* functions

2011-08-19 Thread Chouser
On Thu, Aug 18, 2011 at 1:39 AM, Jim Blomo jim.bl...@gmail.com wrote:
 Hi, I'm enjoying playing with ClojureScript so far, great job guys!
 I'm wondering if functions like ns-aliases and Vars like *ns* will be
 implemented in future versions of ClojureScript.  If not, are there
 recommended workarounds or should I just hardcode the values?  Thanks,

That's a good question.  Namespaces in ClojureScript are mainly a
compile-time concept.  By the time you're running in JavaScript, real
namespaces are gone and all you've got are JS objects full of object,
functions, etc, so you can do some amount of introspection there.

Along with namespaces disappearing by runtime, all aliases have been
expanded so the short names won't be available there.

*ns* only has meaning at compile time in Clojure, and ClojureScript is
the same -- macros can use *ns*, but it's pretty much meaningless by
runtime.

Does that help?
--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: Errors in Clojure

2011-08-19 Thread Chouser
2011/8/19 J. Pablo Fernández pup...@pupeno.com:
 Petr, I do not care about this particular error, but about how to deal with
 this one liners. Ambrose's reply is what I needed, and no, it's not
 PostgreSQL problem. It's a library trying to establish a connection when it
 shouldn't with credentials that should never be used because I never
 specified them anywhere, so, I kinda need the stack trace to track down the
 problem.

Some versions of Clojure provide a function pst at the repl:

(pst)

This tries to print the stack trace in a prettier way.

--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: Toward in-browser ClojureScript debugging ?

2011-08-09 Thread Chouser
On Tue, Aug 9, 2011 at 2:27 AM, Thomas CORDIVAL tuxe...@gmail.com wrote:
 Hello everybody,
 I ran across a nice feature the Firefox and Webkit developers are currently
 working on: the possibility of mapping the javascript source code executed
 by the VM and another file of source code, for example written in
 clojurescript or coffeescript. This feature is already implemented as a
 Firefox extension (closure inspector) that reads a mapping file generated by
 the google closure library.
 Given the closure library can already create the mapping file between the
 javascript it compiles from and its result, how hard do you think it would
 be to generate the first part of the mapping: between the .cljs input file
 and the javascript generated by the ClojureScript compiler ?

This was a TODO from early on in ClojureScript development, but I'm
not sure how far it got or if anybody is actively working on it at the
moment.

It would certainly be nice to have!

--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: Referencing Clojure code from the ClojureScript namespace

2011-08-08 Thread Chouser
On Mon, Aug 8, 2011 at 12:59 PM, Alen Ribic alen.ri...@gmail.com wrote:
 It seems that the only way to reference Clojure code [1] from the
 ClojureScript namespace is via the ns require-macros keyword.
 Is this correct and if so, why the reference to macros only and not to
 general functions too. (I'm sure there is a good reason if it is the
 case; I'm hoping to get a better understanding).

Clojure is not available to the JavaScript runtime that is actually
executing the ClojureScript.  It is often easy to port some Clojure
code to ClojureScript but of course in that case it's actually
ClojureScript code with is easy enough to :require in your
ClojureScript code.

:require-macros is different because macros are only used at *compile*
time.  So you can :require-macros to pull in a Clojure namespace, and
those Clojure macros can use any Clojure functions they want to, but
that all happens while the ClojureScript is being compiled.  The
macros must produce valid ClojureScript code so that it can be
compiled to JavaScript, at which point it has lost all access to
Clojure and must make do with ClojureScript and JavaScript functions.

--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: ClojureScript binding problem

2011-08-01 Thread Chouser
On Mon, Aug 1, 2011 at 8:54 AM, Dmitry Gutov raa...@gmail.com wrote:
 On Aug 1, 1:32 pm, Brian McKenna puffnfr...@gmail.com wrote:
 For anyone else with the same problem, I just found the nice way to do it:

     (def iframe (. field (getEditableIframe)))

 This should be equivalent to (def iframe (.getEditableIframe field))
 which is the usual way to do method calls on the host language objects.

In Clojure you are correct, as that is unambiguous on the JVM.
However, in JavaScript the meaning of that expression is ambiguous and
so ClojureScript always treats (.foo bar) as *field* access, not a
method call.  So in the above example, iframe will be equal to the
*function* getEditableframe.

There are two options if you want to call a method with no arguments:
1. (. obj (method))  ; As shown by Brian above
2. (.method obj ())

They're both ugly, but valid syntax in Clojure and ClojureScript.
Actually, style (1) is classic Clojure and used to be the only word
order for doing host method calls.

Anyway, Rich has expressed a preference for style (1).

I'm personally ambivalent -- I might prefer the potential of someone
reading to code mistakenly thinking () is an empty list to them
thinking that (method) is a normal function call.  Actually, I'm still
hoping we'll be able to come up with something less ugly that is
nevertheless consistent with normal Clojure syntax.  I have no idea
what that would be.

--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: Alright, fess up, who's unhappy with clojurescript?

2011-07-25 Thread Chouser
On Sun, Jul 24, 2011 at 11:19 AM, James Keats james.w.ke...@gmail.com wrote:

 Google Closure is too Java. It's not idiomatic JavaScript. I find it
 disappointing that rather than porting from a functional language like
 Clojure straight to another functional language like Javascript, the
 google closure with its ugly Java-isms is right there obnoxiously in
 the middle.

It is interesting to me that you say this, because it's an argument
I've used against other JavaScript libraries. In particular I think
Zimbra is weak in this way. For a specific example, to register an
event handler using the Zimbra event system, you can't just pass in a
function, you have to pass in an instance of an AjxListener. This
definitely strikes me as a useless Java-ism.

The G. Closure library doesn't have that particular problem -- it's
clearly aware that functions are first-class objects in JavaScript and
takes advantage of that fact. Is there some other specific way in
which the G. Closure library is too Java-like? How does that specific
way actual harm the development process or the final product?

 Then, there's the elephant in the room, and that elephant is Jquery.

I like jQuery. It's a huge win compared to vanilla JavaScript for the
browser. Now, I personally plan to write my ClojureScript code to
target the G. Closure library and then run it through the
advanced-mode G. Closure compiler, but there's no reason *you* have
to.  You argue elsewhere that the G. Closure compiler is unnecessary
(citing streaming HD video in comparison to minified JavaScript) -- if
you don't use the compiler (or use it only in simple mode) you should
have no problem using jQuery. Your resulting .js will be quite a bit
larger because you'll have a couple of the G. Closure library files
that ClojureScript itself uses, but nothing compared to streaming HD
video.

So, you could use ClojureScript and jQuery to write a snappy little
demo and prove to everyone the value of that approach. I'm sure I'm
not the only one that would be interested in seeing such a demo.

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

2011-07-21 Thread Chouser
Video is now available of Rich Hickey's talk at ClojureNYC yesterday
announcing ClojureScript.

http://blip.tv/clojure/rich-hickey-unveils-clojurescript-5399498

Thanks to the Clojure/core team for getting this online so rapidly!
--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: Most concise way to determine that a sequence is consecutive integers starting with one?

2011-07-01 Thread Chouser
On Fri, Jul 1, 2011 at 3:51 PM, David Nolen dnolen.li...@gmail.com wrote:
 On Fri, Jul 1, 2011 at 3:28 PM, .Bill Smith william.m.sm...@gmail.com
 wrote:

 I want a concise function that, given an arbitrary length sequence,
 determines whether the sequence is of consecutive integers starting with
 one.  So:
  (f [1 2 3]) returns true
  (f [1 2 4]) returns false
  (f [0 1 2]) returns false
 My first try, which I am not proud of, follows:

 (defn f [numbers]
   (every? (fn [[x y]] (= x y)) (partition 2 (interleave (iterate inc 1)
 numbers

 Can someone suggest something better?

 (defn f [xs] (every? #(apply = %) (map vector xs (iterate inc 1

(defn f [xs] (every? true? (map = xs (iterate inc 1

--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: Re: first element after an element in the sorted-set?

2011-05-24 Thread Chouser
On Tue, May 24, 2011 at 4:18 AM, Meikel Brandmeyer m...@kotka.de wrote:
 Hi,

 maybe subseq to the rescue?

 user= (first (subseq (sorted-set 1 2 3 4 5 6)  3))
 4

 I'm not sure about the perfomance, but I'd think it's fast?

Yes, this is right.

Note you can also walk the other direction using rsubseq:

(first (rsubseq (sorted-set 1 2 3 4 5 6)  3))
;= 2

--Chouser
http://joyofclojure.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: Applying collection of functions

2011-04-07 Thread Chouser
On Thu, Apr 7, 2011 at 8:56 AM, Baishampayan Ghose b.gh...@gmail.com wrote:
 Given a collection of functions

 (def fs [#(* % 10) #(+ % 1)])

 and some numbers

 (def c [1 2 3])

 How do I apply all the functions to c so that the results of one
 function are passed to the other. In the same way - works. Thus in
 this case the expected result would be: 11 21 31

 A typical use-case for map  comp -

 (map (apply comp (reverse fs)) c)
 ; = (11 21 31)

Or if you don't want to use reverse:

(map #(reduce (fn [x f] (f x)) % fs) c)

Hm, BG's solution compiles no new classes, while mine generates two.
More classes is better, right? :-P

--Chouser
http://joyofclojure.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: Applying collection of functions

2011-04-07 Thread Chouser
On Thu, Apr 7, 2011 at 9:11 AM, Baishampayan Ghose b.gh...@gmail.com wrote:
 On Thu, Apr 7, 2011 at 6:34 PM, Chouser chou...@gmail.com wrote:
 Given a collection of functions

 (def fs [#(* % 10) #(+ % 1)])

 and some numbers

 (def c [1 2 3])

 How do I apply all the functions to c so that the results of one
 function are passed to the other. In the same way - works. Thus in
 this case the expected result would be: 11 21 31

 A typical use-case for map  comp -

 (map (apply comp (reverse fs)) c)
 ; = (11 21 31)

 Or if you don't want to use reverse:

 (map #(reduce (fn [x f] (f x)) % fs) c)

 Hm, BG's solution compiles no new classes, while mine generates two.
 More classes is better, right? :-P

 Sir Chouser is right! ;)

 On a more serious note, how do I find out how many classes a form compiles to?

I was just eyeballing it -- one class per function definition (note
this is *not* one class per closure instance created).  I suppose you
should be able to clear out your *compile-path* directory, AOT compile
your forms, and count the number of new .class files in
*compile-path*.  You should have one per fn, #(), or defn, plus one
for each defrecord, deftype, definterface, gen-class, proxy, reify,
etc., plus a couple per namespace.  But I haven't checked that myself
in a while.

--Chouser
http://joyofclojure.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: Your favorite utility function or macro.

2011-03-25 Thread Chouser
On Fri, Mar 25, 2011 at 8:21 AM, Meikel Brandmeyer m...@kotka.de wrote:
 Ah. There it is again: the classic.
 http://groups.google.com/group/clojure/browse_thread/thread/66ff0b89229be894/c3d4a6dae45d4852

It goes back further:
http://clojure-log.n01se.net/date/2008-04-14.html#22:10- 23:07

In fact, I would guess people wrote it for other lisps even previous to that.

--Chouser
http://joyofclojure.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: Comparing clojure speed to java speed

2011-03-11 Thread Chouser
On Thu, Mar 10, 2011 at 11:26 PM, Jarl Haggerty jarlhagge...@gmail.com wrote:
 Hmm, I should have thought of that.

 New Clojure:

 (ns hello.test
  (import org.jbox2d.common.Vec2)
  (:gen-class))

 (defn -main [ args]
  (dotimes [q 5]
    (let [#^Vec2 a (Vec2. 1 2)
          #^Vec2 b (Vec2. 3 4)]
      (time (loop [x (int 0)]
              (when ( x (int 1e9))
                (.addLocal a b)
                (recur (unchecked-inc x

I think if you turn on reflection warnings and remove those type
hints, you'll find those hints aren't useful.  In which case I'd
recommend leaving them out.

--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: Clojure on JS VMs

2011-03-03 Thread Chouser
On Thu, Mar 3, 2011 at 9:56 AM, Timothy Baldridge tbaldri...@gmail.com wrote:
 I know we have Scriptjure. But has there been any concentrated effort
 to port Clojure to JS? This may sound odd, but personally I would love
 to use Clojure in the browser. Scriptjure would work fairly well, but
 from what I see, it doesn't support persistent maps and instead relies
 on JS objects.

There has been, but it's extremely out of date at this point:

https://github.com/clojure/clojure-contrib/tree/master/clojurescript

That's a pre-1.0 version of Clojure that does indeed compile to
JavaScript.  It supports persistent hash maps and vectors
(pre-transients), lazy sequences (actually, lazy-con, pre-chunking),
and most of the clojure.core functions.  There's no attempt to support
Clojure's concurrency constructs, and it relies on the Java-based
compiler rather than having a port of the compiler itself to
JavaScript.

I gave up trying to hand-port all the features from the Java half of
Clojure's implementation over to JavaScript, with the hope that when
we eventually have clojure-in-clojure this task would be significantly
easier.

You can even try it out in a browser (doesn't work on Macs, I think):
http://clojurescript.n01se.net/

That loads the clojure-to-javascript compiler as a Java applet, after
which you can run Clojure commands in the browser, like:

(- document .body)

or:

(set! (- document .body .style .background) orange)

I'm sorry it's too out of date to be of much real use now, but it does
show it's possible and hopefully has some tidbits that will be useful
in later implementations.

--Chouser
http://joyofclojure.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: Problems with lazy-xml

2011-02-12 Thread Chouser
On Sat, Feb 12, 2011 at 4:16 AM, Marko Topolnik
marko.topol...@gmail.com wrote:
  Just guessing, but is it something to do with this (from the docstring
  of parse-seq)?

  it will be run in a separate thread and be allowed to get
   ahead by queue-size items, which defaults to maxint.

 As I've figured it out, when there's XPP on the classpath, and I'm
 using it, the code that does the parsing is entirely different and
 does not involve a separate thread (see with_pull.clj). The parser
 sits and waits for events to be requested from the lazy seq.

Yes, XPP is superior to SAX, especially for this sort of laziness.

 Finally, you might want to be able to walk an XML document larger
 than would fit in memory.  I'm not sure if lazy-xml has ever been
 able to do this as it would need to be vigilant about not
 retaining the root of the returned document tree.

 I was under the impression that if the client was careful to lose the
 nodes' parents, they would be free for garbage collection, as well as
 previous siblings. The point is to first navigate to the
 desired :content lazy seq and then lose all other refs. Then you are
 in the same position as with any old lazy seq -- you run through it
 without retaining the head, and things are good.

It may work, but wasn't a design goal when I was originally writing
lazy-xml, so it's possible I have stray head- or root-holding in the
code.

The problem you're observing is because of my use of drop-last, which
forces the parsing of one extra sibling at *each* level of the tree.
In your test case, this is a *lot* of extra parsing at exactly the
point where you don't want it.  The drop-last is used because the last
node of each interior sequence holds the non-descendant events and so
must be dropped from the content seq.

I'm currently trying to come up with a different way of passing around
the non-descendant events so that drop-last isn't necessary, but it's
...tricky, at least for my poor fuzzy brain.

--Chouser
http://joyofclojure.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: Problems with lazy-xml

2011-02-11 Thread Chouser
On Fri, Feb 11, 2011 at 2:35 PM, Chris Perkins chrisperkin...@gmail.com wrote:
 On Feb 11, 5:07 am, Marko Topolnik marko.topol...@gmail.com wrote:
 http://db.tt/iqTo1Q4

 This is a sample XML file with 1000 records -- enough to notice a
 significant delay when evaluating the code from the original post.

 Chouser, could you spare a second here? I've been looking and looking
 at mktree and siblings for two days now and can't for the life of me
 find out why it would eagerly parse the whole contents of an element
 as soon as I acces its struct! The code looks perfectly correct.

I can reproduce the behavior you describe.  I'll look into it.

 Just guessing, but is it something to do with this (from the docstring
 of parse-seq)?

 it will be run in a separate thread and be allowed to get
  ahead by queue-size items, which defaults to maxint.

 Doesn't sound like it's actually lazy unless you explicitly specify a
 queue-size.

There's a few different reasons someone might want lazy.

You might want to be able to start examining the tree before it's
done being parsed -- this is the default behavior of lazy-xml.
Your code will block if it catches up with the parser, but
shouldn't block earlier than it has to.

Having the parsing thread do no work more than necessary (queue
size 1) is another possibly desired behavior -- sounds like the
OP's desire in which case the queue size does need to be
specified.

Finally, you might want to be able to walk an XML document larger
than would fit in memory.  I'm not sure if lazy-xml has ever been
able to do this as it would need to be vigilant about not
retaining the root of the returned document tree.

--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: Efficient queue types for Clojure.

2011-01-22 Thread Chouser
On Sat, Jan 22, 2011 at 2:14 PM, Mark Engelberg
mark.engelb...@gmail.com wrote:
 Clojure already has a built in queue.  The empty queue is:
 clojure.lang.PersistentQueue/EMPTY
 and then you can use all the usual conj/into/pop/peek functions on it.
 For some reason, PersistentQueue is not documented, so new users have
 no reason to know about it until they happen to ask about it here.

 You might be interested to compare your priority queue implementation
 to my priority map in 1.3 alpha's contrib, which also supports
 updating items' priorities.

 As far as I can tell, your priority queue's pop is not O(1), because
 the underlying sorted map doesn't support first in O(1).  It's
 actually O(log32#of priorities).  My priority map is similar, and I
 agree that this behavior is quite fast, but it's worth noting that
 it's not truly O(1).

Clojure's sorted collections are binary trees thus log2, not log32
like the hashed collections.

--Chouser
http://joyofclojure.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: Testing if a sequence is lazy

2011-01-19 Thread Chouser
On Tue, Jan 18, 2011 at 12:22 AM, Nick Brown nwbr...@gmail.com wrote:
 Hi, I'm wondering if there is a good way to test if a given sequence
 is lazy, and if so, how much of it has been evaluated.  I know the
 fact that it is lazy should be transparent, but I'm thinking in the
 context of unit testing knowing that could be valuable.  For instance
 if you know a particular sequence could be particularly large or
 expensive in certain situations, you may want your tests to assert
 that it is not getting evaluated prematurely.

 I suppose I could hack the generator function to cause a side effect
 that I could test for, but is there an easier way?

I've got some code that changes the way the REPL prints lazy seqs so
that it never forces the realization of anything.  It prints anything
that's already been forced, but then prints ...unrealized... for the
rest.  I don't know if this is useful for unit testing, but I've found
it helpful at the REPL.

Also note that it's a complete hack -- includes big chunks of code
copied from clojure.core (hence the copyright notice), makes use of
internal clojure details that could change at any time, probably fails
in various spectacular ways.  Use at your own risk. :-)

http://gist.github.com/589694

--Chouser
http://joyofclojure.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: a loop gives boxing warning when it shouldn't

2011-01-03 Thread Chouser
On Sat, Jan 1, 2011 at 5:47 PM, Albert Cardona sapri...@gmail.com wrote:
 Hi all,

 I'd apreciate help on figuring out why a loop gets number boxing
 warnings, when it shouldn't:

 http://clojure.pastebin.com/9uLZqGhy

I just filed this as:
http://dev.clojure.org/jira/browse/CLJ-701

--Chouser
http://joyofclojure.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 - javascript

2010-12-21 Thread Chouser
On Tue, Dec 21, 2010 at 6:51 AM, Shane Daniel simrpg...@gmail.com wrote:
 Hi everybody,
 Just for kicks I took Chouser's good start on the PersistentVector port and
 threw it in a Github gist, and demonstrated using it in jsFiddle. I love the
 cloud these days ;)
 Anyway, I hope you don't mind Chouser. I plan to refactor your code to use
 Javascript's prototype system, but really just wanted it online because it's
 an excellent starting point. Now it could be forked and demo'd easily.

I'd be happy if someone were to get more use out it.  Eventually
I hope we have JS generated from a pure-Clojure implementations
of all the collection types, but until then I guess this will
have to do.  Thanks for getting it out there.

--Chouser
http://joyofclojure.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: Error Handling for Callback API to Blocking API example in Joy of Clojure

2010-12-21 Thread Chouser
On Sun, Dec 19, 2010 at 3:36 AM, HiHeelHottie hiheelhot...@gmail.com wrote:

 In Joy of Clojure, there is a callback API to blocking API example in
 the section on promises.  Chouser outlines it a briefly in a
 discussion on Promise/Deliver use cases here -
 http://groups.google.com/group/clojure/browse_thread/thread/b1548aa40ba8072/210ec81bfe26032e?lnk=gstq=promise#210ec81bfe26032e:

 I've used them to convert a callback-based (continuation-passing
 style, if you will) API into a blocking one.  The lib I was using
 provides something you can call like:
        (rpc-call destination method-args done)
 Where 'done' is a function that gets called with the results of
 the remote procedure call.  But I want to write a function that
 does rpc but *returns* the result, so...
        (let [p (promise)]
          (rpc-call destination method-args #(deliver p %))
         �...@p)
 This will work just fine whether rpc-call calls 'done'
 synchronously, or if it returns right away and 'done' is called
 by some other thread later.
 --Chouser

 This is very neat.  Is this robust as is or would you need to add code
 to handle error cases such as an unavailable rpc server, rpc server
 never returning, an error trying to make the rpc call, etc.

It depends entirely on how rpc-call handles error cases.  If it
promises to always call its call back with something, even on
error cases (perhaps passing in an Error object or something),
then this would sufficient as-is.

However, anything that would cause the call back to be skipped
will of course cause the deliver to also be skipped, and the
deref on the promise will block forever.  The easiest way for
this to happen accidentally is if an exception is thrown, so
catching those and turning them into calls to the callback with
an error object is certainly a good idea.

--Chouser
http://joyofclojure.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: Let usage question

2010-10-28 Thread Chouser
On Wed, Oct 20, 2010 at 3:21 PM, Rich Hickey richhic...@gmail.com wrote:


 On Oct 20, 1:34 pm, cej38 junkerme...@gmail.com wrote:
 This question leads into something that I read in Joy of Clojure (page
 161 in the latest MEAP edition):
 If you manage to hold onto the head of a sequence somewhere within a
 function, then that sequence will be prevented from being garbage
 collected. The simplest way to retain the head of sequence is to bind
 it to a local. This condition can occur with any type of value bind be
 it to a reference type or through the usage of let or binding.

 I am not sure what this means, but I think it would mean that using
 let as you do, could cause garbage collection problems.  Thus, it
 might be better to follow the advice of Stuart and Luc.

 Chad

 PS. Clarification of the statement from the Joy of Clojure would be
 helpful.


 That advice seems stale, given:

 http://groups.google.com/group/clojure/msg/9b4e268b85c20cd6

 let-bound locals get cleared on last use.

The quoted section should perhaps be clarified with better
wording, but the example immediately following that quote still
accurately demonstrates the point we were trying to make:

(let [r (range 1e9)] [(first r) (last r)])
;= [0 9]

(let [r (range 1e9)] [(last r) (first r)])
; java.lang.OutOfMemoryError: GC overhead limit exceeded

Clojure's compiler can deduce that in the first example the
retention of `r` is no longer needed when the computation of
`(last r)` occurs and therefore aggressively clear it.  However,
in the second example the head is needed later in the overall
computation and can no longer be safely cleared.

This is dramatically better than the invisible head-holding
that sometimes happened in earlier versions of Clojure (and was
noted in earlier versions of JoC), but is still good to be aware
of.

--Chouser
http://joyofclojure.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: finding value nearest x

2010-09-25 Thread Chouser
On Sat, Sep 25, 2010 at 10:44 AM, Nicolas Oury nicolas.o...@gmail.com wrote:
 On Sat, Sep 25, 2010 at 3:40 PM, Jules julesjac...@gmail.com wrote:
 Maybe this: (min-key #(abs (- % 136)) xs)

 Wouldn't that be (apply min-key #(abs (- % 136)) xs)?

Where's your 'abs' function coming from?  This works for me:

(apply min-key #(Math/abs (- % 136)) xs)

Or if you want something slower when building the collection but
faster when looking it up, you can use a sorted set:

(let [ss (sorted-set 1 2 134 139 4),
  asc (subseq ss = 136),
  desc (rsubseq ss = 136)]
  (min-key #(Math/abs (- % 136)) (first asc) (first desc)))

That's O(log n) instead the simpler (apply min-key ...) which is O(n).

--Chouser
http://joyofclojure.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: partition-starting-every : yet another partition function

2010-09-16 Thread Chouser
On Fri, Sep 10, 2010 at 4:26 PM, Matt  Smith m0sm...@gmail.com wrote:
 problem: convert a collection [1 2 0 1 2 3 0 1 2 3 0 0 1 2] into
 partitions like:
 ((1 2) (0 1 2 3) (0 1 2 3) (0) (0 1 2))
 In this case, start each partition on a 0.


 I looked at the various partition functions but none of them would do
 the trick without adding unnecessary complexity.  Instead  I wrote a
 new function based on partition-by:

 Solution:
 (defn partition-starting-every
  Partition the sequence starting each partition when the f is true.
  [f coll]
  (if-let [coll (seq coll)]
    (let [p (cons (first coll) (take-while (complement f) (rest
 coll)))]
      (lazy-seq (cons p (partition-starting-every f (drop (count p)
 coll)))

 user=(partition-starting-every zero? [1 2 0 1 2 3 0 1 2 3 0 0 1 2])
 ((1 2) (0 1 2 3) (0 1 2 3) (0) (0 1 2))

Iteration at a rate other than once per input seq item suggests iterate:

(defn partition-starting-every [f coll]
  (- [nil coll]
   (iterate (fn [[p [x :as s1]]]
  (let [[n s2] (split-with (complement f) (next s1))]
(when (seq s1)
  [(cons x n) s2]
   (map first)
   next
   (take-while identity)))

Ugh.  Well, maybe partition-by can be used after all:

(defn partition-starting-every [f coll]
  (let [pb (partition-by #(and (f %) (Object.)) coll)]
(- (map (fn [[a :as as] [b :as bs]]
(cond
  (nil? as) (when-not (f b) bs)
  (and (f a) (f b)) as
  (f a) (concat as bs)))
  (cons nil pb) pb)
 (remove nil?

Bleh.  Looks lazy-seq is the way to go. :-)

BTW, it's generally best to have the lazy-seq outside the empty
test to make your fn as lazy as possible.  And I'd use split-with:

(defn partition-starting-every
  Partition the sequence starting each partition when the f is true.
  [f coll]
  (lazy-seq
(when-let [[x  xs] (seq coll)]
  (let [[a b] (split-with (complement f) xs)]
(cons (cons x a) (partition-starting-every f b))

--Chouser
http://joyofclojure.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: Line numbers for forms embedded in macros

2010-09-12 Thread Chouser
On Sun, Sep 12, 2010 at 4:22 PM, Brian Marick mar...@exampler.com wrote:
 In my test framework, Midje, http://github.com/marick/Midje, a test written 
 in the most heavily syntactically-sugared form might look like this:

 (facts
   (complicated-function ...some-integer...) = 5
   (provided
        (simple-function ...some-integer...) = 2
        (other-function ...some-integer...) = 3
        ...some-integer... = even?)
   ...)

 A test failure could be associated with any point where there's an arrow. 
 Because (fact) is a macro, the straightforward way of getting the line number 
 gets the line number of the very beginning of the form. Is there a clever way 
 to get the line number of the arrows? (There's no hook into the reader, is 
 there?)

 What I'm going to do unless you save me is two things:

 1) the failure messages will tell you the failure is associated with, say, 
 the 3rd arrow.

 2) When emacs sends the form down to the interpreter, I'll have it annotate 
 it with the correct line numbers. That way, a simple keyboard gesture will 
 take me to the failing line.

 Better ideas for fallbacks?

In your macro, try printing out your input forms with *print-meta* on.

(defmacro print-meta [ args]
  (binding [*print-meta* true]
(prn args)))

I think you'll find some useful data in there. There won't be line
numbers on your arrows, but will be on the preceding forms.

--Chouser
http://joyofclojure.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: Thinking in Clojure

2010-09-03 Thread Chouser
On Thu, Sep 2, 2010 at 11:36 PM, Peter Buckley buckmeist...@gmail.com wrote:

 One of the things that stuck out for me that I heard somewhere (can't
 remember exactly) was that OOP is about framing questions in terms of
 nouns and FP is about framing questions in terms of verbs.

Perhaps you heard it in Yegge's enjoyable essay:

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

--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: Does 'require' with the :reload option have a tendency to build up memory?

2010-09-03 Thread Chouser
On Fri, Sep 3, 2010 at 6:05 AM, Rayne disciplera...@gmail.com wrote:
 Indeed, that I did. I ran it through jvisualvm and it's definitely
 growing objects. It's odd though, because I don't see any reason why
 any of the namespaces I'm reloading would do that. It's not any one
 namespace, but all of them together. That's why I was thinking that it
 may have possibly been some implicit weirdness with reload.

Which classes show the most increase in instance count?  Or
perhaps you could attach or post the full list of before and
after instance counts somewhere.

--Chouser
http://joyofclojure.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: Does 'require' with the :reload option have a tendency to build up memory?

2010-09-02 Thread Chouser
On Thu, Sep 2, 2010 at 7:47 PM, Rayne disciplera...@gmail.com wrote:
 I've got a curious little bit of a memory leak of sorts that I'm
 trying to narrow down.

 I have an application (betcha can guess what it is if you know me from
 IRC :) that, in order to reload plugins, requires each of them with
 the :reload option whenever you ask them to be reloaded.

 Each of these plugins calls a macro that defines a set of defmethods
 for a multimethod in a namespace that never does get reloaded. They
 also define a single function that isn't a method.

 Whenever these 'plugins' are reloaded (there are about 20 of them),
 the memory my application uses is raised by about 3MB, as monitored
 with htop. It's very consistent and always raises 2-3MB each time. The
 less plugins being reloaded, the less dramatic the memory jump.

 Now, my question is: can require with :reload a lot of namespaces like
 this cause this sort of thing to happen? I mostly just need to know
 whether or not I'm going in the wrong direction. I've never had this
 sort of problem before.

 If so, are there any steps I can take to keep memory from building up
 like this?

I'd recommend using a memory profiling tool that lists the object
counts by class.  I think jvisualvm that comes with Sun's JDK
will do it, and I know yourkit will.  Check your counts before
a :reload and again after -- might give a good clue as to what's
going on.

--Chouser
http://joyofclojure.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: Why do is used in this function?

2010-08-31 Thread Chouser
On Tue, Aug 31, 2010 at 11:08 AM, Justin Kramer jkkra...@gmail.com wrote:
 Another tip: per the doc for 'empty?', (seq s) is preferred over (not
 (empty? s)). Oh, and 'str' isn't necessary since 'println' adds spaces
 between arguments:

 (defn printall [s]
  (when (seq s)
   (println Item: (first s))
   (recur (rest s

Good tips!  Another option:

(defn printall [s]
  (doseq [i s]
(println Item: i)))

--Chouser
http://joyofclojure.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: Basic colour in the standard REPL

2010-08-27 Thread Chouser
On Fri, Aug 27, 2010 at 9:48 AM, Ramakrishnan Muthukrishnan
vu3...@gmail.com wrote:
 On Fri, Aug 27, 2010 at 4:39 PM, frou m...@frou.org wrote:
 Is it or would it be possible to add some basic text colouring to the
 standard REPL (the one started with the clj shell script).

 It would be nice to be able to make the prompt, e.g. user= coloured
 (green in my case) so that you get at-a-glance distinction between
 your inputs and the results printed.

 If you use rlwrap to invoke the clojure repl, you can do that with
 --prompr-colour option

 eg;

 rlwrap -pred java -cp blah blah clojure.main

I didn't know about that.  Cool tip, but for me it pretty easily
gets confused when the prompt changes (such as when moving
between namespaces).

I've been using this for a while -- not perfect either, but it
attempts to print a green line before each prompt, and color
return values blue.

(defn my-repl []
  (binding [*pprint* true]
(clojure.main/repl
  :prompt #(printf
 \033[32m-\033[m\n%s= 
 (ns-name *ns*))
  :print (try
   (fn [x]
 (print \033[34m)
 (if *pprint*
   (clojure.pprint/pprint x)
   (prn x))
 (print \033[m)
 (flush))
   (catch Exception e
 (prn e))

You can either just run (my-repl) at the REPL, or start Clojure
with -e '(my-repl)'  If you then run a little test, you can see
each of the different colors:

(do (println hi) 5)

--Chouser
http://joyofclojure.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: inserting into vector

2010-08-26 Thread Chouser
On Thu, Aug 26, 2010 at 9:44 AM, Jon Seltzer seltzer1...@gmail.com wrote:
 I know what assoc does:

 user= (assoc [\a \b \c] 0 \d)  ;please extend to much larger vector
 with index somewhere in the middle
 [\d \b \c]

 but what if I want:

 user= (assoc-x [\a \b \c] 0 \d)  ;is there an assoc-x
 [\a \d \b \c]

 I don't see a function that does this.  I'm sure I'm missing it.  I,
 of course, know this could be done with a combination of other
 functions like subvec and/or into but it seems fundamental enough to
 have its function.

The internal structure of vectors is such that this cannot be
done efficiently, which is why no function to do it is included
in clojure.core.  You can do it inefficiently like this:

(let [v '[a b c d e f]
  i 3]
  (into (subvec v 0 i) (cons 'X (subvec v i
;= [a b c X d e f]

That's about as good as you're going to get with vectors, O(n)
where n is (- (count v) i).

--Chouser
http://joyofclojure.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: inserting into vector

2010-08-26 Thread Chouser
On Thu, Aug 26, 2010 at 11:53 AM, Chouser chou...@gmail.com wrote:
 On Thu, Aug 26, 2010 at 9:44 AM, Jon Seltzer seltzer1...@gmail.com wrote:
 I know what assoc does:

 user= (assoc [\a \b \c] 0 \d)  ;please extend to much larger vector
 with index somewhere in the middle
 [\d \b \c]

 but what if I want:

 user= (assoc-x [\a \b \c] 0 \d)  ;is there an assoc-x
 [\a \d \b \c]

 I don't see a function that does this.  I'm sure I'm missing it.  I,
 of course, know this could be done with a combination of other
 functions like subvec and/or into but it seems fundamental enough to
 have its function.

 The internal structure of vectors is such that this cannot be
 done efficiently, which is why no function to do it is included
 in clojure.core.  You can do it inefficiently like this:

    (let [v '[a b c d e f]
          i 3]
      (into (subvec v 0 i) (cons 'X (subvec v i
    ;= [a b c X d e f]

 That's about as good as you're going to get with vectors, O(n)
 where n is (- (count v) i).

I messed up the analysis of the complexity there.  It may
actually be worse than O(n), and there may be a more efficient
solution.

--Chouser
http://joyofclojure.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: inserting into vector

2010-08-26 Thread Chouser
On Thu, Aug 26, 2010 at 12:43 PM, David Nolen dnolen.li...@gmail.com wrote:
 On Thu, Aug 26, 2010 at 11:53 AM, Chouser chou...@gmail.com wrote:

 On Thu, Aug 26, 2010 at 9:44 AM, Jon Seltzer seltzer1...@gmail.com
 wrote:
  I know what assoc does:
 
  user= (assoc [\a \b \c] 0 \d)  ;please extend to much larger vector
  with index somewhere in the middle
  [\d \b \c]
 
  but what if I want:
 
  user= (assoc-x [\a \b \c] 0 \d)  ;is there an assoc-x
  [\a \d \b \c]
 
  I don't see a function that does this.  I'm sure I'm missing it.  I,
  of course, know this could be done with a combination of other
  functions like subvec and/or into but it seems fundamental enough to
  have its function.

 The internal structure of vectors is such that this cannot be
 done efficiently, which is why no function to do it is included
 in clojure.core.  You can do it inefficiently like this:

    (let [v '[a b c d e f]
          i 3]
      (into (subvec v 0 i) (cons 'X (subvec v i
    ;= [a b c X d e f]

 That's about as good as you're going to get with vectors, O(n)
 where n is (- (count v) i).

 --Chouser
 http://joyofclojure.com/

 How is the performance of your FingerTrees looking? ;)
 David

I'm actually working on it again, now that the book is requiring less
time.  When it's ready, I won't be shy about announcing it. :-)

--Chouser
http://joyofclojure.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: Simple Regex Question

2010-08-21 Thread Chouser
On Sat, Aug 21, 2010 at 7:11 PM, CuppoJava patrickli_2...@hotmail.com wrote:
 Hi Everyone,

 I'm extremely stuck on this simple regex question, which I'm sure
 someone with a little more experience will be able to write in a
 second. I would really appreciate the help.

 Given a string consisting of a's, b's, and spaces:  aaa bbb abb ab
 bb

 I want to tokenize this into string's of a's and b's.
  eg. aaa, bbb, a, bb, a, b, bb

 AND also, I have to be able to tell which of the strings of b's was
 preceded with an a, and which was preceded by a space.

(- aaa bbb abb ab bb
  (re-seq #(?=(.))?(\w)\2*)
  (map (fn [[s pre]] {:s s, :pre pre})))

returns a lazy seq:
({:s aaa, :pre nil}
 {:s bbb, :pre  }
 {:s a, :pre  }
 {:s bb, :pre a}
 {:s a, :pre  }
 {:s b, :pre a}
 {:s bb, :pre  })

--Chouser
http://joyofclojure.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: Today's clojure trick question

2010-08-18 Thread Chouser
On Wed, Aug 18, 2010 at 11:09 AM, Brian Hurt bhur...@gmail.com wrote:
 Consider the following bit of code:

 (let [ x (new java.lang.Boolean false) ] (if x trouble ok))

The Javadoc for Boolean has something to say on this subject[1]
as does the following excerpt from Fogus' book The Joy of
Clojure:

Don't create Boolean objects


It is possible to create an object that looks a lot like, but is
not actually, `false`.

Java has left a little landmine for you here, so take a moment to
look at it so that you can step past it gingerly and get on with
your life:

(def evil-false (Boolean. false)) ; NEVER do this

This creates a new instance of Boolean -- and that's already
wrong!  Since there are only two possible values of Boolean, an
instance of each has already been made for you -- they're named
`true` and `false`.  But here you've gone and done it anyway,
created a new instance of Boolean and stored it in a Var named
`evil-false`.  It looks like false:

evil-false
;= false

Sometimes it even acts like false:

(= false evil-false)
;= true

But once it gains your trust, it will show you just how wicked it
is by acting like `true`:

(if evil-false :truthy :falsey)
;= :truthy

Java's own documentation warns against the creation of this evil
thing, and now you've been warned again.  If you just want to
parse a string, use Boolean's static method instead of its
constructor. This is the right way:

(if (Boolean/valueOf false) :truthy :falsey)
;= :falsey

--Chouser
http://joyofclojure.com/

1: 
http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/lang/Boolean.html#Boolean%28boolean%29

-- 
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: Nil Coalesce

2010-08-17 Thread Chouser
On Tue, Aug 17, 2010 at 9:30 AM, Rising_Phorce josh.fe...@gmail.com wrote:
 Hi All:

 First of all thanks for the replies to my last post the clojure
 community is great!

 I've been trying to find a succinct way to do the following.  Given
 two sequences, product a new sequence which takes items from the first
 sequence unless null in which case it will take an item from the
 second, until the first sequence is exhausted.  If nil is encountered
 in the first sequence and the second sequence is exhaused, nil will be
 returned:

 e.g.  user (nil-coalesce (nil 1 2 3 nil nil) (4 5))
 (4 1 2 3 5 nil)

Clojure golf is the most fun golf!

  (defn nil-coalesce [a b]
(map #(or %1 %2) a (concat b (repeat nil

Or if you really want to treat nil and false differently:

  (defn nil-coalesce [a b]
(map #(if (nil? %1) %2 %1) a (concat b (repeat nil

--Chouser
http://joyofclojure.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: Nil Coalesce

2010-08-17 Thread Chouser
On Tue, Aug 17, 2010 at 1:38 PM, Nicolas Oury nicolas.o...@gmail.com wrote:

 Clojure golf is the most fun golf!

  (defn nil-coalesce [a b]
    (map #(or %1 %2) a (concat b (repeat nil

 Or if you really want to treat nil and false differently:

  (defn nil-coalesce [a b]
    (map #(if (nil? %1) %2 %1) a (concat b (repeat nil



 I am not sure to get it.
 Won't map advance in  parrallel in the sequences, jumping over the
 values in b where there is something in a?

Oh, indeed.  I misunderstood the problem statement.  My
apologies.

--Chouser
http://joyofclojure.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: Nil Coalesce

2010-08-17 Thread Chouser
On Tue, Aug 17, 2010 at 3:56 PM, Rising_Phorce josh.fe...@gmail.com wrote:
 I posted because clojure *tends* to be so succinct and in this case
 the solution complexity seems disproportionate to the problem.  In my
 first post I forgot to mention my second attempt...

 (map #(if (nil? %1) %2 %1) [nil 1 2 3 nil nil] [4 5])

 but it got ugly because I needed to extend the replacements to the the
 same length as the maybe-nil collection...

 (defn nil-coalesce2 [maybe-nil replacements]
  (let [cnt-mn (count maybe-nil)
        cnt-r (count replacements)]
    (if (= cnt-mn cnt-r)
      (map #(if (nil? %1) %2 %1) maybe-nil replacements)
    (map #(if (nil? %1) %2 %1) maybe-nil (concat replacements (repeat
 (- cnt-mn cnt-r) nil))

Ok, maybe I understand the task now?

(defn nil-coalesce [a b]
  (- a
(reductions (fn [[_ b] a]
  (if (nil? a)
[(first b) (rest b)]
[a b]))
[0 b])
rest
(map first)))

This is much like Jeff Valks solution, but lazy.

--Chouser
http://joyofclojure.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: Bug in try/finally?

2010-08-11 Thread Chouser
On Tue, Aug 10, 2010 at 1:09 PM, joegg joega...@gmail.com wrote:

 This fixes the behavior we're seeing, but, ummm... might break other
 things, I suppose.  The tests I've written don't cover all the
 expected behavior of try/catch/finally.

You wrote some nice tests for these that could be included in
clojure-test, but I don't see your name on the contributor's
list: http://clojure.org/contributing

Have you sent in your CA?

--Chouser
http://joyofclojure.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: Bug in try/finally?

2010-08-11 Thread Chouser
On Wed, Aug 11, 2010 at 8:01 AM, Stuart Halloway
stuart.hallo...@gmail.com wrote:
 Ticket and patch welcome!

Done and done: https://www.assembla.com/spaces/clojure/tickets/422

--Chouser
http://joyofclojure.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: jna Java Native Acess and clojure ....

2010-08-11 Thread Chouser
On Wed, Aug 11, 2010 at 5:18 AM, mac markus.gustavs...@gmail.com wrote:

 It is certainly theoretically possible to call C++ from Clojure/Java
 but it requires deep knowledge and lots of code for each C++ compiler
 one would like to support.

I've done a fair amount of work getting specific C++ libraries to
work with Clojure.  I recommend swig, but even with that it's
a messy and error-prone process, requires integration with your
AOT build process, etc.

Once that's all set up for each individual C++ lib, the Clojure
code you write to use it can look as good and work as well as any
Java interop code, so quite well and naturally.

--Chouser
http://joyofclojure.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: Question on defrecord

2010-08-11 Thread Chouser
On Wed, Aug 11, 2010 at 1:03 PM, Shantanu Kumar
kumar.shant...@gmail.com wrote:
 I tried to assign a data type to a var and then instantiate it using
 the var, but it doesn't seem to work:

 user= (defrecord X [])
 user.X

 user= (X.)
 #:user.X{}

 user= X
 user.X

 user= (def hey X)
 #'user/hey

 user= (hey.)
 java.lang.IllegalArgumentException: Unable to resolve classname: hey
 (NO_SOURCE_FILE:59)

 user= (new X)
 #:user.X{}

 user= (new hey)
 java.lang.IllegalArgumentException: Unable to resolve classname: hey
 (NO_SOURCE_FILE:61)

 user= (apply new hey)
 java.lang.Exception: Unable to resolve symbol: new in this context
 (NO_SOURCE_FILE:62)

 Can anybody help me understand how to accomplish this when using the
 var? This will give me a generic way to instantiate the type when I
 know the parameters.

The problem is that X. is a special form, so when you say
hey. it's looking for a class literally named hey.

The best solution is to provide for each defrecord a real Clojure
function to act as a factory.  There are several places that such
a function can be helpful, and in real-world code you almost
always run into at least one of them:

(defrecord X [])
(defn new-X [] (X.))

(def hey new-X)

(hey)
;= #:user.X{}

If you don't like the idea of a named factory function for each
record type, you can create an anonymous fn on the fly instead:

(defrecord X [])

(def hey #(X.))

(hey)
;= #:user.X{}

Note in either case when you define the factory fn (named or
not), you need to specify all the args the real record
constructor requires.

--Chouser
http://joyofclojure.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: lazy-seq realization/retention within futures

2010-08-11 Thread Chouser
On Wed, Aug 11, 2010 at 1:25 AM, timcharper timchar...@gmail.com wrote:

 I've distilled the issue down to a series of two tests: in one case,
 the head is properly released, and in the other, the head is retained
 even though it seems it shouldn't be.

 http://gist.github.com/510601

Those are nice tests.  Please excuse my poorer ones below...

...but I think this isn't specifically about lazy seqs or
futures, though those clearly are affected.  It's actually about
gc and closures.

Let's start with a helper function that retains a reference to
a closure while trying to GC a possibly related object:

  (defn attempt-gc [closure weak-ref n]
(loop [i 0]
  (System/gc)
  (when (and ( i n) (.get weak-ref))
(Thread/sleep 1000)
(recur (inc i
closure)

Now if we call this with a closure that does *not* close over the
object the weak-ref refers to, the object gets GC'ed promptly and
control returns immediately:

  (let [x (Object.), r (java.lang.ref.WeakReference. x)]
(attempt-gc #(do nil) r 5))

Note that the Clojure compiler's local-clearing is helping us
here -- it's noticing nothing in the body of the let needs x, so
it's getting cleared and GC'ed before the attempt-gc loop has to
run more than once.

But if the closure *does* close over the object, the closure
itself retains a reference to it and local-clearing in the 'let'
doesn't help.  So attempt-gc tries for several seconds before
giving up:

  (let [x (Object.), r (java.lang.ref.WeakReference. x)]
(attempt-gc #(do x nil) r 5))

It's not clear to me whether or not the Compiler could do
something about this.

Note there's no lazy seq or future (or indeed thread boundaries
of any kind) in either of my examples, though of course retaining
the head of a lazy seq retains the entire seq, and creating
a future does create a closure.

--Chouser
http://joyofclojure.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: lazy-seq realization/retention within futures

2010-08-11 Thread Chouser
On Wed, Aug 11, 2010 at 3:06 PM, Stuart Halloway
stuart.hallo...@gmail.com wrote:
 Chouser,

 There is now a ticket and roadmap for fixing this: See 
 https://www.assembla.com/spaces/clojure/tickets/423-make-sure-future-clears-closed-overs.

Did you see that my examples didn't use future at all?

--Chouser
http://joyofclojure.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: order of returned values from keys and vals

2010-08-11 Thread Chouser
On Wed, Aug 11, 2010 at 4:53 PM, Kent squi...@aol.com wrote:
 Hi,

 Is it safe to assume that the values returned from (keys mp) and (vals
 mp) will be in the same order? In other words, will (zipmap (keys mp)
 (vals mp)) always return mp?

 My experience has been that this does work, and it seems very
 reasonable that it should work, but I don't see it documented anywhere
 and I don't want to write a bunch of code that assumes it will work
 and then have that code break in the future.

keys, vals, and seq all do walk the map in the same order.

I believe this is promised, though I agree having it in the
docstring of keys and vals would be nice.

--Chouser
http://joyofclojure.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: Bug in try/finally?

2010-08-10 Thread Chouser
On Tue, Aug 10, 2010 at 1:09 PM, joegg joega...@gmail.com wrote:
 diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/
 Compiler.java
 index f5684f1..af55660 100644
 --- a/src/jvm/clojure/lang/Compiler.java
 +++ b/src/jvm/clojure/lang/Compiler.java
 @@ -1775,7 +1775,7 @@ public static class TryExpr implements Expr{
                        gen.visitTryCatchBlock(startTry, endTry,
 clause.label, clause.c.getName().replace('.', '/'));
                        }
                if(finallyExpr != null)
 -                       gen.visitTryCatchBlock(startTry, endTryCatch,
 finallyLabel, null);
 +                       gen.visitTryCatchBlock(startTry, endTry,
 finallyLabel, null);
                for(int i = 0; i  catchExprs.count(); i++)
                        {
                        CatchClause clause = (CatchClause)
 catchExprs.nth(i);


 This fixes the behavior we're seeing, but, ummm... might break other
 things, I suppose.  The tests I've written don't cover all the
 expected behavior of try/catch/finally.

That patch seems to essentially reverse this one:

http://github.com/clojure/clojure/commit/5e9f2b293b307aa7953cd390360d24549e542b92

...which suggests to me there must be a better solution, though I
don't see yet what it would be.
--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: Bug in try/finally?

2010-08-10 Thread Chouser
On Tue, Aug 10, 2010 at 2:51 PM, Chouser chou...@gmail.com wrote:

 That patch seems to essentially reverse this one:

 http://github.com/clojure/clojure/commit/5e9f2b293b307aa7953cd390360d24549e542b92

 ...which suggests to me there must be a better solution, though I
 don't see yet what it would be.

Ok, it looks to me like the above commit was an insufficient
solution for the problem it was trying to solve.  Since the
content of the finally block is emitted after the main try
block as well as after each catch block, a single finally handler
for all them together (which is what the above commit does)
cannot avoid potentially re-running some parts of the finally
clause.

To see what javac emits in similar circumstances, I wrote
a foo.java and disassmbled it here: http://gist.github.com/517865

It looks like javac protects the try block and each catch block
individually with separate entries in the exception table, all of
them pointing to the final finally block.

The patch at the top of that gist attempts to do the same thing,
and also fully reverses the earlier endTryCatch commit.  This
passes all tests, including new ones Joe Gallo wrote based on
reports in this thread: http://gist.github.com/517871

--Chouser
http://joyofclojure.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: jna Java Native Acess and clojure ....

2010-08-09 Thread Chouser
On Mon, Aug 9, 2010 at 10:55 AM, Sunil Nandihalli
sunil.nandiha...@gmail.com wrote:
 Hello everybody,
  I have been trying to use the native libraries in clojure. I have
 found clj-native and clojure-jna which may serve the purposes. I would
 like to get a feed back from the community .. Which of these is good
 to use .. Or do you have any other suggestions..

I wrote clojure-jna, but although I haven't had a chance to use
clj-native yet I understand it's significantly more advanced and
efficient than clojure-jna.  So I'd recommend at least starting with
clj-native to see if it will meet your needs.

--Chouser
http://joyofclojure.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: explode string

2010-07-01 Thread Chouser
(next (.split #(?=) string))

But why do you one-char strings instead of just a seq of chars?

--Chouser
http://joyofclojure.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: Can't send from agent error handler?

2010-06-29 Thread Chouser
On Wed, Jun 23, 2010 at 11:27 AM, Shawn Hoover shawn.hoo...@gmail.com wrote:
 My first thought for an agent error handler was to send the exception to
 another agent.
 user= (let [handler (agent nil)
             a (agent 42
                      :error-handler
                      (fn [_ ex] (send handler
                                       (fn [_] (println ex)]
           (send a (fn [_] (throw (Exception. bad news
           (await a)
          �...@a)
 42
 ;; No println!
 user=
 Is this the way it should work? I saw some stuff about it in the wiki [1],
 but it's hard to tell what was decided explicitly.

Thanks for the report.  Ticket is here:
http://www.assembla.com/spaces/clojure/tickets/390

Please try out the patch there and see if it works and/or causes
other problems.  Thanks.

--Chouser
http://joyofclojure.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: Can't send from agent error handler?

2010-06-29 Thread Chouser
On Thu, Jun 24, 2010 at 6:51 AM, ka sancha...@gmail.com wrote:
 I'm also facing the same problem -

 (let [handler (agent 50)
        a (agent 42
            :error-handler
            (fn [_ ex]
              (do
                (println Inside agent a error handler fn (Thread/
 currentThread))
                (send handler
                  (fn [_] (do (println ex (Thread/currentThread)))
 60))
                (println Inside agent a error handler fn - after
 sending to the handler agent)
                (await handler)
                (println CODE DOESN'T REACH HERE ??)
                (println State of handler agent: @handler]
    (send a (fn [_]
              (println Inside agent a function (Thread/
 currentThread))
              (throw (Exception. bad news
    (Thread/sleep 1000)
    ;(println Errors with a: (agent-error a))
    ;(println Errors with handler: (agent-error handler))
    (shutdown-agents)
    (println Errors with a: (agent-error a))
    (println Errors with handler: (agent-error handler))
    (println @a)
    (println @handler))

With the patch in http://www.assembla.com/spaces/clojure/tickets/390
your example will get a little further, but it has another
problem.  The error handler is still executed serially with agent
action, as if it was itself an agent action, but you may not use
'await' inside an agent action.  Using await there throws an
exception, but since you're already in an error handler, that
exception is silently thrown away and you still won't see the
CODE DOESN'T REACH HERE message.  If you wrap your await call
in its own exception handler, you'll be able to see that's what's
going on.

--Chouser
http://joyofclojure.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: Protocols

2010-06-28 Thread Chouser
On Sun, Jun 27, 2010 at 10:18 AM, Rich Hickey richhic...@gmail.com wrote:

 On Jun 27, 2010, at 1:09 AM, Mark Engelberg wrote:

 Is there a list somewhere of all the protocols built-in to Clojure
 1.2's core that are available for extension?


 There are no extension points built on protocols in Clojure yet. Delivering
 protocols is step one, re-architecting the core abstractions in terms of
 protocols is still to come.

I was confused on this point because the docs for
clojure.core.protocols.InternalReduce claim it's used by
clojure.core/reduce.

But after looking into it a bit more, it appears that docstring
is not (yet?) accurate.

--Chouser
http://joyofclojure.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: Question: pmap + number of threads + number of cpus

2010-06-28 Thread Chouser
On Sat, Jun 26, 2010 at 7:01 PM, toddg t.greenwoodg...@gmail.com wrote:
 (running clojure 1.2 snapshot)

 Q1: Why does pmap use the number of available processors + 2? I would
 have thought it would just use the number of avail processors...

I'm not entirely sure, but I think the idea is to prevent too
much context-switching on each core.  Perhaps +2 helps fill in
gaps in the processor's pipelines or something.  The agent pool
for 'send' has a similar limit formula.

 Q2: Could someone clear up my misunderstanding of pmap w/ respect to
 the code snippets below? Pmap doesn't seem to be limiting the number
 of threads to the number of processors + 2...

 I've created an anon func that does't return, so I wouldn't expect the
 pmap step function to advance beyond 4 (I have 2 processors):

 #1: Limit pmap to # of processors
 --

[snip]

 -- just two threads running, as expected


 #2: Limit pmap to # of processors * 10
 --

 user= (pmap #(while true (do (println Thread:  (.getId (Thread/
 currentThread)) item:  %)(Thread/sleep 500))) (range (* 10
 (.availableProcessors (Runtime/getRuntime)
 Thread: Thread:   12 item:  0
 (Thread:  25 item:  13
 Thread:  24 item:  12
 Thread:  23 item:  11
 Thread:  22 item:  10
 Thread:  21 item:  9
 Thread:  20 item:  8
 Thread:  19 item:  7
 Thread:  18 item:  6
 Thread:  17 item:  5
 Thread:  16 item:  4
 Thread:  15 item:  3

 -- In this short snippet, you can see  4 threads running...expected?

Range produces a chunked seq, which if my answer to Q1 is
correct, I guess pmap isn't expecting.  So pmap creates one
'future' per element, but instead of only doing this for procs+2
elements at a time, it does so for every element of the first
chunk.  If you use range of more than 32 elements, you'll see
your example doesn't go beyond the first 32 (range's chunk size).
...or you can use a PersistentList instead of a range, which
produces unchunked seqs, and see that it only uses procs+2
threads.

--Chouser
http://joyofclojure.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: lazy-xml defect (?)

2010-06-23 Thread Chouser
On Wed, Jun 23, 2010 at 7:17 AM, Stuart Halloway
stuart.hallo...@gmail.com wrote:
 I am trying to track down and solve the issues Phil Hazelden
 reported on Hacker News [1]. I suspect that the XML issue was
 this one:

 It appears that the code has moved on since this report-- the
 emit-element fn mentions a :pad option but I don't see it being
 used anywhere. Is there an issue here we should open a ticket
 for?

Right, the way lazy-xml's emit works now is completely different.
It now uses an XML Transformer which handles the indenting, as
well as controlling character encoding, xml declaration, content
escaping, etc.

I think the mention of :pad in the emit-element docsctring is
just out-of-date documentation, which I'd be happy to remove.
emit-element is private anyway.

On the other hand, clojure.xml/emit is in pretty bad shape and
has been for a long time.  It inserts newlines when it shouldn't
and fails to escape text and attribute values.  I'd be happy to
see it use lazy-xml's implementation instead, unless people have
issues with how lazy-xml does it.

--Chouser
http://joyofclojure.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: Unexpected conj behavior

2010-06-15 Thread Chouser
On Mon, Jun 14, 2010 at 11:06 AM, Sean Devlin francoisdev...@gmail.com wrote:

 This behavior becomes a pain when trying to use into:

 ;Good
 user= (into {} [[:a 1] [:b 2] [:c 3] [:d 4]])
 {:a 1, :b 2, :c 3, :d 4}

 ;Bad
 user= (into {} (partition 2 [:a 1 :b 2 :c 3 :d 4]))
 #CompilerException java.lang.ClassCastException: clojure.lang.Keyword
 cannot be cast to java.util.Map$Entry (NO_SOURCE_FILE:...)

Stuart S. already covered the reasons for this behavior.  Given
those reasons, a solution that works for your last example there
is:

(apply array-map [:a 1 :b 2 :c 3 :d 4])
;= {:a 1, :b 2, :c 3, :d 4}

--Chouser
http://joyofclojure.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: Non-tail recursion (Clojure way to hierarchies)

2010-06-15 Thread Chouser
On Sun, Jun 13, 2010 at 8:39 AM, Oleg oleg.richa...@gmail.com wrote:
 Thank you, but could you provide me a little code snippet which will
 iterate through collection and assoc children key for each row.

 On 13 июн, 16:35, Andrzej ndrwr...@googlemail.com wrote:
 On Sun, Jun 13, 2010 at 7:35 PM, Oleg oleg.richa...@gmail.com wrote:

  Currently i'm just calling function, but there is a danger of
  StackOverflow. I can't use recur, because it's not last statement. As
  i can understand recur is good to build long sequences, but in my case
  i'm building hierarchy.

 Two potential solutions:
 1. Build a lazy hierarchy, i.e. instead of returning a nested
 structure, return a function that produces it. It might be better to
 use a built-in function tree-seq though (check the implementation of
 file-seq and xml-seq).

I think a lazy hierarchy is the way to go, but tree-seq is a way
to walk a tree, not build one.

For a real example of a lazy hierarchy, you can look at
clojure.contrib.lazy-xml, which builds a lazy tree of XML nodes.
But it may be hard to learn from without getting lost in SAX API
craziness, so here's an attempt at a simpler example:

First, a function to return some children for a given parent:

(defn children [parent]
  (vec (map + (repeat (* 10 parent)) (range 10

(children 42)
;= [420 421 422 423 424 425 426 427 428 429]

Note this is a vector and thus non-lazy, just as in your problem
description.

Now we want a function that returns a tree node for a given item.
For this example a node will be just a map with an :item and
a lazy sequence of :kids:

(defn node [item]
  {:item item
   :kids (map node (children item))})

The fact that 'map' is lazy is critical here.  If we force that
map when creating a node, our first call to 'node' will force the
whole tree and could have unbounded recursion.  But 'map' is lazy
so we know that a single call to node will be O(1).  Only when we
actually realize the :kids seq will 'children' be called.

We can now build a tree and look something up in it:

(- (node 0) :kids (nth 3) :kids (nth 5) :kids (nth 8) :item)
;= 358

So this is an infinitely deep tree that we can navigate without
any actual recursion, just as we can walk an infinite lazy seq
without recursion, and thus there's no threat that the stack will
overflow:

(:item (reduce #(nth (:kids %1) %2)
   (node 0)
   (take 5000 (cycle (range 10)
;= 123456789012345678...67890123456789

Note that since these trees are infinitely deep, a depth-first
walk like tree-seq does is probably not very useful:

(take 8 (map :item (tree-seq :kids :kids (node 1
;= (1 10 100 1000 1 10 100 1000)

Hope that helps!

--Chouser
http://joyofclojure.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: update-in oddness

2010-06-04 Thread Chouser
On Fri, Jun 4, 2010 at 10:04 AM, Heinz N. Gies he...@licenser.net wrote:

 On Jun 4, 2010, at 14:11 , Heinz N. Gies wrote:


 On Jun 4, 2010, at 14:03 , Joost wrote:

 On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote:
 Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 
 3}))

 Yes, that gives {nil {2 3}, 1 2}

 You're not giving any key in the key list, so that is the reason
 there's a nil key now, and {2 3} is just the value that you give it,
 since that's what ((constantly {2 3}) nil) returns.

 Seems correct as far as the documentation of update-in is concerned.


 So for how I'd expect it to work:

 (defn update-in*
  ([m [k  ks] f  args]
   (if ks
     (assoc m k (apply update-in* (get m k) ks f args))
     (if k
       (assoc m k (apply f (get m k) args))
       (apply f  m args)

 user (get-in {1 2} [])
 {1 2}
 user (update-in* {1 2} [] assoc  1 3)
 {1 3}

I agree with the spirit of your argument, but not your
implementation:

  (update-in* {nil 2} [nil] (constantly 3))
  ;= 3

Perhaps:

  (defn update-in*
[m ks f  args]
(if-let [[k  mk] ks]
(if mk
(assoc m k (apply update-in* (get m k) mk f args))
(assoc m k (apply f (get m k) args)))
  (apply f m args)))

  (update-in* {nil 2} [nil] (constantly 3))
  ;= {nil 3}

--Chouser
http://joyofclojure.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: Question on destructure source

2010-06-03 Thread Chouser
On Thu, Jun 3, 2010 at 9:38 AM, YD ydong.pub...@gmail.com wrote:
 Hi,

 When 'destructure' is doing a map destructuring, 'pmap' is the
 function to use. 'pmap' will do some kind of process to the given
 bindings using these lines of code:
                                bes (reduce
                                     (fn [bes entry]
                                       (reduce #(assoc %1 %2 ((val
 entry) %2))
                                               (dissoc bes (key
 entry))
                                               ((key entry) bes)))
                                     (dissoc b :as :or)
                                     {:keys #(keyword (str %)), :strs
 str, :syms #(list `quote %)})

 I'm confused. Since every time ((key entry) bes) evaluates to nil, the
 inner reduce will never really do some useful thing. What's the
 purpose of this piece of code?

Yes, if ((key entry) bes) is nil then the inner reduce simply
returns the binding map as it stands.  The purpose of this code
is to support the :keys, :strs, and :syms keys in map
destructuring:

(let [{:keys [a b]} {:a 1 :b 2}] [a b])
;= [1 2]

In this example, (key entry) will be :keys for one of the
iterations of the inner reduce.  When (key entry) is :keys, ((key
entry) bes) will be [a b], and the inner reduce will process each
item of that vector, finally returning {a :a b :b} as the whole
binding map.

Which means the above example does exactly the same things as:

(let [{a :a b :b} {:a 1 :b 2}] [a b])
;= [1 2]

...which is what you'd do if there was no support for :keys

--Chouser
http://joyofclojure.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: Insert into an indexed seq

2010-04-27 Thread Chouser
On Tue, Apr 27, 2010 at 1:31 PM, Sean Devlin francoisdev...@gmail.com wrote:
 Is there a built in to insert a value into an indexed seq?

 For example:

 user= (insert [:a :b :c :d] 2 :q)
 (:a :b :q :c :d)

 Not sure if I'm missing something simple...

That's a vector, which cannot efficiently splice internally, so
it's not supported directly.  However, you can build a new vector
with your value included:

  (apply conj [:a :b] :q [:c :d])
  ;= [:a :b :q :c :d]

 Also, why does this work:
 user= (assoc [:a :b :c :d] 2 :q)
 [:a :b :q :d]

 And this doesn't:
 user= (dissoc [:a :b :c :d] 2)
 #CompilerException java.lang.ClassCastException:
 clojure.lang.PersistentVector cannot be cast to
 clojure.lang.IPersistentMap (NO_SOURCE_FILE:286)

 Annoying.

Again, vectors cannot efficiently insert or remove items except
from the right-hand end, though as you note items can replaced
internally.

  (let [v [:a :b :c :d]]
(into (subvec v 0 2) (subvec v 3)))
  ;= [:a :b :d]

There are immutable collections that support both numeric-indexed
lookups and internal splicing, they're just not currently included
with Clojure.  See for example finger trees:


http://functionaljava.googlecode.com/svn/artifacts/2.21/javadoc/fj/data/Seq.html

--Chouser
http://joyofclojure.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: let's all link to the getting started pages!

2010-04-06 Thread Chouser
On Tue, Apr 6, 2010 at 4:55 PM, Stuart Halloway
stuart.hallo...@gmail.com wrote:
 People getting started with Clojure have struggled to find an up-to-date
 source for information on getting their editor of choice up and running.
 This is unfortunate, since there is good support in a bunch of different
 editors.

 The Getting Started page on Assembla
 (http://www.assembla.com/wiki/show/clojure/Getting_Started) should
 ameliorate this problem. A bunch of people have contributed or tested
 instructions for Netbeans/Enclojure, Eclipse/Counterclockwise, IDEA/La
 Clojure, Emacs, Vim, and Leiningen.

 Now we just need to make this page more google-findable. If you have a
 blog/twitter/whatever-the-kids-use-these-days, please link out to the
 Assembla page, especially if you written up your own getting started
 instructions.

Google's top hit for clojure getting started is
http://clojure.org/getting_started -- should that page be
replaced or at least simplified and include a prominent link to
the assembla page?

--Chouser
http://joyofclojure.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: Set as function

2010-04-05 Thread Chouser
On Apr 6, 2010, at 12:20 AM, Mark Engelberg mark.engelb...@gmail.com  
wrote:





On Mon, Apr 5, 2010 at 8:56 PM, Richard Newman holyg...@gmail.com  
wrote:

Why this behavior?

It's useful: e.g., you can use a set as a filter.

user= (filter #{2 3 4 5} (range 1 10))
(2 3 4 5)


filter works just as well with a function that returns true and  
false, so that's not a particularly good example.


Which of the items in this set comes first in this vector?

(some #{:b :c} [:a :c :d])
;= :c

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

To unsubscribe, reply using remove me as the subject.


Re: Confused about =, native java arrays and seqs...

2010-03-24 Thread Chouser
On Wed, Mar 24, 2010 at 4:17 PM, Frank Siebenlist
frank.siebenl...@gmail.com wrote:
 Thanks for the response - guess it is the best one can do living in this 
 mixed mutable/immutable world.

 Has the seq'ed version of the java byte array become immutable or do we have 
 to pray that nobody changes the underlying array values?

Pray.

  (let [a (into-array (range 5)),
s (seq a)]
(prn s)
(aset a 1 42)
(prn s))

  ; (0 1 2 3 4)
  ; (0 42 2 3 4)

I'd recommend keeping the exposure of arrays to very small and
isolated pieces of code, if they must be used at all.

--Chouser
http://joyofclojure.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

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Java method call irritation

2010-03-19 Thread Chouser
On Fri, Mar 19, 2010 at 4:04 AM, Per Vognsen per.vogn...@gmail.com wrote:
 On Fri, Mar 19, 2010 at 2:46 PM, Konrad Hinsen
 konrad.hin...@fastmail.net wrote:
 On 18 Mar 2010, at 16:55, Per Vognsen wrote:

 Is there any reason why a .method occurrence in non-operator position
 doesn't just do the closure wrapping automagically?

 There is two reasons I can think of, though of course I can't know if they
 are the real ones.

 First, a technical reason: .method is handled as part of macro expansion:

        user (macroexpand-1 '(.hashCode 3))
        (. 3 hashCode)

 The result is a special form for Java interop. Symbols in non-operator
 positions are not macro-expanded, so some other mechanism would have to be
 invented to handle them in a special way. It would in fact create a first
 special symbol category, complicating the semantics of the language, so
 this is not just a technical reason.

 Interesting. I had tacitly assumed there was already some special
 symbol magic going on and so did not know it was a simple case of
 macro expansion with a little reader support.


 Second, a semantic reason: Java method calls are resolved statically if
 possible (you can use reflection warnings to find out where this fails),
 making them very fast. Creating and calling a closure is a much slower
 operation. Rich has stated at several occasions that he considers
 performance in important part of the interface of a function, so making a
 clear syntactic distinction between a fast and a slow operation would fit
 well with that point of view.

 I thought of this as well before posting. A few comments:

 1. Creation: You only need to create one closure per function, once
 and for all; the closure does not close over anything in the
 surrounding scope, it's just a wrapper.
 2. Calling: This is such a straightforward case of inlining that
 HotSpot will eat it for breakfast. Clojure is full of idioms that
 would be death to performance if not for such behavior from HotSpot.
 3. Type hinting: This is a deeper problem with first-class methods.
 The current manner of type hinting does not work well here. If you
 could write SomeClass.someMethod to refer to a specific class's method
 and perhaps supply further signature hints in the case of same-arity
 overloads, e.g. #^([Integer]) ResultSet.getObject, then this could be
 resolved.

This has been discussed some, including alternate hinting
syntaxes not entirely unlike what you suggest:

http://clojure-log.n01se.net/date/2010-01-21.html#08:34

--Chouser
http://joyofclojure.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

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Long-running STM updates will never complete... is there a solution?

2010-03-16 Thread Chouser
On Tue, Mar 16, 2010 at 5:25 AM, Christophe Grand christo...@cgrand.net wrote:
 On Mon, Mar 15, 2010 at 11:27 PM, Chouser chou...@gmail.com wrote:

 I make no claims about the Rightness of this suggestion, but
 simply offer another example of a work-around:

    (dosync (alter r identity) (alter r f))

 That is, a dummy write via alter is also sufficient to allow
 the transaction to succeed, just like 'ensure'.

 This is an interesting idea which can be automated (well, to be frank, an
 implicit ensure could also be automated but it doesn't feel kosher) by
 adding a doAlter to c.l.LockingTransaction:

Well, what you've got there seems much cleaner than a dummy
write, and makes 'alter' do a lot less work than it did.  I won't
pretend to understand the STM well enough to know if it's all
correct though.

--Chouser
http://joyofclojure.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: A Tour of Enlive

2010-03-15 Thread Chouser
Very nice, David!  I'll be reading that again in the future, next
time I actually need to use enlive.

A couple things I noticed...

On Mon, Mar 15, 2010 at 12:43 PM, David Nolen dnolen.li...@gmail.com wrote:

 Wow thanks for pointing that out. Turns out that section is way off! It can
 be expressed like so:

 (html/deftemplate index tutorial/template1.html
   [ctxt]
   [:p#message] (html/content (get ctxt :message Nothing to set here))

Did you mean to change see to set?

Also, I'd recommend a slight change to how you load the
namespaces.  Specifically, I'd recommend doing the load first:

(load scrape1)

And then using in-ns to change the REPL's namespace:

(in-ns 'tutorial.scrape1)

...mainly because 'ns' is meant to be used as a declaration at
the top of a file, not for interactively changing the REPL
namespace.  There is techincally only a slight difference today
(using 'ns' automatically refers all of clojure.core, regardless
of what the ns block at the top of the loaded file says), but
the differences may drift in the future.  I also think reversing
the order helps slightly to clarify what's actually going on in
the load step -- it's not loading code into your current
namespace but into the one declared in scrape1.

Anyway, that's a minor nit -- it's a great tutorial, thanks for
writing it up!

--Chouser
http://joyofclojure.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: Long-running STM updates will never complete... is there a solution?

2010-03-15 Thread Chouser
On Mon, Mar 15, 2010 at 5:17 PM, Christophe Grand christo...@cgrand.net wrote:
 On Mon, Mar 15, 2010 at 10:41 PM, ataggart alex.tagg...@gmail.com wrote:

 On Mar 15, 1:43 pm, Michał Marczyk michal.marc...@gmail.com wrote:
  On 15 March 2010 21:08, Meikel Brandmeyer m...@kotka.de wrote:
 
   Now I'm confused. Calling ensure on r shouldn't have an effect since
   we
   call alter on r anyway, no?
 
  ensure protects the ref from modification by other transactions
  (from the docs). alter does not.
 
  Reading into the Java code, ensure puts a lock on the ref, which, once
  in place, guarantees that the transaction doing the ensuring has an
  exclusive right to modify the ref until it commits / retries... or
  something, my Java-fu is still nothing to boast about, regrettably.
 
  At any rate, my current understanding is that, in Garth's example, the
  ensure gives (alter r f) all the time it needs to modify r's value
  while putting all other transactions which attempt to modify r on
  hold. alter, by itself, never interferes with background transactions;
  should something disappear from under its feet, it expects to be
  retried.
 
  Ok, back to improving my Java chops in the hope of grasping all the
  intricasies of Rich's code sometime... *sigh*
 
  Sincerely,
  Michał

 I'm inclined to say this is incorrect as I'm on my iphone so I can't
 look at the source. The concurrency functions (e.g., ref-set, alter,
 ensure) only lock their refs during the commit process.

 Michal is right: ensure effectively readlocks the ref -- ref-set (and alter
 since it is currently implemented on top of ref-set) writelocks a ref twice:
 the first time to touch it, the second time to commit.

 However I think it's trying to read too much in Protects the ref from
 modification by other transactions to conclude that ensure guarantees the
 ref to be locked.

 The issue Garth describes is a case of live-locking, an extant failure
 mode of the STM.  Some solutions would be to break up the work from
 just a single transaction (though sacrificing consistency), or use the
 locking construct:

 http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/locking


 One should also try to put most of the calculation outside of the
 transaction or to make retries cheapr (eg through partial memoization).

I make no claims about the Rightness of this suggestion, but
simply offer another example of a work-around:

(dosync (alter r identity) (alter r f))

That is, a dummy write via alter is also sufficient to allow
the transaction to succeed, just like 'ensure'.

--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: (seq? x) vr.s (not (empty? x))

2010-03-11 Thread Chouser
On Thu, Mar 11, 2010 at 2:19 PM, Brian Hurt bhur...@gmail.com wrote:
 So the doc comment on empty? reads, in part:

 Please use the idiom (seq x) rather than (not (empty? x))

 A heads up to people: these two code sequences are *not* identical in
 behavior:

 user= (seq? '())
 true
 user= (not (empty? '()))
 false

What you demonstrated is that (seq x) is not the same as
(seq? x) -- useful to know, but not the point of the docstring.

Also note that it's not necessary or idiomatic to quote the empty
list:

user= (seq ())
nil

--Chouser
http://joyofclojure.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 Implementation issues that may affect performance?

2010-03-09 Thread Chouser
On Tue, Mar 9, 2010 at 1:44 AM, Timothy Pratley
timothyprat...@gmail.com wrote:
 On 9 March 2010 04:03, Jonathan Shore jonathan.sh...@gmail.com wrote:
 (defn fib [#^Integer a]
   (if ( a 2)
     a
     (+ (fib (- a 1)) (fib (- a 2)
 I'm just learning, so I may have overlooked something that mitigates or
 otherwise avoids dispatch.

 You might want to experiment with something like
 (defn fib [a]
  (let [ia (int a)]
    ..))

 I know that seems a little weird but anything passed into or out of a
 function gets boxed to an object type. (int a) coerces to a primitive
 int which for some operations has much better performance.

When using primitive locals as Tim is suggesting, remember that
currently numeric literals are boxed by default as well.  So you
actually want ( ia (int 2)) and so on as well.

--Chouser
http://joyofclojure.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: Bug in Clojure 1.2 case macro

2010-02-24 Thread Chouser
On Wed, Feb 24, 2010 at 8:57 PM, pthatcher pthatc...@gmail.com wrote:
 Ouch.  Burned by documented behavior :).  Thanks for pointing that
 out.

 Seriously, though, I'm not the last that will get confused by this.
 My suggestion would be to make (case) copy the value from the *var* at
 compile time and use that.

But eval at compile time is completely different than eval at
runtime, and not generally not useful.

 ; these now work:
 (def *abc* ABC)

 (case-eval ABC
  ABC
    :abc)

 (case-eval ABC
  *abc*
    :abc)

 (case-eval ABC
  (*abc*)
    :abc)

Sure, but these don't:

(let [xyz XYZ] (case-eval XYZ xyz :xyz))
java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.UnsupportedOperationException: Can't eval locals
(NO_SOURCE_FILE:36) (NO_SOURCE_FILE:36)


(def *xyz* update later)
(defn xyz? [] (case-eval XYZ *xyz* :xyz))
(def *xyz* XYZ)
(xyz?)
java.lang.IllegalArgumentException: No matching clause: XYZ (NO_SOURCE_FILE:0)

The first case fails because locals don't have values yet when
macros used in their scope are being expanded.

The second case fails because the var's value is inserted into
the expanded code before it's updated.

The implementation of 'case' is built around the test values
being constants, and when that's what you have offers excellent
performance.  If your test values are not known until runtime,
use 'if', 'cond', or 'condp'.

--Chouser
http://joyofclojure.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: Using zip-filter to remove nodes

2010-02-24 Thread Chouser
On Wed, Feb 24, 2010 at 8:09 PM, James Sofra james.so...@gmail.com wrote:
 Hi all,

 I am trying to use (abuse? *) zip-filter to remove some nodes and
 return the xml tree to me.
 If I do something like this:
    (xml1- zipped-xml zf/descendants :model zip/remove zip/root)

 I can remove one :model node, but what if I want to remove more than
 one or all of the :model nodes?

 If I do this:
    (xml- zipped-xml zf/descendants :model zip/remove zip/root)

 I get multiple xml-trees each with one node removed from each. So I
 wrote a function zip-top to take me back to the top (like zip/root
 but returns the loc not node) and can do this:
    (xml- zipped-xml zf/descendants :model zip/remove zip-top zf/
 descendants :model zip/remove zip/root)

 and that will remove two of them but that is not really ideal I would
 like to remove all of them ... any ideas? am I way off track? is there
 better ways to manipulate xml trees in clojure? Enlive maybe? I
 haven't played with it yet.

 * I realise this probably abusing zip-filter since it is only supposed
 to take predicates and zip/remove is not really a predicate.

You have correctly identified the behavior of zip-filter and its
negative consequences.  I didn't realize until too late that my
design for zip-filter essentially prevents using it to edit more
than a single filter result.  I haven't thought deeply about what
could be done to fix it -- I think it would have to be pretty
radical.  Instead of returning a lazy seq it would have to have
some kind of mechanism for continuation, or perhaps using a monad
or one of these new cells.

Christophe Grand's enlive lib address a lot of these problems
for html and some xml.  I'd recommend you take a look at it and
see if it would work in your case.

--Chouser
http://joyofclojure.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: Bug in Clojure 1.2 case macro

2010-02-23 Thread Chouser

On Feb 23, 2010, at 8:47 PM, pthatcher pthatc...@gmail.com wrote:


I noticed a funny bug in Clojure 1.2's case macro.  It doesn't work
with *vars*.  For example:

(def *a* a)

;this is true
(case a
a true
false)

;but this is false!
(case a
*a* true
false)


If you read the first line or two of the docs for case I think you'll  
see it's not a bug but documented behavior.  The values in the case  
test clauses must be constants, so not a var or local.  If you need  
those test values to be evaluated then your work around of using  
condp (or cond) is entirely appropriate.


--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: Clojure on Go

2010-02-20 Thread Chouser
On Sat, Feb 20, 2010 at 3:59 PM, Joop Kiefte iko...@gmail.com wrote:
 I read this part...

 http://www.reddit.com/r/programming/comments/b3sb1/golisp_a_lisp_interpreter_in_go/

 and thought, would someone be able to do that for clojure? (the
 Clojure in Clojure stuff might make this easier :))

 Is this a weird idea?

Clojure supports compilation, so might as go all the way and have
add a golang target to complie Clojure code directly to golang
code.  Not a weird idea at all. :-)

 I like a lot of ideas in go, and it's speed, but Clojure is just some
 bits nicer. When we have clojure on go, we can have compiled clojure
 without java runtime and fast, can't we?

I don't know if you'll get better runtime speed out of golang or
not, but I bet you'd get much better startup speed, and for some
use cases that's highly desirable.

 It sure has advantages, and as a toy project it might be cool. And
 most of Clojure's code is in clojure anyway, so that eases porting I
 guess.

Here I'm afraid you may be disappointed.  Currently all of
Clojure's reader, compiler, persistent data structures (vector,
list, maps, queues, and sets), reference types (refs, agents,
vars, etc.), and much of the support code (STM, namespaces, etc.)
are all written almost entirely in Java.

This is already beginning to change (see Rich's recent work on
cells and generic vectors), but there's quite a ways to go yet.
When that work is done, compiling Clojure to golang might indeed
be a fun project.

--Chouser
http://joyofclojure.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


  1   2   3   4   5   6   7   >