Re: partition-starting-every : yet another partition function

2010-09-16 Thread Thomas
I agree with number 2: it would be very nice to have this in contrib.
I needed it last month and rolled my own (less clean) version.

Thomas

On Sep 10, 10:26 pm, Matt  Smith  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))
>
> Questions:
> 1 - Is there a simpler way to do this using existing partition
> functions?
> 2 - If not, is this something people are interested in having
> contributed?
>
> In looking at the partition functions they are very similar.  Maybe
> there is a why to combine them in to a single function.

-- 
You 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 Christophe Grand
On Thu, Sep 16, 2010 at 10:45 PM, Chouser  wrote:

> On Fri, Sep 10, 2010 at 4:26 PM, Matt  Smith  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.
>
> 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?
>
>
Nice trick that your #(and (f %) (Object.)) however #(when (f %) (Object.))
would be better because it would produce only one false value (nil) instead
of two (nil and false).

For comprehensiveness, let's not forget reductions :-)
(defn partition-starting-every
 "Partition the sequence starting each partition when the f is true."
 [f coll]
 (map #(map first %)
   (partition-by second
 (map vector coll
   (rest (reductions #(if (f %2) (inc %1) %1) 0 coll))

 Christophe


-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

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

Re: practical clojure

2010-09-16 Thread Stuart Sierra
Thanks! Glad you liked the book.
-S

On Sep 14, 8:37 am, faenvie  wrote:
> i just emerged from a whirlwind read
> through 'practical clojure'. i like this book
> very much.
>
> it's a very well structured, carefully written
> book. kind of a minimalistic approach but minimalistic
> in the positive sense clojure itself is.
>
> so now 'students' have really good choices
> among 4 high quality introductions and can
> combine them.
>
> for the future: some books about solving state of
> the art problems with clojure would be nice to come.
> something like peter norvigs book on AI programming.

-- 
You 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  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: simplest graphics?

2010-09-16 Thread Lee Spector
On Sep 16, 2010, at 12:13 PM, Alan wrote:
> I think you may have misunderstood the first suggestion I made, about
> keeping (shape, color) pairs in your atomic vector. I really meant
> java.awt.Shape and java.awt.Color objects, rather than a symbol
> (keyword is better as Christophe suggests) and a bunch of numbers.
> Like so:
> (defn render-shape [g shape color]
>  (doto g
>(.setColor color)
>(.fill shape)))
> 
> (draw-shape (Rectangle. 50 50 200 100) (Color. 0 0 255 75))
> 
> Java already has the "multi-method" Christophe suggests, in the form
> of Graphics.fill(Shape); you don't have to implement it yourself.

Ah -- I didn't misunderstand, but I also didn't know about Graphics.fill(Shape) 
so I didn't see the full picture or the real benefit. This should indeed help 
to neaten things up a bit. 

(And thanks Christophe for the keyword advice -- my use of symbols is another 
old Lisp habit, which wasn't great even there.)

I guess the main remaining issue is just the code to create the window and 
panel, which is still pretty big and cumbersome to be part of the sort of 
ultra-simple graphical "hello world" that I had in mind. But if there's no 
simpler way to do that with the built-in java libraries then I guess I'm stuck 
with that.

Thanks, -Lee

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


Re: simplest graphics?

2010-09-16 Thread Alan
I think you may have misunderstood the first suggestion I made, about
keeping (shape, color) pairs in your atomic vector. I really meant
java.awt.Shape and java.awt.Color objects, rather than a symbol
(keyword is better as Christophe suggests) and a bunch of numbers.
Like so:
(defn render-shape [g shape color]
  (doto g
(.setColor color)
(.fill shape)))

(draw-shape (Rectangle. 50 50 200 100) (Color. 0 0 255 75))

Java already has the "multi-method" Christophe suggests, in the form
of Graphics.fill(Shape); you don't have to implement it yourself.

On Sep 15, 8:15 pm, Lee Spector  wrote:
> On Sep 15, 2010, at 1:57 PM, Alan wrote:
>
> > This looks a lot like what I would do - I'm afraid I don't have any
> > brilliant insights for you. I do have a couple ways you could make
> > this smaller, though:
>
> > - Instead of (atom ()) and convoluted swap! logic, what about (atom
> > []) and (swap! shapes conj new-shape)?
> > - Similarly don't use (list shape-name...), try [shape-name...]
> > -- (defn render-shape [shape-name [x y w h] color])
> > -- (render-shape 'rect (take 4 (repeatedly #(rand-int 400))) blue)
>
> > The last two combine to let you avoid writing rand-int so many times.
>
> Thanks Alan. Using vectors instead of lists does clean things up a little. 
> I've spent a lot of my life in other Lisps and so lists spring to mind first.
>
> FYI below is a slightly nicer version that uses vectors and also adds line 
> drawing. I didn't follow your other suggestions because I was interested in 
> minimizing the tool, not the example.
>
> I'd still be quite interested in any advise anyone has on minimizing the code 
> for initializing/buffering the window (using only core, contrib, and built-in 
> java libraries -- but maybe different built-in java libraries? I'm coming 
> from Lisp, not from Java, and I'm not sure what's in there.)
>
> Also, this would have a smaller impact but I'm curious about it: is there a 
> way to treat method names as data and then make calls to them, as one can 
> with clojure functions? Then I could pass things like fillRect, or map rect 
> to fillRect, etc. This would make things slightly simpler here but be handy 
> in other cases... but I don't see how to do it.
>
> Thanks, -Lee
>
> --
> (def max-x 500)
> (def max-y 500)
> (def shapes (atom []))
>
> (defn render-shape
>   [graphics [shape-name x y w h r g b a]]
>     (.setColor graphics (java.awt.Color. r g b a))
>     (case shape-name
>       rect (.fillRect graphics x y w h)
>       oval (.fillOval graphics x y w h)
>       line (.drawLine graphics x y w h)))
>
> (def panel
>   (let [jp (proxy [javax.swing.JPanel]
>              []
>              (getPreferredSize [] (java.awt.Dimension. max-x max-y))
>              (paint [g]
>                (render-shape g ['rect 0 0 max-x max-y 255 255 255 255])
>                (doall (map #(render-shape g %) @shapes]
>     (doto (new javax.swing.JFrame "My graphics window")
>       (.setSize max-x max-y)
>       (.add jp)
>       (.setVisible true))
>     jp))
>
> (defn draw-shape [& shape]
>   "Adds a shape to the current drawing. The first argument should be one of
> the following symbols: rect, oval, or line. For rect or oval  this should
> be followed by: x, y, width, height, red, green, blue, alpha. The x and y
> coordinates specify the upper right corner. Color values (including alpha,
> which is opacity) should range from 0 to 255. For line the arguments are
> the remaining arguments are x-start, y-start, x-end, y-end, red, green,
> blue, alpha."
>   (swap! shapes conj shape)
>   (.paint panel (.getGraphics panel)))
>
> ;; test it out by drawing a bunch of shapes
> (draw-shape 'rect 20 20 460 80 255 128 0 255)
> (draw-shape 'oval 120 120 300 100 100 100 0 20)
> (draw-shape 'oval 300 50 100 300 10 100 200 20)
> (draw-shape 'line 0 0 500 500 255 0 0 255)
>
> --
> Lee Spector, Professor of Computer Science
> School of Cognitive Science, Hampshire College
> 893 West Street, Amherst, MA 01002-3359
> lspec...@hampshire.edu,http://hampshire.edu/lspector/
> Phone: 413-559-5352, Fax: 413-559-5438
>
> Check out Genetic Programming and Evolvable 
> Machines:http://www.springer.com/10710-http://gpemjournal.blogspot.com/

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


Re: thinking in clojure

2010-09-16 Thread Btsai
That pattern will be a great addition to the toolbox, thank you :)

On Sep 16, 9:58 am, Laurent PETIT  wrote:
> And note that the pattern works at any level, and is easily readable, since
> update-in "flattens" the arguments of the modifying function :
>
> If you want to "touch" the path [:a :b :c :d] and provide specific default
> values at each level if the key is not found, it's as "simple" as :
>
> (update-in coll
>   [:a] (fnil update-in default-for-first-level)
>   [:b] (fnil update-in default-for-second-level)
>   [:c] (fnil update-in default-for-third-level)
>   [:d] (fnil update-in default-for-fourth-level)
>   the-function-you-wanted-to-use-in-the-first-place
>   arg2-for-the-function
>   arg3-for-the-function ...)
>
> 2010/9/16 Laurent PETIT 
>
>
>
> > So nested calls to update-in are needed in order to be able to provide a
> > specific default value, everytime just having an empty map created isn't
> > sufficient.
>
> > So instead of (update-in {} [:a :b] identity) which returns {:a {:b nil}} ,
> > you can break the key path at :a so that the default value if no :a is
> > specified by (fnil XXX default-value). And by specifying that XXX is
> > update-in, you can continue your "key path" where you stopped (after :a),
> > either using the found value at :a, either the provided default value :
>
> > (update-in {} [:a] (fnil update-in {:label "great label"}) [:b] identity)
> > => {:a {:b nil, :label "great label"}}
>
> > or you can also decide that it's not a map which should be the default
> > value, imagine you want to modify a path [:a 2] :
>
> > (update-in {} [:a] (fnil update-in [:foo :bar :baz]) [2] str) => {:a [:foo
> > :bar ":baz"]}
>
> > 2010/9/16 Btsai 
>
> > My poor brain can't handle nested calls to update-in, so this is what
> >> I came up with:
>
> >> (defn add-meetings [data k meetings]
> >>  (cond
> >>   (nil? (data k)) (assoc data k {:title "title" :meetings meetings})
> >>   :else (update-in data [k :meetings] concat meetings)))
>
> >> On Sep 16, 8:53 am, Laurent PETIT  wrote:
> >> > 2010/9/16 Meikel Brandmeyer 
>
> >> > > Hi Laurent,
>
> >> > > On 16 Sep., 15:54, Laurent PETIT  wrote:
>
> >> > > > you don't like my one-liner ? :-)
>
> >> > > I saw your message only after I sent mine. :)
>
> >> > > > (update-in coll [k] (fnil update-in *default-value*) [:meetings]
> >> (comp
> >> > > vec
> >> > > > concat) data)
>
> >> > > Hmm... (comp vec concat) == into?
>
> >> > Yep.
> >> > so this is the killer one : :-)
>
> >> > (update-in coll [k] (fnil update-in *default-value*) [:meetings] into
> >> data)
>
> >> --
> >> You received this message because you are subscribed to the Google
> >> Groups "Clojure" group.
> >> To post to this group, send email to clojure@googlegroups.com
> >> Note that posts from new members are moderated - please be patient with
> >> your first post.
> >> To unsubscribe from this group, send email to
> >> clojure+unsubscr...@googlegroups.com >>  >
> >> For more options, visit this group at
> >>http://groups.google.com/group/clojure?hl=en

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


Re: thinking in clojure

2010-09-16 Thread Laurent PETIT
And note that the pattern works at any level, and is easily readable, since
update-in "flattens" the arguments of the modifying function :

If you want to "touch" the path [:a :b :c :d] and provide specific default
values at each level if the key is not found, it's as "simple" as :

(update-in coll
  [:a] (fnil update-in default-for-first-level)
  [:b] (fnil update-in default-for-second-level)
  [:c] (fnil update-in default-for-third-level)
  [:d] (fnil update-in default-for-fourth-level)
  the-function-you-wanted-to-use-in-the-first-place
  arg2-for-the-function
  arg3-for-the-function ...)



2010/9/16 Laurent PETIT 

> So nested calls to update-in are needed in order to be able to provide a
> specific default value, everytime just having an empty map created isn't
> sufficient.
>
> So instead of (update-in {} [:a :b] identity) which returns {:a {:b nil}} ,
> you can break the key path at :a so that the default value if no :a is
> specified by (fnil XXX default-value). And by specifying that XXX is
> update-in, you can continue your "key path" where you stopped (after :a),
> either using the found value at :a, either the provided default value :
>
> (update-in {} [:a] (fnil update-in {:label "great label"}) [:b] identity)
> => {:a {:b nil, :label "great label"}}
>
> or you can also decide that it's not a map which should be the default
> value, imagine you want to modify a path [:a 2] :
>
> (update-in {} [:a] (fnil update-in [:foo :bar :baz]) [2] str) => {:a [:foo
> :bar ":baz"]}
>
> 2010/9/16 Btsai 
>
> My poor brain can't handle nested calls to update-in, so this is what
>> I came up with:
>>
>> (defn add-meetings [data k meetings]
>>  (cond
>>   (nil? (data k)) (assoc data k {:title "title" :meetings meetings})
>>   :else (update-in data [k :meetings] concat meetings)))
>>
>> On Sep 16, 8:53 am, Laurent PETIT  wrote:
>> > 2010/9/16 Meikel Brandmeyer 
>> >
>> > > Hi Laurent,
>> >
>> > > On 16 Sep., 15:54, Laurent PETIT  wrote:
>> >
>> > > > you don't like my one-liner ? :-)
>> >
>> > > I saw your message only after I sent mine. :)
>> >
>> > > > (update-in coll [k] (fnil update-in *default-value*) [:meetings]
>> (comp
>> > > vec
>> > > > concat) data)
>> >
>> > > Hmm... (comp vec concat) == into?
>> >
>> > Yep.
>> > so this is the killer one : :-)
>> >
>> > (update-in coll [k] (fnil update-in *default-value*) [:meetings] into
>> data)
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>

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

Re: thinking in clojure

2010-09-16 Thread Laurent PETIT
So nested calls to update-in are needed in order to be able to provide a
specific default value, everytime just having an empty map created isn't
sufficient.

So instead of (update-in {} [:a :b] identity) which returns {:a {:b nil}} ,
you can break the key path at :a so that the default value if no :a is
specified by (fnil XXX default-value). And by specifying that XXX is
update-in, you can continue your "key path" where you stopped (after :a),
either using the found value at :a, either the provided default value :

(update-in {} [:a] (fnil update-in {:label "great label"}) [:b] identity)
=> {:a {:b nil, :label "great label"}}

or you can also decide that it's not a map which should be the default
value, imagine you want to modify a path [:a 2] :

(update-in {} [:a] (fnil update-in [:foo :bar :baz]) [2] str) => {:a [:foo
:bar ":baz"]}

2010/9/16 Btsai 

> My poor brain can't handle nested calls to update-in, so this is what
> I came up with:
>
> (defn add-meetings [data k meetings]
>  (cond
>   (nil? (data k)) (assoc data k {:title "title" :meetings meetings})
>   :else (update-in data [k :meetings] concat meetings)))
>
> On Sep 16, 8:53 am, Laurent PETIT  wrote:
> > 2010/9/16 Meikel Brandmeyer 
> >
> > > Hi Laurent,
> >
> > > On 16 Sep., 15:54, Laurent PETIT  wrote:
> >
> > > > you don't like my one-liner ? :-)
> >
> > > I saw your message only after I sent mine. :)
> >
> > > > (update-in coll [k] (fnil update-in *default-value*) [:meetings]
> (comp
> > > vec
> > > > concat) data)
> >
> > > Hmm... (comp vec concat) == into?
> >
> > Yep.
> > so this is the killer one : :-)
> >
> > (update-in coll [k] (fnil update-in *default-value*) [:meetings] into
> data)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

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

Re: missing queue function in core?

2010-09-16 Thread nickikt
I thought it was odd too so I think something that makes this easier
would be good.

On Sep 15, 9:00 pm, grignaak  wrote:
> Does it seem odd to anyone else that this function is missing in core?
> I propose it gets added.
>
> (defn queue
>  ([] clojure.lang.PersistentQueue/EMPTY )
>  ([x] (conj (queue) x))
>  ([x y] (conj (queue x) y))
>  ([x y & more] (into (queue x y) more)))
>
> Also, to get a good string representation in the repl, you have to
> call seq on the queue. This should probably be fixed as well
>
> --grignaak

-- 
You 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-16 Thread Btsai
My poor brain can't handle nested calls to update-in, so this is what
I came up with:

(defn add-meetings [data k meetings]
  (cond
   (nil? (data k)) (assoc data k {:title "title" :meetings meetings})
   :else (update-in data [k :meetings] concat meetings)))

On Sep 16, 8:53 am, Laurent PETIT  wrote:
> 2010/9/16 Meikel Brandmeyer 
>
> > Hi Laurent,
>
> > On 16 Sep., 15:54, Laurent PETIT  wrote:
>
> > > you don't like my one-liner ? :-)
>
> > I saw your message only after I sent mine. :)
>
> > > (update-in coll [k] (fnil update-in *default-value*) [:meetings] (comp
> > vec
> > > concat) data)
>
> > Hmm... (comp vec concat) == into?
>
> Yep.
> so this is the killer one : :-)
>
> (update-in coll [k] (fnil update-in *default-value*) [:meetings] into data)

-- 
You 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: Talk at QCon SP

2010-09-16 Thread Vivek Khurana


On Sep 14, 3:49 am, Pedro Teixeira  wrote:
> Last night, I had the chance to talk about some of the technologies
> I've put together in a recent project.
> In particular, it's about mixing clojure + cqrs + event sourcing +
> cep.
>
> I made slides available athttp://tinyurl.com/pedroqcon-- and I'll
> soon publish a sample demo on github.

Is the video of your presentation available ?

regards
Vivek

-- 
You 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: missing queue function in core?

2010-09-16 Thread Sean Devlin
+1

On Sep 15, 3:00 pm, grignaak  wrote:
> Does it seem odd to anyone else that this function is missing in core?
> I propose it gets added.
>
> (defn queue
>  ([] clojure.lang.PersistentQueue/EMPTY )
>  ([x] (conj (queue) x))
>  ([x y] (conj (queue x) y))
>  ([x y & more] (into (queue x y) more)))
>
> Also, to get a good string representation in the repl, you have to
> call seq on the queue. This should probably be fixed as well
>
> --grignaak

-- 
You 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-16 Thread Laurent PETIT
2010/9/16 Meikel Brandmeyer 

> Hi Laurent,
>
> On 16 Sep., 15:54, Laurent PETIT  wrote:
>
> > you don't like my one-liner ? :-)
>
> I saw your message only after I sent mine. :)
>
> > (update-in coll [k] (fnil update-in *default-value*) [:meetings] (comp
> vec
> > concat) data)
>
> Hmm... (comp vec concat) == into?
>

Yep.
so this is the killer one : :-)

(update-in coll [k] (fnil update-in *default-value*) [:meetings] into data)

-- 
You 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-16 Thread Meikel Brandmeyer
Hi Laurent,

On 16 Sep., 15:54, Laurent PETIT  wrote:

> you don't like my one-liner ? :-)

I saw your message only after I sent mine. :)

> (update-in coll [k] (fnil update-in *default-value*) [:meetings] (comp vec
> concat) data)

Hmm... (comp vec concat) == into?

Meikel

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


Re: partition-starting-every : yet another partition function

2010-09-16 Thread Nicolas Oury
I think that unfold (or co-reduce, or generate) should find its way in contrib.

I am not sure we need finished arg though. The traditional finish in
the seq family is nil.

My own version of unfold:

(defn unfold
  "(unfold seed grow) use the seed and a function grow that returns an
element and another seed
   to creates a lazy seq.
   The seq is stopped the grow function returns nil."
  [seed grow]
  (if-let [[elt next-seed] (grow seed)]
(cons elt
  (lazy-seq (unfold next-seed grow)))
()))

Whether the cons is in or outside the lazy-seq is debatable. (I like
to think of seq as the fixpoint of the functor (X -> Cons Object (lazy
X)))

Best,

Nicolas.

-- 
You 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: Feature idea: meta-macros

2010-09-16 Thread Nicolas Oury
The logged function would have to be already a generic method, no?

On Wed, Sep 15, 2010 at 7:50 PM, Matt Fowles  wrote:
> All~
> My clojure is fairly weak, but the particular example given would be
> accomplished in common lisp using generic methods and the
>  :around modifier...
> http://www.aiai.ed.ac.uk/~jeff/clos-guide.html
> Matt
>
> On Wed, Sep 15, 2010 at 2:26 PM, Alan  wrote:
>>
>> My guess is no. It would remove a huge benefit of Clojure, which is
>> that you can tell, without having to look over the whole codebase,
>> exactly what a given form does. (my-thing 20 [x y]) invokes my-thing,
>> a function or macro, with 20 as its first argument, and then a vector
>> of locals. No need to hunt down x and y, they're in the lexical scope;
>> no need to guess at the syntax for my-thing. If you can have magical
>> functions that transparently adjust forms all over the codebase, it
>> becomes extremely difficult to be sure of what some code is doing,
>> even without "abuse".
>>
>> Also, metamacros would be very hard to write *right*. Two of them
>> might compete over a chunk of code, accidentally falling into infinite
>> co-recursion. Layering them would be very tricky, too: do you apply
>> them before or after regular macros? If you try to do both you may end
>> up compiling forever, alternating between different types of macro
>> expansions. But suppose you want to write your logging function to
>> modify all function definitions, and someone has written this code:
>> (def call-listish (fn [fn elem] (fn [elem] 10)))
>>
>> How on earth will you know that the first instance of (fn [x] y) is a
>> function declaration, and the second isn't?
>>
>> On Sep 15, 11:03 am, Luke VanderHart 
>> wrote:
>> > Any thoughts? I grant you, the potential for abuse is huge. Would the
>> > benefits outweigh it?
>> >
>> > Thanks,
>> > -Luke V.
>>
>> --
>> You 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



-- 
Sent from an IBM Model M, 15 August 1989.

-- 
You 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: inline vs extended types

2010-09-16 Thread Meikel Brandmeyer
Hi,

On 15 Sep., 12:55, SIdhant Godiwala 
wrote:

> Is there any way to define the MultiMap protocol inline with the
> clashing methods?

How could there be one? The compiler cannot decide which method to
call. Although their name is the same the could have completely
different meaning for the different interfaces. Maybe you can go with
definterface and derive your IPersistentMultiMap from IPersistentMap
instead of using a protocol.

When you extend the protocol to the MultiMap type, then the MultiMap
does not implement the underlying interface and no clash happens.

Sincerely
Meikel

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


Re: ClassCastException: class to interface

2010-09-16 Thread Michael Wood
On 15 September 2010 05:31, JonnyB  wrote:
> Thank you very much, for your quick reply! At least, i can be sure
> now, that in principle it should be working.
>
> What i wanna do is wrap the jMonkeyEngine3.
> The hello world example (http://jmonkeyengine.org/wiki/doku.php/
> jme3:beginner:hello_simpleapplication)
> works fine (code below).
>
> But when i add the addControls function  (commented in code below)
> from the
> input example (http://jmonkeyengine.org/wiki/doku.php/
> jme3:beginner:hello_input_system).
> I get the following error:
>
>
> Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
> java.lang.ClassCastException: Cannot cast
> com.jme3.input.controls.KeyTrigger to
> [Lcom.jme3.input.controls.Trigger;

"[L..." is an array of ..., so it looks like you need to create a Java
array to give it.

-- 
Michael Wood 

-- 
You 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-16 Thread Laurent PETIT
Hi Meikel,

you don't like my one-liner ? :-)

(update-in coll [k] (fnil update-in *default-value*) [:meetings] (comp vec
concat) data)

2010/9/16 Meikel Brandmeyer 

> Hi,
>
> On 16 Sep., 15:36, Meikel Brandmeyer  wrote:
>
> > >   (if (not (nil? (next collection)
> >
> > You can save the nil?. (if (not (next collection))) will also work.
> > nil is logically false.
>
> And of course this should be (if (next collection)). The not belongs
> to the "You can save" part.
>
> Sincerely
> Meikel
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

-- 
You 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-16 Thread Meikel Brandmeyer
Hi,

On 16 Sep., 15:36, Meikel Brandmeyer  wrote:

> >   (if (not (nil? (next collection)
>
> You can save the nil?. (if (not (next collection))) will also work.
> nil is logically false.

And of course this should be (if (next collection)). The not belongs
to the "You can save" part.

Sincerely
Meikel

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


Re: thinking in clojure

2010-09-16 Thread Meikel Brandmeyer
Hi,

maybe this does what you want. I'm not sure, since you add the new
meeting to *all* meetings? And where does the :title come from when
you add a new meeting? I assume you have a map of a meeting title and
a meeting and want to add this to the corresponding entry in the data
map. If the meeting is not contained it will be added as n+1.

(defn insert-meeting-data
  [data {:keys [title meeting]}]
  (if-let [k (some #(when (= title (get-in data [% :title])) %) (keys
data))]
(update-in data [k :meetings] conj meeting)
(let [k (inc (apply max (keys data)))]
  (assoc data k {:title title :meetings [meeting]}

To be used eg. as:
(reduce insert-meeting-data data sequence-of-title-meeting-maps)

> Also, as a secondary concern, I read on here a while ago that when you
> find yourself typing "((" it's a sign of an issue - how, given the
> data structure I've to work with, woud you access the title of a value
> if not using that "((" syntax, i.e. ((data key) :title)?

(( is not necessarily a sign of an issue, but for your example you can
do (:title (data key)) or (get-in data [key :title]).

> (loop [data (sorted-map)
>  collection newData
>  meeting (first collection)]
>
>   (def key (  ))

Almost surely not what you want. You want a let, not a def. def is
always global and in 95% of the cases should only be used in global
context. Exceptions are for example closures.

(let [hidden-atom (atom nil)]
  (defn can-access-hidden-atom
[..]
))

>   (if (not (nil? (next collection)

You can save the nil?. (if (not (next collection))) will also work.
nil is logically false.

> (recur (cond (not (nil? (data key)))
>(true? true)

*ieeck* Please do (cond ... :else default-clause). Not true, or (true?
true) or other stuff.

-- 
You 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-16 Thread Laurent PETIT
Something along those lines :

(def t { 0 {:title "some" :meetings [ :d1 ]} 2 {:title "some2" :meetings [
:d2 ]}})

user=> (pprint (update-in t [1] (fnil update-in {:title "title" :meetings
[]}) [:meetings] (comp vec concat) [:d1 :d2]int (update-in t [1] (fnil
update-in {:title "title" :meetings []}) [:meetings] (comp vec concat) [:d1
:d2]))
{1 {:title "title", :meetings [:d1 :d2]},
 0 {:title "some", :meetings [:d1]},
 2 {:title "some2", :meetings [:d2]}}

and in a function:
(def *default-value* {:title "title" :meetings []})
(defn assoc-data
  "data is considered a seq of additional meeting objects to insert at the
end of the meetings of key k"
  [coll k data]
  (update-in coll [k] (fnil update-in *default-value*) [:meetings] (comp vec
concat) data))

Concise again, isn't it ? ;-)

HTH,

-- 
Laurent

2010/9/15 Michael Ossareh 

> Hi Guys,
>
> One of the things that has struck me about clojure, by virtue of being
> a lisp, is the concision of the code - I really find it very
> attractive. However yesterday I found something that I couldn't work
> out how to do in a concise manner. Clearly commenting the code was a
> priority once I got it working, however I'd like to ensure I'm doing
> this correctly.
>
> Much of my functional experience comes from JS and dealing with the
> immutability of our data structures is a very interesting learning
> process.
>
> I have a map (a sorted map) which maps an int to a map. The inner map
> contains a vector of data to which I want to conj elements into.
>
>
> { 0 {:title "some str"
>  :meetings [{ ... meeting data ... }
>  { ... meeting data ... }
>  { ... meeting data ...}]}
>
>  1 {:title "some other str"
>  :meetings [{ ... meeting data ... }
>  { ... meeting data ... }
>  { ... meeting data ...}]}
>
>  .
>
>  n {:title "some n str"
>  :meetings [{ ... meeting data ... }
>  { ... meeting data ... }
>  { ... meeting data ...}]}}
>
>
> In JS I'd have a loop which looks somewhat like this (assume the data
> above is called storedData and that newData has the data which I wish
> to insert into storedData);
>
> newData.forEach(function(data) {
>
>  var key =  ;
>
>  if (!storedData[key])
>storedData[key] = {title: "title"}, meetings:[]}
>
>  storedData[key].meetings.push(data) ;
>
> })
>
> In clj, I've ended up with something along the lines of the following
> (edited from what I have in my code base to match the JS example
> above):
>
> (loop [data (sorted-map)
> collection newData
> meeting (first collection)]
>
>  (def key (  ))
>
>  (if (not (nil? (next collection)
>
>(recur (cond (not (nil? (data key)))
>
>   (assoc data key
>  (assoc (data key)
>:meetings
>(conj ((data key) :meetings) meeting)))
>
>   (true? true)
> (conj data [key {:title "some str" :meetings [meeting]}])))
>
>   data))
>
>
> The middle section, with the assoc(es) and conj, just doesn't read as
> nicely as the rest of my clojure. Is this a symptom of my data
> structure or is there a more concise way to conj my data into these
> inner vectors?
>
> Also, as a secondary concern, I read on here a while ago that when you
> find yourself typing "((" it's a sign of an issue - how, given the
> data structure I've to work with, woud you access the title of a value
> if not using that "((" syntax, i.e. ((data key) :title)?
>
> Cheers,
>
> mike
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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

Re: thinking in clojure

2010-09-16 Thread Mike Meyer
On Wed, 15 Sep 2010 11:48:09 -0700
Michael Ossareh  wrote:

> Hi Guys,
> 
> One of the things that has struck me about clojure, by virtue of being
> a lisp, is the concision of the code - I really find it very
> attractive. However yesterday I found something that I couldn't work
> out how to do in a concise manner. Clearly commenting the code was a
> priority once I got it working, however I'd like to ensure I'm doing
> this correctly.
> 
> Much of my functional experience comes from JS and dealing with the
> immutability of our data structures is a very interesting learning
> process.
> 
> I have a map (a sorted map) which maps an int to a map. The inner map
> contains a vector of data to which I want to conj elements into.
> 
> 
> { 0 {:title "some str"
>   :meetings [{ ... meeting data ... }
>   { ... meeting data ... }
>   { ... meeting data ...}]}
> 
>  1 {:title "some other str"
>   :meetings [{ ... meeting data ... }
>   { ... meeting data ... }
>   { ... meeting data ...}]}
> 
>  .
> 
>  n {:title "some n str"
>   :meetings [{ ... meeting data ... }
>   { ... meeting data ... }
>   { ... meeting data ...}]}}
> 
> 
> In JS I'd have a loop which looks somewhat like this (assume the data
> above is called storedData and that newData has the data which I wish
> to insert into storedData);
> 
> newData.forEach(function(data) {
> 
>   var key =  ;
> 
>   if (!storedData[key])
> storedData[key] = {title: "title"}, meetings:[]}
> 
>   storedData[key].meetings.push(data) ;
> 
> })
> 
> In clj, I've ended up with something along the lines of the following
> (edited from what I have in my code base to match the JS example
> above):
> 
> (loop [data (sorted-map)
>  collection newData
>  meeting (first collection)]
> 
>   (def key (  ))

As a general rule, def should only be used at the top level. You
probably want (let [key ...] (if ...) here.

>   (if (not (nil? (next collection)

Minor nit: (not (nil? X)) is better spelled (seq? X))
And you seem to be missing a close paren or two here.

> (recur (cond (not (nil? (data key)))
> 
>(assoc data key
>   (assoc (data key)
> :meetings
> (conj ((data key) :meetings) meeting)))
> 
>(true? true)
>  (conj data [key {:title "some str" :meetings [meeting]}])))
> 
>data))
> 
> 
> The middle section, with the assoc(es) and conj, just doesn't read as
> nicely as the rest of my clojure. Is this a symptom of my data
> structure or is there a more concise way to conj my data into these
> inner vectors?

That's actually a standard idiom, except you missed the assoc-in and
get-in functions:

(assoc-in data key :meetings (conj (get-in data key :meetings) meeting)

Should do what you want.

> Also, as a secondary concern, I read on here a while ago that when you
> find yourself typing "((" it's a sign of an issue - how, given the
> data structure I've to work with, woud you access the title of a value
> if not using that "((" syntax, i.e. ((data key) :title)?

I'm not sure where that came from, bug get-in and assoc-in solve that
as well.

http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: thinking in clojure

2010-09-16 Thread David Nolen
On Wed, Sep 15, 2010 at 2:48 PM, Michael Ossareh  wrote:

> Hi Guys,
>
> One of the things that has struck me about clojure, by virtue of being
> a lisp, is the concision of the code - I really find it very
> attractive. However yesterday I found something that I couldn't work
> out how to do in a concise manner. Clearly commenting the code was a
> priority once I got it working, however I'd like to ensure I'm doing
> this correctly.
>
> Much of my functional experience comes from JS and dealing with the
> immutability of our data structures is a very interesting learning
> process.


You should look at update-in, assoc-in. Then you could write something like
this (not tested):

(defn add-meeting [xs key meeting]
 (for [x xs]
   (update-in x [key :meetings] conj meeting)))

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

missing queue function in core?

2010-09-16 Thread grignaak
Does it seem odd to anyone else that this function is missing in core?
I propose it gets added.

(defn queue
 ([] clojure.lang.PersistentQueue/EMPTY )
 ([x] (conj (queue) x))
 ([x y] (conj (queue x) y))
 ([x y & more] (into (queue x y) more)))

Also, to get a good string representation in the repl, you have to
call seq on the queue. This should probably be fixed as well

--grignaak

-- 
You 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: Feature idea: meta-macros

2010-09-16 Thread Matt Fowles
All~

My clojure is fairly weak, but the particular example given would be
accomplished in common lisp using generic methods and the  :around
 modifier...

http://www.aiai.ed.ac.uk/~jeff/clos-guide.html

Matt

On Wed, Sep 15, 2010 at 2:26 PM, Alan  wrote:

> My guess is no. It would remove a huge benefit of Clojure, which is
> that you can tell, without having to look over the whole codebase,
> exactly what a given form does. (my-thing 20 [x y]) invokes my-thing,
> a function or macro, with 20 as its first argument, and then a vector
> of locals. No need to hunt down x and y, they're in the lexical scope;
> no need to guess at the syntax for my-thing. If you can have magical
> functions that transparently adjust forms all over the codebase, it
> becomes extremely difficult to be sure of what some code is doing,
> even without "abuse".
>
> Also, metamacros would be very hard to write *right*. Two of them
> might compete over a chunk of code, accidentally falling into infinite
> co-recursion. Layering them would be very tricky, too: do you apply
> them before or after regular macros? If you try to do both you may end
> up compiling forever, alternating between different types of macro
> expansions. But suppose you want to write your logging function to
> modify all function definitions, and someone has written this code:
> (def call-listish (fn [fn elem] (fn [elem] 10)))
>
> How on earth will you know that the first instance of (fn [x] y) is a
> function declaration, and the second isn't?
>
> On Sep 15, 11:03 am, Luke VanderHart 
> wrote:
> > Any thoughts? I grant you, the potential for abuse is huge. Would the
> > benefits outweigh it?
> >
> > Thanks,
> > -Luke V.
>
> --
> You 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

thinking in clojure

2010-09-16 Thread Michael Ossareh
Hi Guys,

One of the things that has struck me about clojure, by virtue of being
a lisp, is the concision of the code - I really find it very
attractive. However yesterday I found something that I couldn't work
out how to do in a concise manner. Clearly commenting the code was a
priority once I got it working, however I'd like to ensure I'm doing
this correctly.

Much of my functional experience comes from JS and dealing with the
immutability of our data structures is a very interesting learning
process.

I have a map (a sorted map) which maps an int to a map. The inner map
contains a vector of data to which I want to conj elements into.


{ 0 {:title "some str"
  :meetings [{ ... meeting data ... }
  { ... meeting data ... }
  { ... meeting data ...}]}

 1 {:title "some other str"
  :meetings [{ ... meeting data ... }
  { ... meeting data ... }
  { ... meeting data ...}]}

 .

 n {:title "some n str"
  :meetings [{ ... meeting data ... }
  { ... meeting data ... }
  { ... meeting data ...}]}}


In JS I'd have a loop which looks somewhat like this (assume the data
above is called storedData and that newData has the data which I wish
to insert into storedData);

newData.forEach(function(data) {

  var key =  ;

  if (!storedData[key])
storedData[key] = {title: "title"}, meetings:[]}

  storedData[key].meetings.push(data) ;

})

In clj, I've ended up with something along the lines of the following
(edited from what I have in my code base to match the JS example
above):

(loop [data (sorted-map)
 collection newData
 meeting (first collection)]

  (def key (  ))

  (if (not (nil? (next collection)

(recur (cond (not (nil? (data key)))

   (assoc data key
  (assoc (data key)
:meetings
(conj ((data key) :meetings) meeting)))

   (true? true)
 (conj data [key {:title "some str" :meetings [meeting]}])))

   data))


The middle section, with the assoc(es) and conj, just doesn't read as
nicely as the rest of my clojure. Is this a symptom of my data
structure or is there a more concise way to conj my data into these
inner vectors?

Also, as a secondary concern, I read on here a while ago that when you
find yourself typing "((" it's a sign of an issue - how, given the
data structure I've to work with, woud you access the title of a value
if not using that "((" syntax, i.e. ((data key) :title)?

Cheers,

mike

-- 
You 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 Gijs S.
This answers neither question 1 nor 2, but there is a function from
the map, filter and reduce family of higher order functions that is
applicable to this problem. The function is called unfold and is the
opposite of reduce (see http://en.wikipedia.org/wiki/Anamorphism).

"An unfold builds a (potentially infinite) list from a seed value.
Typically, the unfold takes a seed value x, a one-place operation
unspool that yields a pairs of such items, and a predicate finished
which determines when to finish the list (if ever)."

I could not find unfold or an equivalent function in clojure or
clojure.contrib, so here it is:

(defn unfold [unspool finished x]
  (lazy-seq
(when-not (finished x)
  (let [[a y] (unspool x)]
(cons a (unfold unspool finished y))

;; the example from the wikipedia page:
(defn iterate-unfold [f x]
  (unfold (fn [a] [a (f a)]) (fn [_] false) x))

=> (take 10 (iterate-unfold inc 0))
(0 1 2 3 4 5 6 7 8 9)

The idea is to pass an unspool function that splits a collection at
every occurrence of an item for which (pred item) is true. The unspool
function in partition-starting-every produces a vector of the
partition "cut off" of the collection and the rest of the collection
to be processed.

(defn partition-starting-every [f coll]
  (unfold (fn [[head & tail]]
(let [[run more] (split-with (complement f) tail)]
  [(cons head run) more])) empty? coll))

=> (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))

The reason that I suggest the unfold function is because it can also
be used for other partitioning functions:

(defn partition-all-unfold [n step coll]
(unfold (fn [c]
  [(take n c) (drop step c)]) empty? coll))

=> (partition-all 3 2 (range 0 10))
((0 1 2) (2 3 4) (4 5 6) (6 7 8) (8 9))
=> (partition-all-unfold 3 2 (range 0 10))
((0 1 2) (2 3 4) (4 5 6) (6 7 8) (8 9))

Hope this helps,
-Gijs

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


inline vs extended types

2010-09-16 Thread SIdhant Godiwala

Hey guys,

I'm having some issues with defining types using deftype and would 
really appreciate some help.


Inspired by Mark Engelberg's PersistentPriorityMap 
http://github.com/clojure/clojure-contrib/blob/master/modules/priority-map/src/main/clojure/clojure/contrib/priority_map.clj, 
I decided to try out types and protocols with a MultiMap implementation


A MultiMap is just a map with more than one value associated with a key 
and I created a new type (PersistentMultiMap) and a new Protocol 
(MultiMap) with the following methods


(defprotocol MultiMap
  (seq-pairs [this])
  (assoc-swap [this key coll])
  (conj-swap [this key-coll])
  (dissoc-one [this key val]))

The problem is that the MultiMap protocol alone makes no semantic sense 
without functions like assoc and dissoc, so updating MultiMap


(defprotocol MultiMap
  (count [this])
  (assoc [this key val])
  (empty [this])
  (cons [this e])
  (equiv [this o])
  (containsKey [this key])
  (entryAt [this key])
  (seq [this])
  (without [this key])
  (seq-pairs [this])
  (conj-swap [this key-coll] [this key-coll & key-colls])
  (assoc-swap [this key coll] [this key coll & key-colls])
  (dissoc-one [this key val] [this key val & kvs]))

Great, now for the implementation.

My first attempt was a deftype (like the PersistentPriorityMap). The 
problem was that since PersistentMultiMap also implemented 
clojure.lang.IPersistentMap the methods clashed and the code would not 
compile. #gist http://gist.github.com/580454#file_gistfile1.clj


After implementing MultiMap with extend-type, the code compiled and 
everything worked fine #gist 
http://gist.github.com/580454#file_gistfile2.clj


I removed the clashing methods and redefined it inline and then the 
compilation went without a hitch #gist 
http://gist.github.com/580454#file_gistfile3.clj


Is there any way to define the MultiMap protocol inline with the 
clashing methods?


--
You 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: ClassCastException: class to interface

2010-09-16 Thread JonnyB
Thank you very much, for your quick reply! At least, i can be sure
now, that in principle it should be working.

What i wanna do is wrap the jMonkeyEngine3.
The hello world example (http://jmonkeyengine.org/wiki/doku.php/
jme3:beginner:hello_simpleapplication)
works fine (code below).

But when i add the addControls function  (commented in code below)
from the
input example (http://jmonkeyengine.org/wiki/doku.php/
jme3:beginner:hello_input_system).
I get the following error:


Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.ClassCastException: Cannot cast
com.jme3.input.controls.KeyTrigger to
[Lcom.jme3.input.controls.Trigger;
at java.lang.Class.cast(Class.java:3007)
at clojure.lang.Reflector.boxArg(Reflector.java:364)
at clojure.lang.Reflector.boxArgs(Reflector.java:397)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:55)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
at hello$hello_jme3$fn__1654.invoke(NO_SOURCE_FILE:1)
at hello.proxy$com.jme3.app.SimpleApplication$0.simpleInitApp(Unknown
Source)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:
158)
at hello.proxy$com.jme3.app.SimpleApplication$0.initialize(Unknown
Source)
at
com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:
102)
at
com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:
147)
at java.lang.Thread.run(Thread.java:636)

;;; 
j
(add-classpath "your-path-to-jme/jMonkeyEngine3.jar")

(ns hello
  (:import com.jme3.app.SimpleApplication
   com.jme3.material.Material
   com.jme3.math.Vector3f
   com.jme3.scene.Geometry
   com.jme3.scene.shape.Box
   com.jme3.math.ColorRGBA
   com.jme3.material.MaterialDef

   [com.jme3.input
KeyInput
InputManager]

   [com.jme3.input.controls
Trigger
KeyTrigger]))

(defn hello-jme3 []
  (let [b (Box. Vector3f/ZERO 1 1 1)
geom  (Geometry. "Box" b)]
(proxy [SimpleApplication] []
  (simpleInitApp []
 (let [rn (proxy-super getRootNode)
am (proxy-super getAssetManager )
m   "Common/MatDefs/Misc/SolidColor.j3md"
   mat (Material. am m)]

   (let [im (proxy-super getInputManager)]
;Here's the error:
;  (.addMapping im "Pause" (KeyTrigger. KeyInput/KEY_0))
 )

(.setColor mat "m_Color" ColorRGBA/Blue)
(.setMaterial geom mat)
(.attachChild rn  geom))

(.start (hello-jme3))
;;;


Any hints where to start searching the error?

Thank you!
JonnyB


-- 
You 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 doesn't a function have a type ?

2010-09-16 Thread Thierry Pirot
Belun writes:
> why isn't the type of a function : clojure.lang.IFn ?
> it's this instead :
> user=> (type #(str "wonder" "what" "this" "is"))
> user$eval7$fn__8

user> (class #(str "wonder" "what" "this" "is"))
user$eval3515$fn__3516
user> (pprint1 (ancestors *1))
#{clojure.lang.Fn
  clojure.lang.IMeta
  java.lang.Runnable
  java.lang.Object
  clojure.lang.IObj
  clojure.lang.IFn
  java.util.concurrent.Callable
  clojure.lang.AFn
  clojure.lang.AFunction
  java.io.Serializable
  java.util.Comparator}
nil

> would love if you would [...]
>
Sorry, no love tonite.  
-- 
   Take it Easy  Don't HurryBe Happy

   Thierry

°°şo§oş°°şo§oş°°şo§oş°°şo§oş°°şo§oş°°

-- 
You 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: logging

2010-09-16 Thread lprefontaine
We use common logging with a thin Clojure layer around it. It allows us to
have different behaviors in dev pre-prod and production. We avoid the hassle
of configuring log4j in dev.
The default implementation (simple logging) is more than enough most of the
time.

In prod, we specify the log4j configuration on the java command line
and we then get rolling appenders, etc... which are essential features given
the nature of our application.

Luc P.


ataggart  wrote ..
> We are speaking of two different things.
> 
> SLF4J is a facade, like commons-logging (and to some extent
> c.c.logging). Their intent is to allow *libraries* to make logging
> calls, but leave the actual logging implementation up to the runtime
> application.  This in principle allows multiple libraries' log
> messages to get routed using whatever implementation the ultimate
> application wishes.  If you're the only one that's ever going to run
> your code, then writing java calls directly to log4j is fine, though
> doing that in clojure is a bit of a hassle, hence c.c.logging
> benefitting from delayed evaluation, etc.
> 
> My earlier comment about log4j was in terms of what actually gets
> configured to do the work of logging messages.
> 
> 
> 
> On Sep 15, 5:10 pm, Daniel Simms  wrote:
> > On Wed, Sep 15, 2010 at 12:23 PM, ataggart  wrote:
> > > If you really need logging, then log4j is probably your best bet
> > > anyway.
> >
> > Or SLF4J, which seems to be the way many (most?) java libraries depend
> > on a some logging library.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first
> post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


Re: simplest graphics?

2010-09-16 Thread Christophe Grand
Hi Lee,

On Thu, Sep 16, 2010 at 5:15 AM, Lee Spector  wrote:

> Also, this would have a smaller impact but I'm curious about it: is there a
> way to treat method names as data and then make calls to them, as one can
> with clojure functions? Then I could pass things like fillRect, or map rect
> to fillRect, etc. This would make things slightly simpler here but be handy
> in other cases... but I don't see how to do it.
>

There's memfn but its usage is discouraged as one should favor #() but in
this case #(.fillRect %1 %2 %3 %4 %5) looks ugly. A macro can ease the pain
though.

About your code, it's nitpicking but you should use keywords instead of
quoted symbols.
You could also define render-shape to be backed by a multi-method to be able
to add new custom shapes but it won't minimize the tool.

hth,

Christophe

-- 
You 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: simplest graphics?

2010-09-16 Thread Michael Gardner
On Sep 15, 2010, at 10:15 PM, Lee Spector wrote:

> Also, this would have a smaller impact but I'm curious about it: is there a 
> way to treat method names as data and then make calls to them, as one can 
> with clojure functions? Then I could pass things like fillRect, or map rect 
> to fillRect, etc. This would make things slightly simpler here but be handy 
> in other cases... but I don't see how to do it.

As you've discovered, Java method names are unfortunately not first-class 
functions in Clojure. You have to wrap them with memfn or a lambda like 
#(.fillRect %).

-- 
You 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: Feature idea: meta-macros

2010-09-16 Thread Laurent PETIT
2010/9/16 Christophe Grand 

> Hi,
>
>
> On Wed, Sep 15, 2010 at 8:52 PM, Luke VanderHart <
> luke.vanderh...@gmail.com> wrote:
>
>> Oh, you're right, of course.
>>
>> Still, that doesn't quite meet the case I described, since the
>> bindings won't effect any spawned threads/agents.
>>
>
> (alter-var-root #'sql log-around) then


With the caveat that it will have no effect for vars which are directly
bound at compile time, though

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

Re: Feature idea: meta-macros

2010-09-16 Thread Christophe Grand
Hi,

On Wed, Sep 15, 2010 at 8:52 PM, Luke VanderHart
wrote:

> Oh, you're right, of course.
>
> Still, that doesn't quite meet the case I described, since the
> bindings won't effect any spawned threads/agents.
>

(alter-var-root #'sql log-around) then

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