Boggle solver

2009-11-07 Thread james

Hey!

As a learning exercise I wrote a simple boggle solver in clojure.
I'm sure there is lots of room for improvement to make it more
idiomatic and perform better so I would be grateful if anyone would
care to cast their eye over it.

http://wiki.github.com/phraemer/Boggle-Solver

thanks,

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
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: Code formatter

2009-11-07 Thread mudphone

Um, I use butterflies?

On Nov 6, 5:35 pm, John Harrop  wrote:
> On Fri, Nov 6, 2009 at 7:41 PM, Tim Dysinger  wrote:
> > Use emacs! It formats your code while you type :)
>
> Nasty side effect though -- it formats your brain while you type, too.
> Eventually you wind up a gibbering lunatic. :) I'll keep my Netbeans,
> thanks. :)

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



Re: clojure.xml/parse of XHTML yields a 503 on the DTD

2009-11-07 Thread Joubert Nel

Perhaps xml/parse shouldn't fetch the DTD, as per the W3C
recommendation?


On Nov 7, 2:46 am, Christophe Grand  wrote:
> The w3c filters traffic to DTDs, see here for more 
> details:http://www.w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic
>
> Christophe
>
>
>
>
>
> On Sat, Nov 7, 2009 at 7:21 AM, Joubert Nel  wrote:
>
> > Hi,
>
> > I'm trying to parse the XHTML at
> >http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_042108_Antar...
>
> > But, I get a 503:
>
> > java.io.IOException: Server returned HTTP response code: 503 for URL:
> >http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
> > (NO_SOURCE_FILE:12)
>
> > The DTD at this URL is available, however (I can get it just fine
> > using my browser).
>
> > Advice?
>
> > Joubert
>
> --
> Professional:http://cgrand.net/(fr)
> On Clojure:http://clj-me.cgrand.net/(en)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: newbie question

2009-11-07 Thread Christophe Grand

Can I play too?

Non-lazy version (basically the same as Chouser's with reduce instead of loop):
(defn partition-when [pred coll]
  (reduce #(if (pred %2)
 (conj %1 [%2])
 (conj (pop %1) (conj (peek %1) %2)))
[[]] coll))

user=> (partition-when odd? (range 1 15))
[[] [1 2] [3 4] [5 6] [7 8] [9 10] [11 12] [13 14]]
user=> (partition-when even? (range 1 15))
[[1] [2 3] [4 5] [6 7] [8 9] [10 11] [12 13] [14]]


