Re: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread cameron

Hi Marshall,
  the megamorphic call site hypothesis does sound plausible but I'm not 
sure where the following test fits in.
If I understand correctly we believe that it's the fact that the base case 
(an PersistentList$EmptyList instance)
and the normal case (an PersistsentList instance) have different types and 
when run in paralell the interleaving
invocations are causing problems for the JIT but when we use a vector it's 
a single type so we see a better speedup.

I was toying with the idea of replacing the EmptyList class with a 
PersistsentList instance to mitigate the problem
in at least one common case, however it doesn't seem to help.
If I replace the reverse call in burn with the following code:
  #(reduce conj (list nil) %)
I get the same slowdown as we see if reverse (equivalent to #(reduce conj 
'() %))

where:
  (class '())=> clojure.lang.PersistentList$EmptyList
  (class (list nil)) => clojure.lang.PersistentList

I'm not convinced were at the bottom of it yet, perhaps the earlier post on 
memory contention by Carlos might
yield some clues. If the issue was related to memory access it might help 
explain why the impact differed
significantly between intel and amd hardware.

Cameron.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: STM - a request for "war stories"

2012-12-12 Thread john
So is the bottom line:  STM Should have not been added to clojure ( because it 
is not pratical)

Many Grettings
John

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


Re: why is nth called here?

2012-12-12 Thread Dennis Haupt
if anyone is interested, i used reduces instead of reductions.


2012/12/11 Dennis Haupt 

> i just saw my error :/
>
>
> Am 11.12.2012 22:22, schrieb Ben Wolfson:
> > nth is called in doing the destructuring for the argument lists in
> > your fns defined in try-find-sequence.
> >
> > On Tue, Dec 11, 2012 at 1:20 PM, Dennis Haupt 
> wrote:
> >> i am trying to solve euler problem 125. when i tested this code:
> >>
> >> (ns euler.Problem125)
> >>
> >> (defn is-palindrome [n]
> >>   (let [s (str n)]
> >> (= (seq s) (reverse s
> >>
> >> (defn to-check []
> >>   (filter is-palindrome (range 1 1000)))
> >>
> >> (defn square-root [n]
> >>   (Math/sqrt n))
> >>
> >> (defn squared [n]
> >>   (* n n))
> >>
> >> (defn try-find-sequence [n]
> >>   (loop [start-at (int (square-root n))]
> >> (let [combinator (fn [[sum smallest] element] [(+ sum element) (dec
> >> element)])
> >>   reduced (reduce combinator [0 start-at] (range start-at 0 -1))
> >>   pred (fn [[sum smallest]] (> sum n))
> >>   until-match-or-overflow (take-while pred reduced)
> >>   solution-or-not (last until-match-or-overflow)]
> >>   (cond
> >> (= (first solution-or-not) n) nil
> >> (= (first solution-or-not) n) (second solution-or-not)
> >> :else (recur (dec start-at))
> >> (println (try-find-sequence 595))
> >>
> >> i get:
> >> Exception in thread "main" java.lang.UnsupportedOperationException: nth
> >> not supported on this type: Long
> >> at clojure.lang.RT.nthFrom(RT.java:846)
> >> at clojure.lang.RT.nth(RT.java:796)
> >> at
> euler.Problem125$try_find_sequence$pred__16.invoke(Problem125.clj:20)
> >> at clojure.core$take_while$fn__4116.invoke(core.clj:2512)
> >>
> >> but why? i don't call nth on anything!
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> >> Groups "Clojure" group.
> >> To post to this group, send email to clojure@googlegroups.com
> >> Note that posts from new members are moderated - please be patient with
> your first post.
> >> To unsubscribe from 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: STM - a request for "war stories"

2012-12-12 Thread Marko Topolnik
I wouldn't say that it should not have been added since its presence isn't 
harming anything. You could say, though, that rarely anyone would realize 
something was missing if Clojure didn't have the STM.

On Wednesday, December 12, 2012 9:50:31 AM UTC+1, john wrote:
>
> So is the bottom line:  STM Should have not been added to clojure ( 
> because it is not pratical)
>
> Many Grettings
> John
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: start-process-shell-command: Spawning child process: invalid argument

2012-12-12 Thread Myrna van de Burgwal
I also have a problem when I type in 'M-x slime' in Emacs. It causes the 
same error (spawning child process: invalid argument).
I assume I installed slime correctly and I rewrote ~/.emacs.
What could ben the problem?

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

Re: start-process-shell-command: Spawning child process: invalid argument

2012-12-12 Thread Stathis Sideris
I've had this problem before when emacs was trying to start an external 
executable whose path contained spaces. Are you running Windows by any 
chance? Is your Java under "Program Files"? Try moving it to a space free 
path like "C:\development\tools\".

On Wednesday, 12 December 2012 12:20:46 UTC, Myrna van de Burgwal wrote:
>
> I also have a problem when I type in 'M-x slime' in Emacs. It causes the 
> same error (spawning child process: invalid argument).
> I assume I installed slime correctly and I rewrote ~/.emacs.
> What could ben the problem?
>

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

Re: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Marshall Bockrath-Vandegrift
Andy Fingerhut  writes:

> I'm not practiced in recognizing megamorphic call sites, so I could be
> missing some in the example code below, modified from Lee's original
> code.  It doesn't use reverse or conj, and as far as I can tell
> doesn't use PersistentList, either, only Cons.

...

> Can you try to reproduce to see if you get similar results?  If so, do
> you know why we get bad parallelism in a single JVM for this code?  If
> there are no megamorphic call sites, then it is examples like this
> that lead me to wonder about locking in memory allocation and/or GC.

I think your benchmark is a bit different from Lee’s original.  The
`reverse`-based versions perform heavily allocation as they repeatedly
reverse a sequence, but each thread will hold a sequence of length at
most 10,000 at any given time.  In your benchmark, each thread holds a
sequence of at most 2,000,000 elements, for a naive 200x increase in
memory pressure and a potential increase in the number of objects being
promoted out of the young generation.

I ran your run benchmark under a version of Cameron’s criterium-based
speed-up measurement wrapper I’ve modified to pass in the `pmap`
function to use.  I reduced the number of iterations in your algorithm
by a factor of 5 to get it to run in a reasonable amount of time.  And I
ran it using default JVM GC settings, on a 32-way AMD system.

I get the following numbers for 1-32 way parallelism with a 500MB heap:

andy  1 : smap-ms 7.5, pmap-ms 7.7, speedup 0.97
andy  2 : smap-ms 7.8, pmap-ms 9.8, speedup 0.80
andy  4 : smap-ms 8.5, pmap-ms 10.6, speedup 0.80
andy  8 : smap-ms 8.6, pmap-ms 11.5, speedup 0.75
andy 16 : smap-ms 8.1, pmap-ms 12.5, speedup 0.65
andy 32 : [java.lang.OutOfMemoryError: Java heap space]

And these numbers with a 4GB heap:

andy  1 : smap-ms 3.8, pmap-ms 4.0, speedup 0.95
andy  2 : smap-ms 4.2, pmap-ms 2.1, speedup 2.02
andy  4 : smap-ms 4.2, pmap-ms 1.7, speedup 2.48
andy  8 : smap-ms 4.2, pmap-ms 1.2, speedup 3.44
andy 16 : smap-ms 4.4, pmap-ms 1.0, speedup 4.52
andy 32 : smap-ms 4.0, pmap-ms 1.6, speedup 2.55

I’m running out of time for breakfast experiments, but it seems
relatively likely to me that the increased at-once sequence size in your
benchmark is increasing the number of objects making it out of the young
generation.  This in turn is increasing the number of pause-the-world
GCs, which increase even further in frequency at lower heap sizes.  I’ll
run these again later with GC logging and report if the results are
unexpected.

-Marshall

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Marshall Bockrath-Vandegrift
cameron  writes:

>   the megamorphic call site hypothesis does sound plausible but I'm
> not sure where the following test fits in.

...

> I was toying with the idea of replacing the EmptyList class with a
> PersistsentList instance to mitigate the problem
> in at least one common case, however it doesn't seem to help.
> If I replace the reverse call in burn with the following code:
>   #(reduce conj (list nil) %)
> I get the same slowdown as we see if reverse (equivalent to #(reduce
> conj '() %))

Ah, but include your own copy of `conj` and try those two cases.  The
existing clojure.core/conj has already been used on multiple types, so
you need a new IFn class with a fresh call site.  Here are the numbers I
get when I do that:

w/o EmptyList : smap-ms 6.1, pmap-ms 1.2, speedup 5.26
w/  EmptyList : smap-ms 10.4, pmap-ms 16.2, speedup 0.64
w/o EmptyList : smap-ms 10.5, pmap-ms 16.3, speedup 0.64

That said, I’m slightly less convinced than I was earlier.  I’m having
difficulty producing a minimal example demonstrating the issue, and the
results wmjosiah reported for modifying their actual code are
disheartening.  I just don’t have anything else which begins to explain
the transition from speedup to inverse speedup in the above benchmarking
sequence.

-Marshall

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.string/capitalize API

2012-12-12 Thread Pierre Allix
Hello,

The clojure.string/capitalize function is defined as follow:

Converts first character of the string to upper-case, all other

characters to lower-case.


I think it does not follow principle of least astonishment. I would have 
expected to convert only the first character. Moreover converting the other 
characters make the function almost useless, I for instance had this string to 
capitalize:

"if P is true then do W" which is converted into "If p is true then do w". This 
is not helpful.


Is there a good reason to convert the other characters? Shouldn't this be done 
explicitly by the user? Would it make sense to change the capitalize function 
in the next versions? 


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.string/capitalize API

2012-12-12 Thread Chris Ford
This seems like quite a specialised function to have in a core string
library.

To me, the only behaviour that would be generic enough to include in a core
library would be to capitalise all the letters of the string.

On 12 December 2012 17:12, Pierre Allix  wrote:

> Hello,
>
> The clojure.string/capitalize function is defined as follow:
>
> Converts first character of the string to upper-case, all other
>
> characters to lower-case.
>
>
> I think it does not follow principle of least astonishment. I would have 
> expected to convert only the first character. Moreover converting the other 
> characters make the function almost useless, I for instance had this string 
> to capitalize:
>
> "if P is true then do W" which is converted into "If p is true then do w". 
> This is not helpful.
>
>
> Is there a good reason to convert the other characters? Shouldn't this be 
> done explicitly by the user? Would it make sense to change the capitalize 
> function in the next versions?
>
>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Andy Fingerhut
Lee:

I believe you said that with your benchmarking code achieved good speedup when 
run as separate JVMs that were each running a single thread, even before making 
the changes to the implementation of reverse found by Marshall.  I confirmed 
that on my own machine as well.

Have you tried running your real application in a single thread in a JVM, and 
then run multiple JVMs in parallel, to see if there is any speedup?  If so, 
that would again help determine whether it is multiple threads in a single JVM 
causing the slowdown, or something to do with the hardware or OS that is the 
limiting factor.

Andy


On Dec 11, 2012, at 4:37 PM, Lee Spector wrote:

> 
> On Dec 11, 2012, at 1:06 PM, Marshall Bockrath-Vandegrift wrote:
>> So I think if you replace your calls to `reverse` and any `conj` loops
>> you have in your own code, you should see a perfectly reasonable
>> speedup.
> 
> Tantalizing, but on investigation I see that our real application actually 
> does very little explicitly with reverse or conj, and I don't actually think 
> that we're getting reasonable speedups (which is what led me to try that 
> benchmark). So while I'm not sure of the source of the problem in our 
> application I think there can be a problem even if one avoids direct calls to 
> reverse and conj. Andy's recent tests also seem to confirm this.
> 
> BTW benchmarking our real application (https://github.com/lspector/Clojush) 
> is a bit tricky because it's riddled with random number generator calls that 
> can have big effects, but we're going to look into working around that. 
> Recent postings re: seedable RNGs may help, although changing all of the RNG 
> code may be a little involved because we use thread-local RNGs (to avoid 
> contention and get good multicore speedups... we thought!).
> 
> -Lee

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


Re: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Lee Spector

On Dec 12, 2012, at 10:03 AM, Andy Fingerhut wrote:
> 
> Have you tried running your real application in a single thread in a JVM, and 
> then run multiple JVMs in parallel, to see if there is any speedup?  If so, 
> that would again help determine whether it is multiple threads in a single 
> JVM causing the slowdown, or something to do with the hardware or OS that is 
> the limiting factor.

I don't think we've tried this exact test but we will now. Because we haven't 
yet engineered all of the randomness out of the application we'll do a bunch of 
runs in each condition and average the times. Based on recent tests I think 
this will give reasonably stable results if we do 10 runs or so in each 
condition. I'll keep you posted.

Thanks!

 -Lee

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


Re: clojure.string/capitalize API

2012-12-12 Thread Grant Rettke
On Wed, Dec 12, 2012 at 8:12 AM, Pierre Allix
wrote:

> I think it does not follow principle of least astonishment. I would have 
> expected to convert only the first character. Moreover converting the other 
> characters make the function almost useless, I for instance had this string 
> to capitalize:
>
>
Fro that principle, who is the least astonished who is it based on?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Christophe Grand
Lee, while you are at benchmarking, would you mind running several threads
in one JVM with one clojure instance per thread? Thus each thread should
get JITted independently.

Christophe


On Wed, Dec 12, 2012 at 4:11 PM, Lee Spector  wrote:

>
> On Dec 12, 2012, at 10:03 AM, Andy Fingerhut wrote:
> >
> > Have you tried running your real application in a single thread in a
> JVM, and then run multiple JVMs in parallel, to see if there is any
> speedup?  If so, that would again help determine whether it is multiple
> threads in a single JVM causing the slowdown, or something to do with the
> hardware or OS that is the limiting factor.
>
> I don't think we've tried this exact test but we will now. Because we
> haven't yet engineered all of the randomness out of the application we'll
> do a bunch of runs in each condition and average the times. Based on recent
> tests I think this will give reasonably stable results if we do 10 runs or
> so in each condition. I'll keep you posted.
>
> Thanks!
>
>  -Lee
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>



-- 
On Clojure http://clj-me.cgrand.net/
Clojure Programming http://clojurebook.com
Training, Consulting & Contracting http://lambdanext.eu/

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.string/capitalize API

2012-12-12 Thread Jim foo.bar
There is an easy solution to your problem...Just hange the fn definition 
slightly. For example I am regularly using this:


(defn un-capitalize [^String s]
(let [Cfirst (subs s 0 1)
Crest (subs s 1) ]
(str (.toLowerCase Cfirst) Crest)))


It is pretty obvious what you need to do to convert the above to 
"capitalize" which only capitalises the 1st charater...


I agree that with regards to 'least astonishment' the core fn should 
capitalize all characters. This is what I'd expect from a fn called 
'capitalize'.


Jim


On 12/12/12 14:12, Pierre Allix wrote:

Hello,

The clojure.string/capitalize function is defined as follow:

Converts first character of the string to upper-case, all other
characters to lower-case.
I think it does not followprinciple of least astonishment. I would have 
expected to convert only the first character. Moreover converting the other 
characters make the function almost useless, I for instance had this string to 
capitalize:
"if P is true then do W" which is converted into "If p is true then do w". This 
is not helpful.

Is there a good reason to convert the other characters? Shouldn't this be doneexplicitly by the user? Would it make sense to change the capitalize function in the next versions?  


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from 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: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Lee Spector

On Dec 12, 2012, at 10:45 AM, Christophe Grand wrote:
> Lee, while you are at benchmarking, would you mind running several threads in 
> one JVM with one clojure instance per thread? Thus each thread should get 
> JITted independently.

I'm not actually sure how to do that. We're starting runs with "lein run", 
which, if I understand correctly launches a JVM and a Clojure instance within 
it. Within that Clojure instance we can do things in either a single threaded 
or a multi threaded way. How would I change our method to do what you're asking 
here? We're not particularly Java savvy (I come from the Lisp side of things).

Thanks,

 -Lee

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


Re: STM - a request for "war stories"

2012-12-12 Thread Warren Lynn


On Wednesday, December 12, 2012 4:46:06 AM UTC-5, Marko Topolnik wrote:
>
> I wouldn't say that it should not have been added since its presence isn't 
> harming anything. You could say, though, that rarely anyone would realize 
> something was missing if Clojure didn't have the STM.
>
>
>  
Although I am convinced that STM can solve things that locks cannot (See 
the claim "*lock-based programs do not compose" *on Wikipedia page 
http://en.wikipedia.org/wiki/Software_transactional_memory), I feel this 
feature is so much over-sold. Whenever you read someone raves about Clojure 
on the web, they mention "STM" as a key feature and how wonderful it is. My 
own experience is similar to yours, atoms work most of the time and I also 
need to use locks. I benefit more from the fact that Clojure clearly marks 
what is mutable and what is not than any of those "advanced" features.





-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Jim foo.bar

On 12/12/12 00:16, Mark Engelberg wrote:
I would much prefer to have some sort of core function that serves as 
a polymorphic constructor.  This way users don't need to require the 
concrete implementations individually.


I faced the same sort of issue a couple of months ago. Just like you, I 
wanted end-users to be able to instantiate their own records via a 
polymorphic function in the core ns. In other words, I wanted a way of 
instantiating records by passing only the record name (fully qualified 
of course) and whatever parameters the constructor expects. If i 
understand correctly this is what you're after yes?


There is a simple way of doing this but it is very very slow. Basically 
you need to resort to reflection...Chris Houser had posted such  a 
record-factory fn on StackOverflow a while back. Here it is:


(defn record-factory [recordname]
(let [recordclass ^Class (resolve (symbol recordname))
max-arg-count (apply max (map #(count (.getParameterTypes 
^java.lang.reflect.Constructor %))

(.getConstructors recordclass)))
args (map #(symbol (str "x" %)) (range (- max-arg-count 2)))]
(eval `(fn [~@args] (new ~(symbol recordname) ~@args)

even though i was very excited at the time i saw this, I later decided 
that it's not worth the performance cost for my use-case.


Jim

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

Re: clojure.string/capitalize API

2012-12-12 Thread Marek Kubica
On Wed, 12 Dec 2012 09:44:28 -0600
Grant Rettke  wrote:

> Fro that principle, who is the least astonished who is it based on?

I jsut wanted to say, people coming e.g. from Python. But then I
realized it does the same thing and afterwards I was enlightened that
it doesn't matter since I never use it.

regards,
Marek

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Mark Engelberg
On Wed, Dec 12, 2012 at 8:22 AM, Jim foo.bar  wrote:

>  On 12/12/12 00:16, Mark Engelberg wrote:
>
> I would much prefer to have some sort of core function that serves as a
> polymorphic constructor.  This way users don't need to require the concrete
> implementations individually.
>
>
> I faced the same sort of issue a couple of months ago. Just like you, I
> wanted end-users to be able to instantiate their own records via a
> polymorphic function in the core ns. In other words, I wanted a way of
> instantiating records by passing only the record name (fully qualified of
> course) and whatever parameters the constructor expects. If i understand
> correctly this is what you're after yes?
>

Yes and no.  That's basically what I'm trying to do, but I only have a
handful of concrete implementations to choose from, so I don't mind writing
a hard-coded cond that chooses between them based on some sort of keyword
that the user passes in.  So the reflection aspect of this is not what
interests me.

My problem is that I can't figure out how to put the implementations in
different namespaces without introducing circular dependencies.  The
implementations need the core in order to implement the protocol.  The core
needs the implementation namespaces in order to provide a general
constructor that can build all the concrete implementations.  Does the use
of reflection solve the circular dependency problem?  I don't see how it
would.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: STM - a request for "war stories"

2012-12-12 Thread Paul Butcher
Hey Stuart,

Thanks for the response.

What I'm trying to do is keep each chapter focussed on an approach, rather than 
a language. For example, in the chapter on Actors, I'll be showing examples in 
Scala, but the discussion won't be (I hope!) particularly Scala-specific. I 
hope to leave the reader with general lessons which could be applied to Scala, 
Erlang, or any other language with Actor support. Similarly, when talking about 
Threads and Locks, I'll be showing examples in Java, but the lessons should be 
equally applicable to C/C++, etc.

I completely take your point about Clojure's approach being a great deal more 
than STM. I guess that I chose STM as the title because it's got visibility - 
people are talking about it, and there will be an expectation on the part of 
the reader that any book that covers concurrency will spend some time talking 
about it.

I'd be very interested to hear any suggestions for an alternative chapter 
title. I guess what best sums up Clojure's approach is that it separates state 
from identity - but "Separating State from Identity" isn't exactly pithy, and I 
fear won't mean much at first glance to most readers.

--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: p...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

On 11 Dec 2012, at 19:41, Stuart Halloway  wrote:

> Hi Paul,
> 
> If it isn't too late to change your chapter title, I would encourage 
> emphasizing Clojure's model of references and values in general, and the 
> option of implementing a variety of different reference semantics that all 
> conform to the same basic API shape.
> 
> That general approach has been game-changing for me, and the STM occupies a 
> rather small niche in the overall space.
> 
> Datomic stores the entire database in an atom (not an STM ref), and updates 
> it with a call to swap!  It is literally no more complex than a trivial 
> hackneyed book example. :-)
> 
> Cheers,
> Stu
> 
> 
> 
> On Sun, Dec 2, 2012 at 11:03 AM, Paul Butcher  wrote:
> All,
> 
> I have a request which I hope the members of this group are uniquely 
> positioned to help with. I have recently started working on a new book for 
> The Pragmatic Programmers with the working title "Seven Concurrency Models in 
> Seven Weeks" (it follows on from their existing "Seven Languages" and "Seven 
> Databases" titles).
> 
> One of the approaches that I'll be covering is STM, and I'll be presenting it 
> in Clojure.
> 
> What I'd like to solicit are "war stories" about problems you've solved using 
> STM, which demonstrate the strengths of the technique over and above (say) 
> threads and locks.
> 
> I'm looking for real-world examples instead of presenting yet another 
> hackneyed atomically-make-a-bank-account-withdrawal :-)
> 
> Very many thanks in advance for your help!
> 
> --
> paul.butcher->msgCount++
> 
> Snetterton, Castle Combe, Cadwell Park...
> Who says I have a one track mind?
> 
> http://www.paulbutcher.com/
> LinkedIn: http://www.linkedin.com/in/paulbutcher
> MSN: p...@paulbutcher.com
> AIM: paulrabutcher
> Skype: paulrabutcher
> 
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from 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

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Karsten Schmidt
What's stopping you to include the immigrate fn into your own library?
Source is here:
http://clojuredocs.org/clojure_contrib/clojure.contrib.ns-utils/immigrate

There's also Zach Tellman's Potemkin lib, which can be used to
immigrate individual vars:
https://github.com/ztellman/potemkin

(Although I found it can have a bad influence on startup time,
depending on the number of vars you import)

Hth!

On 12 December 2012 17:37, Mark Engelberg  wrote:
> On Wed, Dec 12, 2012 at 8:22 AM, Jim foo.bar  wrote:
>>
>> On 12/12/12 00:16, Mark Engelberg wrote:
>>
>> I would much prefer to have some sort of core function that serves as a
>> polymorphic constructor.  This way users don't need to require the concrete
>> implementations individually.
>>
>>
>> I faced the same sort of issue a couple of months ago. Just like you, I
>> wanted end-users to be able to instantiate their own records via a
>> polymorphic function in the core ns. In other words, I wanted a way of
>> instantiating records by passing only the record name (fully qualified of
>> course) and whatever parameters the constructor expects. If i understand
>> correctly this is what you're after yes?
>
>
> Yes and no.  That's basically what I'm trying to do, but I only have a
> handful of concrete implementations to choose from, so I don't mind writing
> a hard-coded cond that chooses between them based on some sort of keyword
> that the user passes in.  So the reflection aspect of this is not what
> interests me.
>
> My problem is that I can't figure out how to put the implementations in
> different namespaces without introducing circular dependencies.  The
> implementations need the core in order to implement the protocol.  The core
> needs the implementation namespaces in order to provide a general
> constructor that can build all the concrete implementations.  Does the use
> of reflection solve the circular dependency problem?  I don't see how it
> would.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en



-- 
Karsten Schmidt
+44 7875 524 336

http://postspectacular.com | http://toxiclibs.org | http://toxi.co.uk

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Jim - FooBar();

On 12/12/12 17:37, Mark Engelberg wrote:
Yes and no.  That's basically what I'm trying to do, but I only have a 
handful of concrete implementations to choose from, so I don't mind 
writing a hard-coded cond that chooses between them based on some sort 
of keyword that the user passes in.  So the reflection aspect of this 
is not what interests me.


aaa ok...I see. Well, your core ns certainly needs access to the 
implementation ns if you are going to use a plain cond.


My problem is that I can't figure out how to put the implementations 
in different namespaces without introducing circular dependencies.  
The implementations need the core in order to implement the protocol.  
The core needs the implementation namespaces in order to provide a 
general constructor that can build all the concrete implementations.  
Does the use of reflection solve the circular dependency problem?  I 
don't see how it would. 


Yes it would...You're using reflection so no need to :use or :require 
the namespaces any more.

Point your browser here if you're not following:
https://github.com/jimpil/Clondie24/blob/master/src/Clondie24/lib/util.clj

this namespace depends on nothing (apart from clojure.pprint). However 
all the namespaces in games (the concrete implementations) depend on it. 
I can easily create a ChessPiece from within my chess ns using the 
record-factory in util.clj (even though util.clj knows nothing about 
games). However, as i said I'm not doing that...I'm advicing users to 
use the constructor (Foo.) or the factory fn (->Foo) cause they are 
massively faster...In my case it not that big of a deal cos the user is 
already is his namespace (in his game) so he does have access to 
everything he needs. I just wanted to streamline the process and 
essentially hide all the interop calls. No biggie for me...


hope that helps...

Jim

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

Re: Need ideas for carving project into namespaces

2012-12-12 Thread Mark Engelberg
Thanks.  I was hoping that someone would see a way to organize the
namespaces to avoid circular dependencies, but perhaps there's simply no
way to do that short of what I already outlined.

I especially appreciate the pointer to Potemkin.  Just reading through the
"apologia", it sounds like it is meant to solve exactly the kind of problem
I frequently find myself in.  It seems that any time I work with a
large-ish Clojure code base, I find myself wrestling with how to chop into
namespaces, and it is always unpleasant and non-trivial because of the
circularity constraints.

I feel Zach hits the nail on the head when he says that namespaces conflate
implementation partitioning with usage.  I have often found this to be a
problem when consuming other libraries, such as incanter, where it can
sometimes be difficult to remember where different functions reside.  The
incanter tutorials all solve this problem by "use"ing all of the related
namespaces, but that's not always a viable solution.

If there are any more general concepts or techniques I should keep in mind
when partitioning my implementation into namespaces while maintaining a
front-end that users can require from just one namespace, I'm all ears.

On Wed, Dec 12, 2012 at 9:46 AM, Karsten Schmidt  wrote:

> There's also Zach Tellman's Potemkin lib, which can be used to
> immigrate individual vars:
> https://github.com/ztellman/potemkin
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Mark Engelberg
On Wed, Dec 12, 2012 at 9:53 AM, Jim - FooBar(); wrote:

> Yes it would...You're using reflection so no need to :use or :require the
> namespaces any more.
> Point your browser here if you're not following:
> https://github.com/jimpil/Clondie24/blob/master/src/Clondie24/lib/util.clj
>

What gets those classes loaded/imported to begin with?  I don't see how the
classes ever get built if nobody requires the file containing the
defrecords.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Michał Marczyk
@Jim:

That function generates factory functions which themselves use no
reflection and incur no performance penalty at all. The only
performance hit visible at runtime comes from the fact that generating
those factory functions involves compiling code at runtime (but you
should hopefully be able to arrange things so that you only need to do
it once per type).

Also, the class named by the recordname argument needs to exist when
record-factory is called, so I'm not sure it can really be of much
help in dealing with circular dependencies.

Cheers,
Michał


On 12 December 2012 18:53, Jim - FooBar();  wrote:
> On 12/12/12 17:37, Mark Engelberg wrote:
>
> Yes and no.  That's basically what I'm trying to do, but I only have a
> handful of concrete implementations to choose from, so I don't mind writing
> a hard-coded cond that chooses between them based on some sort of keyword
> that the user passes in.  So the reflection aspect of this is not what
> interests me.
>
>
> aaa ok...I see. Well, your core ns certainly needs access to the
> implementation ns if you are going to use a plain cond.
>
> My problem is that I can't figure out how to put the implementations in
> different namespaces without introducing circular dependencies.  The
> implementations need the core in order to implement the protocol.  The core
> needs the implementation namespaces in order to provide a general
> constructor that can build all the concrete implementations.  Does the use
> of reflection solve the circular dependency problem?  I don't see how it
> would.
>
>
> Yes it would...You're using reflection so no need to :use or :require the
> namespaces any more.
> Point your browser here if you're not following:
> https://github.com/jimpil/Clondie24/blob/master/src/Clondie24/lib/util.clj
>
> this namespace depends on nothing (apart from clojure.pprint). However all
> the namespaces in games (the concrete implementations) depend on it. I can
> easily create a ChessPiece from within my chess ns using the record-factory
> in util.clj (even though util.clj knows nothing about games). However, as i
> said I'm not doing that...I'm advicing users to use the constructor (Foo.)
> or the factory fn (->Foo) cause they are massively faster...In my case it
> not that big of a deal cos the user is already is his namespace (in his
> game) so he does have access to everything he needs. I just wanted to
> streamline the process and essentially hide all the interop calls. No biggie
> for me...
>
> hope that helps...
>
> Jim
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


Clojurescript Component-Entity-System game engine

2012-12-12 Thread aboy021


I just read a fascinating post by Chris 
Granger(of Light 
Table  fame) 

   - Chris Granger - Anatomy of a 
knockout 

In it he talks about using a Component Entity System approach to building a 
game. 

The topic of how to do a game in Clojure has come up a number of times on 
this group, and this approach seems applicable to a lot more situations 
than just that.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 emulate Java sub-classing using closure with a macro?

2012-12-12 Thread Gary Verhaegen
I'm a little late here, but I wanted to point out that there is a pretty
good match between what you're describing as an FSM and Akka actors. In
case you're still looking into this, you might want to check out Okku, my
(very thin) Clojure wrapper for Akka.

On Sunday, November 18, 2012, timc wrote:

> Hello - I would appreciate some advice on how to implement something
> equivalent to sub-classing.
>
> The context for this is a finite state machine (FSM), by which I mean a
> thread that waits on a queue of events, then deals with each event (one at
> a time) according to the state it is in, possibly changing state in the
> process.
>
> In Java, an (abstract) super class might be defined for all FSMs, which
> contains common fields such as the current state, timer ID, event queue,
> etc, together with methods for getting and setting the state, starting and
> stopping timers, handling timeouts (this inserts a timeout event into the
> event queue), putting an event into the queue and waiting on the next event
> in the queue. The method to insert an event is generally public so that
> other objects may insert events.
>
> Then, a particular FSM is written as a sub-class; this comprises code to
> execute before the first event is waited for, a loop which waits for then
> processes each event, then code that is executed when the FSM is exited for
> the last time.
> The code that implements all the above naturally makes use of the
> super-class methods and fields, since they are within the scope of the
> sub-class.
>
> It is easy enough to implement all the above as closure of the form
>
>   (defn fsm []
> "Start a thread that is a finite state machine.
>  Return [putEventF stopF] where putEventF[ev] is a function that adds
> an event to the event queue,
>  and stopF[] is a function that stops the state machine.
>  Events are vectors of the form [kind & data]."
> (let [eventQ (java.util.concurrent.LinkedBlockingQueue.)
>   putEventF (fn [ev] (.put eventQ ev))
>   stopF (fn [] (putEventF [:stop]))
>   state (atom nil)
>   going (atom true)
>   timerID (atom nil)
>   timerExpired (fn [id data]
>  (when (and @timerID (= id timerID))
>(.put eventQ [:timeout data])))
>   stopTimer (fn []
>   (when @timerID
> (extStopTimer @timerID)
> (reset! timerID nil)))
>   startTimer (fn [period data]
>(stopTimer)
>(reset! timerID (extStartTimer period timerExpired
> data)))
>   nextState #(reset! state %)]
>   (inThread
> (do
>   (nextState :init)
>   ; Starting stuff ...
>   (print "started"))
> (while @going
>   (let [[kind & data :as ev] (.get eventQ)]
> (cond = @state
>   :init (do
>   ; Initialization stuff ...
>   )
>   :state1 (do
> ; state 1 stuff ...
> )
>   :state2 (do
> ; state 2 stuff ...
> )
>   ; etc...
>   :stop (do
>   ; Stopping stuff ...
>   (reset! going false))
>   (error "bad state"
> (do
>   ; Exit stuff ...
>   (print "terminated")))
>   [putEventF stopF]))
>
> where extFunction... are externally defined functions (implementing timers
> etc) and inThread is a macro that executes a form in a newly created thread.
> Within the body of the FSM, the code can of course directly refer to all
> the things defined in the let by name.
>
> The problem is that I have numerous FSMs and it's really tedious to repeat
> all the stuff in the initial let of the closure.
>
> One solution is to define a *context* that contains the values defined in
> the closure (as a map with keys instead of the explicit names shown above),
> created by a context factory function.
> Then the code has to refer to all the things via a lookup in the context
> map - quite ugly and also tedious.
>
> Another option is that the context factory creates a closure, then returns
> a vector of all the functions defined in the let binding, which can then be
> used directly by the FSM code - that's even more ugly and error prone.
>
> So - the question is - what about an anaphoric macro that creates the
> closure, so that the FSM code can still refer to all that stuff by name?
> If this is the way to go, please an example of the syntax (say the
> timerExpired function). The macro syntax really is confusing to me :(
>
> Or, I imagine a macro called myFsmMacro that takes a map as parameter and
> has the same effect as the fsm function above, something like this:
>
> (def myFsmDefinition  {
>:preamble (do
>  

way to test if a coll is a record?

2012-12-12 Thread Ben Wolfson
Given something like this:

(defrecord F [a])

This fails:

(clojure.walk/postwalk identity [(F. 1)])

because although (coll? (F. 1)) is true, (empty (F. 1)) fails ("can't
create empty").

I've had to write an alternative to walk anyway (it discards
metadata), and I'd like it to be able to accommodate this case more
elegantly than calling empty and catching the exception if the object
happens to be a record. (I suppose the best way would be to define
walk in terms of something like fmap, so that individual records could
decide whether they can be recursed into or not, but that might be
overkill.)

So:

Q1: is this a bug in walk?
Q2: is there a way to tell if something is an instance of a class
created with defrecord?

-- 
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks,
which may be sweet, aromatic, fermented or spirit-based. ... Family
and social life also offer numerous other occasions to consume drinks
for pleasure." [Larousse, "Drink" entry]

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: way to test if a coll is a record?

2012-12-12 Thread Andy Fingerhut
I haven't dug into the details, but this Clojure ticket looks like it might be 
related, if not the same issue:

http://dev.clojure.org/jira/browse/CLJ-1105

It has been vetted by Stuart Halloway, so patches are welcome, but likely 
wouldn't get in until after Clojure 1.5 is released (my guess).

Andy

On Dec 12, 2012, at 11:42 AM, Ben Wolfson wrote:

> Given something like this:
> 
> (defrecord F [a])
> 
> This fails:
> 
> (clojure.walk/postwalk identity [(F. 1)])
> 
> because although (coll? (F. 1)) is true, (empty (F. 1)) fails ("can't
> create empty").
> 
> I've had to write an alternative to walk anyway (it discards
> metadata), and I'd like it to be able to accommodate this case more
> elegantly than calling empty and catching the exception if the object
> happens to be a record. (I suppose the best way would be to define
> walk in terms of something like fmap, so that individual records could
> decide whether they can be recursed into or not, but that might be
> overkill.)
> 
> So:
> 
> Q1: is this a bug in walk?
> Q2: is there a way to tell if something is an instance of a class
> created with defrecord?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Need ideas for carving project into namespaces

2012-12-12 Thread Karsten Schmidt
FWIW, also having struggled with overcoming circular ns deps in the
past, I adopted the approach/compromise below which still provides an
IMHO decent/sound usercode experience.

A contrived example:

 core.clj
(ns mylib.core
  (:require [mylib.types])
  (:import [mylib.types Rect Circle]))

(defprotocol IShape
  (bounds [this] "Returns shape's bounding rect")
  (bounding-circle [this] "Returns shape's bounding circle"))

 types.clj
(ns mylib.types)

(defrecord Rect [x y w h])
(defrecord Circle [x y r])

 rect.clj
(ns mylib.rect
  (:require [mylib.core :as c])
  (:import [mylib.types Rect Circle]))

(extend-type Rect
  c/IShape
  (bounds [this] this)
  (bounding-circle [{:keys [x y w h]}]
(Circle. (+ x (/ w 2)) (+ y (/ h 2)) (/ (Math/sqrt (+ (* w w) (* h
h))) 2

(defn make-rect
  "Factory fn with default values"
  [& {:keys [x y w h] :or {x 0 y 0 w 1 h 1}}]
  (Rect. x y w h))

;(defn other-rect-specific-fn [] ...)

 circle.clj
(ns mylib.circle
  (:require
[mylib.core :as c])
  (:import [mylib.types Rect Circle]))

;(defn circle-specific-fn [x] ...)

(extend-type Circle
  c/IShape
  (bounds [{:keys [x y r]}] (Rect. (- x r) (- y r) (* r 2) (* r 2)))
  (bounding-circle [this] this))

(defn make-circle
  "Factory fn with default values"
  [& {:keys [x y r] :or {x 0 y 0 r 1}}]
  (Circle. x y r))

etc.

As a library user I then only need to require mylib.core and the
namespaces of the types i want to work with. If my type namespaces
provide additional type-specific fns (beyond the implementations of
core protocols), then I know exactly where to find them...

The other thing worth noting here is that this approach also provides
a workaround for cases where there's a circular dependency between
types as shown in the example above, i.e. getting the bounding circle
of a rect & getting the bounding rect of a circle. This is achieved by
the extra level of indirection via the mylib.types ns... In those
cases one can't use the more handy factory fns of these types and has
to resort to direct ctor calls, but this is only *inside* the library
namespace and not in userland...

I would be interested/keen to hear other opinions/approaches too. Thanks!

On 12 December 2012 18:00, Michał Marczyk  wrote:
> @Jim:
>
> That function generates factory functions which themselves use no
> reflection and incur no performance penalty at all. The only
> performance hit visible at runtime comes from the fact that generating
> those factory functions involves compiling code at runtime (but you
> should hopefully be able to arrange things so that you only need to do
> it once per type).
>
> Also, the class named by the recordname argument needs to exist when
> record-factory is called, so I'm not sure it can really be of much
> help in dealing with circular dependencies.
>
> Cheers,
> Michał
>
>
> On 12 December 2012 18:53, Jim - FooBar();  wrote:
>> On 12/12/12 17:37, Mark Engelberg wrote:
>>
>> Yes and no.  That's basically what I'm trying to do, but I only have a
>> handful of concrete implementations to choose from, so I don't mind writing
>> a hard-coded cond that chooses between them based on some sort of keyword
>> that the user passes in.  So the reflection aspect of this is not what
>> interests me.
>>
>>
>> aaa ok...I see. Well, your core ns certainly needs access to the
>> implementation ns if you are going to use a plain cond.
>>
>> My problem is that I can't figure out how to put the implementations in
>> different namespaces without introducing circular dependencies.  The
>> implementations need the core in order to implement the protocol.  The core
>> needs the implementation namespaces in order to provide a general
>> constructor that can build all the concrete implementations.  Does the use
>> of reflection solve the circular dependency problem?  I don't see how it
>> would.
>>
>>
>> Yes it would...You're using reflection so no need to :use or :require the
>> namespaces any more.
>> Point your browser here if you're not following:
>> https://github.com/jimpil/Clondie24/blob/master/src/Clondie24/lib/util.clj
>>
>> this namespace depends on nothing (apart from clojure.pprint). However all
>> the namespaces in games (the concrete implementations) depend on it. I can
>> easily create a ChessPiece from within my chess ns using the record-factory
>> in util.clj (even though util.clj knows nothing about games). However, as i
>> said I'm not doing that...I'm advicing users to use the constructor (Foo.)
>> or the factory fn (->Foo) cause they are massively faster...In my case it
>> not that big of a deal cos the user is already is his namespace (in his
>> game) so he does have access to everything he needs. I just wanted to
>> streamline the process and essentially hide all the interop calls. No biggie
>> for me...
>>
>> hope that helps...
>>
>> Jim
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email

max doesn't return max?

2012-12-12 Thread Dennis Haupt
maybe i am blind, but why does max return the complete lazy seq here
instead of the maximum number? if i just print as-products, i get a list
of numbers. (count solution) tells me there are 1000+
and yet max gives me the complete list?

(ns euler.Problem8)

(def digits
  "73167176531330624919225119674426574742355349194934
  96983520312774506326239578318016984801869478851843
  85861560789112949495459501737958331952853208805511
  12540698747158523863050715693290963295227443043557
  66896648950445244523161731856403098711121722383113
  6222989342338030813533627661428280686645238749
  30358907296290491560440772390713810515859307960866
  70172427121883998797908792274921901699720888093776
  65727333001053367881220235421809751254540594752243
  52584907711670556013604839586446706324415722155397
  53697817977846174064955149290862569321978468622482
  83972241375657056057490261407972968652414535100474
  82166370484403199890008895243450658541227588666881
  16427171479924442928230863465674813919123162824586
  17866458359124566529476545682848912883142607690042
  2421902267105562632109370544217506941658960408
  07198403850962455444362981230987879927244284909188
  84580156166097919133875499200524063689912560717606
  05886116467109405077541002256983155200055935729725
  71636269561882670428252483600823257530420752963450")

(def solution
  (let [as-ints (map int (seq digits))
partitions (partition 5 1 as-ints)
as-products (map #(reduce * %) partitions)]
 (max as-products)))
(println solution)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: max doesn't return max?

2012-12-12 Thread Timothy Baldridge
(doc max)

user=> (doc max)
-
clojure.core/max
([x] [x y] [x y & more])
  Returns the greatest of the nums.
nil

max doesn't take a sequence, it takes one or more values and finds the max
of them. So use (apply max coll) to get what you want.

Timothy

On Wed, Dec 12, 2012 at 2:12 PM, Dennis Haupt  wrote:

> (def digits
>   "73167176531330624919225119674426574742355349194934
>   96983520312774506326239578318016984801869478851843
>   85861560789112949495459501737958331952853208805511
>   12540698747158523863050715693290963295227443043557
>   66896648950445244523161731856403098711121722383113
>   6222989342338030813533627661428280686645238749
>   30358907296290491560440772390713810515859307960866
>   70172427121883998797908792274921901699720888093776
>   65727333001053367881220235421809751254540594752243
>   52584907711670556013604839586446706324415722155397
>   53697817977846174064955149290862569321978468622482
>   83972241375657056057490261407972968652414535100474
>   82166370484403199890008895243450658541227588666881
>   16427171479924442928230863465674813919123162824586
>   17866458359124566529476545682848912883142607690042
>   2421902267105562632109370544217506941658960408
>   07198403850962455444362981230987879927244284909188
>   84580156166097919133875499200524063689912560717606
>   05886116467109405077541002256983155200055935729725
>   71636269561882670428252483600823257530420752963450")
>
> (def solution
>   (let [as-ints (map int (seq digits))
> partitions (partition 5 1 as-ints)
> as-products (map #(reduce * %) partitions)]
>  (max as-products)))
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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

Re: Autotest for Clojure/Midje?

2012-12-12 Thread Wes Williams
thanks Brian that was just what I was looking for! just getting started 
with Midje and this made it much faster.

On Tuesday, December 11, 2012 11:00:03 AM UTC-8, Brian Marick wrote:
>
>
> On Dec 11, 2012, at 12:38 PM, Timothy Baldridge 
> > 
> wrote: 
>
> > For a project I'm working on it would be awesome to have my tests 
> auto-rerun after every file change. I know lazy test exists, but it doesn't 
> work with Lein2 it seems. 
>
> (defproject ... 
>   :profiles {:dev {:dependencies [[midje "1.4.0"] 
>   [com.stuartsierra/lazytest "1.2.3"]] 
>:plugins [[lein-midje "2.0.3"]]}} 
>
>   :repositories {"stuartsierra-releases" "http://stuartsierra.com/maven2"}) 
>
>
> $ lein midje --lazytest 
>
> I just tried this and it works. 
>
> The 1.5 version of Midje will add autotesting to the new repl tools, and 
> lein midje will then be changed to use that. At that point the old 
> dependency on lazytest will go away. 
>
>  
> Occasional consulting on programming technique 
> Contract programming in Ruby and Clojure 
> Latest book: /Functional Programming for the Object-Oriented Programmer/ 
> https://leanpub.com/fp-oo 
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: max doesn't return max?

2012-12-12 Thread Juan Martín Muñoz Facorro
Arguments to *max* should be supplied explicitly. If you want to use a 
sequence you should use *apply* with *max*:

(apply max [1 2 0.5])

Regars,

Juan

On Wednesday, December 12, 2012 6:12:20 PM UTC-3, HamsterofDeath wrote:
>
> maybe i am blind, but why does max return the complete lazy seq here 
> instead of the maximum number? if i just print as-products, i get a list 
> of numbers. (count solution) tells me there are 1000+ 
> and yet max gives me the complete list? 
>
> (ns euler.Problem8) 
>
> (def digits 
>   "73167176531330624919225119674426574742355349194934 
>   96983520312774506326239578318016984801869478851843 
>   85861560789112949495459501737958331952853208805511 
>   12540698747158523863050715693290963295227443043557 
>   66896648950445244523161731856403098711121722383113 
>   6222989342338030813533627661428280686645238749 
>   30358907296290491560440772390713810515859307960866 
>   70172427121883998797908792274921901699720888093776 
>   65727333001053367881220235421809751254540594752243 
>   52584907711670556013604839586446706324415722155397 
>   53697817977846174064955149290862569321978468622482 
>   83972241375657056057490261407972968652414535100474 
>   82166370484403199890008895243450658541227588666881 
>   16427171479924442928230863465674813919123162824586 
>   17866458359124566529476545682848912883142607690042 
>   2421902267105562632109370544217506941658960408 
>   07198403850962455444362981230987879927244284909188 
>   84580156166097919133875499200524063689912560717606 
>   05886116467109405077541002256983155200055935729725 
>   71636269561882670428252483600823257530420752963450") 
>
> (def solution 
>   (let [as-ints (map int (seq digits)) 
> partitions (partition 5 1 as-ints) 
> as-products (map #(reduce * %) partitions)] 
>  (max as-products))) 
> (println solution) 
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread cameron


On Thursday, December 13, 2012 12:51:57 AM UTC+11, Marshall 
Bockrath-Vandegrift wrote:
>
> cameron > writes: 
>
> >   the megamorphic call site hypothesis does sound plausible but I'm 
> > not sure where the following test fits in. 
>
> ... 
>
> > I was toying with the idea of replacing the EmptyList class with a 
> > PersistsentList instance to mitigate the problem 
> > in at least one common case, however it doesn't seem to help. 
> > If I replace the reverse call in burn with the following code: 
> >   #(reduce conj (list nil) %) 
> > I get the same slowdown as we see if reverse (equivalent to #(reduce 
> > conj '() %)) 
>
> Ah, but include your own copy of `conj` and try those two cases.  The 
> existing clojure.core/conj has already been used on multiple types, so 
> you need a new IFn class with a fresh call site.  Here are the numbers I 
> get when I do that: 
>
 
Ah, I've also been looking at this in the morning and missed that bit.
When I use a copy of conj I get similar results to yourself:
  w/ list-base : map-ms: 4.0, pmap-ms 0.6, speedup 7.02
  w/ empty-list-base : map-ms: 9.9, pmap-ms 20.4, speedup 0.48
  w/ list-base : map-ms: 9.4, pmap-ms 20.7, speedup 0.45
  w/ vector : map-ms: 4.5, pmap-ms 1.4, speedup 3.28

It does seem that once used on the empty list case conj gets tainted and 
all future list
uses incur a performance penalty. On that basis it would seem reasonable
 to convert the EmptyList uses in core.lang to a PersistentList instance.

Interestingly using a tainted conj with other types doesn't seem to incur 
the penalty
(the last vector in the times above)

If I get time I might look at a protocol based version of conj out of 
interest.

Cameron.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Slime and heroku setup question

2012-12-12 Thread Jim Crossley
FWIW, direct socket access via an ssh tunnel is allowed on OpenShift, so
connecting to the remote REPL (either nREPL or Swank) is simple and
requires no HTTP transport, but all of Phil's general advice regarding
the remote disk applies there, too.

For an example, see http://immutant.org/news/2012/12/11/openshift-postgresql/

Jim

Phil Hagelberg  writes:

> On Tue, Dec 11, 2012 at 6:55 PM, Jonathon McKitrick
>  wrote:
>> Well, I've used slime with SBCL for quite a while, but this is my first
>> foray into clojure and heroku.  Are you basically saying the best approach
>> is just to edit locally, push to heroku, and run?
>
> I suppose if you ensure everything gets required when you boot your
> app and you limit yourself to commands which operate on the region
> rather than loading from disk (and avoid reloads) then you should be
> fine. It's just easy to get into an inconsistent state between what's
> on disk locally and what's in memory during any repl-driven
> development; throwing in a third factor of the remote disk just adds
> more room for error.
>
> -Phil

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: abysmal multicore performance, especially on AMD processors

2012-12-12 Thread Christophe Grand
See https://github.com/flatland/classlojure for a, nearly, ready-made
solution to running several Clojures in one JVM.


On Wed, Dec 12, 2012 at 5:20 PM, Lee Spector  wrote:

>
> On Dec 12, 2012, at 10:45 AM, Christophe Grand wrote:
> > Lee, while you are at benchmarking, would you mind running several
> threads in one JVM with one clojure instance per thread? Thus each thread
> should get JITted independently.
>
> I'm not actually sure how to do that. We're starting runs with "lein run",
> which, if I understand correctly launches a JVM and a Clojure instance
> within it. Within that Clojure instance we can do things in either a single
> threaded or a multi threaded way. How would I change our method to do what
> you're asking here? We're not particularly Java savvy (I come from the Lisp
> side of things).
>
> Thanks,
>
>  -Lee
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>



-- 
On Clojure http://clj-me.cgrand.net/
Clojure Programming http://clojurebook.com
Training, Consulting & Contracting http://lambdanext.eu/

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Slime and heroku setup question

2012-12-12 Thread Jonathon McKitrick
So basically, I need to get used to editing in emacs, uploading to heroku, 
and (perhaps) interactively testing via a remote repl, correct?  Sorry to 
belabor the point, but I'm trying to flatten the learning curve.

On Wednesday, December 12, 2012 2:22:33 AM UTC-5, Phil Hagelberg wrote:
>
> On Tue, Dec 11, 2012 at 6:55 PM, Jonathon McKitrick 
> > wrote: 
> > Well, I've used slime with SBCL for quite a while, but this is my first 
> > foray into clojure and heroku.  Are you basically saying the best 
> approach 
> > is just to edit locally, push to heroku, and run? 
>
> I suppose if you ensure everything gets required when you boot your 
> app and you limit yourself to commands which operate on the region 
> rather than loading from disk (and avoid reloads) then you should be 
> fine. It's just easy to get into an inconsistent state between what's 
> on disk locally and what's in memory during any repl-driven 
> development; throwing in a third factor of the remote disk just adds 
> more room for error. 
>
> -Phil 
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Slime and heroku setup question

2012-12-12 Thread Sean Corfield
You should be able to run your app locally and do all your testing and
development locally. Heroku is "just" a remote server for deployment. I'd
suggest ignoring Heroku at first and focusing on getting your Clojure app
running locally. Presumably you are building a Ring / Jetty app?


On Wed, Dec 12, 2012 at 4:09 PM, Jonathon McKitrick wrote:

> So basically, I need to get used to editing in emacs, uploading to heroku,
> and (perhaps) interactively testing via a remote repl, correct?  Sorry to
> belabor the point, but I'm trying to flatten the learning curve.
>
>
> On Wednesday, December 12, 2012 2:22:33 AM UTC-5, Phil Hagelberg wrote:
>
>> On Tue, Dec 11, 2012 at 6:55 PM, Jonathon McKitrick
>>  wrote:
>> > Well, I've used slime with SBCL for quite a while, but this is my first
>> > foray into clojure and heroku.  Are you basically saying the best
>> approach
>> > is just to edit locally, push to heroku, and run?
>>
>> I suppose if you ensure everything gets required when you boot your
>> app and you limit yourself to commands which operate on the region
>> rather than loading from disk (and avoid reloads) then you should be
>> fine. It's just easy to get into an inconsistent state between what's
>> on disk locally and what's in memory during any repl-driven
>> development; throwing in a third factor of the remote disk just adds
>> more room for error.
>>
>> -Phil
>>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

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

ANN: stream-stream 0.2.0

2012-12-12 Thread Stephen Compall
This is the second release of a simple data-conversion library between
input streams, output streams, and purely lazy lists of blocks read from
them.  It's for Clojure-JVM 1.4.0.

Clojars has it: https://clojars.org/com.nocandysw/stream-stream .

See https://answers.launchpad.net/stream-stream/+faq/2156 to get an idea
of what the library has to offer.  The project homepage is
https://launchpad.net/stream-stream .

Important changes in this release, since 0.1.0:

* Support for Clojure 1.4.0, Leiningen 2.

* block-seq->seq, views our seqs of blocks as Clojure chunked seqs.

* ->char-array-seq-sequence implements all of CharSequence.

While this release doesn't have types, typed-clojure gave me the impetus
to clean this up and finish the outstanding TODOs, so special thanks to
Ambrose Bonnaire-Sergeant for providing that.

-- 
Stephen Compall
^aCollection allSatisfy: [:each|aCondition]: less is better

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: ANN: stream-stream 0.2.0

2012-12-12 Thread Frank Siebenlist
Hi Stephen,

Could you give a few use cases that shows what your library can be used for?

Is it only for those of us that require a stream/seq of single bytes/chars?

Would that make it easier to generate sha1's for example?
Is it useful for sound/video-like streams?

Sorry if I missed the point completely…

-FrankS.



On Dec 12, 2012, at 6:10 PM, Stephen Compall  wrote:

> This is the second release of a simple data-conversion library between
> input streams, output streams, and purely lazy lists of blocks read from
> them.  It's for Clojure-JVM 1.4.0.
> 
> Clojars has it: https://clojars.org/com.nocandysw/stream-stream .
> 
> See https://answers.launchpad.net/stream-stream/+faq/2156 to get an idea
> of what the library has to offer.  The project homepage is
> https://launchpad.net/stream-stream .
> 
> Important changes in this release, since 0.1.0:
> 
> * Support for Clojure 1.4.0, Leiningen 2.
> 
> * block-seq->seq, views our seqs of blocks as Clojure chunked seqs.
> 
> * ->char-array-seq-sequence implements all of CharSequence.
> 
> While this release doesn't have types, typed-clojure gave me the impetus
> to clean this up and finish the outstanding TODOs, so special thanks to
> Ambrose Bonnaire-Sergeant for providing that.
> 
> -- 
> Stephen Compall
> ^aCollection allSatisfy: [:each|aCondition]: less is better
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from 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: ANN: stream-stream 0.2.0

2012-12-12 Thread Stephen Compall
On Wed, 2012-12-12 at 18:41 -0800, Frank Siebenlist wrote:
> Could you give a few use cases that shows what your library can be used
> for?

Sure; it is, after all, a little abstract.

The library helps you separate I/O from pure, composable functions,
while retaining performance.  It does for input streams what chunked
seqs do for lazy seqs.

Say you have a text file f, let r = (reader f).

Let bs = (read-block-seq r).  bs is a lazy seq of Java char arrays, a
"block seq", each read from the stream as requested.

Let s = (block-seq->seq bs).  s is a seq of Java chars, still lazy,
efficiently represented by the input arrays in a chunked seq.

Let lstr = (->char-array-seq-sequence bs). lstr is a Java CharSequence
(the base interface of strings), still lazily backed by the same
underlying seq of char arrays, complete with structural sharing on
subSequence.

Now you can write pure functions on these structures at whatever level
is convenient for you, and as long as you do not close the stream before
you finish processing the input, it'll work out.

> Is it only for those of us that require a stream/seq of single
> bytes/chars?

I believe that criteria covers everyone :)

> Would that make it easier to generate sha1's for example?
> Is it useful for sound/video-like streams?

In both cases, I imagine so.

-- 
Stephen Compall
"^aCollection allSatisfy: [:each | aCondition]": less is better than


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: ANN: stream-stream 0.2.0

2012-12-12 Thread Frank Siebenlist
Thanks Stephen - that's helpful.

Just a few more Qs:

In your example you have bs = (read-block-seq r),
where "bs is a lazy seq of Java char arrays…"

Does that imply that bs is an immutable seq?
That I can reread - peek at the first chars without consuming?

Also, can it be used with stdin?
Can I use it for interactive input from a terminal until the user sends 
CTRL-D/EOF?

-FrankS.


On Dec 12, 2012, at 7:43 PM, Stephen Compall  wrote:

> On Wed, 2012-12-12 at 18:41 -0800, Frank Siebenlist wrote:
>> Could you give a few use cases that shows what your library can be used
>> for?
> 
> Sure; it is, after all, a little abstract.
> 
> The library helps you separate I/O from pure, composable functions,
> while retaining performance.  It does for input streams what chunked
> seqs do for lazy seqs.
> 
> Say you have a text file f, let r = (reader f).
> 
> Let bs = (read-block-seq r).  bs is a lazy seq of Java char arrays, a
> "block seq", each read from the stream as requested.
> 
> Let s = (block-seq->seq bs).  s is a seq of Java chars, still lazy,
> efficiently represented by the input arrays in a chunked seq.
> 
> Let lstr = (->char-array-seq-sequence bs). lstr is a Java CharSequence
> (the base interface of strings), still lazily backed by the same
> underlying seq of char arrays, complete with structural sharing on
> subSequence.
> 
> Now you can write pure functions on these structures at whatever level
> is convenient for you, and as long as you do not close the stream before
> you finish processing the input, it'll work out.
> 
>> Is it only for those of us that require a stream/seq of single
>> bytes/chars?
> 
> I believe that criteria covers everyone :)
> 
>> Would that make it easier to generate sha1's for example?
>> Is it useful for sound/video-like streams?
> 
> In both cases, I imagine so.
> 
> -- 
> Stephen Compall
> "^aCollection allSatisfy: [:each | aCondition]": less is better than
> 
> 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: ANN: stream-stream 0.2.0

2012-12-12 Thread Ambrose Bonnaire-Sergeant
Lovely, glad that Typed Clojure helps clarify things. Exciting to see it
being used in real code!

Thanks,
Ambrose

On Thu, Dec 13, 2012 at 10:10 AM, Stephen Compall  wrote:

> This is the second release of a simple data-conversion library between
> input streams, output streams, and purely lazy lists of blocks read from
> them.  It's for Clojure-JVM 1.4.0.
>
> Clojars has it: https://clojars.org/com.nocandysw/stream-stream .
>
> See https://answers.launchpad.net/stream-stream/+faq/2156 to get an idea
> of what the library has to offer.  The project homepage is
> https://launchpad.net/stream-stream .
>
> Important changes in this release, since 0.1.0:
>
> * Support for Clojure 1.4.0, Leiningen 2.
>
> * block-seq->seq, views our seqs of blocks as Clojure chunked seqs.
>
> * ->char-array-seq-sequence implements all of CharSequence.
>
> While this release doesn't have types, typed-clojure gave me the impetus
> to clean this up and finish the outstanding TODOs, so special thanks to
> Ambrose Bonnaire-Sergeant for providing that.
>
> --
> Stephen Compall
> ^aCollection allSatisfy: [:each|aCondition]: less is better
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: ANN: stream-stream 0.2.0

2012-12-12 Thread Stephen Compall
On Wed, 2012-12-12 at 19:57 -0800, Frank Siebenlist wrote:
> In your example you have bs = (read-block-seq r),
> where "bs is a lazy seq of Java char arrays…"
> 
> Does that imply that bs is an immutable seq?
> That I can reread - peek at the first chars without consuming?

Absolutely.

> Also, can it be used with stdin?

You can apply it to stdin, but...

> Can I use it for interactive input from a terminal until the user sends
> CTRL-D/EOF?

No line-oriented or multiple-stream coordination features are included,
so you would still need to write a new loop here.  clojure.core provides
`line-seq', which, for line-buffered streams like stdin, would provide
the functionality you want.

-- 
Stephen Compall
"^aCollection allSatisfy: [:each | aCondition]": less is better than


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 videos deleted from blip.tv?

2012-12-12 Thread Alex Grigorovich
Hi,

I was trying to watch Rich's videos on http://clojure.blip.tv and got a 404 
Not Found. Searching blip.tv for "clojure" brings up on entry that is 
"pending deletion". Are these videos available elsewhere? What's going on?

-- 
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: Clojure videos deleted from blip.tv?

2012-12-12 Thread Ben Smith-Mannschott
I have no idea what is going on. Looks to me like blip decided to redo their 
web site and in the process throw out old content. or something.  I've got 
local copies of:

Alex Miller_ _Tree Editing with Zippers_.m4v
Chris Houser_ _Finger Trees_ Custom Persistent Collections_.m4v
Christophe Grand_ (not= DSL macros).m4v
Clojure Concurrency.m4v
Clojure Concurrency.mp4
Clojure Data Structures - Part 1.mov
Clojure Data Structures - Part 2.mov
Clojure for Java Programmers - 1 of 2.mov
Clojure for Java Programmers - 2 of 2.mov
Clojure for Lisp Programmers Part 1.mov
Clojure for Lisp Programmers Part 2.mov
Datomic-Introduction.mp4
Datomic-Query-Tutorial.mp4
David Liebke_ _From Concurrency to Parallelism_.m4v
Hammock-driven Development.m4v
Laurent Petit_ _State of Counterclockwise_ Past, Present and Future_.m4v
Luke VanderHart_ _Clojure Zippers_.m4v
Mark McGranaghan_ _One Ring to Bind Them_.m4v
Michael Fogus_ _Fertile Ground_ The Roots of Clojure_.m4v
Phil Hagelberg_ _Making Leiningen Work for You_.m4v
Rich Hickey Unveils ClojureScript.m4v
Sean Devlin_ Protocol XIII_ Clojure Protocols Explained.m4v
Starting Clojure 2012.mp4
Stuart Halloway_ _Simplicity Ain't Easy_.m4v
Tom Faulhaber_ Lisp, Functional Programming, and the State of Flow.m4v
Zach Tellman_ _Aleph_ A Framework for Asynchronous Communication_.m4v
clojure-sequences.mov

Some of these were originally hosted on blip.tv

// ben



On Dec 13, 2012, at 05:40, Alex Grigorovich  wrote:

> Hi,
> 
> I was trying to watch Rich's videos on http://clojure.blip.tv and got a 404 
> Not Found. Searching blip.tv for "clojure" brings up on entry that is 
> "pending deletion". Are these videos available elsewhere? What's going on?
> 
> -- 
> 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

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