Re: Another "closure" available

2009-11-08 Thread Daniel Janus

On 8 Lis, 08:11, pmf  wrote:

> > Hmm, someone else has made another "closure" available :).
>
> >http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html
>
> There's also Clozure Common Lisp [1], which is conceptually closer to
> Clojure.

There's also a web browser written in CL called Closure
(http://common-lisp.net/project/closure/)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 sort these data...

2009-11-08 Thread Michael Jaaka

Hello I have such data

[ [ "tom" 23 ] [ "ann" 4434 ] [ "tom" 1234 ] ["mike" 34 ] ]

I would like to sort these data so finally i got

[ [ "ann" 4434 ] ["mike" 34 ] [ "tom" 23 ] [ "tom" 1234 ]  ]

note that i don't care the order between "tom" keys (1234 can be
before 23)

I have seen sort-by but I can't find tutorial how to use keyfn

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



Feedback on a simplified regexp implementation

2009-11-08 Thread Matthew Denson

Hi All,

I have been watching Clojure for about 6 months.  I finally sat down
and tried to code a non-trivial task with it.  I come from Java and
have dabbled in LISP but never for something significant.

So I am asking if you would look at the following code and provide
feedback on how it can be made less "Java" and more "Clojure" in terms
of style and approach.

The code is basically a translation of the code in the first chapter
of _Beautiful Code_.  It is a simple regexp matcher that matches ^,
$, .(dot), *, and literal characters.  I didn't change much of the
structure because the structure made sense to my Java sensibilities.
I learned a lot in getting it to work.  I had to figure out how to
iterate over a string, use loop...recur, etc.  But the style of coding
can't be gotten from the API docs.  So is this way off?  Or are there
different ways of thinking about the solution that would be more in
line with a "Clojure way"?

I must confess that the result here doesn't make me happy.  The C code
from the article looked very clear and extension (+, ?, character
classes) looked like it would be fairly straightforward.  I'm not sure
that is true with my code here.

Finally, this is just an exercise.  If I needed regexp in another
problem, I would use the clojure tools.

Thanks in advance,
Matthew

P.S. There must be some libraries for testing that would be better
than what I've done, but I didn't find anything I could get to work.

(declare matchhere)

