Re: How to create and read from a stream of random characters?

2009-01-11 Thread Chouser

On Sun, Jan 11, 2009 at 9:35 PM, GS  wrote:
>
> Hi,
>
> For the purposes of testing another function (not discussed here), I
> wrote a function to generate random strings.  This is what I ended up
> with after some trial and error.
>
>  (defn generate-data [size maxlength]
>; Returns a collection of 'size random strings, each at most 'maxlength 
> chars.
>(let [alphabet "abcdefghijklmnopqrstuvwxyz"
>  rand-letter  (fn [_] (nth alphabet (rand-int 26)))
>  rand-stream  (map rand-letter (iterate inc 0))
>  rand-string  (fn [n] (apply str (take n rand-stream)))]
>  (map (fn [_] (rand-string (rand-int maxlength)))
>   (range size
>
>; test
>  (generate-data 25 19)
>
> The output of the testing function is something like ("gr", "gry",
> "gr", "g", "gry").  That is, is always _takes_ from the same sequence
> of random characters.
>
> Is there a way I might modify the above code so rand-stream is indeed
> a stream (with new random data each time) instead of a sequence (where
> every _take_ starts from the beginning)?

That generates a single rand-stream and then takes various amounts
from it in your 'map'.  To get a new random sequence each time, you'd
have to move the definition of rand-stream into your 'map' fn so that
each item of the map gets its own random stream.

Here's one way to do that:

(defn generate-data [size maxlength]
  (for [i (range size)]
(apply str (take (rand-int maxlength)
 (repeatedly #(char (+ (int \a) (rand-int 26

But since this is returning a lazy stream (as your original did),
there's not much value in passing in the size:

(defn seq-of-rand-strings [maxlength]
  (repeatedly (fn []
(apply str (take (rand-int maxlength)
 (repeatedly #(char (+ (int \a) (rand-int 26)

user=> (take 3 (seq-of-rand-strings 10))
("kae" "xwuwyp" "xa")

--Chouser

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e
a few fixes.  still not there yet.

(defn elisort [toSort]
 (with-local-vars [my-list (for [x toSort] [x])]
   (while (rest (var-get my-list))
 (let [[l1 l2 & my-list2] (var-get my-list)]
   (var-set my-list (concat my-list2 (listmerge [l1] [l2] (first
(var-get my-list)


On Mon, Jan 12, 2009 at 1:47 AM, e  wrote:

> I'm not planning on programming like this, but just to try to finish this
> up . . . .it's still not working.  I get an odd error when I actually try to
> sort something that iSeq doesn't work on integers.  I have no idea where to
> still the (first my-list) at the end so it returns, too.  No need to reply,
> per se.  Just reporting on how far I got tonight.  I'm sure someone answered
> this already and I haven't read through it all enough.
>
> (defn listmerge [l1 l2]
>  (let [l1first (first l1) l2first (first l2)]
>(cond
>  (empty? l1) l2
>  (empty? l2) l1
>  (< l1first l2first)
>(cons l1first (listmerge (rest l1) l2))
>  :else
>(cons l2first (listmerge (rest l2) l1))
>
> (defn msort [toSort]
>  (with-local-vars [my-list (for [x toSort] [x])]
>(while (rest (var-get my-list))
>  (let [[l1 l2 & my-list2] (var-get my-list)]
>(var-set my-list (concat my-list2 (listmerge l1 l2 (first
> my-list
>
> ;; test it out
> (msort [4 53 54 3 5 7 8])
>
>
>
> On Mon, Jan 12, 2009 at 1:29 AM, e  wrote:
>
>> looks like an awesome book.  will check it out more.  thanks.
>>
>>
>> On Mon, Jan 12, 2009 at 1:06 AM, Josip Gracin wrote:
>>
>>>
>>> On Sun, Jan 11, 2009 at 10:33 PM, e  wrote:
>>> > thanks for your patience.  I think I'm starting to get it.
>>> > Interesting discussion on tail recursion.
>>>
>>> Just to add $0.02... The fact that 'recur' in Clojure is actually used
>>> to implement iterative and not recursive processes is easier to
>>> understand after reading SICP (chapter 1,
>>> http://mitpress.mit.edu/sicp/full-text/book/book.html).
>>>
>>> >>>
>>>
>>
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e
I'm not planning on programming like this, but just to try to finish this up
. . . .it's still not working.  I get an odd error when I actually try to
sort something that iSeq doesn't work on integers.  I have no idea where to
still the (first my-list) at the end so it returns, too.  No need to reply,
per se.  Just reporting on how far I got tonight.  I'm sure someone answered
this already and I haven't read through it all enough.

(defn listmerge [l1 l2]
 (let [l1first (first l1) l2first (first l2)]
   (cond
 (empty? l1) l2
 (empty? l2) l1
 (< l1first l2first)
   (cons l1first (listmerge (rest l1) l2))
 :else
   (cons l2first (listmerge (rest l2) l1))

(defn msort [toSort]
 (with-local-vars [my-list (for [x toSort] [x])]
   (while (rest (var-get my-list))
 (let [[l1 l2 & my-list2] (var-get my-list)]
   (var-set my-list (concat my-list2 (listmerge l1 l2 (first
my-list

;; test it out
(msort [4 53 54 3 5 7 8])


On Mon, Jan 12, 2009 at 1:29 AM, e  wrote:

> looks like an awesome book.  will check it out more.  thanks.
>
>
> On Mon, Jan 12, 2009 at 1:06 AM, Josip Gracin wrote:
>
>>
>> On Sun, Jan 11, 2009 at 10:33 PM, e  wrote:
>> > thanks for your patience.  I think I'm starting to get it.
>> > Interesting discussion on tail recursion.
>>
>> Just to add $0.02... The fact that 'recur' in Clojure is actually used
>> to implement iterative and not recursive processes is easier to
>> understand after reading SICP (chapter 1,
>> http://mitpress.mit.edu/sicp/full-text/book/book.html).
>>
>> >>
>>
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e
looks like an awesome book.  will check it out more.  thanks.

On Mon, Jan 12, 2009 at 1:06 AM, Josip Gracin wrote:

>
> On Sun, Jan 11, 2009 at 10:33 PM, e  wrote:
> > thanks for your patience.  I think I'm starting to get it.
> > Interesting discussion on tail recursion.
>
> Just to add $0.02... The fact that 'recur' in Clojure is actually used
> to implement iterative and not recursive processes is easier to
> understand after reading SICP (chapter 1,
> http://mitpress.mit.edu/sicp/full-text/book/book.html).
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Timothy Pratley

> is the @ symbol the same as a var-get . . . or is that an atom.

@ is a reader macro that translates to (deref ) which works on vars,
atoms, refs, agents.
and yes is interchangeable with var-get.

> Your sentence about atoms was very compound.  I'm not sure if you said that 
>you
> used an atom but you didn't have to . . . .or you didn't use an atom because
> it wasnt necessary . . . . or you did use an atom because it was necessary
> with 'with-local-vars', but it wasn't necessary to use 'with-local-vars'?
> So I don't understand your point, even after reading the thread you referred
> me to.  Did you use an unsafe atom?  I assume that's what you were saying.

I should have been more clear. Someone else recommended using an atom,
I was explaining why that might not be a good idea. I am not
advocating using either a variable or atom.

> incidentally, the following code works:
>
> (with-local-vars [x 3]
>  (while (> (var-get x) 0)
>    (var-set x (- (var-get x) 1)))
>  (var-get x))
>
> did I replace your use of unsafe atoms with closure.lang.Vars  or,
> again, is @ just short hand for var-get?

Yup, just shorthand for var-get.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Java interop question

2009-01-11 Thread wal

On 12 янв, 01:01, Chouser  wrote:
> On Sun, Jan 11, 2009 at 3:30 PM, wal  wrote:
>
> > Is it possible to access a constant inside a public static class which
> > is defined inside a public interface?
>
> > For example:
>
> > package com.rabbitmq.client;
>
> > import java.io.IOException;
> > [...skipped...]
>
> > public interface AMQP
> > {
> >    public static class PROTOCOL {
> >        public static final int MAJOR = 8;
> >        public static final int MINOR = 0;
> >        public static final int PORT = 5672;
> >    }
>
> >    public static final int FRAME_METHOD = 1;
> >    public static final int FRAME_HEADER = 2;
> >    public static final int FRAME_BODY = 3;
>
> > [...skipped...]
> > }
>
> Probably com.rabbitmq.client.AMQP$PROTOCOL/PORT without parens since
> it's a field not a method.
>
> Documented athttp://clojure.org/java_interop-- search for NestedClass
>
> --Chouser

Yes, it worked! Thanks a lot!
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: when performance matters

2009-01-11 Thread e
I can't speak for clojure, so I'm interested in seeing how people who can
will answer.

There's so much to consider.  I've heard Haskell is getting faster and has
(or will have) parallel programming under the scenes (automatically doing
independent parts of operations).  There are other fast functional
languages, like OCaml and Clean, but I don't know about concurrency.

As for C++, can you afford a Cray?  They have pragmas for making parallelism
easy, and a special CPU that can do like 128 operations (one for each of 128
simultaneous streams of input) in a single cycle . . . which I think is
really cool!  If THAT becomes mainstream, I'm not sure one could argue that
C++ will be left in the dust.  Now, if Cray, stays super duper expensive,
then it's not really part of the discussion.

On Mon, Jan 12, 2009 at 12:41 AM, Mark P  wrote:

>
> I have recently found out about Clojure and am
> rather impressed.  I am seriously considering
> whether Clojure is a viable language for use at
> work.  The main stumbling block would be if
> performance (both speed and memory) turns out
> to be insufficent.  I currently use C++, but I'd love
> to be able to leave C++ behind and use Clojure
> (or similar) instead.
>
> The programs I write perform applied mathematical
> optimization (using mainly integer arithmetic)
> and often take hours (occasionally even days)
> to run.  So even small percentage improvements
> in execution speed can make a significant
> practical difference.  And large problems can use
> a large amount of memory - so memory efficiency
> is also a concern.
>
> Given these performance considerations, at first
> glance Clojure does not seem like a good choice.
> But I don't want to give up on the idea just yet.
> The allure of modernized lisp-style programming
> is really tempting.
>
> There are three key factors that still give me
> hope:
>
> 1. Some of the algorithms I use have the potential
> to be parallelized.  I am hoping that as the number
> of cores in PCs increase, at some point Clojure's
> performance will beat C++'s due to Clojure's
> superior utilization of multiple cores.  (Any ideas
> on how many cores are needed for this to become
> true?)
>
> 2. The JVM is continually being improved.  Hopefully
> in a year or two, the performance of HotSpot will be
> closer to that of C++.  (But maybe this is just
> wishful thinking.)
>
> 3. Maybe I can implement certain performance critical
> components in C++ via the JNI.  (But I get the impression
> that JNI itself isn't particularly efficient.  Also, the more
> I pull over into the C++ side, the fewer advantages to
> using Clojure.)
>
> If all else fails, maybe I could use Clojure as a prototyping
> language.  Then when I get it right, I code up the actual
> programs in C++.  But probably a lot would get lost in
> the translation from Clojure -> C++ so would it be worth
> it?
>
> I'd love to be convinced that Clojure is a viable choice,
> but I need to be a realist too.  So what do people think?
> How realistic are my three "hopes"?  And are there
> any other performance enhancing possibilities that I
> have not taken into account?
>
> Thanks,
>
> Mark P.
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Some code review for clj-record?

2009-01-11 Thread John D. Hume

Hi Emeka,
Sorry for the slow response. I don't get that message with the latest
clojure, clojure-contrib, and clj-record. (load-file just returns
nil.)

What version of clojure are you running? Do you have the base
directory of clj-record on your classpath?

Also, that file just contains the library, so you probably want to
require it rather than load-file. Or if you want to run the tests,
(load-file "clj_record/test/main.clj")


On Thu, Jan 8, 2009 at 7:01 AM, Emeka  wrote:
>
> user=> (load-file "clj_record/core.clj")
> I got clj_record/util not in system path. Why is it so?

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e
I'm sure you are right.  I'm going to have to be good at making these
arguments with my coworkers (or find somewhere else to work, maybe?  :) ) so
I appreciate the depth people are going to.

One of my next bouts of confusion is going to come from trying to figure out
what's already done.  Like I read a Brodal paper once one purely functional
heaps implemented using a forest of persistent skew-binomial trees.  But is
that sort of thing already all done?  Do I just find a heap and know that
find-min and reduce-key are as fast as they can be?  That'll be interesting.

I also want to play around with a parallel knapsack solver.  Also I want to
integrate clojure with JMonkeyEngine and do some parallel graphics/physics
stuff.

Still, the riskiest part of this all is the programming environment, as I
see it.  The language is pretty unreadible, so say many people who haven't
given it the 3 weeks (that part doesn't bother me -- just gotta learn it).
But things like the errors not referencing clojure line numbers?  No way
that I have figured out how to step through code in a debugger?  Well, it's
a hard sell without an 800-core machine sitting right in the room begging to
be programmed on.

On Mon, Jan 12, 2009 at 12:53 AM, Adrian Cuthbertson <
adrian.cuthbert...@gmail.com> wrote:

>
> Bear with the trials and tribulations (of grokking
> functional/clojure). It takes a few weeks of trying things out,
> absorbing the documentation and group archives, watching the group
> posts and then suddenly there are  one or two "aha" moments and then
> the flood gates open! When you've crossed the threshold, it's too late
> - you can never go back. You'll want to go and redo everything you've
> ever done imperatively! For me the "aha" moments came when I first
> (really) understood reduce, map and fn. I'd reccomend focusing on
> those and trying to (first) do all your looping constructs with those
> rather than loop/recur - that forces you to learn to think functional
> while loop/recur still lets your mind stick to imperative patterns.
>
> Regards, Adrian.
>
> On Mon, Jan 12, 2009 at 7:24 AM, e  wrote:
> > here's a good explanation:
> >
> http://groups.google.com/group/clojure/browse_thread/thread/3c22b35f079e0de6/95fc0b334ab77c1f
> >
> > I wasn't thinking about closures since I've only recently even learned
> what
> > they are.  I actually don't know if it will ever occur to me to use them,
> > but it sounds like they are the reason we are encouraged to jump through
> > such hoops even for local variables.  closures allow them to "leak".
> >
> > It's funny, whenever I tried to be all safe like this and take the time
> to
> > make stuff safe in C++, coworkers would say, "we are grown-ups.  At some
> > point you gotta stop being a paranoid programmer.  Document the usage,
> and
> > woe be it unto the user who doesn't 'RTFM'".
> >
> > Another thing is to make the common case easy . . . .and uh, mutable
> local
> > variables are pretty darn common, as Rich anticipated when he predicted
> that
> > people would be excited about the 'with-local-vars' macro.  I was
> thinking
> > the same thing, "fine, I'll learn how to write macros, then".  I can see
> > that this issue comes up again and again with everyone who walks in the
> > door, and it probably will continue to.  Who knows, maybe Rich will
> change
> > the world.  It sure will take a lot of energy.  That's for sure.
> >
> > On Sun, Jan 11, 2009 at 10:27 PM, Timothy Pratley <
> timothyprat...@gmail.com>
> > wrote:
> >>
> >> > thread should own the memory that's created.  Each thread should have
> >> > its own asynchronous stack to push local variables onto that no one
> >> > else is allowed to see.
> >>
> >> Just for the record, Clojure does support local variable that behave
> >> exactly as you would expect them:
> >> (with-local-vars [x 3]
> >>  (while (> @x 0)
> >>(var-set x (- @x 1)))
> >>  @x)
> >> -> 0
> >>
> >> Using an atom is unnecessary in this case because access is totally
> >> local. Using an unsafe atom set is a bad habit, as discussed in detail
> >> on another thread:
> >>
> >>
> http://groups.google.com/group/clojure/browse_thread/thread/6497e7c8bc58bb4e/c5b3c9dbe6a1f5d5
> >>
> >> However as you have already seen there are more elegant ways to write
> >> the solution without either.
> >>
> >>
> >>
> >
> >
> > >
> >
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Josip Gracin

On Sun, Jan 11, 2009 at 10:33 PM, e  wrote:
> thanks for your patience.  I think I'm starting to get it.
> Interesting discussion on tail recursion.

Just to add $0.02... The fact that 'recur' in Clojure is actually used
to implement iterative and not recursive processes is easier to
understand after reading SICP (chapter 1,
http://mitpress.mit.edu/sicp/full-text/book/book.html).

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Timothy Pratley

My point was that it is not a missing capability,

Say you want to accumulate some changes, in this case sum odd numbers:
In C++ someone might write this:
int x = 0;
for (int i=0; i<100; i++) {
   if ( i%2==1 ) x+=i;
}

However in Clojure you have a choice:
(reduce + (range 1 100 2))

Or you could do a direct translation to Clojure:
(with-local-vars [i 0, x 0]
  (while (< @i 100)
(if (= 1 (rem @i 2)) (var-set x (+ @x @i)))
(var-set i (inc @i)))
  @x)

Both get the same result, but have very different styles.
The version without variables is much easier to understand, provided
you know what reduce does. So it takes a little bit of work initially
to stop using variables, but it is well worth the effort.


Regards,
Tim.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Adrian Cuthbertson

Bear with the trials and tribulations (of grokking
functional/clojure). It takes a few weeks of trying things out,
absorbing the documentation and group archives, watching the group
posts and then suddenly there are  one or two "aha" moments and then
the flood gates open! When you've crossed the threshold, it's too late
- you can never go back. You'll want to go and redo everything you've
ever done imperatively! For me the "aha" moments came when I first
(really) understood reduce, map and fn. I'd reccomend focusing on
those and trying to (first) do all your looping constructs with those
rather than loop/recur - that forces you to learn to think functional
while loop/recur still lets your mind stick to imperative patterns.

Regards, Adrian.

On Mon, Jan 12, 2009 at 7:24 AM, e  wrote:
> here's a good explanation:
> http://groups.google.com/group/clojure/browse_thread/thread/3c22b35f079e0de6/95fc0b334ab77c1f
>
> I wasn't thinking about closures since I've only recently even learned what
> they are.  I actually don't know if it will ever occur to me to use them,
> but it sounds like they are the reason we are encouraged to jump through
> such hoops even for local variables.  closures allow them to "leak".
>
> It's funny, whenever I tried to be all safe like this and take the time to
> make stuff safe in C++, coworkers would say, "we are grown-ups.  At some
> point you gotta stop being a paranoid programmer.  Document the usage, and
> woe be it unto the user who doesn't 'RTFM'".
>
> Another thing is to make the common case easy . . . .and uh, mutable local
> variables are pretty darn common, as Rich anticipated when he predicted that
> people would be excited about the 'with-local-vars' macro.  I was thinking
> the same thing, "fine, I'll learn how to write macros, then".  I can see
> that this issue comes up again and again with everyone who walks in the
> door, and it probably will continue to.  Who knows, maybe Rich will change
> the world.  It sure will take a lot of energy.  That's for sure.
>
> On Sun, Jan 11, 2009 at 10:27 PM, Timothy Pratley 
> wrote:
>>
>> > thread should own the memory that's created.  Each thread should have
>> > its own asynchronous stack to push local variables onto that no one
>> > else is allowed to see.
>>
>> Just for the record, Clojure does support local variable that behave
>> exactly as you would expect them:
>> (with-local-vars [x 3]
>>  (while (> @x 0)
>>(var-set x (- @x 1)))
>>  @x)
>> -> 0
>>
>> Using an atom is unnecessary in this case because access is totally
>> local. Using an unsafe atom set is a bad habit, as discussed in detail
>> on another thread:
>>
>> http://groups.google.com/group/clojure/browse_thread/thread/6497e7c8bc58bb4e/c5b3c9dbe6a1f5d5
>>
>> However as you have already seen there are more elegant ways to write
>> the solution without either.
>>
>>
>>
>
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e
is the @ symbol the same as a var-get . . . or is that and atom.  Your
sentence about atoms was very compound.  I'm not sure if you said that you
used an atom but you didn't have to . . . .or you didn't use an atom because
it wasnt necessary . . . . or you did use an atom because it was necessary
with 'with-local-vars', but it wasn't necessary to use 'with-local-vars'?
So I don't understand your point, even after reading the thread you referred
me to.  Did you use an unsafe atom?  I assume that's what you were saying. .
.

incidentally, the following code works:

(with-local-vars [x 3]
 (while (> (var-get x) 0)
   (var-set x (- (var-get x) 1)))
 (var-get x))

did I replace your use of unsafe atoms with closure.lang.Vars  or,
again, is @ just short hand for var-get?

Thanks.

On Sun, Jan 11, 2009 at 10:27 PM, Timothy Pratley
wrote:

>
> > thread should own the memory that's created.  Each thread should have
> > its own asynchronous stack to push local variables onto that no one
> > else is allowed to see.
>
> Just for the record, Clojure does support local variable that behave
> exactly as you would expect them:
> (with-local-vars [x 3]
>  (while (> @x 0)
>(var-set x (- @x 1)))
>  @x)
> -> 0
>
> Using an atom is unnecessary in this case because access is totally
> local. Using an unsafe atom set is a bad habit, as discussed in detail
> on another thread:
>
> http://groups.google.com/group/clojure/browse_thread/thread/6497e7c8bc58bb4e/c5b3c9dbe6a1f5d5
>
> However as you have already seen there are more elegant ways to write
> the solution without either.
>
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



when performance matters

2009-01-11 Thread Mark P

I have recently found out about Clojure and am
rather impressed.  I am seriously considering
whether Clojure is a viable language for use at
work.  The main stumbling block would be if
performance (both speed and memory) turns out
to be insufficent.  I currently use C++, but I'd love
to be able to leave C++ behind and use Clojure
(or similar) instead.

The programs I write perform applied mathematical
optimization (using mainly integer arithmetic)
and often take hours (occasionally even days)
to run.  So even small percentage improvements
in execution speed can make a significant
practical difference.  And large problems can use
a large amount of memory - so memory efficiency
is also a concern.

Given these performance considerations, at first
glance Clojure does not seem like a good choice.
But I don't want to give up on the idea just yet.
The allure of modernized lisp-style programming
is really tempting.

There are three key factors that still give me
hope:

1. Some of the algorithms I use have the potential
to be parallelized.  I am hoping that as the number
of cores in PCs increase, at some point Clojure's
performance will beat C++'s due to Clojure's
superior utilization of multiple cores.  (Any ideas
on how many cores are needed for this to become
true?)

2. The JVM is continually being improved.  Hopefully
in a year or two, the performance of HotSpot will be
closer to that of C++.  (But maybe this is just
wishful thinking.)

3. Maybe I can implement certain performance critical
components in C++ via the JNI.  (But I get the impression
that JNI itself isn't particularly efficient.  Also, the more
I pull over into the C++ side, the fewer advantages to
using Clojure.)

If all else fails, maybe I could use Clojure as a prototyping
language.  Then when I get it right, I code up the actual
programs in C++.  But probably a lot would get lost in
the translation from Clojure -> C++ so would it be worth
it?

I'd love to be convinced that Clojure is a viable choice,
but I need to be a realist too.  So what do people think?
How realistic are my three "hopes"?  And are there
any other performance enhancing possibilities that I
have not taken into account?

Thanks,

Mark P.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e
here's a good explanation:
http://groups.google.com/group/clojure/browse_thread/thread/3c22b35f079e0de6/95fc0b334ab77c1f

I wasn't thinking about closures since I've only recently even learned what
they are.  I actually don't know if it will ever occur to me to use them,
but it sounds like they are the reason we are encouraged to jump through
such hoops even for local variables.  closures allow them to "leak".

It's funny, whenever I tried to be all safe like this and take the time to
make stuff safe in C++, coworkers would say, "we are grown-ups.  At some
point you gotta stop being a paranoid programmer.  Document the usage, and
woe be it unto the user who doesn't 'RTFM'".

Another thing is to make the common case easy . . . .and uh, mutable local
variables are pretty darn common, as Rich anticipated when he predicted that
people would be excited about the 'with-local-vars' macro.  I was thinking
the same thing, "fine, I'll learn how to write macros, then".  I can see
that this issue comes up again and again with everyone who walks in the
door, and it probably will continue to.  Who knows, maybe Rich will change
the world.  It sure will take a lot of energy.  That's for sure.

On Sun, Jan 11, 2009 at 10:27 PM, Timothy Pratley
wrote:

>
> > thread should own the memory that's created.  Each thread should have
> > its own asynchronous stack to push local variables onto that no one
> > else is allowed to see.
>
> Just for the record, Clojure does support local variable that behave
> exactly as you would expect them:
> (with-local-vars [x 3]
>  (while (> @x 0)
>(var-set x (- @x 1)))
>  @x)
> -> 0
>
> Using an atom is unnecessary in this case because access is totally
> local. Using an unsafe atom set is a bad habit, as discussed in detail
> on another thread:
>
> http://groups.google.com/group/clojure/browse_thread/thread/6497e7c8bc58bb4e/c5b3c9dbe6a1f5d5
>
> However as you have already seen there are more elegant ways to write
> the solution without either.
>
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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 aren't lists callable?

2009-01-11 Thread Mark Fredrickson

I can't imagine this idea will be met warmly, but I have a suggestion.  
It requires ending maps and vectors as functions of keys. Instead,  
make the first argument to a collection be a function which is mapped  
to across the collection. Any additional arguments are passed to the  
function on each invocation. For maps and hashes, this would only be  
applied to the values. Keys would remain the same.

Some examples:
('(1 2 3) * 2) => (2 4 6)
({:greet "hello" :farewell "goodbye"} str " Mark") => {:greet "hello  
Mark" :farewell "goodbye Mark"}

If the primary type used as keys are keywords or symbols, we don't  
give up much. As (:key map) still works in place of (map :key).

I'm not tied to this idea. I thought of it a while ago, and it  
certainly has its draw backs. I wouldn't suggest a 1/2 way solution --  
making lists functions of functions and maps functions of keys --  
thats certainly a world of headaches.

Anyway, back to business as usual.

Cheers,
-Mark


On Jan 11, 2009, at 9:59 PM, Chouser wrote:

>
> On Sun, Jan 11, 2009 at 9:38 PM, Ethan Herdrick   
> wrote:
>>
>> Why aren't all sequences callable, i.e. why don't they all implement
>> IFn?  I'd like to use lists like this sometimes.
>
> When you call maps and vectors, it acts as if you're calling 'get'.
> But 'get' doesn't do anything useful for lists.  So what should a list
> do when called?
>
> --Chouser
>
> >


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: trouble with java.lang.OutOfMemoryError

2009-01-11 Thread Adrian Cuthbertson

>I might look at the JEdit plugin though - JEdit is nice, for simple
>editing, which might be good enough for me for now.

I similarly haven't had time to relearn emacs and have used jedit quite
sucessfully with jedit-mode. I keep one or more terminal window tabs open
each with a REPL launched with rlwrap and then just copy and paste from the
associated jedit tab/buffer. With up_arrow and dn_arrow bound to
"back_history" and "forward_history" in rlwrap, it's easy to try stuf in the
REPL, recall/edit previous lines, etc, and copy/paste back to jedit when
necessary. The main advantage for me is this works identically when I have
an ssh session open to a server with REPL/rlwrap. I can similarly copy/paste
from jedit and do very interactive development directly on the server as
well as on my local machine, switching between everything with one or two
keystrokes. I'm just about down to a pure keystroke driven dev environment
with almost never touching the mouse. Primiive and a bit messy, but it works
well.

[Footnote to the above - I also have a terminal tab open just for compiles.
Using ant (build.xml's adapted from clojure's build), the full cycle
includes then tabbing to the ant terminal, recalling/running the build and
using rsync to copy changed classes to the server. I can then immediately
switch to the server/ssh tab and reload/work with the newly built code.]



On Mon, Jan 12, 2009 at 5:28 AM, Korny Sietsma  wrote:
>
> I have had similar problems with enclojure.  But having gone through
> similar IDE pain working in Ruby on Rails, the Netbeans support ended
> up being way ahead of most IDEs, so I have hopes that enclojure will
> get there in time.  (My biggest annoyance?  The fact that you can't
> open existing code as a new project - I want to browse
> clojure-contrib, but I can only do it by creating a new "hello world"
> project first!)
>
> I'd kind-of like to re-learn emacs - many years ago I was a keen emacs
> user - my biggest problem is that I'm on a Mac, and I have to keep
> switching between IDEs and PCs (my work desktop is Linux) not to
> mention languages.  I don't have the spare brain cells to learn
> another set of key bindings!  I need an IDE with easy built-in help,
> and while "M-x slime-cheatsheet" is handy, it doesn't spare me the
> world-o-pain when I hit "Alt-w" (one of the few keystrokes my fingers
> remember from last time) and my emacs window closes!  Argh!
>
> So I try to stick with IDEs that have everything on menus, so when I
> forget the "open file anywhere in project" command for a particular
> IDE, I can look it up.  (Does Emacs have this, by the way?  It doesn't
> really have a "project" concept... )
>
> I might look at the JEdit plugin though - JEdit is nice, for simple
> editing, which might be good enough for me for now.
>
> Incidentally, if you want a language with an editor built in, why not
> look at Smalltalk?  I vaguely recall that was a big part of the
> original language concept.  I haven't ever played with it myself, but
> the most popular current flavour seems to be Squeak:
> http://www.squeak.org/
>
> - Korny
>
>
> On Sun, Jan 11, 2009 at 1:18 PM, e  wrote:
>>
>> seems like enclosjure addresses a bunch of my problems/questions.  It
>> also seems to work like we wanted SLIME to work, more or
>> less . . .where you attach to the vm that's used for execution . . .
>> only you attach to the REPL, I think, which still accomplishes the
>> goal of keeping the editor separate from the memory, but what about
>> having the REPL being able to attach to the vm it is managing.  Then
>> it wouldn't be something that NetBeans/enclosure is doing . . . rather
>> something that's part of the language.
>>
>> So, yeah.  enslojure sets up a HelloWorld that you can play with right
>> away.  In fact, when you click on "build" it even tells you how you
>> could run your application from the command line using a java
>> command.  It jars up you whole clojure project and everything.  Nice.
>> On the other hand, I couldn't figure out how to use NetBeans' run
>> button.  it couldn't find main or something.  So I also couldn't debug
>> using NetBeans' debugger because of this.  Also, it isn't clear how to
>> get different clojure files to work together.  Do you use the (load)
>> function?  If so, I don't know how the project thinks of relative file
>> locations.  It's not as clean/clear as java (for a beginner, at least)
>> where you just import classes you want to use . . and make
>> packages. . . . or modules in python.  I don't know what the notion of
>> "path" is in clojure.  I see the namespace stuff but have no clue how
>> to make it work yet.  Are you just supposed to use one giant file for
>> all your work?  That wouldn't be good for teams, for sure. . . only
>> for hacking.  Also the REPL errors are USELESS to a beginner.
>> something about iSeq all the time.  The moral for me there was no to
>> make an error.  Better than where I was before enclojure.  Again, I
>> contend that 

Re: SLIME: trouble with java.lang.OutOfMemoryError

2009-01-11 Thread Eric Lavigne
>
>
> Incidentally, if you want a language with an editor built in, why not
> look at Smalltalk?  I vaguely recall that was a big part of the
> original language concept.  I haven't ever played with it myself, but
> the most popular current flavour seems to be Squeak:
> http://www.squeak.org/
>

Smalltalk is an excellent language (though I have a personal preference for
Lisp). It also provides a glimpse into what the term "object-oriented"
originally meant. In case anyone reading this thread decides to explore
Smalltalk, here are a few pointers to introductory information.

Yes, Squeak is popular, mostly because it is very portable, easy to install,
and open source. It is also developed primarily as an introductory
programming environment for children, and that has held it back as an
environment for professional programmers.

Pharo is a recent fork of Squeak, with the intention of completely ignoring
the needs of children and focusing on making a good environment for
professional programmers.

http://code.google.com/p/pharo/

Also, there is a very nice web development framework for Smalltalk.
Smalltalk is worth learning just for a chance to see a new way of doing web
development.

http://seaside.st/

I would recommend starting with Squeak as it is very easy to work with (if
children can handle it, so can you), and switch to Pharo later when you are
ready for production deployment. The following book is a good starting point
for either environment (and is available for free online).

http://squeakbyexample.org/

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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 aren't lists callable?

2009-01-11 Thread Chouser

On Sun, Jan 11, 2009 at 9:38 PM, Ethan Herdrick  wrote:
>
> Why aren't all sequences callable, i.e. why don't they all implement
> IFn?  I'd like to use lists like this sometimes.

When you call maps and vectors, it acts as if you're calling 'get'.
But 'get' doesn't do anything useful for lists.  So what should a list
do when called?

--Chouser

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: trouble with java.lang.OutOfMemoryError

2009-01-11 Thread Korny Sietsma

I have had similar problems with enclojure.  But having gone through
similar IDE pain working in Ruby on Rails, the Netbeans support ended
up being way ahead of most IDEs, so I have hopes that enclojure will
get there in time.  (My biggest annoyance?  The fact that you can't
open existing code as a new project - I want to browse
clojure-contrib, but I can only do it by creating a new "hello world"
project first!)

I'd kind-of like to re-learn emacs - many years ago I was a keen emacs
user - my biggest problem is that I'm on a Mac, and I have to keep
switching between IDEs and PCs (my work desktop is Linux) not to
mention languages.  I don't have the spare brain cells to learn
another set of key bindings!  I need an IDE with easy built-in help,
and while "M-x slime-cheatsheet" is handy, it doesn't spare me the
world-o-pain when I hit "Alt-w" (one of the few keystrokes my fingers
remember from last time) and my emacs window closes!  Argh!

So I try to stick with IDEs that have everything on menus, so when I
forget the "open file anywhere in project" command for a particular
IDE, I can look it up.  (Does Emacs have this, by the way?  It doesn't
really have a "project" concept... )

I might look at the JEdit plugin though - JEdit is nice, for simple
editing, which might be good enough for me for now.

Incidentally, if you want a language with an editor built in, why not
look at Smalltalk?  I vaguely recall that was a big part of the
original language concept.  I haven't ever played with it myself, but
the most popular current flavour seems to be Squeak:
http://www.squeak.org/

- Korny


On Sun, Jan 11, 2009 at 1:18 PM, e  wrote:
>
> seems like enclosjure addresses a bunch of my problems/questions.  It
> also seems to work like we wanted SLIME to work, more or
> less . . .where you attach to the vm that's used for execution . . .
> only you attach to the REPL, I think, which still accomplishes the
> goal of keeping the editor separate from the memory, but what about
> having the REPL being able to attach to the vm it is managing.  Then
> it wouldn't be something that NetBeans/enclosure is doing . . . rather
> something that's part of the language.
>
> So, yeah.  enslojure sets up a HelloWorld that you can play with right
> away.  In fact, when you click on "build" it even tells you how you
> could run your application from the command line using a java
> command.  It jars up you whole clojure project and everything.  Nice.
> On the other hand, I couldn't figure out how to use NetBeans' run
> button.  it couldn't find main or something.  So I also couldn't debug
> using NetBeans' debugger because of this.  Also, it isn't clear how to
> get different clojure files to work together.  Do you use the (load)
> function?  If so, I don't know how the project thinks of relative file
> locations.  It's not as clean/clear as java (for a beginner, at least)
> where you just import classes you want to use . . and make
> packages. . . . or modules in python.  I don't know what the notion of
> "path" is in clojure.  I see the namespace stuff but have no clue how
> to make it work yet.  Are you just supposed to use one giant file for
> all your work?  That wouldn't be good for teams, for sure. . . only
> for hacking.  Also the REPL errors are USELESS to a beginner.
> something about iSeq all the time.  The moral for me there was no to
> make an error.  Better than where I was before enclojure.  Again, I
> contend that a language is only as good as the IDE that has been
> written for it, which is why it's cool to see enclojure coming along
> (even though it means learning NetBeans instead of Eclipse).
>
>
> On Jan 10, 5:31 pm, Paul  Mooser  wrote:
>> If I'm not mistaken, this is fairly close to how SLIME works, when
>> connected to a remote VM. The remote VM is running some server code
>> which allows it to communicate with SLIME, which is running inside of
>> emacs.
>>
>> On Jan 10, 2:15 pm, e  wrote:
>>
>> > exactly. . . .but I bet a lot of people would just reply that this is
>> > not possible to address since the REPL is the one and only vm.
>> > Disclaimer, I'm only guessing at that, too.  I don't understand any of
>> > this, yet.  But if that's the case, fix that.  Have the REPL send
>> > messages to the vm that's running the program . . . instead of the
>> > REPL being the program.
>>
>> > On Jan 10, 5:00 pm, Paul  Mooser  wrote:
>>
>> > > Yeah, I'm not really sure how I think the problem would be ideally
>> > > solved. It would just be nice for an interactive programming
>> > > environment to be able to recover from all exceptions that happen at a
>> > > higher level than the VM itself.
>>
>> > > On Jan 10, 12:20 pm, "Christian Vest Hansen" 
>> > > wrote:
>>
>> > > > I don't think it is possible to define a way to deal with heap
>> > > > saturation that is general enough to cover all programs written in
>> > > > Clojure, and therefor I don't think this is something that the Clojure
>> > > > runtime should deal with at 

Re: non recursive impl in presence of persistence?

2009-01-11 Thread Timothy Pratley

> thread should own the memory that's created.  Each thread should have
> its own asynchronous stack to push local variables onto that no one
> else is allowed to see.

Just for the record, Clojure does support local variable that behave
exactly as you would expect them:
(with-local-vars [x 3]
  (while (> @x 0)
(var-set x (- @x 1)))
  @x)
-> 0

Using an atom is unnecessary in this case because access is totally
local. Using an unsafe atom set is a bad habit, as discussed in detail
on another thread:
http://groups.google.com/group/clojure/browse_thread/thread/6497e7c8bc58bb4e/c5b3c9dbe6a1f5d5

However as you have already seen there are more elegant ways to write
the solution without either.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Why aren't lists callable?

2009-01-11 Thread Ethan Herdrick

Why aren't all sequences callable, i.e. why don't they all implement
IFn?  I'd like to use lists like this sometimes.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



How to create and read from a stream of random characters?

2009-01-11 Thread GS

Hi,

For the purposes of testing another function (not discussed here), I
wrote a function to generate random strings.  This is what I ended up
with after some trial and error.

  (defn generate-data [size maxlength]
; Returns a collection of 'size random strings, each at most
'maxlength chars.
(let [alphabet "abcdefghijklmnopqrstuvwxyz"
  rand-letter  (fn [_] (nth alphabet (rand-int 26)))
  rand-stream  (map rand-letter (iterate inc 0))
  rand-string  (fn [n] (apply str (take n rand-stream)))]
  (map (fn [_] (rand-string (rand-int maxlength)))
   (range size

; test
  (generate-data 25 19)


The output of the testing function is something like ("gr", "gry",
"gr", "g", "gry").  That is, is always _takes_ from the same sequence
of random characters.

Is there a way I might modify the above code so rand-stream is indeed
a stream (with new random data each time) instead of a sequence (where
every _take_ starts from the beginning)?

Of course, I'd love to see other people's approach to implementing
'generate-data, but I'm also curious about the idea of streams
themselves.

Cheers,
Gavin [second post]
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: what does -> mean?

2009-01-11 Thread Mark Triggs

I've also found this useful for accessing members in nested maps.  For
example:

  (let [me {:person {:name {:first "Mark"
:last "Triggs"}
 :email "mark.h.tri...@gmail.com"}}]
(-> me :person :name :first))

  => "Mark"

On Jan 12, 1:04 pm, kkw  wrote:
> One use I've found for -> (though there are others I haven't come to
> appreciate yet) is when I have something like:
> (f1 (f2 (f3 (f4 x
>
> which can be re-written as
> (-> x f4 f3 f2 f1)
>
> I find the latter expression easier to read.
>
> Kev
>
> On Dec 30 2008, 2:49 pm, wubbie  wrote:
>
> > Very criptic for newbie.
> > What  does "Threads the expr through the forms." mean?
> > Does it create a thread to execute?
>
> > thanks
> > sun
>
> > On Dec 29, 10:07 pm, Paul Barry  wrote:
>
> > > You can look up the documentation for a function/macro interactively
> > > from the repl:
>
> > > user=> (doc ->)
> > > -
> > > clojure.core/->
> > > ([x form] [x form & more])
> > > Macro
> > >   Threads the expr through the forms. Inserts x as the
> > >   second item in the first form, making a list of it if it is not a
> > >   list already. If there are more forms, inserts the first form as the
> > >   second item in second form, etc.
> > > nil
>
> > > On Dec 29, 8:27 pm, wubbie  wrote:
>
> > > > Hi all,
>
> > > > Looking intoants.clj, I came across
> > > > (defn place [[x y]]
> > > >   (-> world (nth x) (nth y)))
>
> > > > What -> mean here?
>
> > > > thanks
> > > > sun
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: what does -> mean?

2009-01-11 Thread kkw

One use I've found for -> (though there are others I haven't come to
appreciate yet) is when I have something like:
(f1 (f2 (f3 (f4 x

which can be re-written as
(-> x f4 f3 f2 f1)

I find the latter expression easier to read.

Kev

On Dec 30 2008, 2:49 pm, wubbie  wrote:
> Very criptic for newbie.
> What  does "Threads the expr through the forms." mean?
> Does it create a thread to execute?
>
> thanks
> sun
>
> On Dec 29, 10:07 pm, Paul Barry  wrote:
>
> > You can look up the documentation for a function/macro interactively
> > from the repl:
>
> > user=> (doc ->)
> > -
> > clojure.core/->
> > ([x form] [x form & more])
> > Macro
> >   Threads the expr through the forms. Inserts x as the
> >   second item in the first form, making a list of it if it is not a
> >   list already. If there are more forms, inserts the first form as the
> >   second item in second form, etc.
> > nil
>
> > On Dec 29, 8:27 pm, wubbie  wrote:
>
> > > Hi all,
>
> > > Looking intoants.clj, I came across
> > > (defn place [[x y]]
> > >   (-> world (nth x) (nth y)))
>
> > > What -> mean here?
>
> > > thanks
> > > sun
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Newbie: Creating a macro that just calls a function but evaluates its arguments lazily

2009-01-11 Thread samppi

The problem is that even though "some" and "filter" are lazy, "alt" is
still not, so calling "(alt (sub-function1 c) ...)" in the meta-meta-
function still evaluates (sub-function1 c), etc. It could be shown in
the REPL:

Clojure
user=> (defn alt [& functions]
  (fn [tokens]
(some #(% tokens) functions)))
#'user/alt
user=> (defn sub-function1 [c] (println "1:" c) (fn [c] false))
#'user/sub-function1
user=> (defn sub-function2 [c] (println "2:" c) (fn [c] true))
#'user/sub-function2
user=> (defn sub-function3 [c] (println "3:" c) (fn [c] false))
#'user/sub-function3
user=> (defn a-meta-meta-function [c]
  (alt (sub-function1 c) (sub-function2 c) (sub-function3 c)))
#'user/a-meta-meta-function
user=> ((a-meta-meta-function "CONTEXT") [:a :b :c])
1: CONTEXT
2: CONTEXT
3: CONTEXT
true

What I wish is for calling '((a-meta-meta-function "CONTEXT")
[:a :b :c])' to output:
1: CONTEXT
2: CONTEXT

...only, which means that the sub-functions are called only until a
sub-function's created function returns a true value. The root of the
problem is that in Clojure's rules (I think), the arguments of a
regular function are all evaluated before being plugged into the
function. That's why I'm wondering if a macro could solve my problem.

Thanks for your answers!

On Jan 11, 3:02 pm, Stuart Sierra  wrote:
> "some" is already lazy, so you may not need to change anything at
> all.  You might also be able to use "filter", which will not do
> anything until you consume the output sequence.
> -Stuart Sierra
>
> On Jan 11, 4:44 pm, samppi  wrote:
>
> > Let's say I have a function, alt:
>
> > (defn alt [& functions]
> >   (fn [tokens]
> >     (some #(% tokens) functions)))
>
> > It creates a function from a bunch of sub-functions that accepts one
> > collection of tokens and figures out which sub-function returns a true
> > value when the tokens are plugged into it.
>
> > Is there a way to change alt—maybe to a macro—that lazily evaluates
> > the functions? This is so that with:
>
> > (defn a-meta-meta-function [c]
> >   (alt (sub-function1 c) (sub-function2 c) (sub-function3 c)))
>
> > ...calling ((a-meta-meta-function foo) some-tokens) doesn't evaluate
> > (sub-function 2 c) and (sub-function3 c) until needed to receive some-
> > tokens.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Newbie: Creating a macro that just calls a function but evaluates its arguments lazily

2009-01-11 Thread Stuart Sierra

"some" is already lazy, so you may not need to change anything at
all.  You might also be able to use "filter", which will not do
anything until you consume the output sequence.
-Stuart Sierra


On Jan 11, 4:44 pm, samppi  wrote:
> Let's say I have a function, alt:
>
> (defn alt [& functions]
>   (fn [tokens]
>     (some #(% tokens) functions)))
>
> It creates a function from a bunch of sub-functions that accepts one
> collection of tokens and figures out which sub-function returns a true
> value when the tokens are plugged into it.
>
> Is there a way to change alt—maybe to a macro—that lazily evaluates
> the functions? This is so that with:
>
> (defn a-meta-meta-function [c]
>   (alt (sub-function1 c) (sub-function2 c) (sub-function3 c)))
>
> ...calling ((a-meta-meta-function foo) some-tokens) doesn't evaluate
> (sub-function 2 c) and (sub-function3 c) until needed to receive some-
> tokens.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Java interop question

2009-01-11 Thread Chouser

On Sun, Jan 11, 2009 at 3:30 PM, wal  wrote:
>
> Is it possible to access a constant inside a public static class which
> is defined inside a public interface?
>
> For example:
>
> package com.rabbitmq.client;
>
> import java.io.IOException;
> [...skipped...]
>
> public interface AMQP
> {
>public static class PROTOCOL {
>public static final int MAJOR = 8;
>public static final int MINOR = 0;
>public static final int PORT = 5672;
>}
>
>public static final int FRAME_METHOD = 1;
>public static final int FRAME_HEADER = 2;
>public static final int FRAME_BODY = 3;
>
> [...skipped...]
> }

Probably com.rabbitmq.client.AMQP$PROTOCOL/PORT without parens since
it's a field not a method.

Documented at http://clojure.org/java_interop -- search for NestedClass

--Chouser

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Newbie: Creating a macro that just calls a function but evaluates its arguments lazily

2009-01-11 Thread samppi

Let's say I have a function, alt:

(defn alt [& functions]
  (fn [tokens]
(some #(% tokens) functions)))

It creates a function from a bunch of sub-functions that accepts one
collection of tokens and figures out which sub-function returns a true
value when the tokens are plugged into it.

Is there a way to change alt—maybe to a macro—that lazily evaluates
the functions? This is so that with:

(defn a-meta-meta-function [c]
  (alt (sub-function1 c) (sub-function2 c) (sub-function3 c)))

...calling ((a-meta-meta-function foo) some-tokens) doesn't evaluate
(sub-function 2 c) and (sub-function3 c) until needed to receive some-
tokens.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Java interop question

2009-01-11 Thread wal

Is it possible to access a constant inside a public static class which
is defined inside a public interface?

For example:

package com.rabbitmq.client;

import java.io.IOException;
[...skipped...]

public interface AMQP
{
public static class PROTOCOL {
public static final int MAJOR = 8;
public static final int MINOR = 0;
public static final int PORT = 5672;
}

public static final int FRAME_METHOD = 1;
public static final int FRAME_HEADER = 2;
public static final int FRAME_BODY = 3;

[...skipped...]
}

I did a lot of experimentartion in the REPL, but no success yet - I
can't figure out how to access com.rabbimq.client.AMQP.PROTOCOL.PORT
constant in Clojure.

It is possible to (import 'com.rabbitmq.client.AMQP), but (import
'com.rabbitmq.client.AMQP.PROTOCOL) gives ClassNotFoundException.

(. com.rabbimq.AMQP FRAME_METHOD) returns 1, but neither (.
com.rabbitmq.client.AMQP.PROTOCOL PORT), nor
(com.rabbitmq.client.AMQP.PROTOCOL/PORT) works.

What I'm doing wrong?

Best regards,
Vladimir

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Dead code in generated bytecode

2009-01-11 Thread LS

While trying to run clojure on JNode I noticed that some dead code in
the ASM generated bytecode of clojure makes it fail because it
confuses the JIT.
One example of the problem can be seen with javap:
 javap -c clojure.core\$last__2780

Result (relevant part) :

public java.lang.Object invoke(java.lang.Object)   throws
java.lang.Exception;
  Code:
   0:   getstatic   #22; //Field const__0:Lclojure/lang/Var;
   3:   invokevirtual   #37; //Method clojure/lang/Var.get:()Ljava/
lang/Object;
   6:   checkcast   #39; //class clojure/lang/IFn
   9:   aload_1
   10:  invokeinterface #41,  2; //InterfaceMethod clojure/lang/
IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
   15:  dup
   16:  ifnull  47
   19:  getstatic   #47; //Field java/lang/Boolean.FALSE:Ljava/
lang/Boolean;
   22:  if_acmpeq   48
   25:  getstatic   #22; //Field const__0:Lclojure/lang/Var;
   28:  invokevirtual   #37; //Method clojure/lang/Var.get:()Ljava/
lang/Object;
   31:  checkcast   #39; //class clojure/lang/IFn
   34:  aload_1
   35:  invokeinterface #41,  2; //InterfaceMethod clojure/lang/
IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
   40:  astore_1
   41:  goto0
   44:  goto65
   47:  pop
   48:  getstatic   #26; //Field const__1:Lclojure/lang/Var;
   51:  invokevirtual   #37; //Method clojure/lang/Var.get:()Ljava/
lang/Object;
   54:  checkcast   #39; //class clojure/lang/IFn
   57:  aload_1
   58:  aconst_null
   59:  astore_1
   60:  invokeinterface #41,  2; //InterfaceMethod clojure/lang/
IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
   65:  areturn

By investigating the bytecode one can notice that line: "44:  goto
65" in unreachable. This creates the problem.
After some investigation of the clojure source code I came to the
conclusion that for this particular case changing the
clojure.lang.Compiler, r1193 at line 2367 to:
if(!(thenExpr instanceof RecurExpr))
gen.goTo(endLabel);
That is: if the thenExpr of the if node is such that it wouldn't fall
through to the elseExpr then there is no need to emit a goto bytecode
for jumping to the end of the if statement, bacause it will be
unreachable. With this change I rebuilt clojure and apparently it's
working fine, the bytecode of the  method above is correct, but
unfortunately there are similar situations in other parts of the code
where usesless bytecode is emited.
For instance clojure.core$partition__3754.invoke(Object,Object,Object)
also contains deadcode similar to the above and it's related to the if
node.

If clojure will be used on other experimental, limited or non-
mainstream Java platforms such problems in the generated bytecode will
surface and create problems. The bugs in such paltforms (their
intolerance to various non-fatal byecode problems) can stay hidden
because the bytecode generated by javac doesn't have such problems.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

thanks for your patience.  I think I'm starting to get it.
Interesting discussion on tail recursion.  Add a lot of depth to what
Rich was talking about.  Really smart work-around!

On Jan 11, 2:50 pm, James Reeves  wrote:
> On Jan 11, 7:19 pm, e  wrote:
>
> > oh.  I missed the "recur my-list" in your answer.  So we still don't
> > have an iterative solution.  Recursion should never be necessary.  I
> > agree that it simplifies things sometimes and you can use it when you
> > are stuck. . . . .but no need to push a whole stack frame for such a
> > simple problem, I would posit.
>
> Actually, that's the nice thing about loop/recur: it looks recursive
> but is actually iterative.
>
> So a recursive function like this:
>
> (defn sum [total list]
>   (if list
>     (sum (+ total (first list))
>          (rest list))
>     total))
>
> Can be turned into an iterative one via recur:
>
> (defn sum [total list]
>   (if list
>     (recur (+ total (first list))
>            (rest list))
>     total))
>
> Note that if there is no matching loop construct, it uses the
> containing function instead.
>
> Most functional languages actually optimize functions like the one
> above automatically, without a need for an explicit recur. It's called
> tail call optimization; if a function calls itself last of all,
> there's no need to keep the stack around. Unfortunately, the JVM
> doesn't have this capability, so we need to explicitly tell Clojure to
> do it via recur.
>
> Note that for recur to work, it needs to be the last thing called. So
> a more naive implementation of sum wouldn't be able to use recur:
>
> (defn sum [list]
>   (if list
>     (+ (first list) (sum (rest list)))
>     0))
>
> In this case, the last function called is +, so you can't substitute
> "sum" for "recur" in this case.
>
> - James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread James Reeves

On Jan 11, 7:19 pm, e  wrote:
> oh.  I missed the "recur my-list" in your answer.  So we still don't
> have an iterative solution.  Recursion should never be necessary.  I
> agree that it simplifies things sometimes and you can use it when you
> are stuck. . . . .but no need to push a whole stack frame for such a
> simple problem, I would posit.

Actually, that's the nice thing about loop/recur: it looks recursive
but is actually iterative.

So a recursive function like this:

(defn sum [total list]
  (if list
(sum (+ total (first list))
 (rest list))
total))

Can be turned into an iterative one via recur:

(defn sum [total list]
  (if list
(recur (+ total (first list))
   (rest list))
total))

Note that if there is no matching loop construct, it uses the
containing function instead.

Most functional languages actually optimize functions like the one
above automatically, without a need for an explicit recur. It's called
tail call optimization; if a function calls itself last of all,
there's no need to keep the stack around. Unfortunately, the JVM
doesn't have this capability, so we need to explicitly tell Clojure to
do it via recur.

Note that for recur to work, it needs to be the last thing called. So
a more naive implementation of sum wouldn't be able to use recur:

(defn sum [list]
  (if list
(+ (first list) (sum (rest list)))
0))

In this case, the last function called is +, so you can't substitute
"sum" for "recur" in this case.

- James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread James Reeves

On Jan 11, 7:09 pm, e  wrote:
> if it has tighter scope, then I don't understand why you don't have an
> infinite loop.  The nested my-list that you redefined should have
> nothing to do with the my-list that you are doing the 'rest' check
> on.

That's what the loop/recur form does. Again, loop/recur can be defined
in terms of functions:

(defn f [xs]
  (loop [ys xs, s 0]
(if ys
  (recur (rest ys) (+ s 1))
  s)))

Is equivalent to the following Python:

def f(xs):
  def g(ys, s):
if ys:
  return g(xs[1:], s + 1)
  return s
  return g(xs, 0)

When recur is called, it acts similarly to a recursive call. The loop
part defines the arguments the loop acts on. The recur part signifies
the loop should be repeated with new arguments. Just like the inner
function, g.

So in my previous code, it's true that the new my-list has a small
scope. But I pass it back to the loop which defines a new variable,
also called my-list, for the next iteration.

I guess it would be clearer if I used different names:

(defn msort [some-list]
  (loop [list-A (vec (map vector some-list))]
(if (rest my-list)
  (let [[l1 l2 & list-B] list-A
list-merge  (some-merge-function l1 l2)
list-C  (conj list-B list-merge)]
(recur list-C))
  (first my-list

So list-A is used to make list-B, which is used to make list-C, and on
the next iteration of the loop, list-C becomes bound to list-A again.

> that must be some magic about the loop construct.  I dunno.  I'm still
> confused.  Every version of the python code makes sense.  I've got
> this reference to my-list, and I can change that reference.  I see the
> same thing happening here, but it's scoped inside a let barrier.

Basically, everything to do with scoping in Lisp can be explained in
terms of functions:

(let [x y] ...)
=
((fn [x] ...) y)

(loop [x y]
  (recur x)
=
(defn f [x]
  (f x)

Though loop and let are more efficient than their function
equivalents.

- James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: list merge help

2009-01-11 Thread e

ahhh I see.  That makes sense.  So it's not like procedural
programming.  You could see what I was trying to understand.

I didn't want case/swtich semantics.  like the (cond) or if, else if
style.  I was trying to return at the first true thing, but it doesn't
work like that.  it always gets to expr3.  the thing I thought was
returning after expr1 was just an opportunity to do a side effect.
Thanks.


On Jan 11, 1:26 pm, "Eric Lavigne"  wrote:
> > this seemed like a clean, nice way to merge to sorted lists into one
> > sorted list.  I'm not getting clojure syntax, it seems:
>
> > (defn listmerge [l1 l2]
> >  (let [l1first (first l1) l2first (first l2)]
> >    (if (= l1first nil) l2)
> >    (if (= l2first nil) l1)
> >    (if (< l1first l2first)
> >      (cons l1first (listmerge (rest l1) l2))
> >      (cons l2first (listmerge (rest l2) l1)))
> >    ))
>
> > psuedocode:
>
> > listmerge (list l1, list l2):
> >   if l1 is empty, return l2
> >   if l2 is empty return l1
> >   if l1[0] is less than l2[0],
> >        return l1[0] + listmerge(rest(l1), l2)
> >   otherwise return l2[0] + listmerge(rest(l2), l1)
>
> Read James' answer first. I just wish to add something.
>
> When you say (let [bindings...] expr1 expr2 expr3) the result is the return
> value of expr3. expr1 and expr2 return values are relevant, so the only
> reason to have expr1 and expr2 is if they have side-effects, such as
> changing the value of a Ref or updating a database or printing to the
> terminal.
>
> --
> Education is what survives when what has been learned has been forgotten.
>
>                    - B. F. Skinner
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

oh.  I missed the "recur my-list" in your answer.  So we still don't
have an iterative solution.  Recursion should never be necessary.  I
agree that it simplifies things sometimes and you can use it when you
are stuck. . . . .but no need to push a whole stack frame for such a
simple problem, I would posit.

On Jan 11, 1:41 pm, James Reeves  wrote:
> On Jan 11, 6:19 pm, e  wrote:
>
> > This gets to my question perfectly.  Why is your code "my-list
> > (rest (rest my-list)) " legal?
>
> Because you're not actually changing anything.
>
> In theory, the let form can be derived from anonymous functions. So
> (let [x y] ...) is the same as ((fn [x] ...) y).
>
> Or, to give you a more practical example:
>
> (defn f [x]
>   (let [x (+ x 1)]
>     (* 2 x)))
>
> Is the same as the following Python code:
>
> def f(x):
>   def g(x):
>     return x * 2
>   return g(x + 1)
>
> We're not changing the value of x, we're just rebinding it within the
> scope of the function. The value of x in g is not the same as the
> value of x in f.
>
> In practice, let forms are never actually implemented as nested
> functions, because that would be far too slow. But in theory, nested
> functions are equivalent to let forms.
>
> > seems like:
> > [my-list (for [x some-list] [x])]
>
> > is simpler to understand than:
> > [my-list (vec (map vector some-list))]
>
> It probably is :) - I just haven't had the opportunity to use the for
> macro yet.
>
> - James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

if it has tighter scope, then I don't understand why you don't have an
infinite loop.  The nested my-list that you redefined should have
nothing to do with the my-list that you are doing the 'rest' check
on.  (rest my-list) should always be non-nil because the inner let is
operating on a different my-list.  That's how it looks to me, at
least.  I saw that there's a re-def function that I bet would work,
but everyone says to avoid def because of it's global scope.  hm
that must be some magic about the loop construct.  I dunno.  I'm still
confused.  Every version of the python code makes sense.  I've got
this reference to my-list, and I can change that reference.  I see the
same thing happening here, but it's scoped inside a let barrier.  I
seem to remember in clisp, there was a setq.  maybe that's what I'm
missing.

On Jan 11, 1:41 pm, James Reeves  wrote:
> On Jan 11, 6:19 pm, e  wrote:
>
> > This gets to my question perfectly.  Why is your code "my-list
> > (rest (rest my-list)) " legal?
>
> Because you're not actually changing anything.
>
> In theory, the let form can be derived from anonymous functions. So
> (let [x y] ...) is the same as ((fn [x] ...) y).
>
> Or, to give you a more practical example:
>
> (defn f [x]
>   (let [x (+ x 1)]
>     (* 2 x)))
>
> Is the same as the following Python code:
>
> def f(x):
>   def g(x):
>     return x * 2
>   return g(x + 1)
>
> We're not changing the value of x, we're just rebinding it within the
> scope of the function. The value of x in g is not the same as the
> value of x in f.
>
> In practice, let forms are never actually implemented as nested
> functions, because that would be far too slow. But in theory, nested
> functions are equivalent to let forms.
>
> > seems like:
> > [my-list (for [x some-list] [x])]
>
> > is simpler to understand than:
> > [my-list (vec (map vector some-list))]
>
> It probably is :) - I just haven't had the opportunity to use the for
> macro yet.
>
> - James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread James Reeves

On Jan 11, 6:19 pm, e  wrote:
> This gets to my question perfectly.  Why is your code "my-list
> (rest (rest my-list)) " legal?

Because you're not actually changing anything.

In theory, the let form can be derived from anonymous functions. So
(let [x y] ...) is the same as ((fn [x] ...) y).

Or, to give you a more practical example:

(defn f [x]
  (let [x (+ x 1)]
(* 2 x)))

Is the same as the following Python code:

def f(x):
  def g(x):
return x * 2
  return g(x + 1)

We're not changing the value of x, we're just rebinding it within the
scope of the function. The value of x in g is not the same as the
value of x in f.

In practice, let forms are never actually implemented as nested
functions, because that would be far too slow. But in theory, nested
functions are equivalent to let forms.

> seems like:
> [my-list (for [x some-list] [x])]
>
> is simpler to understand than:
> [my-list (vec (map vector some-list))]

It probably is :) - I just haven't had the opportunity to use the for
macro yet.

- James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Setting a value inside a map of map of maps...

2009-01-11 Thread CuppoJava

That's exactly what I was looking for.
Thank you Brian.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Eric Lavigne
>
> i see that "my-list  (rest (rest my-list))" is in a let section.  That
> seems like the scope would mean we are talking about a different my-
> list.
>

Yes, it is a new my-list with a smaller scope. I didn't search for the
expression (rest (rest my-list)) before my earlier response.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Eric Lavigne
>
>
> This gets to my question perfectly.  Why is your code "my-list
> (rest (rest my-list)) " legal?
> I wouldn't have even thought to try that because, in essence, you are
> changing my-list.  I mean, I know how persistence works.  You are just
> reassigning what you think of as the start of my-list, and if no one
> else is looking at the old version then it can get gc'd.  I guess I
> just assumed it would be harder some how.
>

The expression (rest (rest my-list)) does not change anything. Its return
value is a list that has fewer elements, and the original (unchanged) list
still exists. This is common in the functional style of programming - most
operations  do not modify their arguments.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

i see that "my-list  (rest (rest my-list))" is in a let section.  That
seems like the scope would mean we are talking about a different my-
list.

On Jan 11, 1:19 pm, e  wrote:
> that's awesome, and I hope it helps others, too.  Thanks for starting
> with python.
>
> This gets to my question perfectly.  Why is your code "my-list
> (rest (rest my-list)) " legal?
> I wouldn't have even thought to try that because, in essence, you are
> changing my-list.  I mean, I know how persistence works.  You are just
> reassigning what you think of as the start of my-list, and if no one
> else is looking at the old version then it can get gc'd.  I guess I
> just assumed it would be harder some how.
>
> how do people feel about the list comprehension thing I did?
>
> seems like:
> [my-list (for [x some-list] [x])]
>
> is simpler to understand than:
> [my-list (vec (map vector some-list))]
>
> The former is just like math.  says, "give me a list of '[x]' for each
> element 'x' in some-list"
> The second says, "apply the vector operation to each element of some-
> list and then make a vector of those."  seems lower level, more
> rudimentary.
>
> Thanks for all the help.  This is great fun.
>
> On Jan 11, 12:07 pm, James Reeves  wrote:
>
> > Thinking functionally is hard when you're used to programming
> > imperatively. So instead of leaping straight into Clojure, lets stick
> > with Python for the time being.
>
> > So let's take your Python code:
>
> > def msort(someList):
> >   myList = [[x] for x in someList]
> >   while len(myList) > 1:
> >     l1 = myList.pop(0)
> >     l2 = myList.pop(0)
> >     listmerge = some_merge_function(l1, l2)
> >     myList.append(listmerge)
> >   return myList[0]
>
> > (I'm assuming you meant msort(someList) and not msort(myList))
>
> > Remove all functions and methods that change their arguments, and
> > replace them with equivalent assignments:
>
> > def msort(someList):
> >   myList = [[x] for x in someList]
> >   while len(myList) > 1:
> >     l1 = myList[0]
> >     l2 = myList[1]
> >     myList = myList[2:]
> >     listmerge = some_merge_function(l1, l2)
> >     myList = myList + [listmerge]
> >   return myList[0]
>
> > Next we need to turn the while loop into a recursive function. We can
> > do this by identifying what the while loop changes (myList), and then
> > using that as the function's input and output:
>
> > def msort(someList):
> >   myList = [[x] for x in someList]
> >   def recursive_loop(myList)
> >     if len(myList) > 1:
> >       l1 = myList[0]
> >       l2 = myList[1]
> >       myList = myList[2:]
> >       listmerge = some_merge_function(l1, l2)
> >       myList = myList + [listmerge]
> >       myList = recursive_loop(myList)
> >       return myList
> >     else:
> >       return myList
> >   return recursive_loop(myList)[0]
>
> > Once you've replaced mutable functions and methods with assignments,
> > and replaced loops with recursive functions, you can convert your code
> > into Clojure:
>
> > (defn msort [some-list]
> >   (let
> >     [my-list (vec (map vector some-list))
> >      recursive-loop
> >       (fn [my-list]
> >         (if (> (count my-list) 1)
> >           (let [l1         (my-list 0)
> >                 l2         (my-list 1)
> >                 my-list    (rest (rest my-list))
> >                 list-merge (some-merge-function l1 l2)
> >                 my-list    (conj my-list listmerge)
> >                 my-list    (recursive-loop my-list)]
> >             my-list)
> >           my-list))]
> >     ((recursive-loop my-list) 0)))
>
> > Now we have a functional program, it's time to start taking advantage
> > of all the nice Clojure functions and macros. Let's start with the
> > loop/recur form, which we can use to replace the recursive-loop
> > function:
>
> > (defn msort [some-list]
> >   (loop [my-list (vec (map vector some-list))]
> >     (if (> (count my-list) 1)
> >       (let [l1         (my-list 0)
> >             l2         (my-list 1)
> >             my-list    (rest (rest my-list))
> >             list-merge (some-merge-function l1 l2)
> >             my-list    (conj my-list listmerge)]
> >         (recur my-list))
> >       (my-list 0
>
> > Clojure also supports destructuring binding in let forms, so lets use
> > that:
>
> > (defn msort [some-list]
> >   (loop [my-list (vec (map vector some-list))]
> >     (if (> (count my-list) 1)
> >       (let [[l1 l2 & my-list] my-list
> >             list-merge       (some-merge-function l1 l2)
> >             my-list          (conj my-list list-merge)]
> >         (recur my-list))
> >       (my-list 0
>
> > And we can use rest to check if the list has more than one attribute:
>
> > (defn msort [some-list]
> >   (loop [my-list (vec (map vector some-list))]
> >     (if (rest my-list)
> >       (let [[l1 l2 & my-list] my-list
> >             list-merge       (some-merge-function l1 l2)
> >             my-list          (conj my-list list-merge)]
> >         (recur my-list))
> >       (first 

Re: Setting a value inside a map of map of maps...

2009-01-11 Thread Brian Doyle
I think you can just use the update-in function like:

1:1 user=> (def m {:a {:b {:c {:d 3)
#'user/m

1:2 user=> (update-in m [:a :b :c :d] - 5)
{:a {:b {:c {:d -2


On Sun, Jan 11, 2009 at 11:08 AM, CuppoJava wrote:

>
> Hi,
> I'm just wondering if there's a clever way of creating a new map from
> an existing map of map of maps.. with a key deep inside altered.
>
> ie. given this map: {:a {:b {:c {:d 3
>
> i want to create a new map, with the value at :d increased by 5.
>
> I wrote a macro to do this, but it's quite ugly.
>
> Thanks for the tip
>  -Patrick
>
> --
> In case this helps at all, this is the macro that I wrote.
> Usage: (set_map mymap [:a :b :c :d] (+ it 5))
>
> (defmacro -set_map [mymap mykeys expr]
>  (let [syms (take (dec (count mykeys))
>   (repeatedly gensym))
>bindings (interleave
>  (concat syms ['it])
>  (map list
>   mykeys
>   (concat [mymap] syms)))]
>`(let [...@bindings]
>   ~((fn assoc_fn [maps keys expr]
>   (if (empty? keys)
> expr
> `(assoc ~(first maps) ~(first keys)
> ~(assoc_fn (rest maps) (rest keys) expr
> (concat [mymap] syms) mykeys expr
>
> (defmacro set_map [map keys expr]
>  `(let [map# ~map]
> (-set_map map# ~keys ~expr)))
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: list merge help

2009-01-11 Thread Eric Lavigne
>
>
> this seemed like a clean, nice way to merge to sorted lists into one
> sorted list.  I'm not getting clojure syntax, it seems:
>
>
> (defn listmerge [l1 l2]
>  (let [l1first (first l1) l2first (first l2)]
>(if (= l1first nil) l2)
>(if (= l2first nil) l1)
>(if (< l1first l2first)
>  (cons l1first (listmerge (rest l1) l2))
>  (cons l2first (listmerge (rest l2) l1)))
>))
>
> psuedocode:
>
> listmerge (list l1, list l2):
>   if l1 is empty, return l2
>   if l2 is empty return l1
>   if l1[0] is less than l2[0],
>return l1[0] + listmerge(rest(l1), l2)
>   otherwise return l2[0] + listmerge(rest(l2), l1)
>

Read James' answer first. I just wish to add something.

When you say (let [bindings...] expr1 expr2 expr3) the result is the return
value of expr3. expr1 and expr2 return values are relevant, so the only
reason to have expr1 and expr2 is if they have side-effects, such as
changing the value of a Ref or updating a database or printing to the
terminal.

-- 
Education is what survives when what has been learned has been forgotten.

   - B. F. Skinner

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: list merge help

2009-01-11 Thread James Reeves

On Jan 11, 5:53 pm, e  wrote:
> this seemed like a clean, nice way to merge to sorted lists into one
> sorted list.  I'm not getting clojure syntax, it seems:
>
> (defn listmerge [l1 l2]
>   (let [l1first (first l1) l2first (first l2)]
>     (if (= l1first nil) l2)
>     (if (= l2first nil) l1)
>     (if (< l1first l2first)
>       (cons l1first (listmerge (rest l1) l2))
>       (cons l2first (listmerge (rest l2) l1)))
>     ))

You need to nest the ifs, or use a cond:

(defn listmerge [l1 l2]
  (let [l1first (first l1) l2first (first l2)]
(cond
  (empty? l1) l2
  (empty? l2) l1
  (< l1first l2first)
(cons l1first (listmerge (rest l1) l2))
  :else
(cons l2first (listmerge (rest l2) l1))

if statements in Clojure are inline, like the (x if y else z) syntax
in Python.

- James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

that's awesome, and I hope it helps others, too.  Thanks for starting
with python.

This gets to my question perfectly.  Why is your code "my-list
(rest (rest my-list)) " legal?
I wouldn't have even thought to try that because, in essence, you are
changing my-list.  I mean, I know how persistence works.  You are just
reassigning what you think of as the start of my-list, and if no one
else is looking at the old version then it can get gc'd.  I guess I
just assumed it would be harder some how.

how do people feel about the list comprehension thing I did?

seems like:
[my-list (for [x some-list] [x])]

is simpler to understand than:
[my-list (vec (map vector some-list))]

The former is just like math.  says, "give me a list of '[x]' for each
element 'x' in some-list"
The second says, "apply the vector operation to each element of some-
list and then make a vector of those."  seems lower level, more
rudimentary.

Thanks for all the help.  This is great fun.


On Jan 11, 12:07 pm, James Reeves  wrote:
> Thinking functionally is hard when you're used to programming
> imperatively. So instead of leaping straight into Clojure, lets stick
> with Python for the time being.
>
> So let's take your Python code:
>
> def msort(someList):
>   myList = [[x] for x in someList]
>   while len(myList) > 1:
>     l1 = myList.pop(0)
>     l2 = myList.pop(0)
>     listmerge = some_merge_function(l1, l2)
>     myList.append(listmerge)
>   return myList[0]
>
> (I'm assuming you meant msort(someList) and not msort(myList))
>
> Remove all functions and methods that change their arguments, and
> replace them with equivalent assignments:
>
> def msort(someList):
>   myList = [[x] for x in someList]
>   while len(myList) > 1:
>     l1 = myList[0]
>     l2 = myList[1]
>     myList = myList[2:]
>     listmerge = some_merge_function(l1, l2)
>     myList = myList + [listmerge]
>   return myList[0]
>
> Next we need to turn the while loop into a recursive function. We can
> do this by identifying what the while loop changes (myList), and then
> using that as the function's input and output:
>
> def msort(someList):
>   myList = [[x] for x in someList]
>   def recursive_loop(myList)
>     if len(myList) > 1:
>       l1 = myList[0]
>       l2 = myList[1]
>       myList = myList[2:]
>       listmerge = some_merge_function(l1, l2)
>       myList = myList + [listmerge]
>       myList = recursive_loop(myList)
>       return myList
>     else:
>       return myList
>   return recursive_loop(myList)[0]
>
> Once you've replaced mutable functions and methods with assignments,
> and replaced loops with recursive functions, you can convert your code
> into Clojure:
>
> (defn msort [some-list]
>   (let
>     [my-list (vec (map vector some-list))
>      recursive-loop
>       (fn [my-list]
>         (if (> (count my-list) 1)
>           (let [l1         (my-list 0)
>                 l2         (my-list 1)
>                 my-list    (rest (rest my-list))
>                 list-merge (some-merge-function l1 l2)
>                 my-list    (conj my-list listmerge)
>                 my-list    (recursive-loop my-list)]
>             my-list)
>           my-list))]
>     ((recursive-loop my-list) 0)))
>
> Now we have a functional program, it's time to start taking advantage
> of all the nice Clojure functions and macros. Let's start with the
> loop/recur form, which we can use to replace the recursive-loop
> function:
>
> (defn msort [some-list]
>   (loop [my-list (vec (map vector some-list))]
>     (if (> (count my-list) 1)
>       (let [l1         (my-list 0)
>             l2         (my-list 1)
>             my-list    (rest (rest my-list))
>             list-merge (some-merge-function l1 l2)
>             my-list    (conj my-list listmerge)]
>         (recur my-list))
>       (my-list 0
>
> Clojure also supports destructuring binding in let forms, so lets use
> that:
>
> (defn msort [some-list]
>   (loop [my-list (vec (map vector some-list))]
>     (if (> (count my-list) 1)
>       (let [[l1 l2 & my-list] my-list
>             list-merge       (some-merge-function l1 l2)
>             my-list          (conj my-list list-merge)]
>         (recur my-list))
>       (my-list 0
>
> And we can use rest to check if the list has more than one attribute:
>
> (defn msort [some-list]
>   (loop [my-list (vec (map vector some-list))]
>     (if (rest my-list)
>       (let [[l1 l2 & my-list] my-list
>             list-merge       (some-merge-function l1 l2)
>             my-list          (conj my-list list-merge)]
>         (recur my-list))
>       (first my-list
>
> This could be neatened up a bit, but that's basically a functional
> version of your algorithm.
>
> - James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups

Setting a value inside a map of map of maps...

2009-01-11 Thread CuppoJava

Hi,
I'm just wondering if there's a clever way of creating a new map from
an existing map of map of maps.. with a key deep inside altered.

ie. given this map: {:a {:b {:c {:d 3

i want to create a new map, with the value at :d increased by 5.

I wrote a macro to do this, but it's quite ugly.

Thanks for the tip
  -Patrick

--
In case this helps at all, this is the macro that I wrote.
Usage: (set_map mymap [:a :b :c :d] (+ it 5))

(defmacro -set_map [mymap mykeys expr]
  (let [syms (take (dec (count mykeys))
   (repeatedly gensym))
bindings (interleave
  (concat syms ['it])
  (map list
   mykeys
   (concat [mymap] syms)))]
`(let [...@bindings]
   ~((fn assoc_fn [maps keys expr]
   (if (empty? keys)
 expr
 `(assoc ~(first maps) ~(first keys)
 ~(assoc_fn (rest maps) (rest keys) expr
 (concat [mymap] syms) mykeys expr

(defmacro set_map [map keys expr]
  `(let [map# ~map]
 (-set_map map# ~keys ~expr)))
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



list merge help

2009-01-11 Thread e

this seemed like a clean, nice way to merge to sorted lists into one
sorted list.  I'm not getting clojure syntax, it seems:


(defn listmerge [l1 l2]
  (let [l1first (first l1) l2first (first l2)]
(if (= l1first nil) l2)
(if (= l2first nil) l1)
(if (< l1first l2first)
  (cons l1first (listmerge (rest l1) l2))
  (cons l2first (listmerge (rest l2) l1)))
))

psuedocode:

listmerge (list l1, list l2):
   if l1 is empty, return l2
   if l2 is empty return l1
   if l1[0] is less than l2[0],
return l1[0] + listmerge(rest(l1), l2)
   otherwise return l2[0] + listmerge(rest(l2), l1)

. I see one thing.  I could move that second cons statement out of
the 3rd if and put it as the return for the let.
I doubt it will help.

Thanks.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread James Reeves

Thinking functionally is hard when you're used to programming
imperatively. So instead of leaping straight into Clojure, lets stick
with Python for the time being.

So let's take your Python code:

def msort(someList):
  myList = [[x] for x in someList]
  while len(myList) > 1:
l1 = myList.pop(0)
l2 = myList.pop(0)
listmerge = some_merge_function(l1, l2)
myList.append(listmerge)
  return myList[0]

(I'm assuming you meant msort(someList) and not msort(myList))

Remove all functions and methods that change their arguments, and
replace them with equivalent assignments:

def msort(someList):
  myList = [[x] for x in someList]
  while len(myList) > 1:
l1 = myList[0]
l2 = myList[1]
myList = myList[2:]
listmerge = some_merge_function(l1, l2)
myList = myList + [listmerge]
  return myList[0]

Next we need to turn the while loop into a recursive function. We can
do this by identifying what the while loop changes (myList), and then
using that as the function's input and output:

def msort(someList):
  myList = [[x] for x in someList]
  def recursive_loop(myList)
if len(myList) > 1:
  l1 = myList[0]
  l2 = myList[1]
  myList = myList[2:]
  listmerge = some_merge_function(l1, l2)
  myList = myList + [listmerge]
  myList = recursive_loop(myList)
  return myList
else:
  return myList
  return recursive_loop(myList)[0]

Once you've replaced mutable functions and methods with assignments,
and replaced loops with recursive functions, you can convert your code
into Clojure:

(defn msort [some-list]
  (let
[my-list (vec (map vector some-list))
 recursive-loop
  (fn [my-list]
(if (> (count my-list) 1)
  (let [l1 (my-list 0)
l2 (my-list 1)
my-list(rest (rest my-list))
list-merge (some-merge-function l1 l2)
my-list(conj my-list listmerge)
my-list(recursive-loop my-list)]
my-list)
  my-list))]
((recursive-loop my-list) 0)))

Now we have a functional program, it's time to start taking advantage
of all the nice Clojure functions and macros. Let's start with the
loop/recur form, which we can use to replace the recursive-loop
function:

(defn msort [some-list]
  (loop [my-list (vec (map vector some-list))]
(if (> (count my-list) 1)
  (let [l1 (my-list 0)
l2 (my-list 1)
my-list(rest (rest my-list))
list-merge (some-merge-function l1 l2)
my-list(conj my-list listmerge)]
(recur my-list))
  (my-list 0

Clojure also supports destructuring binding in let forms, so lets use
that:

(defn msort [some-list]
  (loop [my-list (vec (map vector some-list))]
(if (> (count my-list) 1)
  (let [[l1 l2 & my-list] my-list
list-merge   (some-merge-function l1 l2)
my-list  (conj my-list list-merge)]
(recur my-list))
  (my-list 0

And we can use rest to check if the list has more than one attribute:

(defn msort [some-list]
  (loop [my-list (vec (map vector some-list))]
(if (rest my-list)
  (let [[l1 l2 & my-list] my-list
list-merge   (some-merge-function l1 l2)
my-list  (conj my-list list-merge)]
(recur my-list))
  (first my-list

This could be neatened up a bit, but that's basically a functional
version of your algorithm.

- James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread Eric Lavigne
On Sun, Jan 11, 2009 at 10:50 AM, e  wrote:

>
> refs seem silly in this context!  Now I REALLY have to get my head
> wrapped around clojure.  sooo I only have one thread, but I have
> to do a dosync?  Why can this whole function just work in a thread
> agnostic way?  It's a local variable!  If a thread calls it, then a
> thread should own the memory that's created.  Each thread should have
> its own asynchronous stack to push local variables onto that no one
> else is allowed to see.  Seems like all that transaction, dosync stuff
> ought to be optional.
>

> (let [x (ref 3)]
>   (dosync
> (while (> @x 0)
>   (ref-set x (- @x 1)))
> @x))

Refs synchronize within a transaction. Atoms only synchronize within a
single operation. swap! takes an atom and a function that should be
atomically applied to that atom.

(let [x (atom 3)]
  (while (> @x 0)
(swap! x dec))
  @x)

http://clojure.org/atoms

But you want to use the (set x (- x 1)) form that is common in many other
languages? We can create an unsafe-set that does that and completely ignores
synchronization, since you know that synchronization won't be needed.
compare-and-set! takes an atom, the atom's expected value, and a new value.
Since you want to just assume that there will be no conflicts, we can make
an unsafe-set that skips the comparison and just performs the operation.

(defn unsafe-set [a v]
  (compare-and-set! a @a v)
  v)

(let [x (atom 3)]
  (while (> @x 0)
(unsafe-set x (- @x 1)))
  @x)


> Oh, and my other choice is to use recursion.  I'll look into that
> recur thing.


The Clojure standard library is designed to support functional programming
(including recursion) and concurrency. I recommend going with the flow, but
the language is flexible enough to work the way you want. Just define the
operations that you like to use. Also, you have access to Java libraries,
which have mutable collections.



>
>
> On Jan 11, 1:27 am, "Eric Lavigne"  wrote:
> > > I have no idea how to iteratively mess with it since everything is
> > > persistent.  Ok, like, say it's a list of lists and I am going to be
> > > merging the lists, like Tarjan's mergesort from some book from
> > > college.
> >
> > Sorting is done much more easily with recursion than with iteration.
> > However, it looks like you are focused on learning language features
> rather
> > than programming strategy, so I will just answer your questions.
> >
> > I have not actually done any iterative programming in Clojure, as I
> prefer
> > the functional approach, so my answers are based on my limited
> understanding
> > of the Clojure documentation.
> >
> > so I have myList with contents [[11] [2] [4] [1] [99]]
> >
> >
> >
> >
> >
> > > here's how I would do it in python:
> >
> > > def msort(myList):
> > >  myList = [[x] for x in someList]
> > >  while len(myList) > 1:
> > >l1 = myList.pop(0)
> > >l2 = myList.pop(0)
> > >listmerge = some_merge_function(l1, l2)
> > >myList.append(listmerge)  # important that newly merged go
> > > to back of queue to get proper runtime
> > >  return myList[0]
> >
> > > here's what I'm trying to do for clojure, and it's a mess:
> >
> > > (defn msort [toSort]
> > >  (def sorted (let
> >
> > Be careful with def. I think that it creates a global, and it looks like
> you
> > want something with a scope limited to this function.
> >
> > http://clojure.org/Vars
> >
> > >   [myList (for [x toSort] [x])]  <- so far so good (not a
> > > real comment.  I don't know how, yet)
> >
> > Use a semicolon to create a comment:
> >
> >  some code ; a comment
> >
> > >   [
> > >(while (> (count myList) 1)  <--- infinite loop the way
> > > written?  I don't know how to overwrite myList
> > >  (let [l1 (nth myList 0)][])
> >
> > The line above does nothing. When you write "(let [x 1] expr1) expr2" the
> > new value of x has a narrow scope so that it only affects expr1.
> >
> > You are wanting to create a local variable that you can change. Refs can
> do
> > that:
> >
> > (let [x (ref 3)]
> >   (dosync
> > (while (> @x 0)
> >   (ref-set x (- @x 1)))
> > @x))
> >
> > http://clojure.org/Refs
> >
> > >  (let [l2 (nth myList 1)][])
> > >  (let [listmerge (some_merge_func l1 l2)][])
> > >  (let [myList (concat (drop 2 myList) listmerge)][myList])  <---
> > > probably a different local variable
> > >  )
> > >   ]))
> > >  sorted)
> >
> > After all that work you just return the original list? I must have missed
> > the part where you tried to change sorted. Any such attempt would fail,
> > though, because Clojure collections are immutable. Maybe sorted should be
> a
> > ref to a list instead of just a list.
> >
> > Here is a discussion of sorting implementations in Clojure. I hope that
> you
> > find it useful.
> >
> > http://www.fatvat.co.uk/2008/12/bubbling-clojure.html
> >
> > --
> > Education is what survives when what has been learned has been forgotten.
> >
> >- B. F.

Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

refs seem silly in this context!  Now I REALLY have to get my head
wrapped around clojure.  sooo I only have one thread, but I have
to do a dosync?  Why can this whole function just work in a thread
agnostic way?  It's a local variable!  If a thread calls it, then a
thread should own the memory that's created.  Each thread should have
its own asynchronous stack to push local variables onto that no one
else is allowed to see.  Seems like all that transaction, dosync stuff
ought to be optional.

I made my own, local list . . . that no one else in the world can
see.  I should be able to call pop_front on it to get back the first
item while also mutating the the list to only contain the rest.

Oh, and my other choice is to use recursion.  I'll look into that
recur thing.

On Jan 11, 1:27 am, "Eric Lavigne"  wrote:
> > I have no idea how to iteratively mess with it since everything is
> > persistent.  Ok, like, say it's a list of lists and I am going to be
> > merging the lists, like Tarjan's mergesort from some book from
> > college.
>
> Sorting is done much more easily with recursion than with iteration.
> However, it looks like you are focused on learning language features rather
> than programming strategy, so I will just answer your questions.
>
> I have not actually done any iterative programming in Clojure, as I prefer
> the functional approach, so my answers are based on my limited understanding
> of the Clojure documentation.
>
> so I have myList with contents [[11] [2] [4] [1] [99]]
>
>
>
>
>
> > here's how I would do it in python:
>
> > def msort(myList):
> >  myList = [[x] for x in someList]
> >  while len(myList) > 1:
> >    l1 = myList.pop(0)
> >    l2 = myList.pop(0)
> >    listmerge = some_merge_function(l1, l2)
> >    myList.append(listmerge)          # important that newly merged go
> > to back of queue to get proper runtime
> >  return myList[0]
>
> > here's what I'm trying to do for clojure, and it's a mess:
>
> > (defn msort [toSort]
> >  (def sorted (let
>
> Be careful with def. I think that it creates a global, and it looks like you
> want something with a scope limited to this function.
>
> http://clojure.org/Vars
>
> >   [myList (for [x toSort] [x])]      <- so far so good (not a
> > real comment.  I don't know how, yet)
>
> Use a semicolon to create a comment:
>
>      some code ; a comment
>
> >   [
> >    (while (> (count myList) 1)      <--- infinite loop the way
> > written?  I don't know how to overwrite myList
> >      (let [l1 (nth myList 0)][])
>
> The line above does nothing. When you write "(let [x 1] expr1) expr2" the
> new value of x has a narrow scope so that it only affects expr1.
>
> You are wanting to create a local variable that you can change. Refs can do
> that:
>
> (let [x (ref 3)]
>   (dosync
>     (while (> @x 0)
>       (ref-set x (- @x 1)))
>     @x))
>
> http://clojure.org/Refs
>
> >      (let [l2 (nth myList 1)][])
> >      (let [listmerge (some_merge_func l1 l2)][])
> >      (let [myList (concat (drop 2 myList) listmerge)][myList])  <---
> > probably a different local variable
> >      )
> >   ]))
> >  sorted)
>
> After all that work you just return the original list? I must have missed
> the part where you tried to change sorted. Any such attempt would fail,
> though, because Clojure collections are immutable. Maybe sorted should be a
> ref to a list instead of just a list.
>
> Here is a discussion of sorting implementations in Clojure. I hope that you
> find it useful.
>
> http://www.fatvat.co.uk/2008/12/bubbling-clojure.html
>
> --
> Education is what survives when what has been learned has been forgotten.
>
>                    - B. F. Skinner
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: update-values for clojure.contrib.sql

2009-01-11 Thread Stephen C. Gilardi


On Jan 2, 2009, at 2:21 AM, budu wrote:


Hi, I was experimenting with clojure-contrib's sql features and found
that there wasn't any update-values function. I've written my own and
I'm sharing it here:

(defn update-values [table where column-names & values]
 "Update columns of a table with values. columns-names is a vector of
 column names (strings or keywords) and the rest of arguments are the
 values for those columns."
 (let [columns (map #(str (the-str %) " = ?") column-names)
   template (if (seq column-names)
 (apply str (interpose "," columns))
 "")]
   (apply do-prepared
  (format "update %s set %s where %s"
  (the-str table) template where)
  [values])))

It only send one set of values to do-prepared because of the where
clause that would have to change according to each sets. I'm ready for
your commentaries and/or suggestions.


Hi budu,

I'd like to include something like this in clojure.contrib.sql. That  
will go smoothest if I can base it directly on what you've written and  
that's only possible if you send in a contributor agreement. Would you  
please send one in?


Please see http://clojure.org/contributing for more info.

Thanks,

--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: SLIME: trouble with java.lang.OutOfMemoryError

2009-01-11 Thread e

great.  will do.

On Jan 11, 9:14 am, lpetit  wrote:
> Hello,
>
> If you like eclipse and would like to see where clojuredev (eclipse
> plugin) is right now, you can give a quick look at the current state
> of clojuredev by trying to immediately install it via the update site
> link :
>
> http://clojure-dev.googlecode.com/svn/updatesite/
>
> Still not ready for public availability (it's alpha alpha), but that's
> a start.
>
> And you could subscribe to clojuredev user ml: very very low traffic
> (no message right now :-), and we could jut publish announces when
> something interesting for users is ready on the update site.
>
> Quickly, what is available right now :
> - enable a java project with clojure dev nature (contextual menu of
> the java project, -> Clojure submenu)
> - wizard for creation of clojure project (= java project + clojure
> nature)
> - syntax coloring
> - some keyboard accelerators for :
>    - jump to matching bracket : Ctr+Shift+P
>    - Go to start of top level defun : Ctrl+Alt+A (or AltGr+A)
>    - Go to end of top level defun : Ctrl+Alt+E (or AltrGr+E)
>    - Select (highlight) top level defun : Ctrl+Altr+H (or AltrGr+H)
> - Launch configuration for clojure : enable to select which files to
> load on startup, and other things similar to java launch
> configuration. Not yet possible to select a main method other than
> clojure.lang.Repl (will change at some point in time)
>
> If you have time, please give it a try, do some feedback, and fill
> free to submit tickets if you find bugs (in the features listed above,
> the other ones you may find via menus are not yet ready, even if the
> menu are there).
>
> Regards,
>
> --
> Laurent
>
> On Jan 11, 3:18 am, e  wrote:
>
> > seems like enclosjure addresses a bunch of my problems/questions.  It
> > also seems to work like we wanted SLIME to work, more or
> > less . . .where you attach to the vm that's used for execution . . .
> > only you attach to the REPL, I think, which still accomplishes the
> > goal of keeping the editor separate from the memory, but what about
> > having the REPL being able to attach to the vm it is managing.  Then
> > it wouldn't be something that NetBeans/enclosure is doing . . . rather
> > something that's part of the language.
>
> > So, yeah.  enslojure sets up a HelloWorld that you can play with right
> > away.  In fact, when you click on "build" it even tells you how you
> > could run your application from the command line using a java
> > command.  It jars up you whole clojure project and everything.  Nice.
> > On the other hand, I couldn't figure out how to use NetBeans' run
> > button.  it couldn't find main or something.  So I also couldn't debug
> > using NetBeans' debugger because of this.  Also, it isn't clear how to
> > get different clojure files to work together.  Do you use the (load)
> > function?  If so, I don't know how the project thinks of relative file
> > locations.  It's not as clean/clear as java (for a beginner, at least)
> > where you just import classes you want to use . . and make
> > packages. . . . or modules in python.  I don't know what the notion of
> > "path" is in clojure.  I see the namespace stuff but have no clue how
> > to make it work yet.  Are you just supposed to use one giant file for
> > all your work?  That wouldn't be good for teams, for sure. . . only
> > for hacking.  Also the REPL errors are USELESS to a beginner.
> > something about iSeq all the time.  The moral for me there was no to
> > make an error.  Better than where I was before enclojure.  Again, I
> > contend that a language is only as good as the IDE that has been
> > written for it, which is why it's cool to see enclojure coming along
> > (even though it means learning NetBeans instead of Eclipse).
>
> > On Jan 10, 5:31 pm, Paul  Mooser  wrote:
>
> > > If I'm not mistaken, this is fairly close to how SLIME works, when
> > > connected to a remote VM. The remote VM is running some server code
> > > which allows it to communicate with SLIME, which is running inside of
> > > emacs.
>
> > > On Jan 10, 2:15 pm, e  wrote:
>
> > > > exactly. . . .but I bet a lot of people would just reply that this is
> > > > not possible to address since the REPL is the one and only vm.
> > > > Disclaimer, I'm only guessing at that, too.  I don't understand any of
> > > > this, yet.  But if that's the case, fix that.  Have the REPL send
> > > > messages to the vm that's running the program . . . instead of the
> > > > REPL being the program.
>
> > > > On Jan 10, 5:00 pm, Paul  Mooser  wrote:
>
> > > > > Yeah, I'm not really sure how I think the problem would be ideally
> > > > > solved. It would just be nice for an interactive programming
> > > > > environment to be able to recover from all exceptions that happen at a
> > > > > higher level than the VM itself.
>
> > > > > On Jan 10, 12:20 pm, "Christian Vest Hansen" 
> > > > > wrote:
>
> > > > > > I don't think it is possible to define a way to deal with heap
> > > > > > saturat

Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

I'm trying to follow.  Can you explain in pseudo code?  That's
impressive that it follows the classic approach on persistent data
structures . . .. from what I can tell.  You successively divide the
list in halves of halves of halves.  Then the lists of size 1 are
merged together as the stack unwinds . . .then I kinda lose it.  Are
lists of equal length merged like what's needed for the runtime?

I mean, if all the size one lists are just merged in with the first
list as they come, then it won't run out of lists NEARLY as quickly as
it should.

so as long as it does that.

so here's the psuedo code I'm trying to implement in clojure. . . .
python code also worked.
The trouble is I can't just do the pop_front thing below, which makes
the code ugly. . . . or can I?

given a list of items in myOriginalList:
1) myBrokenUpList = {[x], foreach x in myOriginalList}

do while myBrokenUpList has more than one mini-list in it:
2) a = pop_front the first list in myBrokenUpList
3) b = pop_front the first list in myBrokenUpList
4) merged = some_merge_func(a, b)
5) myBrokenUpList = myBrokenUpList + merged   <--- important
that the merged list go in at the back.

Is that what yours does?  or does it merge all the singleton lists
into one growing list?  If it is the latter, then that seems to be O
(n^2) time instead of O(n logn)


On Jan 11, 2:41 am, John  wrote:
> Hi,
>
> I'm just learning Clojure too, so I don't have much to add to what
> everyone else has said, but here's my crack at a full implenentation
> of merge-sort in Clojure.  I'm  sure that there is plenty of room for
> improvement (especially wrt. the merge function) but in case it's
> helpful, here it is:
>
> (defn lazy-merge [seq1 seq2]
>   (cond (<= (count seq1) 0) (lazy-cons (first seq2) (rest seq2))
>         (<= (count seq2) 0) (lazy-cons (first seq1) (rest seq1))
>         :else (let [h1 (first seq1)
>                     h2 (first seq2)]
>                 (if (< h1 h2)
>                     (lazy-cons h1 (lazy-merge (rest seq1) seq2))
>                     (lazy-cons h2 (lazy-merge seq1 (rest seq2)))
>
> (defn merge-sort [seq]
>   (if (> (count seq) 1)
>       (apply lazy-merge (map merge-sort (split-at (/ (count seq) 2)
> seq)))
>       seq))
>
> -
> John
>
> On Jan 10, 9:21 pm, e  wrote:
>
> > I'm just trying to understand basic stuff.
> > say I have a local list called "myList" (assigned using 'let' . . .
> > should I have used something else?)  Who cares what's in it.  Maybe I
> > set it up from a list comprehension from some input to my function.
>
> > I have no idea how to iteratively mess with it since everything is
> > persistent.  Ok, like, say it's a list of lists and I am going to be
> > merging the lists, like Tarjan's mergesort from some book from
> > college.
>
> > so I have myList with contents [[11] [2] [4] [1] [99]]
>
> > here's how I would do it in python:
>
> > def msort(myList):
> >   myList = [[x] for x in someList]
> >   while len(myList) > 1:
> >     l1 = myList.pop(0)
> >     l2 = myList.pop(0)
> >     listmerge = some_merge_function(l1, l2)
> >     myList.append(listmerge)          # important that newly merged go
> > to back of queue to get proper runtime
> >   return myList[0]
>
> > here's what I'm trying to do for clojure, and it's a mess:
>
> > (defn msort [toSort]
> >   (def sorted (let
> >    [myList (for [x toSort] [x])]      <- so far so good (not a
> > real comment.  I don't know how, yet)
> >    [
> >     (while (> (count myList) 1)      <--- infinite loop the way
> > written?  I don't know how to overwrite myList
> >       (let [l1 (nth myList 0)][])
> >       (let [l2 (nth myList 1)][])
> >       (let [listmerge (some_merge_func l1 l2)][])
> >       (let [myList (concat (drop 2 myList) listmerge)][myList])  <---
> > probably a different local variable
> >       )
> >    ]))
> >   sorted)
>
> > doesn't compile anyway . . . I see that the let is causing the scope
> > to be all screwed up.  l1 and l2 can't be seen for the merge function.
>
> > should I be using let at all here?  Can things be redefined using
> > def?  see how much simpler it is not to say anything?  Which is
> > it  def or let in python?  Answer: No . . .but I'm sure there's
> > value.  This seems like something that might be in the FAQ. . . .or
> > somewhere back in these discussions.  I'll look around.
>
> > Thanks.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

great.  I wondered about that, too!  thanks.

On Jan 11, 7:27 am, James Reeves  wrote:
> On Jan 11, 6:32 am, "Nick Vogel"  wrote:
>
> > Ok, first of all, here's how I translated that python code:
>
> > (defn msort [myList]
> >   (if (> (count myList) 1)
> >     (let [l1 (first myList) l2 (second myList)]
> >       (recur (concat (drop 2 myList) (my-merge l1 l2
> >     (first myList)))
>
> I'd change (> (count myList) 1) to (rest myList). It should work the
> same way, and won't take O(N) time on seqs.
>
> - James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

that looks interesting, except it is missing the part where you take
the original list and make it into a list of lists using list
comprehension.  That works in python and clojure for me ... "the so
far so good part".  If the recur were to do that repeatedly, the
algorithm would get messed up.  Still awesome to find out
about . . .and actually that's another way to do it because I can call
a helper function after the original divide (list comprehension)
step . . . remembering that mergesort is a divide and conquer problem.

On Jan 11, 1:32 am, "Nick Vogel"  wrote:
> Ok, first of all, here's how I translated that python code:
>
> (defn msort [myList]
>   (if (> (count myList) 1)
>     (let [l1 (first myList) l2 (second myList)]
>       (recur (concat (drop 2 myList) (my-merge l1 l2
>     (first myList)))
>
> The main thing that might need explaining is the recur, which basically goes
> back to either the last function definition or last loop and rebinds
> whatever parameters werre passed in.  In this case it goes back and is as if
> it's calling msort with (concat (drop 2 myList) (my-merge l1 l2)) as
> myList.  The let is just for clarity's sake, you could have just put them in
> place of l1 and l2 in the recur.
>
> On Sun, Jan 11, 2009 at 12:21 AM, e  wrote:
>
> > I'm just trying to understand basic stuff.
> > say I have a local list called "myList" (assigned using 'let' . . .
> > should I have used something else?)  Who cares what's in it.  Maybe I
> > set it up from a list comprehension from some input to my function.
>
> > I have no idea how to iteratively mess with it since everything is
> > persistent.  Ok, like, say it's a list of lists and I am going to be
> > merging the lists, like Tarjan's mergesort from some book from
> > college.
>
> > so I have myList with contents [[11] [2] [4] [1] [99]]
>
> > here's how I would do it in python:
>
> > def msort(myList):
> >  myList = [[x] for x in someList]
> >  while len(myList) > 1:
> >    l1 = myList.pop(0)
> >    l2 = myList.pop(0)
> >    listmerge = some_merge_function(l1, l2)
> >    myList.append(listmerge)          # important that newly merged go
> > to back of queue to get proper runtime
> >  return myList[0]
>
> > here's what I'm trying to do for clojure, and it's a mess:
>
> > (defn msort [toSort]
> >  (def sorted (let
> >   [myList (for [x toSort] [x])]      <- so far so good (not a
> > real comment.  I don't know how, yet)
> >   [
> >    (while (> (count myList) 1)      <--- infinite loop the way
> > written?  I don't know how to overwrite myList
> >      (let [l1 (nth myList 0)][])
> >      (let [l2 (nth myList 1)][])
> >      (let [listmerge (some_merge_func l1 l2)][])
> >      (let [myList (concat (drop 2 myList) listmerge)][myList])  <---
> > probably a different local variable
> >      )
> >   ]))
> >  sorted)
>
> > doesn't compile anyway . . . I see that the let is causing the scope
> > to be all screwed up.  l1 and l2 can't be seen for the merge function.
>
> > should I be using let at all here?  Can things be redefined using
> > def?  see how much simpler it is not to say anything?  Which is
> > it  def or let in python?  Answer: No . . .but I'm sure there's
> > value.  This seems like something that might be in the FAQ. . . .or
> > somewhere back in these discussions.  I'll look around.
>
> > Thanks.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread e

thanks for all the help.  just to answer the last question, 'sorted'
should have taken on the new def before getting returned.  that return
happens after the def is complete.  Will check out refs.  I think
that's what I need to understand.

On Jan 11, 1:27 am, "Eric Lavigne"  wrote:
> > I have no idea how to iteratively mess with it since everything is
> > persistent.  Ok, like, say it's a list of lists and I am going to be
> > merging the lists, like Tarjan's mergesort from some book from
> > college.
>
> Sorting is done much more easily with recursion than with iteration.
> However, it looks like you are focused on learning language features rather
> than programming strategy, so I will just answer your questions.
>
> I have not actually done any iterative programming in Clojure, as I prefer
> the functional approach, so my answers are based on my limited understanding
> of the Clojure documentation.
>
> so I have myList with contents [[11] [2] [4] [1] [99]]
>
>
>
>
>
> > here's how I would do it in python:
>
> > def msort(myList):
> >  myList = [[x] for x in someList]
> >  while len(myList) > 1:
> >    l1 = myList.pop(0)
> >    l2 = myList.pop(0)
> >    listmerge = some_merge_function(l1, l2)
> >    myList.append(listmerge)          # important that newly merged go
> > to back of queue to get proper runtime
> >  return myList[0]
>
> > here's what I'm trying to do for clojure, and it's a mess:
>
> > (defn msort [toSort]
> >  (def sorted (let
>
> Be careful with def. I think that it creates a global, and it looks like you
> want something with a scope limited to this function.
>
> http://clojure.org/Vars
>
> >   [myList (for [x toSort] [x])]      <- so far so good (not a
> > real comment.  I don't know how, yet)
>
> Use a semicolon to create a comment:
>
>      some code ; a comment
>
> >   [
> >    (while (> (count myList) 1)      <--- infinite loop the way
> > written?  I don't know how to overwrite myList
> >      (let [l1 (nth myList 0)][])
>
> The line above does nothing. When you write "(let [x 1] expr1) expr2" the
> new value of x has a narrow scope so that it only affects expr1.
>
> You are wanting to create a local variable that you can change. Refs can do
> that:
>
> (let [x (ref 3)]
>   (dosync
>     (while (> @x 0)
>       (ref-set x (- @x 1)))
>     @x))
>
> http://clojure.org/Refs
>
> >      (let [l2 (nth myList 1)][])
> >      (let [listmerge (some_merge_func l1 l2)][])
> >      (let [myList (concat (drop 2 myList) listmerge)][myList])  <---
> > probably a different local variable
> >      )
> >   ]))
> >  sorted)
>
> After all that work you just return the original list? I must have missed
> the part where you tried to change sorted. Any such attempt would fail,
> though, because Clojure collections are immutable. Maybe sorted should be a
> ref to a list instead of just a list.
>
> Here is a discussion of sorting implementations in Clojure. I hope that you
> find it useful.
>
> http://www.fatvat.co.uk/2008/12/bubbling-clojure.html
>
> --
> Education is what survives when what has been learned has been forgotten.
>
>                    - B. F. Skinner
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: trouble with java.lang.OutOfMemoryError

2009-01-11 Thread lpetit

Hello,

If you like eclipse and would like to see where clojuredev (eclipse
plugin) is right now, you can give a quick look at the current state
of clojuredev by trying to immediately install it via the update site
link :

http://clojure-dev.googlecode.com/svn/updatesite/

Still not ready for public availability (it's alpha alpha), but that's
a start.

And you could subscribe to clojuredev user ml: very very low traffic
(no message right now :-), and we could jut publish announces when
something interesting for users is ready on the update site.

Quickly, what is available right now :
- enable a java project with clojure dev nature (contextual menu of
the java project, -> Clojure submenu)
- wizard for creation of clojure project (= java project + clojure
nature)
- syntax coloring
- some keyboard accelerators for :
   - jump to matching bracket : Ctr+Shift+P
   - Go to start of top level defun : Ctrl+Alt+A (or AltGr+A)
   - Go to end of top level defun : Ctrl+Alt+E (or AltrGr+E)
   - Select (highlight) top level defun : Ctrl+Altr+H (or AltrGr+H)
- Launch configuration for clojure : enable to select which files to
load on startup, and other things similar to java launch
configuration. Not yet possible to select a main method other than
clojure.lang.Repl (will change at some point in time)

If you have time, please give it a try, do some feedback, and fill
free to submit tickets if you find bugs (in the features listed above,
the other ones you may find via menus are not yet ready, even if the
menu are there).

Regards,

--
Laurent

On Jan 11, 3:18 am, e  wrote:
> seems like enclosjure addresses a bunch of my problems/questions.  It
> also seems to work like we wanted SLIME to work, more or
> less . . .where you attach to the vm that's used for execution . . .
> only you attach to the REPL, I think, which still accomplishes the
> goal of keeping the editor separate from the memory, but what about
> having the REPL being able to attach to the vm it is managing.  Then
> it wouldn't be something that NetBeans/enclosure is doing . . . rather
> something that's part of the language.
>
> So, yeah.  enslojure sets up a HelloWorld that you can play with right
> away.  In fact, when you click on "build" it even tells you how you
> could run your application from the command line using a java
> command.  It jars up you whole clojure project and everything.  Nice.
> On the other hand, I couldn't figure out how to use NetBeans' run
> button.  it couldn't find main or something.  So I also couldn't debug
> using NetBeans' debugger because of this.  Also, it isn't clear how to
> get different clojure files to work together.  Do you use the (load)
> function?  If so, I don't know how the project thinks of relative file
> locations.  It's not as clean/clear as java (for a beginner, at least)
> where you just import classes you want to use . . and make
> packages. . . . or modules in python.  I don't know what the notion of
> "path" is in clojure.  I see the namespace stuff but have no clue how
> to make it work yet.  Are you just supposed to use one giant file for
> all your work?  That wouldn't be good for teams, for sure. . . only
> for hacking.  Also the REPL errors are USELESS to a beginner.
> something about iSeq all the time.  The moral for me there was no to
> make an error.  Better than where I was before enclojure.  Again, I
> contend that a language is only as good as the IDE that has been
> written for it, which is why it's cool to see enclojure coming along
> (even though it means learning NetBeans instead of Eclipse).
>
> On Jan 10, 5:31 pm, Paul  Mooser  wrote:
>
> > If I'm not mistaken, this is fairly close to how SLIME works, when
> > connected to a remote VM. The remote VM is running some server code
> > which allows it to communicate with SLIME, which is running inside of
> > emacs.
>
> > On Jan 10, 2:15 pm, e  wrote:
>
> > > exactly. . . .but I bet a lot of people would just reply that this is
> > > not possible to address since the REPL is the one and only vm.
> > > Disclaimer, I'm only guessing at that, too.  I don't understand any of
> > > this, yet.  But if that's the case, fix that.  Have the REPL send
> > > messages to the vm that's running the program . . . instead of the
> > > REPL being the program.
>
> > > On Jan 10, 5:00 pm, Paul  Mooser  wrote:
>
> > > > Yeah, I'm not really sure how I think the problem would be ideally
> > > > solved. It would just be nice for an interactive programming
> > > > environment to be able to recover from all exceptions that happen at a
> > > > higher level than the VM itself.
>
> > > > On Jan 10, 12:20 pm, "Christian Vest Hansen" 
> > > > wrote:
>
> > > > > I don't think it is possible to define a way to deal with heap
> > > > > saturation that is general enough to cover all programs written in
> > > > > Clojure, and therefor I don't think this is something that the Clojure
> > > > > runtime should deal with at all.
>
> > > > > Personally, I only know of two ways 

Re: non recursive impl in presence of persistence?

2009-01-11 Thread John

Hi,

I'm just learning Clojure too, so I don't have much to add to what
everyone else has said, but here's my crack at a full implenentation
of merge-sort in Clojure.  I'm  sure that there is plenty of room for
improvement (especially wrt. the merge function) but in case it's
helpful, here it is:

(defn lazy-merge [seq1 seq2]
  (cond (<= (count seq1) 0) (lazy-cons (first seq2) (rest seq2))
(<= (count seq2) 0) (lazy-cons (first seq1) (rest seq1))
:else (let [h1 (first seq1)
h2 (first seq2)]
(if (< h1 h2)
(lazy-cons h1 (lazy-merge (rest seq1) seq2))
(lazy-cons h2 (lazy-merge seq1 (rest seq2)))

(defn merge-sort [seq]
  (if (> (count seq) 1)
  (apply lazy-merge (map merge-sort (split-at (/ (count seq) 2)
seq)))
  seq))


-
John


On Jan 10, 9:21 pm, e  wrote:
> I'm just trying to understand basic stuff.
> say I have a local list called "myList" (assigned using 'let' . . .
> should I have used something else?)  Who cares what's in it.  Maybe I
> set it up from a list comprehension from some input to my function.
>
> I have no idea how to iteratively mess with it since everything is
> persistent.  Ok, like, say it's a list of lists and I am going to be
> merging the lists, like Tarjan's mergesort from some book from
> college.
>
> so I have myList with contents [[11] [2] [4] [1] [99]]
>
> here's how I would do it in python:
>
> def msort(myList):
>   myList = [[x] for x in someList]
>   while len(myList) > 1:
>     l1 = myList.pop(0)
>     l2 = myList.pop(0)
>     listmerge = some_merge_function(l1, l2)
>     myList.append(listmerge)          # important that newly merged go
> to back of queue to get proper runtime
>   return myList[0]
>
> here's what I'm trying to do for clojure, and it's a mess:
>
> (defn msort [toSort]
>   (def sorted (let
>    [myList (for [x toSort] [x])]      <- so far so good (not a
> real comment.  I don't know how, yet)
>    [
>     (while (> (count myList) 1)      <--- infinite loop the way
> written?  I don't know how to overwrite myList
>       (let [l1 (nth myList 0)][])
>       (let [l2 (nth myList 1)][])
>       (let [listmerge (some_merge_func l1 l2)][])
>       (let [myList (concat (drop 2 myList) listmerge)][myList])  <---
> probably a different local variable
>       )
>    ]))
>   sorted)
>
> doesn't compile anyway . . . I see that the let is causing the scope
> to be all screwed up.  l1 and l2 can't be seen for the merge function.
>
> should I be using let at all here?  Can things be redefined using
> def?  see how much simpler it is not to say anything?  Which is
> it  def or let in python?  Answer: No . . .but I'm sure there's
> value.  This seems like something that might be in the FAQ. . . .or
> somewhere back in these discussions.  I'll look around.
>
> Thanks.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: non recursive impl in presence of persistence?

2009-01-11 Thread James Reeves

On Jan 11, 6:32 am, "Nick Vogel"  wrote:
> Ok, first of all, here's how I translated that python code:
>
> (defn msort [myList]
>   (if (> (count myList) 1)
>     (let [l1 (first myList) l2 (second myList)]
>       (recur (concat (drop 2 myList) (my-merge l1 l2
>     (first myList)))

I'd change (> (count myList) 1) to (rest myList). It should work the
same way, and won't take O(N) time on seqs.

- James
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Ugly Sudoku solver

2009-01-11 Thread Konrad Hinsen

On 11.01.2009, at 08:56, Tzach wrote:

> Following your good advice, I also update the next-cell function to
> work in a lazy way instead of sorting the values of the entire board.

Good idea!

> (defn next-cell [board]
>   "return the next potential cell to set, and the valid alternatives"
>   (first (for [n (range 1 10)]
>   (filter
>#(= n (count (second %)))
>(map-board board valid-values)

Your implementation has the disadvantage of recomputing (map- 
board ...) nine times. You can avoid this with a simple modification:

(defn next-cell [board]
   "return the next potential cell to set, and the valid alternatives"
   (let [vv (map-board board valid-values)]
 (first (for [n (range 1 10)]
  (filter
   #(= n (count (second %)))
   vv)

Since the values of the lazy sequence vv are cached, nothing will  
ever be recomputed.

However, I think there is also a bug in your function: (first  
(for ..)) will return the result of the first iteration of the for,  
even if it is emtpy. What you want is the first element of the first  
non-empty element of the for sequence. You can get this with (first  
(apply concat (for [n ...))). Concat again creates a lazy sequence,  
so nothing is computed unless necessary.

Konrad.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: per-defmulti hierarchies

2009-01-11 Thread Meikel Brandmeyer

Hello,

Am 07.01.2009 um 17:44 schrieb Meikel Brandmeyer:


Please find attached another patch going for IRef instead
of Var directly. And without the other cruft.


Another update in sync with updated issue #8.

Sincerely
Meikel



issue-8b.diff
Description: Binary data




smime.p7s
Description: S/MIME cryptographic signature