Re: Insertion - The clojure way

2010-12-30 Thread Andreas Kostler
Hi All,
It is amazing what a discussion inserstion sort (still) can kick off :)
My intention was to play with algorithms in clojure and be made aware of the 
little
traps one has to look out for coming from scheme for instance. Therefore, 
translating the htdp version to clojure 
and playing with it a little more was the intention. 
I have one more question, though. My initial implementation looked like this:
> (defn insert-into [sorted-vec element]
>(loop [i (count sorted-vec)]
>(if (and (> i 0) (> (nth sorted-vec (dec i)) element))
>(recur (dec i))
>(into (conj (subvec sorted-vec 0 i) element) (subvec 
> sorted-vec i)


Now the discussion evolved around vectors not being suitable for this task. 
Can someone explain why this holds in this context? In my understanding
subvec is a constant time operation. So maybe vector is not that unsuitable
for this task after all?


On 30/12/2010, at 2:31 PM, Mark Engelberg wrote:

>> On Wed, Dec 29, 2010 at 8:13 PM, Mark Engelberg
>>> However, it should be pointed out that even this latest version
>>> doesn't share all the performance characteristics of the classic
>>> functional insertion sort given at the Htdp link.  Specifically, one
>>> of the (few) great things about insertion sort is that it is blazingly
>>> fast on input lists that are already sorted, or nearly sorted.  As a
>>> challenge (to you or Andreas, or anyone who is interested in this
>>> thread), figure out why the original insertion sort works so quickly
>>> on sorted lists, why the above code does not, and then try to
>>> duplicate that performance characteristic with an insertion sort
>>> algorithm in Clojure.
> 
> So here's the answer to the puzzle I posed earlier, for anyone who's
> still following along.  The reason the other implementation is fast on
> already sorted lists is because the insert function only needs to
> traverse as far as the insertion point, and then can share the
> structure of the remainder of the list.  This is handled transparently
> by the recursive process, with the stack accumulating the conses that
> need to be done.  To simulate this in Clojure, you need some way to
> manually accumulate the list of things you traversed on the way to the
> insertion point, and then non-lazily stick them on the front of the
> remainder of the list.
> 
> Here's one way to do that:
> ; (append l1 l2) is equivalent to a non-lazy (concat (reverse l1) l2)
> (defn append [l1 l2]
>  (loop [l1 (seq l1) result l2]
>(if l1
>  (recur (next l1) (cons (first l1) result))
>  result)))
> 
> (defn insert [n alon]
>  (loop [alon (seq alon), traversed nil]
>(cond
> (nil? alon) (append traversed (list n))
> (<= n (first alon)) (append traversed (cons n alon))
> (> n (first alon)) (recur (next alon) (conj traversed (first alon))
> 
> Then, do the actual insertion sort either using Ken's reduce technique
> (on the reverse of the list if stability is desired), or manually
> implementing the equivalent pattern:
> 
> (defn isort [alon]
>  (loop [alon (seq (reverse alon)), sorted nil]
>(if alon
>  (recur (next alon) (insert (first alon) sorted))
>  sorted)))
> 
> This is really fast on sorted lists and as fast as any of the other
> versions we've batted around on random data.  I believe this is the
> closest Clojurian equivalent to the Racket version.  Sadly, it loses
> much of its simplicity.  I have students write insertion sort in
> Racket after only a dozen or so lessons, but writing the equivalent in
> Clojure requires some significant machinations.  (If anyone sees a
> simpler way to accomplish the same thing in Clojure, please let me
> know!)
> 
> Still, I hope this helps explain how to transform stack-consuming
> patterns into Clojure's loop/recur construct.  It can be a bit of
> work, but it's necessary in Clojure to implement many functional
> algorithms.
> 
> -- 
> You 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

--
 “There is a strong correlation between being smart and being a nerd, and an 
even stronger inverse correlation between being a nerd and being popular”
(Paul Graham)
-- 
**
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772 Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

www.leica-geosystems.com*

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.





-- 
You received 

Re: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 12:51 AM, Andreas Kostler
 wrote:
> Now the discussion evolved around vectors not being suitable for this task.
> Can someone explain why this holds in this context? In my understanding
> subvec is a constant time operation. So maybe vector is not that unsuitable
> for this task after all?

I agree.  vector seems like a perfectly reasonable choice, especially
in light of the difficulties that sequences present in implementing
this algorithm.  Your implementation of insert-into looks okay to me.
I was mainly balking at your implementation of insertion-sort, which
still seems a bit strange to me, but you can probably mix something
like Ken's reduce technique with your vector-based insert-into with
good results.

So combining the two, you get something like:
(defn insert-into [sorted-vec element]
   (loop [i (count sorted-vec)]
   (if (and (> i 0) (> (nth sorted-vec (dec i)) element))
   (recur (dec i))
   (into (conj (subvec sorted-vec 0 i) element) (subvec
sorted-vec i)

(defn insertion-sort [s]
 (reduce insert-into [] s))

which is a perfectly reasonable implementation.  By my benchmarking,
it's slightly slower than my complicated sequence-based version, but
it's in the same ballpark.  It's easy to understand and furthermore,
it doesn't blow the stack and it's quick on already sorted lists.

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Wed, Dec 29, 2010 at 11:31 PM, David Nolen  wrote:
> The original algorithm is simply wrong for very large inputs, it cannot be
> TCO'ed. Pick a ridiculously large list size and the Scheme/Racket program
> will barf *immediately*.
> David

Have you tried it?  I tried this particular algorithm, in Racket, on
rather large lists.  It runs seemingly forever (it is a quadratic
algorithm, of course), but I was unable to make Racket "barf
immediately".  In my experience, Racket's more likely to fall over
from trying to create such a large input to begin with (simply because
there's not enough memory to hold a list that large) than it is to
barf from stack size while executing a non-TCO recursive function over
a list.  My understanding is that Racket's key to handling non-TCO
recursion so gracefully is that it traps errors from stack overflows,
and swaps the stack out to memory to make room on the stack to
continue.  So in essence, you get a stack that is bounded only by your
computer's memory (or whatever memory threshold you've enabled in the
settings).

What size input is barfing for you?

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Andreas Kostler
Oh, vectors are indeed bad since vector concatenation is a linear time 
operation. 
My apologies to Meikel, I simply missed your remark about finger trees. 
I guess a version that swaps the values "in place" would be the way to go. 
On 30/12/2010, at 7:34 PM, Mark Engelberg wrote:

> On Wed, Dec 29, 2010 at 11:31 PM, David Nolen  wrote:
>> The original algorithm is simply wrong for very large inputs, it cannot be
>> TCO'ed. Pick a ridiculously large list size and the Scheme/Racket program
>> will barf *immediately*.
>> David
> 
> Have you tried it?  I tried this particular algorithm, in Racket, on
> rather large lists.  It runs seemingly forever (it is a quadratic
> algorithm, of course), but I was unable to make Racket "barf
> immediately".  In my experience, Racket's more likely to fall over
> from trying to create such a large input to begin with (simply because
> there's not enough memory to hold a list that large) than it is to
> barf from stack size while executing a non-TCO recursive function over
> a list.  My understanding is that Racket's key to handling non-TCO
> recursion so gracefully is that it traps errors from stack overflows,
> and swaps the stack out to memory to make room on the stack to
> continue.  So in essence, you get a stack that is bounded only by your
> computer's memory (or whatever memory threshold you've enabled in the
> settings).
> 
> What size input is barfing for you?
> 
> -- 
> You 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

--
 “There is a strong correlation between being smart and being a nerd, and an 
even stronger inverse correlation between being a nerd and being popular”
(Paul Graham)
-- 
**
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772 Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

www.leica-geosystems.com*

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.





-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 3:24 AM, Andreas Kostler
 wrote:
> Oh, vectors are indeed bad since vector concatenation is a linear time 
> operation.
> My apologies to Meikel, I simply missed your remark about finger trees.
> I guess a version that swaps the values "in place" would be the way to go.

When you perform (into v1 v2), the length of the time it takes is
proportional to the length of v2.
This is similar to the amount of work done when doing a list insertion
(must rebuild the portion of the list up to the insertion point, but
not the entire list.

As for finger trees, I have not found them to be useful.  Although
they have good theoretical bounds, they are very slow in practice.
For example, if you try splitting, concatenating, and traversing lists
of, say, 10 elements, these operations on finger trees are still
many times slower than just using a naive take/drop/concat/seq on a
regular list.  How many millions of elements do you need to have for
the so-called "fast" finger tree operations to be worth the overhead?

I think it is highly unlikely that you will see any speed improvement
by converting insertion sort to finger trees, but feel free to try.

[Note: This is just based on my own personal benchmarking, and I would
love to be proven wrong about finger trees],

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Andreas Kostler

On 30/12/2010, at 8:40 PM, Mark Engelberg wrote:

> On Thu, Dec 30, 2010 at 3:24 AM, Andreas Kostler
>  wrote:
>> Oh, vectors are indeed bad since vector concatenation is a linear time 
>> operation.
>> My apologies to Meikel, I simply missed your remark about finger trees.
>> I guess a version that swaps the values "in place" would be the way to go.
> 
> When you perform (into v1 v2), the length of the time it takes is
> proportional to the length of v2.
> This is similar to the amount of work done when doing a list insertion
> (must rebuild the portion of the list up to the insertion point, but
> not the entire list.
Isn't that the problem though? This will make the best case inefficient since
the work performed by into is proportional to the length of v2 (or v1 if you 
swap them around).
Therefore, even thought the list is sorted you still need to traverse v2. A 
simple fix would be
checking (= i 0) but that's kinda ugly. 
> 
> As for finger trees, I have not found them to be useful.  Although
> they have good theoretical bounds, they are very slow in practice.
> For example, if you try splitting, concatenating, and traversing lists
> of, say, 10 elements, these operations on finger trees are still
> many times slower than just using a naive take/drop/concat/seq on a
> regular list.  How many millions of elements do you need to have for
> the so-called "fast" finger tree operations to be worth the overhead?
I have no experience with finger trees what so ever. I only understand Meikels 
comment now :)

> 
> I think it is highly unlikely that you will see any speed improvement
> by converting insertion sort to finger trees, but feel free to try.
> 
> [Note: This is just based on my own personal benchmarking, and I would
> love to be proven wrong about finger trees],
> 
> -- 
> You 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

--
 “There is a strong correlation between being smart and being a nerd, and an 
even stronger inverse correlation between being a nerd and being popular”
(Paul Graham)
-- 
**
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772 Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

www.leica-geosystems.com*

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.





-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Wed, Dec 29, 2010 at 9:31 PM, Mark Engelberg
 wrote:
> So here's the answer to the puzzle I posed earlier

I just realized that the "append" function in my code was unnecessary,
since into serves the same purpose.  Thus my solution could be
rewritten as:

(defn insert [n alon]
  (loop [alon (seq alon), traversed nil]
(cond
 (nil? alon) (into (list n) traversed)
 (<= n (first alon)) (into (cons n alon) traversed)
 (> n (first alon)) (recur (next alon) (conj traversed (first alon))

(defn isort [alon]
  (loop [alon (seq (reverse alon)), sorted nil]
(if alon
  (recur (next alon) (insert (first alon) sorted))
  sorted)))

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 3:49 AM, Andreas Kostler
 wrote:
> Isn't that the problem though? This will make the best case inefficient since
> the work performed by into is proportional to the length of v2 (or v1 if you 
> swap them around).
> Therefore, even thought the list is sorted you still need to traverse v2. A 
> simple fix would be
> checking (= i 0) but that's kinda ugly.

No, v2 in your algorithm is only the portion you've scanned over to
find the insertion (since you scan from the back).  Your algorithm is
fast for sorted lists, I checked.

I think the only way you can beat that (using insertion sort) is if
you have a data structure that allows for both a binary search to
quickly find the insertion point, and then allows for fast insertion
at that point.  So maybe if finger trees can give you both the fast
search and the fast insertion, that might pay off, but I still
speculate it's unlikely to be any faster.

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Andreas Kostler
On 30/12/2010, at 8:54 PM, Mark Engelberg wrote:

> On Thu, Dec 30, 2010 at 3:49 AM, Andreas Kostler
>  wrote:
>> Isn't that the problem though? This will make the best case inefficient since
>> the work performed by into is proportional to the length of v2 (or v1 if you 
>> swap them around).
>> Therefore, even thought the list is sorted you still need to traverse v2. A 
>> simple fix would be
>> checking (= i 0) but that's kinda ugly.
> 
> No, v2 in your algorithm is only the portion you've scanned over to
> find the insertion (since you scan from the back).  Your algorithm is
> fast for sorted lists, I checked.
Oh of course. I apologise. Mark do you mind to lay out how you perform your 
benchmarks.
On my system (insertion-sort (into [] (range 1))) runs for an unacceptable 
amount of time (talking ~10s)
That seems to be quite long for sorting an already sorted vector of 10k 
elements. 

> I think the only way you can beat that (using insertion sort) is if
> you have a data structure that allows for both a binary search to
> quickly find the insertion point, and then allows for fast insertion
> at that point.  So maybe if finger trees can give you both the fast
> search and the fast insertion, that might pay off, but I still
> speculate it's unlikely to be any faster.
With the initial implementation, using binary search to find the insertion 
point should still result in a speed up, right?
> 
> -- 
> You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 4:01 AM, Andreas Kostler
 wrote:
> Oh of course. I apologise. Mark do you mind to lay out how you perform your
> benchmarks.
> On my system (insertion-sort (into [] (range 1))) runs for an
> unacceptable amount of time (talking ~10s)
> That seems to be quite long for sorting an already sorted vector of 10k
> elements.

Maybe you're still using your original version with the good insert,
but the bad sort?
Try this:

(defn insert-into [sorted-vec element]
  (loop [i (count sorted-vec)]
  (if (and (> i 0) (> (nth sorted-vec (dec i)) element))
  (recur (dec i))
  (into (conj (subvec sorted-vec 0 i) element) (subvec
sorted-vec i)

(defn insertion-sort [s]
 (reduce insert-into [] s))

(time (last (insertion-sort (range 1

I get 30ms.

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 4:01 AM, Andreas Kostler
 wrote:
> With the initial implementation, using binary search to find the insertion
> point should still result in a speed up, right?

Sure, that should help, although it doesn't change the overall
quadratic bound unless you can also do the insertion in logarithmic
time.  It might be worth trying a binary search in your vector-based
insert, and see how much of a difference it makes.

-- 
You 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: From Binary Search Trees to the Dining Philosopher

2010-12-30 Thread Laurent PETIT
Gist updated to use watchers for table state reporting, instead of coupling
the reporting with the transaction.

Also, as cgrand pointed to me, note that this implementation using the STM
is somehow related to the "Monitor solution" described in :
http://en.wikipedia.org/wiki/Dining_philosophers_problem#Monitor_solution

https://gist.github.com/759364

Feedback appreciated,

-- 
Laurent

2010/12/30 Laurent PETIT 

> of course there's a little rampant bug, (take) should read (take (count
> phils) ..) not (take (* 3 (count phils)...), gist updated.
>
>
> 2010/12/30 Laurent PETIT 
>
>> And here's the gist, if it's more readable :
>> https://gist.github.com/759364
>>
>> 2010/12/30 Laurent PETIT 
>>
>> Here's my attempt at providing a simple solution to this problem:
>>>
>>> 18 lines of code, not too bad if it's not buggy ;-)
>>>
>>> ;;; Dining philosophers. Solution using Clojure STM.
>>> ;;; What are our identities?
>>> ;;;   The problem talks about forks, and philosophers.
>>> ;;;   Conceptually, forks have a "taken-by" property which can have one
>>> ;;; of three values: :left-philosopher, :righ-philosopher, :nobody.
>>> ;;;   Conceptually, philosophers have a "state" property which can be
>>> ;;; :eating or :thinking.
>>> ;;; Note that with an approach using STM for getting both forks at once
>>> ;;;   atomically or none, and synchronizing the philosopher's value, we
>>> ;;;   will always have the "taken-by" property of the forks and the
>>> "state"
>>> ;;;   property of the philosopher synchronized.
>>> ;;; So we can altogether get rid of the fork concept, use refs for
>>> ;;;   representing philosophers, and allow the change of the state of a
>>> ;;;   philosopher to :eating by ensuring that his neighbours have the
>>> ;;;   :thinking value in the same transaction
>>> ;;; For simulating true concurrent independent philosophers, we will have
>>>
>>> ;;;   one thread per philosopher. Using "future" is just an easy trick
>>> for
>>> ;;;   starting a new thread, and we do not really want to use "future"
>>> beyond
>>> ;;;   its "will run the code in a separate thread" feature.
>>> ;;; Implementation notes:
>>> ;;;  * philosopher "behaviour" is basic : thinks for a while, tries to
>>> eat,
>>> ;;;thinks for a while, stops eating, thinks for a while, tries to
>>> eat,
>>> ;;;thinkgs for a while, etc.
>>> ;;;  * could be enhanced for graceful shutdown of the dinner, etc., but
>>> this
>>> ;;;would clutter with no real value to the essence of the solution
>>>
>>> (def phils (repeatedly 5 #(ref :thinking)))
>>>
>>> (defn snapshot [] (->> phils (map deref) doall dosync))
>>>
>>> (def printer (agent nil))
>>>
>>> (defn react [val neighbours-vals]
>>>   (cond
>>> (= :eating val) :thinking
>>> (some (partial = :eating) neighbours-vals) val
>>> :else :eating))
>>>
>>> (defn phil-fn [p neighbours]
>>>   (Thread/sleep (rand-int 100))
>>>   (dosync
>>> (let [old @p
>>>   new (alter p react (map deref neighbours))]
>>>   (when-not (= old new) (send printer (fn [_] (prn (snapshot
>>>
>>> (defn start-lunch []
>>>   (doseq [[left-phil phil right-phil] (take (* 3 (count phils))
>>> (partition 3 1 (cycle
>>> phils)))]
>>> (future (while true (phil-fn phil [left-phil right-phil])
>>>
>>> ;(start-lunch)
>>>
>>> 2010/12/29 Laurent PETIT 
>>>
>>> Hi Todd,

 2010/12/29 Todd 

 Thanks Ken, Mark, David and Alex for your comments regarding Binary
> Search trees. I've read that thread several times, and ordered Okasaki's
> Purely Functional Data Structures, too. I'll return to this a bit later.
>
> Meanwhile, I decided to tackle learning Clojure from a different
> angle...in this case, implementing a solution for the Dining Philosopher
> problem.
>
> I've posted my code here:
>
> https://gist.github.com/757925
>
> General comments/questions:
>
> 1. I suppose it's from years of OO programming, but it still feels so
> weird not to be creating objects and then hanging methods off those 
> objects.
> In fact, my first approach was to create protocols and records for each of
> the 'objects': chopsticks, philosophers, even the table. But this started 
> to
> get painful, so I shifted gears...
>
> 2. I'm using a number of symbols (:tablestate, :seats, :chopsticks,
> :servings, etc). Shouldn't these be defined somewhere? It feels like I'm
> driving w/o a seatbelt. I'm so used to encapsulating this sort of thing in
> an enum or something, and then relying on java typing to enforce the 
> allowed
> values.
>
> 3. Starting a thread with (future ... This couldn't be easier. Very
> cool.
>
> 4. I tried making the table an agent instead of a ref. Then I was
> sending methods to the table like, start-tableservice or
> stop-tabelservice... I'll investigate further, but is it idiomatic to 
> s

an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Sunil S Nandihalli
Hello everybody,
 An object of class created using defrecord does not implement IFn .. while
it behaves very similar to map otherwise .. Is this way by design? can it be
made to behave like a hash-map without any performance penalty in terms of
behaving like a function?

Thanks,
Sunil.

-- 
You 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: type hinting the arguments of a function ..

2010-12-30 Thread Sunil S Nandihalli
thanks David and Ben for you responses..
Sunil.

On Wed, Dec 29, 2010 at 9:47 PM, David Nolen  wrote:

> On Wed, Dec 29, 2010 at 10:48 AM, B Smith-Mannschott <
> bsmith.o...@gmail.com> wrote:
>
>> - (defn f [[^double x]] x)
>> The compiler (1.3) does not complain about this, though I can't say
>> what kind of code it generates. (I suspect it boxes x, but I don't
>> know.)
>> What did you mean by "You can't cast the contents of a sequence to a
>> primitive type"?
>>
>> // Ben
>
>
> Sorry what I meant was that you won't be taking advantage of 1.3.0's fn
> support for primitive arguments. That's a function that takes an object,
> destructures it and compiler hints a double.
>
> David
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread David Nolen
On Thu, Dec 30, 2010 at 5:34 AM, Mark Engelberg wrote:

> On Wed, Dec 29, 2010 at 11:31 PM, David Nolen 
> wrote:
> > The original algorithm is simply wrong for very large inputs, it cannot
> be
> > TCO'ed. Pick a ridiculously large list size and the Scheme/Racket program
> > will barf *immediately*.
> > David
>
> Have you tried it?  I tried this particular algorithm, in Racket, on
> rather large lists.  It runs seemingly forever (it is a quadratic
> algorithm, of course), but I was unable to make Racket "barf
> immediately".  In my experience, Racket's more likely to fall over
> from trying to create such a large input to begin with (simply because
> there's not enough memory to hold a list that large) than it is to
> barf from stack size while executing a non-TCO recursive function over
> a list.  My understanding is that Racket's key to handling non-TCO
> recursion so gracefully is that it traps errors from stack overflows,
> and swaps the stack out to memory to make room on the stack to
> continue.  So in essence, you get a stack that is bounded only by your
> computer's memory (or whatever memory threshold you've enabled in the
> settings).
>
> What size input is barfing for you?


2e6. Racket can easily create a list of that size. Calling sort on it
however fails fast.

David

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

Re: Insertion - The clojure way

2010-12-30 Thread Daniel Brotsky
@Mark: applause.  A nice pedagogical exercise, and your step-by-step
approach --- so reminiscent of HTDP --- was very effective.

Your final solution reminds me of an undergraduate data structures and
algorithms final I took (too) many years ago on which, after weeks of
doing recursive sorts and traversals, the professor asked us to walk a
tree with three pointer variables and a loop.  As an old (ancient,
really) lisp lover who's just discovered Clojure, this thread feels
like a great intro to what's the same and what's different.  Thanks!

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


Re: Argument is not an array, in a function inside deftype

2010-12-30 Thread Bob Shock
I don't get any errors when I run your code. This is the output:

1  1
1  1
1  1
1  1
1  1
1  1  1  1  1
1  1  1  1  1

Are you sure you are using the latest Clojure 1.2 version and not an
early beta, etc.?

Process finished with exit code 0

On Dec 29, 11:25 pm, Jarl Haggerty  wrote:
> What is wrong with my code(bottom of post)?  I keep getting this
> error.  Line 24 is "(get-cell [x r c] 1))" in the Matrix deftype and
> 36 is "(print (get-cell one r c) " "))" in the first nested "doseq"s.
> I'm on Windows 7 with Clojure 1.2.
>
> Exception in thread "main" java.lang.IllegalArgumentException:
> Argument is not an array (core.clj:0)
>         at clojure.lang.Compiler.eval(Compiler.java:5440)
>         at clojure.lang.Compiler.load(Compiler.java:5857)
>         at clojure.lang.Compiler.loadFile(Compiler.java:5820)
>         at clojure.main$load_script.invoke(main.clj:221)
>         at clojure.main$script_opt.invoke(main.clj:273)
>         at clojure.main$main.doInvoke(main.clj:354)
>         at clojure.lang.RestFn.invoke(RestFn.java:409)
>         at clojure.lang.Var.invoke(Var.java:365)
>         at clojure.lang.AFn.applyToHelper(AFn.java:163)
>         at clojure.lang.Var.applyTo(Var.java:482)
>         at clojure.main.main(main.java:37)
> Caused by: java.lang.IllegalArgumentException: Argument is not an
> array
>         at java.lang.reflect.Array.get(Native Method)
>         at clojure.core$aget.invoke(core.clj:2994)
>         at clojure.lang.AFn.applyToHelper(AFn.java:165)
>         at clojure.lang.RestFn.applyTo(RestFn.java:133)
>         at clojure.core$apply.invoke(core.clj:542)
>         at clojure.core$aget.doInvoke(core.clj:2996)
>         at clojure.lang.RestFn.invoke(RestFn.java:443)
>         at com.curious.scratch.core.Matrix2D.get_cell(core.clj:24)
>         at com.curious.scratch.core$eval122.invoke(core.clj:36)
>         at clojure.lang.Compiler.eval(Compiler.java:5424)
>         ... 10 more
>
> (def float-array-class (class (float-array 1)))
> (defprotocol Matrix
>   (matrix-data [x])
>   (matrix-height [x])
>   (matrix-width [x])
>   (matrix-add [x] [x y] [x y & args])
>   (get-cell [x r] [x r c]))
>
> (deftype Matrix2D [data height width]
>   Matrix
>   (matrix-data [x] data)
>   (matrix-height [x] height)
>   (matrix-width [x] width)
>   (matrix-add [x] x)
>   (matrix-add [x y]
>               (let [x-data (matrix-data x)
>                     y-data (matrix-data y)
>                     z-data (amap ^floats x-data index z-data (+ (aget
> ^floats x-data index) (aget ^floats y-data index)))]
>                 (Matrix2D. z-data (matrix-width x) (matrix-height
> x
>   (matrix-add [x y & args] (reduce matrix-add (matrix-add x y) args))
>   (get-cell [x r] (get-cell x r 0))
>   (get-cell [x r c] 1))
>
> (defn matrix [data height width]
>   (if (instance? float-array-class data)
>     (Matrix2D. data height width)
>     (Matrix2D. (float-array data) height width)))
>
> (def one (matrix (range 10) 5 2))
> (def two (matrix-add one one))
>
> (doseq [r (range (matrix-height one))]
>   (doseq [c (range (matrix-width one))]
>     (print (get-cell one r c) " "))
>   (println))
>
> (doseq [r (range (matrix-height two))]
>   (doseq [c (range (matrix-width two))]
>     (print (get-cell two r c) " "))
>   (println))

-- 
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Chas Emerick
Yes, that's intentional – implementing IFn is (as you can see) orthogonal to 
implementing IPersistentMap, IPersistentCollection, etc.

Of course, keyword access of record slots is most idiomatic, e.g. (:my-slot 
some-record)

If you'd like to pass around a function that accesses a record, there's always 
get, e.g. ((partial get some-record) :my-slot)

- Chas

On Dec 30, 2010, at 8:08 AM, Sunil S Nandihalli wrote:

> Hello everybody,
>  An object of class created using defrecord does not implement IFn .. while 
> it behaves very similar to map otherwise .. Is this way by design? can it be 
> made to behave like a hash-map without any performance penalty in terms of 
> behaving like a function?
> 
> Thanks,
> Sunil.

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


Trick to getting bindings in a repl

2010-12-30 Thread Mike
I'm doing something kind of tricky...I'm running a REPL in my Java
Swing application.  I do something like:

public class MyConsoleClass extends OurEmbeddedInterpreterClass {
  // ...

  // inner class
  private class ReplRunner extends Thread {
public void run() {
  Namespace MYNS = Namespace.findOrCreate(Symbol.create("myns"));
  Var ACCESS_ME =  Var.intern(MYNS, Symbol.create("*me*"));
  Var.pushThreadBindings(RT.map(RT.IN, myIn, RT.OUT, myOut,
RT.ERR, myErr, ACCESS_ME, MyConsoleClass.this);
  BufferedReader script = getMagicInitScript();
  Compiler.load(script, getScriptPath(), getScriptFile());
}
  }
  // ...somewhere, make a ReplRunner and launch it when you're
supposed to
}

The "magic init script" is what runs the repl.  The ins and outs are
mapped into Swing components so you can type commands, it passes to
the repl, and then output comes back to a text pane or the equivalent.

Now, my GUI app puts a KeyListener on the input component so that when
the TAB key is pressed, it runs a completion routine (Java callback)
to try to complete your command.  I wrote a function (in Clojure,
inside the magic init script) that returns all the completions based
on the current command.  My Java callback looks like:

// a method in MyConsoleClass...CodeCompletion is our own little
helper struct...
public List getCompletions(String cmd) {
  Var getFn = RT.var("myns", "get-completions");
  try {
List result = (List)
getFn.invoke(cmd);
return result;
  catch(Exception e) { /* handle e omitted */ }
  return null;
}

The problem is, get-completions uses dir-fn and ns-map to gather
bindings based on the context of the command.  But it's being invoked
in the AWT event thread (which calls this getCompletions method), NOT
the ReplRunner thread that I launch (which is of course just looping
infinitely waiting on input).  So all the local bindings (including
*me* that I bound in ReplRunner.run()) are missing from the results.

Does anybody have any ideas how I can jack into the repl thread to
grab the bindings from it?  I don't think any of Clojure's concurrency
constructs will help me here, because I need to interfere with a
thread that's essentially blocked at the time of the (synchronous)
completion call.

Sorry if this isn't fully specified and hurried...I can't paste the
code directly here because of NDA.  If you need more details I can
provide them.

Thanks in advance for any ideas...
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


Interesting challenge

2010-12-30 Thread David Nolen
>From the Qi mailing list:

http://groups.google.com/group/qilang/browse_thread/thread/e4a2f534fad5032a

"I contend that this kind of problem cannot be solved (efficiently) in any
pure functional programming language. You may disagree"

:D

David

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

Re: Interesting challenge

2010-12-30 Thread Mike Meyer
On Thu, 30 Dec 2010 12:03:14 -0500
David Nolen  wrote:

> From the Qi mailing list:
> 
> http://groups.google.com/group/qilang/browse_thread/thread/e4a2f534fad5032a
> 
> "I contend that this kind of problem cannot be solved (efficiently) in any
> pure functional programming language. You may disagree"

Do you know if his C++ version available for examination?

   thanks,
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: Argument is not an array, in a function inside deftype

2010-12-30 Thread Jarl Haggerty
I'm using the maven plugin so I think I'm using the lastest 1.2, and
I've tried every 1.3 version, but I just got a hold of my laptop, and
I am having no problems on there.

I was having several other problems too(I started another discussion
complaining about a whittled down version of this program that doesn't
work either), maybe when I get home I'll try a reboot.

On Dec 30, 8:33 am, Bob Shock  wrote:
> I don't get any errors when I run your code. This is the output:
>
> 1  1
> 1  1
> 1  1
> 1  1
> 1  1
> 1  1  1  1  1
> 1  1  1  1  1
>
> Are you sure you are using the latest Clojure 1.2 version and not an
> early beta, etc.?
>
> Process finished with exit code 0
>
> On Dec 29, 11:25 pm, Jarl Haggerty  wrote:
>
> > What is wrong with my code(bottom of post)?  I keep getting this
> > error.  Line 24 is "(get-cell [x r c] 1))" in the Matrix deftype and
> > 36 is "(print (get-cell one r c) " "))" in the first nested "doseq"s.
> > I'm on Windows 7 with Clojure 1.2.
>
> > Exception in thread "main" java.lang.IllegalArgumentException:
> > Argument is not an array (core.clj:0)
> >         at clojure.lang.Compiler.eval(Compiler.java:5440)
> >         at clojure.lang.Compiler.load(Compiler.java:5857)
> >         at clojure.lang.Compiler.loadFile(Compiler.java:5820)
> >         at clojure.main$load_script.invoke(main.clj:221)
> >         at clojure.main$script_opt.invoke(main.clj:273)
> >         at clojure.main$main.doInvoke(main.clj:354)
> >         at clojure.lang.RestFn.invoke(RestFn.java:409)
> >         at clojure.lang.Var.invoke(Var.java:365)
> >         at clojure.lang.AFn.applyToHelper(AFn.java:163)
> >         at clojure.lang.Var.applyTo(Var.java:482)
> >         at clojure.main.main(main.java:37)
> > Caused by: java.lang.IllegalArgumentException: Argument is not an
> > array
> >         at java.lang.reflect.Array.get(Native Method)
> >         at clojure.core$aget.invoke(core.clj:2994)
> >         at clojure.lang.AFn.applyToHelper(AFn.java:165)
> >         at clojure.lang.RestFn.applyTo(RestFn.java:133)
> >         at clojure.core$apply.invoke(core.clj:542)
> >         at clojure.core$aget.doInvoke(core.clj:2996)
> >         at clojure.lang.RestFn.invoke(RestFn.java:443)
> >         at com.curious.scratch.core.Matrix2D.get_cell(core.clj:24)
> >         at com.curious.scratch.core$eval122.invoke(core.clj:36)
> >         at clojure.lang.Compiler.eval(Compiler.java:5424)
> >         ... 10 more
>
> > (def float-array-class (class (float-array 1)))
> > (defprotocol Matrix
> >   (matrix-data [x])
> >   (matrix-height [x])
> >   (matrix-width [x])
> >   (matrix-add [x] [x y] [x y & args])
> >   (get-cell [x r] [x r c]))
>
> > (deftype Matrix2D [data height width]
> >   Matrix
> >   (matrix-data [x] data)
> >   (matrix-height [x] height)
> >   (matrix-width [x] width)
> >   (matrix-add [x] x)
> >   (matrix-add [x y]
> >               (let [x-data (matrix-data x)
> >                     y-data (matrix-data y)
> >                     z-data (amap ^floats x-data index z-data (+ (aget
> > ^floats x-data index) (aget ^floats y-data index)))]
> >                 (Matrix2D. z-data (matrix-width x) (matrix-height
> > x
> >   (matrix-add [x y & args] (reduce matrix-add (matrix-add x y) args))
> >   (get-cell [x r] (get-cell x r 0))
> >   (get-cell [x r c] 1))
>
> > (defn matrix [data height width]
> >   (if (instance? float-array-class data)
> >     (Matrix2D. data height width)
> >     (Matrix2D. (float-array data) height width)))
>
> > (def one (matrix (range 10) 5 2))
> > (def two (matrix-add one one))
>
> > (doseq [r (range (matrix-height one))]
> >   (doseq [c (range (matrix-width one))]
> >     (print (get-cell one r c) " "))
> >   (println))
>
> > (doseq [r (range (matrix-height two))]
> >   (doseq [c (range (matrix-width two))]
> >     (print (get-cell two r c) " "))
> >   (println))
>
>

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


Time/size bounded cache?

2010-12-30 Thread Miki
Hello,

I'm wring a service that polls RSS feeds (using feedme). And I'd like to act 
only on the new entries in each feed.
So far I have something like:

(defn get-new-entries [seen]
  (let [seen? (complement seen)]
(filter #(seen? (:id %)) (get-entries

(defn poll [sleep-time]
  (loop [seen #{}]
(let [entries (get-new-entries seen)]
  (doall (map process-entry entries))
  (println "")
  (Thread/sleep sleep-time)
  (recur (union seen (set (map :id entries)))

(Full demo code at https://gist.github.com/760094)

The problem is that "seen" will grow without bounds.
Is there a built in way to have some sort of LRU cache or should I use 
external libraries (like plru)?

Thanks,
--
Miki

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

Boston meetup Jan 11?

2010-12-30 Thread dysinger
10 of us from Sonian are going to converge on Boston the week of Jan
9.  It's always awesome to meet other Clojure hackers. I propose we
meet up somewhere central(ish) Jan 11 @ 7-9pm-ish.  We have room at
our company headquarters in Dedham but that might be a hike for some
people.  Any other places we could meet/greet & hack for an hour or
two central to Boston?

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Ken Wesson
On Thu, Dec 30, 2010 at 6:40 AM, Mark Engelberg
 wrote:
> As for finger trees, I have not found them to be useful.  Although
> they have good theoretical bounds, they are very slow in practice.
> For example, if you try splitting, concatenating, and traversing lists
> of, say, 10 elements, these operations on finger trees are still
> many times slower than just using a naive take/drop/concat/seq on a
> regular list.

I hope that didn't include a naive benchmarking of
take/drop/concat/seq. Because three of those are lazy, you need to
wrap the output of an algorithm using them in a (doall ...) and then
in your timing function to get an accurate read on the amount of time
it actually takes to perform the full algorithm.

-- 
You 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: Time/size bounded cache?

2010-12-30 Thread Chas Emerick
Java's LinkedHashMap provides the hook necessary to implement a simple LRU 
cache.  Here's some code where we use LHM in as an LRU cache, in service of 
providing a variation on the memoization concept:

https://gist.github.com/747395

Whether what's there is sufficient for your needs is another story. :-)

- Chas

On Dec 30, 2010, at 1:35 PM, Miki wrote:

> Hello,
> 
> I'm wring a service that polls RSS feeds (using feedme). And I'd like to act 
> only on the new entries in each feed.
> So far I have something like:
> 
> (defn get-new-entries [seen]
>   (let [seen? (complement seen)]
> (filter #(seen? (:id %)) (get-entries
> 
> (defn poll [sleep-time]
>   (loop [seen #{}]
> (let [entries (get-new-entries seen)]
>   (doall (map process-entry entries))
>   (println "")
>   (Thread/sleep sleep-time)
>   (recur (union seen (set (map :id entries)))
> 
> (Full demo code at https://gist.github.com/760094)
> 
> The problem is that "seen" will grow without bounds.
> Is there a built in way to have some sort of LRU cache or should I use 
> external libraries (like plru)?
> 
> Thanks,
> --
> Miki
> 
> -- 
> You 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: Time/size bounded cache?

2010-12-30 Thread Luke VanderHart
I've been working on a simple Clojure library for bounded caching and
memoization. It's not quite ready for prime-time, but the simple case
that you need is usable.

I'll throw it up on github when I get home tonight and post the URL
here.

On Dec 30, 1:35 pm, Miki  wrote:
> Hello,
>
> I'm wring a service that polls RSS feeds (using feedme). And I'd like to act
> only on the new entries in each feed.
> So far I have something like:
>
> (defn get-new-entries [seen]
>   (let [seen? (complement seen)]
>     (filter #(seen? (:id %)) (get-entries
>
> (defn poll [sleep-time]
>   (loop [seen #{}]
>     (let [entries (get-new-entries seen)]
>       (doall (map process-entry entries))
>       (println "")
>       (Thread/sleep sleep-time)
>       (recur (union seen (set (map :id entries)))
>
> (Full demo code athttps://gist.github.com/760094)
>
> The problem is that "seen" will grow without bounds.
> Is there a built in way to have some sort of LRU cache or should I use
> external libraries (like plru)?
>
> Thanks,
> --
> Miki

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 11:01 AM, Ken Wesson  wrote:
> I hope that didn't include a naive benchmarking of
> take/drop/concat/seq. Because three of those are lazy, you need to
> wrap the output of an algorithm using them in a (doall ...) and then
> in your timing function to get an accurate read on the amount of time
> it actually takes to perform the full algorithm.

Yes, I compared with doall.  Try it and let me know if you get
different results, but I find that traversing a finger tree is so much
slower than traversing a sequence, it all but nullifies any advantages
you get from other operations (even assuming the other operations are
way faster, which they typically are not).

-- 
You 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 can't see a method in my protocol

2010-12-30 Thread André Thieme

Am 30.12.2010 07:54, schrieb Jarl Haggerty:

This code,

(defprotocol Matrix
   (matrix-get [this c r]))

(deftype Matrix2D [data height width]
   Matrix
   (matrix-get [this r c] 1))

Gives me this error

Exception in thread "main" java.lang.IllegalArgumentException: Can't
define method not in interfaces: matrix_get (core.clj:6)
[…]

Simply changing the name of the function to get-cell removed this
problem, but I feel a need to know what is wrong with this.


Do you observe this in a fresh Clojure?
I ran into something similar, but with definterface.
I had a definterface form and later added new functions to it, which I
could not implement before restarting the JVM, as the interface has
already been created the way I specified it in the first place.

--
You 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: Compiling dynamically created namespaces, without on-disk source code?

2010-12-30 Thread Stuart Sierra
You might try `(binding [*compile-files* true] ...)` around whatever code 
creates the namespace. Can't promise that will work.

This still won't let you save definitions entered at the REPL.  Once they're 
compiled and loaded into the JVM, the bytecode is no longer accessible.

-Stuart Sierra
clojure.com

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

Re: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Stuart Sierra
You can make it implement IFn easily enough:

(defrecord Foo [a b c]
  clojure.lang.IFn
  (invoke [this key] (get this key)))

It has been debated whether or not this is a good idea, design-wise, but it 
should not be a performance penalty.


-Stuart Sierra
clojure.com

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

Re: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Alex Baranosky
I've been playing with making a macro to encapsulate Stuart's post, like
this:

(defmacro defrecord-ifn [name & args]
  `(defrecord ~name ~...@args
clojure.lang.IFn
(invoke [this key] (get this key

(defrecord-ifn Foo [a b c])

(def foo (Foo. "A" "B" "C"))

(prn (map foo [:a :c])) => ("A", "C")

I get the error:

"No such var: user/this".  I guess this is because it is expanding 'this' to
'user/this'.  What is the proper way to get a macro like this to expand
properly?

Alex

-- 
You 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: Boston meetup Jan 11?

2010-12-30 Thread Alyssa Kwan
Hi!

You would be more than welcome at the Boston Coding Dojo (http://
www.meetup.com/boston-coding-dojo/).  We meet every other Thursday at
First Church in Boston, in Boston's Back Bay on Marlborough St.  In
January, we are meeting on 1/6 and 1/20, so nothing on the week of
1/9, I'm afraid.  What kind of meeting do you have in mind?  I could
certainly recommend some restaurants that are more conducive to
conversation.  If you are looking for a space to hack, I can certainly
check with the church for availability; we meet in a lovely chapel
with plenty of room.  It would cost $75 for the space for the night.
There's also the Workbar (http://www.workbarboston.com), which is
pricier and a little more cramped... :).

Everyone on the list should also check out Boston Software
Craftsmanship (http://groups.google.com/group/boston-software-
craftsmanship/).  Their next meeting is on 1/24 and is on monads
(http://gathers.us/events/jan-boston-software-craftsmanship-meeting).

Thanks!
Alyssa

On Dec 30, 1:52 pm, dysinger  wrote:
> 10 of us from Sonian are going to converge on Boston the week of Jan
> 9.  It's always awesome to meet other Clojure hackers. I propose we
> meet up somewhere central(ish) Jan 11 @ 7-9pm-ish.  We have room at
> our company headquarters in Dedham but that might be a hike for some
> people.  Any other places we could meet/greet & hack for an hour or
> two central to Boston?

-- 
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Alex Osborne
Alex Baranosky  writes:

> I've been playing with making a macro to encapsulate Stuart's post, like this:
>
> (defmacro defrecord-ifn [name & args]
>   `(defrecord ~name ~...@args
>     clojure.lang.IFn
>     (invoke [this key] (get this key
>
> (defrecord-ifn Foo [a b c])
>
> (def foo (Foo. "A" "B" "C"))
>
> (prn (map foo [:a :c])) => ("A", "C")
>
> I get the error:
>
> "No such var: user/this".  I guess this is because it is expanding
> 'this' to 'user/this'.  What is the proper way to get a macro like
> this to expand properly? 

Use autogensym.  Stick a # on the end of bindings you declare inside
syntax-quote: this# and key#. 

(defmacro defrecord-ifn [name & args]
  `(defrecord ~name ~...@args
clojure.lang.IFn
(invoke [this# key#] (get this# key#

-- 
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Alex Baranosky
Worked like a charm.  Thanks Alex.

-- 
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Alyssa Kwan
Technically, there's no possibility of variable capture, but you
should use gensyms:

(defmacro defrecord-ifn [name & args]
  `(defrecord ~name ~...@args
 clojure.lang.IFn
 (invoke [this# key#] (get this# key#

Thanks,
Alyssa

On Dec 30, 9:29 pm, Alex Baranosky 
wrote:
> I've been playing with making a macro to encapsulate Stuart's post, like
> this:
>
> (defmacro defrecord-ifn [name & args]
>   `(defrecord ~name ~...@args
>     clojure.lang.IFn
>     (invoke [this key] (get this key
>
> (defrecord-ifn Foo [a b c])
>
> (def foo (Foo. "A" "B" "C"))
>
> (prn (map foo [:a :c])) => ("A", "C")
>
> I get the error:
>
> "No such var: user/this".  I guess this is because it is expanding 'this' to
> 'user/this'.  What is the proper way to get a macro like this to expand
> properly?
>
> Alex

-- 
You 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: Boston meetup Jan 11?

2010-12-30 Thread Alex Baranosky
I'll also be at the Boston Coding Dojo sessions on the 6th and 20th, and
would be willing to split the room price if you all wanted to meet during
the week of the 9th-16th.

Alex

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

Clojure in Small Pieces -- Literate Clojure

2010-12-30 Thread Tim Daly

 Well, I previously commented that Advocacy is Volunteering
and then I managed to advocate moving clojure to literate
form. Since I'm studying the details of the inner workings
of Clojure this seemed to be the right time to experiment
with a literate form.

I have put together the beginnings of a Clojure in Small Pieces
book. The PDF of the books is at:
http://daly.axiom-developer.org/clojure.pdf
and the literate program sources are at:
http://daly.axiom-developer.org/clojure.pamphlet

The book is in pure latex and requires a single style file at:
http://daly.axiom-developer.org/clojure.sty

The book is hyperlinked so if your pdf reader supports it you
can go to the index and find pieces of code or move from the
table of contents to the appropriate code chunks. Chunking is
very coarse-grained at the moment but will become smaller as
more code is explained.

The literate chunk machinery uses the previously posted code.

The code has been lightly modified to fit into the page format.
Clearly some of the developers have very wide screens. When
rendered on a page in raw form the code runs off the side of
the page. The book sources are 1.3.0-alpha4 (so far). There is
almost no prose in the book yet as the initial format process
has taken up most of the time so far.

You can see from the outline that there is much to discuss.
The goal is to break out the code that implements various
features into sections organized around the ideas, making
it easier to get a "conceptual view" of the code. Suggestions
for other sections are welcome. Feel free to pick a section
that interests you and we can coordinate adding it to the book.
I'm "Acting Editor-in-Chief" at the moment so I get to choose
the final form (mostly for style, flow, clarity, etc).

The aim of the book is to enable anyone to study and contribute
their understanding of portions of Clojure. I am beginning to
study the PersistentTreeMap which is based on Red-Black trees.
In the book you can see that I've split out portions of the
code into the Red-Black section, the Seq section, and the
Iterator section.

I am also experimenting with parallel programming using both
MPI and MapReduce (Hadoop). The idea is to build a multiple
node Ants demo that has N independent ant colonies, one per
parallel node, all being displayed on a single ant field.
I would like the parallel form to be very close in spirit
to Rich's original version so I'll have to document that in
detail first.

Note that the people named on the front cover are from the
author tags in the source code. I have no idea who else might
have worked on portions of the code. If you know, please let
me know.

Literature references are especially welcome. I have a few,
such as the Multi-Version Concurrency Control papers, which
will be added when I get to the STM section.

In any case, this is purely an experiment in literate clojure.
Feedback is welcome.

Tim Daly

--
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Alyssa Kwan
Argh! Six minutes! :P

On Dec 30, 9:42 pm, Alyssa Kwan  wrote:
> Technically, there's no possibility of variable capture, but you
> should use gensyms:
>
> (defmacro defrecord-ifn [name & args]
>   `(defrecord ~name ~...@args
>      clojure.lang.IFn
>      (invoke [this# key#] (get this# key#
>
> Thanks,
> Alyssa
>
> On Dec 30, 9:29 pm, Alex Baranosky 
> wrote:
>
>
>
> > I've been playing with making a macro to encapsulate Stuart's post, like
> > this:
>
> > (defmacro defrecord-ifn [name & args]
> >   `(defrecord ~name ~...@args
> >     clojure.lang.IFn
> >     (invoke [this key] (get this key
>
> > (defrecord-ifn Foo [a b c])
>
> > (def foo (Foo. "A" "B" "C"))
>
> > (prn (map foo [:a :c])) => ("A", "C")
>
> > I get the error:
>
> > "No such var: user/this".  I guess this is because it is expanding 'this' to
> > 'user/this'.  What is the proper way to get a macro like this to expand
> > properly?
>
> > Alex

-- 
You 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 can't see a method in my protocol

2010-12-30 Thread Ken Wesson
On Thu, Dec 30, 2010 at 7:41 PM, André Thieme
 wrote:
> Do you observe this in a fresh Clojure?
> I ran into something similar, but with definterface.
> I had a definterface form and later added new functions to it, which I
> could not implement before restarting the JVM, as the interface has
> already been created the way I specified it in the first place.

Tangent: this incident is the one I was referring to earlier in
another thread regarding some of the defprotocol-related features
combining poorly with in-REPL development, which I had trouble
locating when I wanted to use it as an example. (And now that other
thread where the topic came up is, of course, the one I can't seem to
locate!)

-- 
You 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 can't see a method in my protocol

2010-12-30 Thread Jarl Haggerty
I didn't think it was a problem with the clojure version because I was
using the maven plugin and tried several versions, but when I got to
my laptop the next day and ran the exact same programs and everything
worked just fine.  At this point my plan is to delete my maven
repositories and if that doesn't work reboot, if that doesn't work
I'll just use it for computer games like I did before.

On Dec 30, 5:41 pm, André Thieme  wrote:
> Am 30.12.2010 07:54, schrieb Jarl Haggerty:
>
>
>
> > This code,
>
> > (defprotocol Matrix
> >    (matrix-get [this c r]))
>
> > (deftype Matrix2D [data height width]
> >    Matrix
> >    (matrix-get [this r c] 1))
>
> > Gives me this error
>
> > Exception in thread "main" java.lang.IllegalArgumentException: Can't
> > define method not in interfaces: matrix_get (core.clj:6)
> > [ ]
>
> > Simply changing the name of the function to get-cell removed this
> > problem, but I feel a need to know what is wrong with this.
>
> Do you observe this in a fresh Clojure?
> I ran into something similar, but with definterface.
> I had a definterface form and later added new functions to it, which I
> could not implement before restarting the JVM, as the interface has
> already been created the way I specified it in the first place.

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


Do type hints cause auto casting?

2010-12-30 Thread Jarl Haggerty
I have this function

(defn floor
  ^int [^float x] x)

and (floor 1.5) returns 1.5 which confuses me as to how type hints
work, I was expecting the result to be truncated or for the program to
spit out some exception about expecting an int and getting a float.

-- 
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread Sunil S Nandihalli
thanks everybody for the responses .. with macros around ... you just have
to wish for it to get it .. but we need to be careful what we wish for :)
Sunil.

On Fri, Dec 31, 2010 at 8:18 AM, Alyssa Kwan wrote:

> Argh! Six minutes! :P
>
> On Dec 30, 9:42 pm, Alyssa Kwan  wrote:
> > Technically, there's no possibility of variable capture, but you
> > should use gensyms:
> >
> > (defmacro defrecord-ifn [name & args]
> >   `(defrecord ~name ~...@args
> >  clojure.lang.IFn
> >  (invoke [this# key#] (get this# key#
> >
> > Thanks,
> > Alyssa
> >
> > On Dec 30, 9:29 pm, Alex Baranosky 
> > wrote:
> >
> >
> >
> > > I've been playing with making a macro to encapsulate Stuart's post,
> like
> > > this:
> >
> > > (defmacro defrecord-ifn [name & args]
> > >   `(defrecord ~name ~...@args
> > > clojure.lang.IFn
> > > (invoke [this key] (get this key
> >
> > > (defrecord-ifn Foo [a b c])
> >
> > > (def foo (Foo. "A" "B" "C"))
> >
> > > (prn (map foo [:a :c])) => ("A", "C")
> >
> > > I get the error:
> >
> > > "No such var: user/this".  I guess this is because it is expanding
> 'this' to
> > > 'user/this'.  What is the proper way to get a macro like this to expand
> > > properly?
> >
> > > Alex
>
> --
> You 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: Do type hints cause auto casting?

2010-12-30 Thread Sunil S Nandihalli
I don't think type hints lead to auto casting .. May be somebody else can
throw more light on it. And it is this way by design.
Sunil.

On Fri, Dec 31, 2010 at 9:35 AM, Jarl Haggerty wrote:

> I have this function
>
> (defn floor
>  ^int [^float x] x)
>
> and (floor 1.5) returns 1.5 which confuses me as to how type hints
> work, I was expecting the result to be truncated or for the program to
> spit out some exception about expecting an int and getting a float.
>
> --
> You 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

vsClojure Release

2010-12-30 Thread jmis
The first release of vsClojure is now available in the Visual Studio
Gallery.  You can download it using the extension manager in Visual
Studio 2010 and searching for "vsClojure".  There should be no manual
setup and the extension will work with the Visual Studio 2010 Shell.

This release focused on implementing basic features, laying the
plumbing for more advanced features and creating a packaging
strategy.  For a complete list of features please visit
http://github.com/jmis/vsClojure.

Future releases depend on your feedback.  Feel free to open issues in
the issue tracker or post suggestions in the discussion group at
http://groups.google.com/group/vsclojure-extension.

Thanks,
jmis

-- 
You 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..

2010-12-30 Thread André Thieme

Am 31.12.2010 03:29, schrieb Alex Baranosky:

I've been playing with making a macro to encapsulate Stuart's post, like
this:

(defmacro defrecord-ifn [name & args]
   `(defrecord ~name ~...@args
 clojure.lang.IFn
 (invoke [this key] (get this key

(defrecord-ifn Foo [a b c])

(def foo (Foo. "A" "B" "C"))

(prn (map foo [:a :c])) => ("A", "C")

I get the error:

"No such var: user/this".  I guess this is because it is expanding
'this' to 'user/this'.  What is the proper way to get a macro like this
to expand properly?


Others have already pointed to “this#”.
I just would like to add that you can as well use “~'this” in some
cases, where your macros generate defns. The advantage is that some
editors (like emacs) will show you the parameter vector and that would
show a useful name and not “this_auto_foobarbaz123456”.

--
You 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: Do type hints cause auto casting?

2010-12-30 Thread Jarl Haggerty
I think I asked the wrong question, not only that but I guess I
answered the question I asked, what I want to know is what exactly is
a type hint.  I think I've failed to understand exactly what a type
hint is, I assumed to give a hint was to statically type something but
that doesn't seem to be what happens here.

On Dec 30, 9:18 pm, Sunil S Nandihalli 
wrote:
> I don't think type hints lead to auto casting .. May be somebody else can
> throw more light on it. And it is this way by design.
> Sunil.
>
> On Fri, Dec 31, 2010 at 9:35 AM, Jarl Haggerty wrote:
>
> > I have this function
>
> > (defn floor
> >  ^int [^float x] x)
>
> > and (floor 1.5) returns 1.5 which confuses me as to how type hints
> > work, I was expecting the result to be truncated or for the program to
> > spit out some exception about expecting an int and getting a float.
>
> > --
> > You 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


Chunking is making my life more difficult.

2010-12-30 Thread ehanneken
I spent a long time debugging some Clojure code yesterday.  The
essence of it looked similar to this:

(defn items []
  (mapcat expensive-function (range 0 4000 100)))

. . . (take 5 (items)) . . .

expensive-function is a function that issues an HTTP GET to retrieve a
vector of data.  Since range's docstring says it returns a lazy
sequence, and since mapcat is defined in terms of map and concat,
which are both supposed to return lazy sequences, I expected (take 5
(items)) to cause only one HTTP GET.  In reality, it causes 32 GETs.
That's kind of costly in time and space, considering I merely wanted
the first 5 of the 100 items returned in the response to the first
GET.

This behavior was baffling to me at first, but after some research I
found section 12.3 of _The Joy of Clojure_, which mentions that ever
since Clojure 1.1 some functions (such as range) which are advertised
as lazy are actually moderately eager, realizing chunks of up to 32
elements at a time.

I retrieved the release notes for Clojure 1.1.  In the section about
chunking, it says, "Please share any use cases where chunked
processing has resulted in behavioral differences that matter to you
on the Clojure Google group."  That's why I posted this.

-- 
You 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: Chunking is making my life more difficult.

2010-12-30 Thread Ken Wesson
On Fri, Dec 31, 2010 at 12:25 AM, ehanneken  wrote:
> I spent a long time debugging some Clojure code yesterday.  The
> essence of it looked similar to this:
>
> (defn items []
>  (mapcat expensive-function (range 0 4000 100)))
>
> . . . (take 5 (items)) . . .
>
> expensive-function is a function that issues an HTTP GET to retrieve a
> vector of data.  Since range's docstring says it returns a lazy
> sequence, and since mapcat is defined in terms of map and concat,
> which are both supposed to return lazy sequences, I expected (take 5
> (items)) to cause only one HTTP GET.  In reality, it causes 32 GETs.
> That's kind of costly in time and space, considering I merely wanted
> the first 5 of the 100 items returned in the response to the first
> GET.
>
> This behavior was baffling to me at first, but after some research I
> found section 12.3 of _The Joy of Clojure_, which mentions that ever
> since Clojure 1.1 some functions (such as range) which are advertised
> as lazy are actually moderately eager, realizing chunks of up to 32
> elements at a time.

Interesting. I find it odd, though, that that would result in
expensive-function being called 32 times. I'd expect mapcat to cause
it to be called once; so you'd realize the first 32 elements of (range
0 4000 100) and consume one, and realize the first 100 elements of
(mapcat expensive-function (range 0 4000 100)) and consume five.

Is mapcat also semi-eager, 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


Re: Insertion - The clojure way

2010-12-30 Thread Ken Wesson
On Thu, Dec 30, 2010 at 4:19 PM, Mark Engelberg
 wrote:
> On Thu, Dec 30, 2010 at 11:01 AM, Ken Wesson  wrote:
>> I hope that didn't include a naive benchmarking of
>> take/drop/concat/seq. Because three of those are lazy, you need to
>> wrap the output of an algorithm using them in a (doall ...) and then
>> in your timing function to get an accurate read on the amount of time
>> it actually takes to perform the full algorithm.
>
> Yes, I compared with doall.  Try it and let me know if you get
> different results, but I find that traversing a finger tree is so much
> slower than traversing a sequence, it all but nullifies any advantages
> you get from other operations (even assuming the other operations are
> way faster, which they typically are not).

Are these searches, which should be log n? Or full (e.g. in-order) traversals?

Traversals of persistent trees can be tricky, since there won't be a
parent pointer on each node. But I'd think a judicious use of tree-seq
would be effective in traversing one decently.

I can test this when I have more time: implement a red-black finger
tree, say, and check the speeds of various operations including a
tree-seq based in-order traversal.

-- 
You 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: Chunking is making my life more difficult.

2010-12-30 Thread Chas Emerick
On Fri, Dec 31, 2010 at 12:25 AM, ehanneken  wrote:
> I spent a long time debugging some Clojure code yesterday.  The
> essence of it looked similar to this:
> 
> (defn items []
>  (mapcat expensive-function (range 0 4000 100)))
> 
> . . . (take 5 (items)) . . .
> 
> expensive-function is a function that issues an HTTP GET to retrieve a
> vector of data.  Since range's docstring says it returns a lazy
> sequence, and since mapcat is defined in terms of map and concat,
> which are both supposed to return lazy sequences, I expected (take 5
> (items)) to cause only one HTTP GET.  In reality, it causes 32 GETs.
> That's kind of costly in time and space, considering I merely wanted
> the first 5 of the 100 items returned in the response to the first
> GET.
> 
> This behavior was baffling to me at first, but after some research I
> found section 12.3 of _The Joy of Clojure_, which mentions that ever
> since Clojure 1.1 some functions (such as range) which are advertised
> as lazy are actually moderately eager, realizing chunks of up to 32
> elements at a time.


Chunking is dependent upon the type of seq being traversed, which is in turn 
dependent upon the type of collection underlying the seq.  Ranges always 
produce chunked seqs, as do non-empty vectors for example.  If chunking is a 
concern, you can always fall back to seqs "grounded" in lists, which are always 
unchunked (and therefore yield one-at-a-time behaviour with e.g. map):

=> (->> (range 50)
 (map println)
 first)
0
1
2
...
31
nil

vs…

=> (->> (range 50)
 (mapcat list)
 (map println)
 first)
0
nil

I'm not sure that this means that map, concat, etc are eager in practical 
terms.  I view the chunking in much the same light as transients vis á vis 
immutability of persistent data structures -- the result is a relative perf 
improvement that doesn't impact semantics in the vast majority of cases.  In my 
experience, chunking is only detrimental when mapping side-effecting (usually 
IO-related) functions across collections, as you're doing.  Given that, using a 
(mapcat list) interstitial to get unchunked seqs is inconsequential w.r.t. 
perf, etc.  I'd be interested in hearing any different perspectives.

FYI, chunked-seq? can be used to determine if a seq supports chunking or not.

- Chas

-- 
You 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: Insertion - The clojure way

2010-12-30 Thread Mark Engelberg
On Thu, Dec 30, 2010 at 9:50 PM, Ken Wesson  wrote:
> Are these searches, which should be log n? Or full (e.g. in-order) traversals?

I'm talking about full traversals.  Finger trees are sequences, and
after building the sequence, splitting, concatenating, or whatever, I
find I eventually need to visit all the elements.  This is something
like a hundred times slower on a large finger tree than a basic
sequence.

I had tried a couple years back to implement finger trees in Racket,
and found it too slow to be of use.  Recently, when I saw chouser had
developed an implementation in Clojure
(https://github.com/clojure/data.finger-tree), I eagerly checked it
out to see if his implementation worked better than my own effort.
It's definitely faster than my Racket attempt, but I still found it to
be quite slow.  I hope I'm incorrect and someone can show me a good
demonstration of an application where finger trees outperform
Clojure's built-in sequences.  But my impression is that even though
they are "asymptotically fast", the constant factors are too large,
and even for lists of hundreds of thousands of elements, you'd be
better off, for example, doing an "inefficient" concatenation of
Clojure's vectors than the "efficient" concatenation of a finger tree.

Play around with chouser's implementation and let me know what you find.

-- 
You 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 in Small Pieces -- Literate Clojure

2010-12-30 Thread Mark Engelberg
I find this exciting!  Thanks for starting this.

-- 
You 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 Build "Slim" Version of clojure-contrib

2010-12-30 Thread OGINO Masanori
Hello.

Thank you for response, Stuart Sierra.
I'm looking forward to complete new build configuration work and I'll
use little build script for a while :-)

Thank you.

2010/12/30, Stuart Sierra :
> Currently, clojure-contrib's pom.xml is configured to build source-only JARs
> for all libraries except those four that require ahead-of-time compilation.
>
> We are in the process of developing a unified build configuration for
> clojure-contrib projects, including new libraries such as core.unify and
> tools.nrepl.  See http://dev.clojure.org/display/design/Common+Contrib+Build
> for details.  I will see if we can make "slim" JARs an available target in
> this new configuration.
>
> In the mean time, you can manually construct a "slim" JAR by calling
> `compile` at the REPL and packaging up the resultant .class files yourself.
>
> -Stuart Sierra
> clojure.com
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en


-- 
Name:  OGINO Masanori (荻野 雅紀)
E-mail: masanori.og...@gmail.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


java/Clojure MPI ..

2010-12-30 Thread Sunil S Nandihalli
Hello everybody,
 I am looking for parallel programming libraries in Clojure. I found JavaMPI
but its website does not seem to be updated since 2003. I would love to hear
anything about where Java stands in distributed parallel computing. I get
the feeling that the Parallel colt libraries are just for shared memory
parallelism. I am primarily interested in large matrix computations.. .
 I currently need something that can do CGLS (conjugate Gradient Least
squares )  in a distributed way. It is available in parallel colt libraries
.. but it is only shared-memory parallel.
  I am sorry this is not directly related to Clojure but would love to hear
what you all have to say.
Thanks,
Sunil.

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