And lazy version:
(defn partition-when [pred coll]
  (let [heads (partial take-while (complement pred))]
(cons (heads coll)
  (mapcat #(when (pred %1) [(cons %1 (heads %2))])
coll (iterate rest (rest coll))

user=> (partition-when odd? (range 1 15))
(() (1 2) (3 4) (5 6) (7 8) (9 10) (11 12) (13 14))
user=> (partition-when even? (range 1 15))
((1) (2 3) (4 5) (6 7) (8 9) (10 11) (12 13) (14))

Christophe

On Sat, Nov 7, 2009 at 1:47 AM, Alex Osborne  wrote:
>
> Alex Osborne wrote:
>> Like Mark's but using split-with instead of split-at:
>>
>> (defn partition-when [pred coll]
>>    (lazy-seq
>>     (when-let [[x & xs] (seq coll)]
>>       (let [[xs ys] (split-with (complement pred) xs)]
>>         (cons (cons x xs) (partition-when pred ys))
>
> Just realised this is almost the same as Warren's -- I had missed
> reading Warren's before posting.  Thought it might be helpful if I
> explain the differences:
>
> * lazy-seq on the outside of the conditional.  This means the seq is
> fully lazy, so if you never call first/next on it, nothing is ever run.
>
> * As suggested by others complement instead of NOT.
>
> * (when (seq coll) ...) instead of (if (empty? coll) () ...).  We can
> simplify things like this as (lazy-seq nil) => () and (seq ()) => nil.
>
> * Using destructuring instead of (first coll) (next coll).  Makes it a
> bit shorter and is quite useful if you're going to use the result of
> (first coll) or (next coll) multiple times, but in this case it doesn't
> really matter.
>
> >
>



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

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



Avoiding reflection/hinting with byte-array.

2009-11-07 Thread David Brown

I can't figure out how to avoid reflection, in the 'update' method of
MessageDigest.  It is overloaded on a single argument with either
'byte', 'byte[]', or 'java.nio.ByteBuffer'.

   (import '(java.security MessageDigest))
   (set! *warn-on-reflection* true)

The compiler didn't seem to like a tag that wasn't actually a class
name:

   (def byte-array-class
 (class (make-array Byte/TYPE 0)))

   ;; "Unable to resolve classname: byte-array-class"
   (defn update1
 [#^MessageDigest md #^{:tag byte-array-class} item]
 (.update md item))

And it seems to have no effect if I expand it as the tag:

   ;; "call to update can't be resolved."
   (defn update2
 [#^MessageDigest md #^{:tag (class (make-array Byte/TYPE 0))} item]
 (.update md item))

In this particular case, I was able to work around the issue one of
two ways, basically by using a different type.

   (defn workaround
 [#^MessageDigest md item]
 (.update md item 0 (count item)))

   (defn workaround2
 [#^MessageDigest md item]
 (.update md (java.nio.ByteBuffer/wrap item)))

Any ideas?  BTW, my real use case is in a defmethod, where I handle
several other types for the update.

Thanks,
David

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



Re: Avoiding reflection/hinting with byte-array.

2009-11-07 Thread Chouser

On Sat, Nov 7, 2009 at 10:41 AM, David Brown  wrote:
>
> I can't figure out how to avoid reflection, in the 'update' method of
> MessageDigest.  It is overloaded on a single argument with either
> 'byte', 'byte[]', or 'java.nio.ByteBuffer'.
>
>   (import '(java.security MessageDigest))
>   (set! *warn-on-reflection* true)
>
> The compiler didn't seem to like a tag that wasn't actually a class
> name:
>
>   (def byte-array-class
>     (class (make-array Byte/TYPE 0)))
>
>   ;; "Unable to resolve classname: byte-array-class"
>   (defn update1
>     [#^MessageDigest md #^{:tag byte-array-class} item]
>     (.update md item))

Right, :tag values should be symbols, not classes or instances of
those classes.  Most of those symbols name actual Java classnames
but a few other symbols are supported, mostly for arrays of
primitives:

  objects  Object[].class;
  ints int[].class;
  longslong[].class;
  floats   float[].class;
  doubles  double[].class;
  charschar[].class;
  shorts   short[].class;
  bytesbyte[].class;
  booleans boolean[].class;

This should work:

(defn update1 [#^MessageDigest md, #^bytes item]
  (.update md item))

--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
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: clojure.xml/parse of XHTML yields a 503 on the DTD

2009-11-07 Thread Stefan Tilkov

On 07.11.2009, at 15:07, Joubert Nel wrote:

>
> Perhaps xml/parse shouldn't fetch the DTD, as per the W3C
> recommendation?
>

It's highly likely it's the underlying Java parser that does so (even  
though it doesn't need to) - the same problem would be there if a Java  
program running in the same environment parsed the XML.

A catalog file would help.

Stefan
--
Stefan Tilkov, http://www.innoq.com/blog/st/



--~--~-~--~~~---~--~~
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: ICFP Proposals

2009-11-07 Thread Dimitri Mallis
Thank you Tim,

I certainly appreciate information like this!

I am busy writing a paper for the IEEE conference later on in 2010. Its for
my honours university work. Bluetooth social messaging and proximity related
activities in and around the university campus.

I have done a lot of work with JAVA, & JAVA byte code this year. I wrote my
own small DSL language for Abstract Algebra. A cycle number compiler, where
a user could write maths statements as they would on paper and have it
compiled into JAVA byte code, that could run on any JVM. (I did not quite
get my AST (Abstract Syntax Tree) 100% correct :( )

Either way, I go my hands messy with JAVA byte code & the sable-jasmin JAVA
byte code compiler.
I read a paper where a lisp was written to run natively on ARM, PPC, x86
cores!
Here is the information about the paper I read.

Verified LISP Implementations on ARM, x86 and PowerPC
Magnus O. Myreen and Michael J.C. Gordon
Computer Laboratory, University of Cambridge, UK

google around for the paper! Its very interesting.


On Sat, Nov 7, 2009 at 7:47 AM, John Harrop  wrote:

> On Fri, Nov 6, 2009 at 3:36 PM, Tim Dysinger  wrote:
>
>> If anyone's interested there is a call for proposals for ICFP 2010
>> http://www.icfpconference.org/icfp2010/cfwp.html & due by Nov 20
>
>
> In the future, you might want to tell people that "ICFP" stands for
> "International Conference on Functional Programming" instead of assuming
> that everyone either already knows or is willing to click through the link
> to find out. You might get more people interested if your announcement
> messages are a little less cryptic. :)
>
> >
>


-- 
Dimitri Mallis
http://www.dimitrimallis.co.za/

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



web REPL

2009-11-07 Thread Mark Volkmann

A couple of months ago I saw a web site that provided a web-based REPL
for many programming languages including Clojure. I can't find it now.
Does anybody have that URL?

-- 
R. Mark Volkmann
Object Computing, Inc.

--~--~-~--~~~---~--~~
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: Avoiding reflection/hinting with byte-array.

2009-11-07 Thread David Brown

On Sat, Nov 07, 2009 at 11:48:32AM -0500, Chouser wrote:

>This should work:
>
>(defn update1 [#^MessageDigest md, #^bytes item]
>  (.update md item))

This does seem to work, thanks.

Any reason that 'doubles' is also defined as an array cast function,
but 'bytes' is not?

David

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



Re: Avoiding reflection/hinting with byte-array.

2009-11-07 Thread Chouser

On Sat, Nov 7, 2009 at 2:57 PM, David Brown  wrote:
>
> On Sat, Nov 07, 2009 at 11:48:32AM -0500, Chouser wrote:
>
>>This should work:
>>
>>    (defn update1 [#^MessageDigest md, #^bytes item]
>>      (.update md item))
>
> This does seem to work, thanks.
>
> Any reason that 'doubles' is also defined as an array cast function,
> but 'bytes' is not?

I don't know of any deep reason.

Not only bytes, but also array-cast functions don't exist for
chars, shorts or booleans.

Also there are factory functions for several primitive array
types, but char-array, short-array, byte-array, and
boolean-array don't exist.

--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
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: web REPL

2009-11-07 Thread Chouser

On Sat, Nov 7, 2009 at 2:50 PM, Mark Volkmann  wrote:
>
> A couple of months ago I saw a web site that provided a web-based REPL
> for many programming languages including Clojure. I can't find it now.
> Does anybody have that URL?

Perhaps this one on Google AppEngine?

http://lotrepls.appspot.com/

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



Adding meta data to a function (from a macro)

2009-11-07 Thread Stefan Arentz


I'm trying to do this:

(defmacro my-defn [name & body]
   `(defn- #^{ :foo-tag "blah" } ~name []
  ~...@body))

The idea is that foo will be defined and that {:foo-tag "blah"} is  
added to its meta-data.

But that does not seem to work:

user> (my-defn foo (println "Hello"))
#'user/foo

user> (foo)
Hello
nil

user> (meta #'foo)
{:ns #, :name foo, :file "NO_SOURCE_FILE", :line  
1, :arglists ([]), :private true}

What is the proper way to do this?

  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: Adding meta data to a function (from a macro)

2009-11-07 Thread Alex Osborne

Stefan Arentz wrote:
> 
> I'm trying to do this:
> 
> (defmacro my-defn [name & body]
>`(defn- #^{ :foo-tag "blah" } ~name []
>   ~...@body))
> 
> The idea is that foo will be defined and that {:foo-tag "blah"} is  
> added to its meta-data.
> 
> But that does not seem to work:

Try this:

(defmacro my-defn [name & body]
   `(defn- ~(with-meta name  {:foo-tag "blah"})  []
   ~...@body))


--~--~-~--~~~---~--~~
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: Adding meta data to a function (from a macro)

2009-11-07 Thread Richard Newman

>> The idea is that foo will be defined and that {:foo-tag "blah"} is
>> added to its meta-data.

... and to explain *why*:

user=> (pprint
  (read-string "(defmacro my-defn [name & body]
   `(defn- #^{ :foo-tag \"blah\" } ~name []
  ~...@body))"))
(defmacro
  my-defn
  [name & body]
  (clojure.core/seq
   (clojure.core/concat
(clojure.core/list 'clojure.core/defn-)
(clojure.core/list name)
(clojure.core/list
 (clojure.core/apply
  clojure.core/vector
  (clojure.core/seq (clojure.core/concat
body)))

No mention of foo-tag in there.

#^ is a reader macro that annotates the next token read with metadata.  
It's not a form that persists into the macroexpansion, so it doesn't  
take effect in your generated defn-.

(There are good reasons for this, not just "that's the way it is": a  
macro is just like any other function, and you might want to add  
metadata such as type annotations just as you would in normal  
functions.)

Using with-meta *does* pass through into the macroexpansion, which is  
what you want.

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



Functions and vars and meta-data

2009-11-07 Thread Stefan Arentz

Another one related to my previous question about meta-data.

user> (defn #^{ :xxx 1} foo [] "foo")
#'user/foo
user> (defn #^{ :xxx 2} bar [] "bar")
#'user/bar

I need to do something similar to this:

user> (map #(:xxx (meta %)) [foo bar])
(nil nil)

Basically accessing the meta data of a function of which I only know  
the 'name'. (Because that is what my macro takes as one of its  
parameters)

I know it works when I use the #' reader macro.

user> (map #(:xxx (meta %)) [#'foo #'bar])
(1 2)

But I'm using this in a bigger macro that takes a bunch of functions  
as a parameter. Is there a way to make this work or should I  
'translate' the functions that I take by name with (var foo)?

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 :-)

  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: Functions and vars and meta-data

2009-11-07 Thread John Harrop
On Sat, Nov 7, 2009 at 8:04 PM, Stefan Arentz  wrote:

> But I'm using this in a bigger macro that takes a bunch of functions
> as a parameter. Is there a way to make this work or should I
> 'translate' the functions that I take by name with (var foo)?


You'll need to translate the symbols into vars using resolve, I think.

--~--~-~--~~~---~--~~
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-07 Thread Stefan Arentz


On 2009-11-07, at 8:28 PM, John Harrop wrote:

> On Sat, Nov 7, 2009 at 8:04 PM, Stefan Arentz   
> wrote:
> But I'm using this in a bigger macro that takes a bunch of functions
> as a parameter. Is there a way to make this work or should I
> 'translate' the functions that I take by name with (var foo)?
>
> You'll need to translate the symbols into vars using resolve, I think.

Hmmm

user=> (var foo)
#'user/foo

user=> (meta (var foo))
{:ns #, :name foo, :file "NO_SOURCE_FILE", :line  
1, :arglists ([]), :xxx 1}

user=> ((var foo))
"foo"

I'll give this a try in my macro later today :-)

  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: Functions and vars and meta-data

2009-11-07 Thread John Harrop
On Sat, Nov 7, 2009 at 8:34 PM, Stefan Arentz  wrote:

> On 2009-11-07, at 8:28 PM, John Harrop wrote:
>
> > On Sat, Nov 7, 2009 at 8:04 PM, Stefan Arentz 
> > wrote:
> > But I'm using this in a bigger macro that takes a bunch of functions
> > as a parameter. Is there a way to make this work or should I
> > 'translate' the functions that I take by name with (var foo)?
> >
> > You'll need to translate the symbols into vars using resolve, I think.
>
> Hmmm
>
> user=> (var foo)
> #'user/foo
>
> user=> (meta (var foo))
> {:ns #, :name foo, :file "NO_SOURCE_FILE", :line
> 1, :arglists ([]), :xxx 1}
>
> user=> ((var foo))
> "foo"
>
> I'll give this a try in my macro later today :-)


Eh. `(var ~argument) should work. You'll need resolve if you ever want to do
this in a function though, or use the var object in the macro body itself
(as opposed to only using the var object in the code that results from the
macro's expansion).

--~--~-~--~~~---~--~~
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-07 Thread Alex Osborne

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


There's three types of objects in play here: symbols, vars and functions:

(defn foo [])

(type foo)
=> user$foo_4703 (a class implementing IFn)

(type 'foo)
=> clojure.lang.Symbol

(type #'foo)
=> clojure.lang.Var

A symbol is just a name.  A Var is an object that is  named by a symbol 
and "bound" to a value.  Normally Clojure will "evaluate" symbols, for 
example when you type this in the REPL:

foo
=> #

The way it does this is by first "resolving" the symbol foo in the 
current namespace.  A namespace is essentialy just a map from symbols to 
vars.  So after resolving, it then has a Var object.  A Var, is as it's 
name suggests, a variable.  It consist of a name (symbol + namespace), 
metadata map and a value (called the binding).  There can actually be 
multiple bindings (for thread-local variables and such) but normally 
there is only one, the "root binding".  So Clojure evaluates the var by 
getting the value bound to it.

Now what if you ask Clojure to evaluate a vector of symbols?  It 
evaluates each symbol (first "resolving" to get a var and then taking 
the binding) and gives you back a vector of function objects:

(def some-number 4)

[foo inc some-number]
=> [#
 #
 4]

Now macros.  When Clojure sees something like this:

   (bar foo inc some-number)

It will first resolve the symbol bar in the current namespace (in this 
case the namespace is "user").  Remember resolving gives you a Var, so 
in this case the Var #'user/foo.  Clojure then looks at the metadata of 
the Var to determine whether it is bound to a macro or a function. 
Normally Clojure evaluates the arguments [foo inc some-number] producing 
[# # 4] and then calls the binding value 
(the actual function object) with them.

Alternatively if the var's metadata says it is bound to a macro, Clojure 
doesn't evaluate the arguments.  It just calls the binding with the 
symbols 'foo 'inc and 'some-number.  Clojure will then evaluate the 
return value of the macro (usually another bunch of symbols and literals).

So when I write this:

(defmacro mymac [sym]
   (println "symbol is:" sym)
   sym)

(mymac foo)
=> symbol is: foo
#

Clojure passes mymac a symbol object.  We print out the symbol "foo" and 
then return it.  Clojure then evaluates the return value (the symbol) 
producing the actual function object that foo is bound to.

Now for metadata "on" functoins.  When you write this:

(defn #^{:xxx 1} greet [] "hello")

The #^{...} syntax means that Clojure creates a list of two symbols 
(defn and greet), and empty vector and a string "hello".  The second 
symbol greet has the metadata {:xxx 1} associated with it.  This will be 
macro-expanded into this:

(def #^{:xxx 1} greet (fn ([] "hello")))

The greet symbol still keeps it's metadata.  Now the def special form:

1. Creates a var.
2. Copies the metadata {:xxx 1} from the symbol greet to the var.
3. Binds the var to the function (fn ([] "hello")).
4. Creates a mapping in the current namespace ("user") from the symbol 
greet to the var.

Now notice the function object itself never has any metadata associated 
with it?  In fact normal Clojure function objects cannot have any metadata:

(with-meta (fn []) {:xxx 1})
=> [Thrown class java.lang.UnsupportedOperationException]

So now suppose we want something that achieves this:

(def #^{:xxx 2} groan (fn ([] "arrrgghhh")))

(get-xxx greet groan)
=> [1 2]

So we need to get at the vars for greet and groan.  First thing to note 
is that get-xxx has to be a macro, if it were a function greet and groan 
would be evaluated to function objects, which don't have metadata.  So 
what we need is a macro that will take the greet and groan symbols, 
resolve them to get vars and then lookup :xxx in the metadata of the 
vars.  So something like:

(defmacro get-xxx [& syms]
(vec (map #(get (meta (resolve %)) :xxx) syms)))

Now what if we want get-xxx to take a vector?  Well no worries we just 
change the signature:

(defmacro get-xxx [syms]
(vec (map #(get (meta (resolve %)) :xxx) syms)))

(get-xxx [greet groan])
=> [1 2]

But hang on, what's going on with this?

(let [fns [greet groan]]
   (get-xxx fns))
=> java.lang.IllegalArgumentException: Don't know how to create ISeq 
from: clojure.lang.Symbol

Remember that the arguments to macros aren't evaluated, so get-xxx is 
being passed the symbol "fns" not a vector!  Well what if use 
macroexpand to explicitly pass it the vector?

(let [fns [greet groan]]
   (macroexpand (list 'get-xxx fns)))
=> java.lang.ClassCastException: user$greet__5100 cannot be cast to 
clojure.lang.Symbol

Another problem.  The let creates a vector function objects not of 
symbols.  So to

Re: newbie question

2009-11-07 Thread Warren Wood



On Nov 6, 12:10 pm, John Harrop  wrote:
> On Fri, Nov 6, 2009 at 1:07 PM, John Harrop  wrote:
> > On Fri, Nov 6, 2009 at 1:01 PM, Warren Wood 
> > wrote:
>
> >> In the meantime, I came up with the following, which seems to work.
> >> I'm sure it can be improved.
>
> >> (defn NOT [pred] (fn [x] (not (pred x
>
> >> ...
>
> > Which leads me to another question, are there standard functions
> >> sitting around somewhere already to do boolean combinations of
> >> predicates (conjoin, disjoin, negate perhaps?)?  Like my NOT above.
>
> > How about complement?
>
> > user=> (def x (complement even?))
> > #'user/x
> > user=> (x 4)
> > false
> > user=> (x 3)
> > true
>
> And WHAT the devil is with complement's messy implementation? (defn
> complement [f] (comp not f)) seems much cleaner. :)

Ok, I'm embarrassed that I didn't find complement.  I know I had known
about it at one time. I think I had been wondering about versions of
union and intersection that would apply to predicates as well as sets,
since mathematically a predicate can be deemed as defining the set of
all things for which it is true.  I was thinking of a procedure like
AND (again probably not a great name... maybe conjunction would be
better).  I don't think anything like comp can be used in this case
since and is a macro.

(defn AND [f g] (fn [x] (and (f x) (g x

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



Re: newbie question

2009-11-07 Thread Warren Wood

Thanks, that was indeed helpful!

On Nov 6, 6:47 pm, Alex Osborne  wrote:
> Alex Osborne wrote:
> > Like Mark's but using split-with instead of split-at:
>
> > (defn partition-when [pred coll]
> >    (lazy-seq
> >     (when-let [[x & xs] (seq coll)]
> >       (let [[xs ys] (split-with (complement pred) xs)]
> >         (cons (cons x xs) (partition-when pred ys))
>
> Just realised this is almost the same as Warren's -- I had missed
> reading Warren's before posting.  Thought it might be helpful if I
> explain the differences:
>
> * lazy-seq on the outside of the conditional.  This means the seq is
> fully lazy, so if you never call first/next on it, nothing is ever run.
>
> * As suggested by others complement instead of NOT.
>
> * (when (seq coll) ...) instead of (if (empty? coll) () ...).  We can
> simplify things like this as (lazy-seq nil) => () and (seq ()) => nil.
>
> * Using destructuring instead of (first coll) (next coll).  Makes it a
> bit shorter and is quite useful if you're going to use the result of
> (first coll) or (next coll) multiple times, but in this case it doesn't
> really matter.
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Gensym collisions can be engineered.

2009-11-07 Thread John Harrop
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: newbie question

2009-11-07 Thread Warren Wood

Thought of this, which I like better.  Again, I'm surprised if
conjunction is not already a standard function, but I can't find it.
I'm still a bit tempted to call it AND for readabilty of code.  (I
spent some time studying combinatory logic back in the day.  (I even
had a "Curry Fellowship" at Penn State where Haskell Curry used to
work.)  Can't remember what combinator letter my "dual" function is.)

(defn dual [x] (fn [f] (f x)))

(defn conjunction [& preds]
 (fn [x] (every? (dual x) preds)))

(filter
  (conjunction even? (partial >= 16) (partial <= 9))
  (range 1 20))

evaluates to

(10 12 14 16)


On Nov 7, 9:39 pm, Warren Wood  wrote:
> On Nov 6, 12:10 pm, John Harrop  wrote:
>
>
>
>
>
> > On Fri, Nov 6, 2009 at 1:07 PM, John Harrop  wrote:
> > > On Fri, Nov 6, 2009 at 1:01 PM, Warren Wood 
> > > wrote:
>
> > >> In the meantime, I came up with the following, which seems to work.
> > >> I'm sure it can be improved.
>
> > >> (defn NOT [pred] (fn [x] (not (pred x
>
> > >> ...
>
> > > Which leads me to another question, are there standard functions
> > >> sitting around somewhere already to do boolean combinations of
> > >> predicates (conjoin, disjoin, negate perhaps?)?  Like my NOT above.
>
> > > How about complement?
>
> > > user=> (def x (complement even?))
> > > #'user/x
> > > user=> (x 4)
> > > false
> > > user=> (x 3)
> > > true
>
> > And WHAT the devil is with complement's messy implementation? (defn
> > complement [f] (comp not f)) seems much cleaner. :)
>
> Ok, I'm embarrassed that I didn't find complement.  I know I had known
> about it at one time. I think I had been wondering about versions of
> union and intersection that would apply to predicates as well as sets,
> since mathematically a predicate can be deemed as defining the set of
> all things for which it is true.  I was thinking of a procedure like
> AND (again probably not a great name... maybe conjunction would be
> better).  I don't think anything like comp can be used in this case
> since and is a macro.
>
> (defn AND [f g] (fn [x] (and (f x) (g x
>
> Is there any standard function like THAT?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Another "closure" available

2009-11-07 Thread Adrian Cuthbertson

Hmm, someone else has made another "closure" available :).

http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html

-Adrian.

--~--~-~--~~~---~--~~
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: Another "closure" available

2009-11-07 Thread pmf

On Nov 8, 6:08 am, Adrian Cuthbertson 
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.

[1] http://www.clozure.com/clozurecl.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
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
-~--~~~~--~~--~--~---