(defn match
  "search for regexp anywhere in text"
  [regexp text]
  (if (= (first regexp) \^)
(matchhere (rest regexp) (seq text))
(loop [re (seq regexp) t (seq text)]
  (if (matchhere re t)  ; always search even if text is empty
true
(if (seq (rest t))
  (recur re (rest t))
  false)

(defn matchstar
  "search for [char]*regexp at beginning of text"
  [char regexp text]
  (loop [c char re regexp t text]
(if (matchhere re t) ; a * matches zero or more instances
  true
  (if (and (seq t)
   (or (= (first t) c) (= c \.)))
(recur c re (rest t))
false

(defn matchhere
  "search for regexp at beginning of text"
  [regexp text]
  (loop [re regexp t text]
(if (nil? re)
  true
  (if (and (= (first re) \$) (nil? (rest re)))
(nil? t)
(if (= (nth re 1 ()) \*)
  (matchstar (first re) (rest (rest re)) t)
  (if (and (seq t)
   (or (= (first re) \.) (= (first re) (first t
(recur (rest re) (rest t))
false))

;;  some of my tests that show usage
(= true (match "a" "a"))
(= false (match "b" "a"))
(= true (match "b" "ab"))

(= true (match "^a" "ab"))
(= false (match "^b" "ab"))

(= true (match "b$" "b"))
(= true (match "a$b" "aaa$bBB"))
(= false (match "ab$" "ab$"))

(= false (match "a.*b" "a"))
(= true (match "a.*b" "aaab"))
(= true (match "a.*b" "aabb"))

;; etc. etc.

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



Re: How to sort these data...

2009-11-08 Thread Michael Jaaka
OK. I have figured it out. I just looked into core.clj and noticed that
keyfn is a function which know how to get a value from an element in a
collection. That value is just compared with other.

2009/11/7 Michael Jaaka 

> Hello I have such data
>
> [ [ "tom" 23 ] [ "ann" 4434 ] [ "tom" 1234 ] ["mike" 34 ] ]
>
> I would like to sort these data so finally i got
>
> [ [ "ann" 4434 ] ["mike" 34 ] [ "tom" 23 ] [ "tom" 1234 ]  ]
>
> note that i don't care the order between "tom" keys (1234 can be
> before 23)
>
> I have seen sort-by but I can't find tutorial how to use keyfn

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



Michael newbee challange nr 1

2009-11-08 Thread Michael Jaaka
Hi! How would you solve such problem:

I have a collection of pairs (key, value) ->
[  [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ]

As you can see keys can occur more than once, also that collection is very
large so it should be evaluated lazily (for example the collection cames
from stream input).

I have function with two arguments key and sequence of its values, the
pseudo code would be:

callbackListener(string key, iterator values)

now I would like get such effect that callbackListener will be called twice
for the example collection.

once with "tom" and iterator (or a lazy seq) to lazy evaluated collection of
(32 and 2333)
and second with "anne" and iterator for collection of (12 and 55)

In Java it is easy because the language is imperative. But how about such
logic in Clojure?
Note that all must be evaluated lazily.

Thanks in advance.

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

2009-11-08 Thread Stefan Arentz

Hi Alex,

Wow! Thank you so much for this excellent explanation! It totally  
makes sense now :-)

  S.

On 2009-11-07, at 9:46 PM, Alex Osborne wrote:

>
> Stefan Arentz wrote:
>
>> I must admin that I don't fully understand the difference between foo
>> and #'foo. That is probably why I'm making this beginner mistake :-)
>
> The difference takes some explanation.  So without further ado...
>
> Functions and Metadata: in Vivacious Gory Detail
> 


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



Converting to TCO

2009-11-08 Thread Robert Campbell

I've started reading SICP and I came across the Fermat primality test
implemented an Scheme. I reimplemented it in Clojure and was able to
switch the recursive call in fast-prime to TCO/recur, but I was unable
to do the same for the exp-mod function.

(defn exp-mod [base exp m]
  (cond
(zero? exp) 1
(even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
:else (mod (* base (exp-mod base (inc exp) m)) m)))

(defn fermat-test [n]
  (defn try-it [a]
(= (exp-mod a n n) a))
  (try-it (inc (rand-int (dec n)

(defn fast-prime? [n times]
  (cond
(zero? times) true
(fermat-test n) (recur n (dec times))
:else false))

Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use TCO?

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

2009-11-08 Thread Robert Campbell

One correction: after playing with the functions a bit I noticed I
screwed up, putting sqrt where I needed square.


On Sun, Nov 8, 2009 at 4:43 PM, Robert Campbell  wrote:
> I've started reading SICP and I came across the Fermat primality test
> implemented an Scheme. I reimplemented it in Clojure and was able to
> switch the recursive call in fast-prime to TCO/recur, but I was unable
> to do the same for the exp-mod function.
>
> (defn exp-mod [base exp m]
>  (cond
>    (zero? exp) 1
>    (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
>    :else (mod (* base (exp-mod base (inc exp) m)) m)))
>
> (defn fermat-test [n]
>  (defn try-it [a]
>    (= (exp-mod a n n) a))
>  (try-it (inc (rand-int (dec n)
>
> (defn fast-prime? [n times]
>  (cond
>    (zero? times) true
>    (fermat-test n) (recur n (dec times))
>    :else false))
>
> Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use 
> TCO?
>

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

2009-11-08 Thread Mark Engelberg

Hint: Use an accumulator.
http://htdp.org/2003-09-26/Book/curriculum-Z-H-39.html#node_chap_31

In fact, you may want to consider reading How to Design Programs before SICP.

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

2009-11-08 Thread Meikel Brandmeyer
Hi,

Am 08.11.2009 um 13:33 schrieb Michael Jaaka:

> Hi! How would you solve such problem:
>
> I have a collection of pairs (key, value) ->
> [  [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ]
>
> As you can see keys can occur more than once, also that collection  
> is very large so it should be evaluated lazily (for example the  
> collection cames from stream input).
>
> I have function with two arguments key and sequence of its values,  
> the pseudo code would be:
>
> callbackListener(string key, iterator values)
>
> now I would like get such effect that callbackListener will be  
> called twice for the example collection.
>
> once with "tom" and iterator (or a lazy seq) to lazy evaluated  
> collection of (32 and 2333)
> and second with "anne" and iterator for collection of (12 and 55)
>
> In Java it is easy because the language is imperative. But how about  
> such logic in Clojure?
> Note that all must be evaluated lazily.

Obviously, this cannot be done completely lazy since changing the  
first element is not a stopping time. You'll always need at least one  
lookahead to determine the change of the key and you'll have to  
realize the input to find all values for a key.

(defn grouped-seq
   [input]
   (lazy-seq
 (when-let [s (seq input)]
   (let [k  (ffirst s)
 [vs r] (split-with #(-> % first (= k)) s)]
 (cons [k vs] (grouped-seq r))

(map #(apply callbackListener %) (grouped-seq [["tom" 32] ["tom" 2333]  
["anne" 12] ["anne" 55]]))

Note: if you try to avoid realizing all values of a given key, you'll  
need two sequences: one to keep track of the key and of for the  
values. While callbackListener realises the values, the key sequence  
will retain the head of the input causing all values to stay in  
memory. If you want really laziness, you'll have to traverse the input  
twice over independent input streams. So if you have a file containing  
the data, you'll have to read the file twice from independent streams  
to get full laziness.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Imperative into functional?

2009-11-08 Thread Michael Jaaka
Can any imperative code be transformed to functional equivalent?
(Give an answer in terms of the same way I can answer on recursion and
loops)

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

2009-11-08 Thread John Harrop
You have a bug:

(defn exp-mod [base exp m]
  (cond
(zero? exp) 1
(even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
:else (mod (* base (exp-mod base (inc exp) m)) m)))

should be

(defn exp-mod [base exp m]
  (cond
(zero? exp) 1
(even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
:else (mod (* base (exp-mod base (dec exp) m)) m)))

The recursion depth is logarithmic in exp so TCO is probably unnecessary
here. But with the bug, it gets locked into a cycle of exp being alternately
2 and 1 and never reaching zero, the base case, so the recursion continues
until the stack blows up.

Meanwhile,

(defn fermat-test [n]
  (defn try-it [a]
(= (exp-mod a n n) a))
 (try-it (inc (rand-int (dec n)

should really be

(defn fermat-test [n]
  (letfn [(try-it [a]
   (= (exp-mod a n n) a))]
   (try-it (inc (rand-int (dec n))

in Clojure, or even

(defn fermat-test
  "Performs the Fermat test on n with a, if specified, or with a random
value from 2 to n."
  ([n a]
(= (exp-mod a n n) a))
  ([n]
(fermat-test n (inc (rand-int (dec n))

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

2009-11-08 Thread Mark Engelberg

On Sun, Nov 8, 2009 at 8:41 AM, Michael Jaaka
 wrote:
> Can any imperative code be transformed to functional equivalent?
> (Give an answer in terms of the same way I can answer on recursion and
> loops)

Short answer: Yes.
Long answer:  Yes, but sometimes the transformation can get rather unwieldy.

Most of the time, such transformations are easy.  For example, when
writing the clojure-contrib combinatorics library, I was transforming
highly imperative register-based algorithms from Knuth's books into
loop/recur using Clojure's functional vectors.  It's just as
inscrutable to read as the original, but it was fairly easy to
transform.

The basic technique is to, rather than change something in place and
"returning void", you return the changed version from a function.

The problem is that sometimes, there are many different pieces of many
different states that need to be updated, and you end up passing more
and more things around in a functional way until eventually you are
threading some monolithic "world state" through all your functions,
basically simulating the imperative process. This is where monads can
come in handy, to help hide the threading of the monolithic state.
But at this point, it's not clear whether you're really any better off
than doing it imperatively to begin with.  That's why it's good that
Clojure has a suite of mechanisms for dealing with state (agents,
refs, vars, atoms...)

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

2009-11-08 Thread John Harrop
On Sun, Nov 8, 2009 at 7:33 AM, Michael Jaaka
wrote:

> Hi! How would you solve such problem:
>
> I have a collection of pairs (key, value) ->
> [  [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ]
>
> As you can see keys can occur more than once, also that collection is very
> large so it should be evaluated lazily (for example the collection cames
> from stream input).
>
> I have function with two arguments key and sequence of its values, the
> pseudo code would be:
>
> callbackListener(string key, iterator values)
>
> now I would like get such effect that callbackListener will be called twice
> for the example collection.
>
> once with "tom" and iterator (or a lazy seq) to lazy evaluated collection
> of (32 and 2333)
> and second with "anne" and iterator for collection of (12 and 55)
>

Something related to

(let [ks (distinct (map first s))
  vals-for-key (fn [k] (map second (filter #(= (first %) k) s)))]
  (doseq [k ks] (callback k (vals-for-key k

or to collect and return the return values of the callbacks, use "for"
instead of "doseq".

The problem is that this will realize s and hold onto its head, as Meikel
points out. To make it really lazy you need something more like

(defn do-it [callback producer]
  (let [ks (fn [p] (distinct (map first (p
vals-for-key (fn [k p] (map second (filter #(= (first %) k) (p]
(doseq [k (ks p)] (callback k (vals-for-key k p

and call this with two arguments, the first the callback that will take a
key and a lazy seq of the associated values, and the second a function that
will produce anew a lazy sequence of key-value pairs from your disk file
each time it's called, with the property that the lazy-seq clause that
returns nil when the sequence is exhausted also has the side effect of
closing the input stream so as not to leak file handles.

This will grovel over the file N+1 times where N is the number of distinct
keys, though, and will have in general two input streams open on the file at
the same time, one of them crawling along discovering more distinct keys,
and the other finding all the values for one key, then for the next, etc.

It will also build up a hashset of all of the keys over time, hidden inside
the "distinct" function's returned seq. So, if the summed lengths of the
distinct keys is going to be big enough to blow the heap all on its own,
you've got real problems and you'll probably need to use a scratch disk
file. In that case I'd recommend a more imperative style with a loop/recur
and lazy-seq, where the outer loop starts with a copy of the input file,
runs the inner loop, and then deletes its input and reruns itself with the
file generated by the inner loop (hence starting with a *copy* of the input
file), and the inner loop reads the first key from the current input file,
creates an empty temp file to be the current output file, then calls the
callback with a lazy seq object whose realization actually advances through
the input file, copying entries to the output file that are not matching the
current key and producing lazy seq elements for entries that do match.

The idea is that if your input file foo.dat reads [[x 1] [y 2] [x 3] [z 4]
[y 5]] it will make a copy foo1.tmp, then call the callback with x and a
lazy seq whose realization emits (1 3) while also generating foo2.tmp = [[y
2] [z 4] [y 5]]; then the outer loop deletes foo1.tmp and repeats on
foo2.tmp and the callback is called with y and a lazy seq whose realization
emits (2 5) while generating foo3.tmp = [[z 4]]; and then the outer loop
deletes foo2.tmp and the callback is called with z and a lazy seq (4) whose
realization creates an empty foo4.tmp; then the outer loop deletes foo3.tmp,
sees foo4.tmp is empty, and deletes foo4.tmp and terminates.

If you want the callback's return values, you'll need to make the outer loop
another lazy-seq.

I'm a bit uncomfortable with lazy-seq bodies that have side effects.

You might want to consider if you need to be using a RDBMS instead of just
disk files for whatever it is you're doing.

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

2009-11-08 Thread Robert Campbell

Mark: that looks a lot like the "collector" I learned about in The
Little Schemer. I actually do have How to Design Programs, but I
wanted to finish Seasoned Schemer first. I was poking around in SICP
because of a Project Euler problem. Thanks for the tip!

John: good catch. Can you confirm the difference between my original
defn and your letfn? Both work, but as I understand it from the
documentation, defn would actually define that local function
globally, while letfn actually does bind it locally to all the expr
which follow in the body..


On Sun, Nov 8, 2009 at 7:01 PM, John Harrop  wrote:
> You have a bug:
> (defn exp-mod [base exp m]
>   (cond
>     (zero? exp) 1
>     (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
>     :else (mod (* base (exp-mod base (inc exp) m)) m)))
> should be
> (defn exp-mod [base exp m]
>   (cond
>     (zero? exp) 1
>     (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
>     :else (mod (* base (exp-mod base (dec exp) m)) m)))
> The recursion depth is logarithmic in exp so TCO is probably unnecessary
> here. But with the bug, it gets locked into a cycle of exp being alternately
> 2 and 1 and never reaching zero, the base case, so the recursion continues
> until the stack blows up.
> Meanwhile,
> (defn fermat-test [n]
>   (defn try-it [a]
>     (= (exp-mod a n n) a))
>  (try-it (inc (rand-int (dec n)
> should really be
> (defn fermat-test [n]
>   (letfn [(try-it [a]
>            (= (exp-mod a n n) a))]
>    (try-it (inc (rand-int (dec n))
> in Clojure, or even
> (defn fermat-test
>   "Performs the Fermat test on n with a, if specified, or with a random
> value from 2 to n."
>   ([n a]
>     (= (exp-mod a n n) a))
>   ([n]
>     (fermat-test n (inc (rand-int (dec n))
>
> >
>

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

2009-11-08 Thread André Ferreira

It's one thing to try to protect the programmer from accidentally
shooting himself on the foot, but I don't think it is as necessary for
a language to prevent him from doing it on purpose.

On 8 nov, 02:59, John Harrop  wrote:
> user=> (def q 'G__723)
> #'user/q
> user=> (def r (gensym))
> #'user/r
> user=> q
> G__723
> user=> r
> G__723
> user=> (= q r)
> true
>
> It's possible to anticipate the next gensym name that will be generated and
> then engineer a collision, and therefore possibly variable capture
> unintended by the author of a macro.
>
> It looks like "manually" generating a name does not remove it from the pool
> of allowable future gensym names.
>
> This shouldn't tend to cause accidental problems in practice, since gensym
> names tend not to collide with the kinds of identifiers programmers
> ordinarily use. Nonetheless it can be partially fixed comparatively easily
> by adding to the runtime a WeakHashMap into which a reference to any symbol,
> however created, is placed and modifying the gensym-generator to, at the
> point where it currently returns a value, first check if the WeakHashMap
> contains it already and if so, generate the next one, and the next, as
> needed until it gets a not-in-use name. This requires gensym creation and
> normal symbol creation to occur in a global lock but symbol creation rarely
> occurs at runtime and even more rarely in any kind of hot-spot at runtime.
> The use of WeakHashMap would prevent the runtime clogging up with
> ungarbagecollectable symbols, so the memory overhead of adding this would be
> smallish, one machine pointer per in-use symbol or so, equivalent to if
> every symbol had a few more characters in its name.
>
> This would stop gensym from producing a name already in use. It wouldn't
> prevent a gensym being generated somewhere and *then* the identical name
> being put together someplace else and passed to the symbol function, though;
> a small loophole. Collisions between gensyms in preexisting code and an
> enclosing lexical scope in new code would become impossible, but collisions
> between gensyms in preexisting code and an enclosed lexical scope (e.g. a
> macro-invocation body, such as a loop body) would remain theoretically
> possible.
>
> That last loophole can't really be plugged without giving Clojure "true"
> gensyms (uninterned anywhere), which would bring with it its own
> architectural problems. If that change were made, the above REPL interaction
> would be possible up to the (= q r) evaluation, but that would return false
> despite the names looking the same, so the symbols wouldn't really collide
> even though a collision of their printed representations could still be
> engineered. One bothersome consequence though would be that the textual
> output of macroexpand-1 could no longer always be substituted for a macro
> call in source code without altering the run-time semantics of that code,
> even when the macro's expansion-generation does not have side effects.
>
> (To reproduce that REPL interaction for yourself, evaluate (gensym) at the
> REPL and note the number. Add seven and then evaluate (def q 'G__#) with #
> replaced with the sum. Then evaluate (def r (gensym)) and, if you like, skip
> straight to (= q r). If that doesn't work, the number it goes up by must
> have changed between Clojure 1.0 and whatever version you're using; evaluate
> (gensym), then (def q 'xyzzy), then (gensym) again and note the increment
> and use that instead of seven. Oh, and don't have any background threads
> running in that JVM instance that might do something autonomously that
> causes a gensym to be generated.)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Converting to TCO

2009-11-08 Thread John Harrop
On Sun, Nov 8, 2009 at 1:39 PM, Robert Campbell  wrote:

> John: good catch.


Thanks.


> Can you confirm the difference between my original
> defn and your letfn? Both work, but as I understand it from the
> documentation, defn would actually define that local function
> globally, while letfn actually does bind it locally to all the expr
> which follow in the body..


Yup.

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



Using Compojure's defroutes in a macro

2009-11-08 Thread Stefan Arentz


I have this Compojure code that works fine:

(defroutes my-routes
   (GET "/api"
 (my-code request)))

I want this code to be generated by a macro. My real code is more  
complex but the error is the same.

(defmacro mydefroutes []
   `(defroutes my-routes
 (GET "/api"
   (my-code request

When I run this code, I get the following error:

(foo)
No such var: webservice/request
   [Thrown class java.lang.Exception]

(webservice is the namespace of my code)

When I macroexpand the code I see this:

webservice> (macroexpand-1 '(foo))
(compojure/defroutes webservice/my-routes
   (compojure/GET "/api" (webservice/my-code webservice/request)))

I'm not sure what to do here.

  S.


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



Re: Using Compojure's defroutes in a macro

2009-11-08 Thread Richard Newman

Try

(defmacro mydefroutes []
   `(defroutes my-routes
 (GET "/api"
   (my-code ~'request

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



Re: Using Compojure's defroutes in a macro

2009-11-08 Thread Stefan Arentz


On 2009-11-08, at 3:40 PM, Richard Newman wrote:

>
> Try
>
> (defmacro mydefroutes []
>   `(defroutes my-routes
> (GET "/api"
>   (my-code ~'request

Brilliant! I learn something new every day :-)

  S.


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

2009-11-08 Thread Phil Hagelberg

On Nov 4, 9:07 pm, Lauri Oherd  wrote:
> With this patch, the trailing whitespace characters in clojure file
> buffer will be deleted automatically before each save if custom
> parameter 'clojure-mode-cleanup-whitespace' is set.
>
> This is based on the js2-mode where similar defcustom parameter is
> used. Many thanks to Steve Yegge for the code.
>
> Any comments and suggestions would be greatly appreciated.

Thanks for this patch, but stripping trailing whitespace is not a
Clojure-specific piece of functionality. I don't think it belongs in
clojure-mode itself. If a user wants to add this functionality to
clojure-mode (or any mode really) he should just put this in his own
configuration:

(add-hook 'clojure-mode-hook (lambda () (set (make-local-variable
'before-save-hook) 'delete-trailing-whitespace))

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



equivalent to Haskell's group function

2009-11-08 Thread Wilson MacGyver

Hi,

I did search in the API docs for both core and contrib, but didn't
find anything like
it.

Does Clojure have a function like Haskell's group?

In Haskell,
Input: group [1,2,2,1,1,1,2,2,2,1]
Output: [[1],[2,2],[1,1,1],[2,2,2],[1]]

Thanks

-- 
Omnem crede diem tibi diluxisse supremum.

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

2009-11-08 Thread Alex Osborne

Wilson MacGyver wrote:
> Does Clojure have a function like Haskell's group?
> 
> In Haskell,
> Input: group [1,2,2,1,1,1,2,2,2,1]
> Output: [[1],[2,2],[1,1,1],[2,2,2],[1]]

(use 'clojure.contrib.seq-utils)

(partition-by identity [1 2 2 1 1 1 2 2 2 1])
=> ((1) (2 2) (1 1 1) (2 2 2) (1))

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

2009-11-08 Thread Wilson MacGyver

ah, thank you for the help!

On Mon, Nov 9, 2009 at 1:57 AM, Alex Osborne  wrote:
>
> Wilson MacGyver wrote:
>> Does Clojure have a function like Haskell's group?
>>
>> In Haskell,
>> Input: group [1,2,2,1,1,1,2,2,2,1]
>> Output: [[1],[2,2],[1,1,1],[2,2,2],[1]]
>
> (use 'clojure.contrib.seq-utils)
>
> (partition-by identity [1 2 2 1 1 1 2 2 2 1])
> => ((1) (2 2) (1 1 1) (2 2 2) (1))
>
> >
>



-- 
Omnem crede diem tibi diluxisse supremum.

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