Re: Deep deref

2009-11-15 Thread Danny Woods
> Danny, could you maybe hack up a possible very simple example of what
> you mean?



> I can not simply store a copy of the Karl person in Tinas :friends
> slot,
> because when Karl gets one year older, then I don‘t want to go through
> all persons, looking for Karls, and have their age updated.

Hi André,

Your shared instance constraint does make things a little more
interesting than in my application, but I think John's suggestion
about not storing friend instances directly is a good thing.  If you
were to instead assign an id to each created person, and have each
friend list be a list of ids, the entity referred to by the id can
still be immutable for a given dereference.  Not sure how much sense
that makes, so here's something crude that I've hacked up:

(def *everyone* (ref {}))
(def *global-id* (ref 0))

(defn next-id [] (dosync (commute *global-id* inc)))

(defstruct person :name :friend-ids :id)

(defn make-person [name] (struct person name [] (next-id)))

(defn make-and-add-person [name]
  (let [person (make-person name)]
(dosync (alter *everyone* assoc (:id person) person

(defn befriend [person friend]
  (let [new-friend-list (conj (:friend-ids person) (:id friend))
new-person (assoc person :friend-ids new-friend-list)]
(dosync
 (alter *everyone* assoc (:id person) new-person

The 'down side' here is simply that you refer to people by ids, rather
than directly, but the up side is that a given deref of *everyone* is
immutable and consistent.

Cheers,
Danny.

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread ajuc


On 15 Lis, 00:21, John Harrop  wrote:
> On Sat, Nov 14, 2009 at 3:03 PM, ajuc  wrote:
> > I have to install java one more time, when I try to start java -
> > server, I get:
> > Error: no `server' JVM at `F:\Program Files\Java\jre6\bin\server
> > \jvm.dll
>
> You need to use the one in F:\Program Files\Java\jdk6 instead.
>
> I'm surprised your IDE didn't select that one automatically. Mine
> (Enclojure) did.

My IDE is waterfront, and it just starts java, and in my path the
first java was jre, I've changed that, problem solved, thanks.

What's intresting, when I run the code in java -server, the difference
between using global, and using literal map expression in let got
bigger.

Now its:
"Elapsed time: 555.810305 msecs" - with global
vs
"Elapsed time: 1091.399046 msecs" - with literal in let

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread John Harrop
On Sun, Nov 15, 2009 at 4:49 AM, ajuc  wrote:

> On 15 Lis, 00:21, John Harrop  wrote:
> > On Sat, Nov 14, 2009 at 3:03 PM, ajuc  wrote:
> > > I have to install java one more time, when I try to start java -
> > > server, I get:
> > > Error: no `server' JVM at `F:\Program Files\Java\jre6\bin\server
> > > \jvm.dll
> >
> > You need to use the one in F:\Program Files\Java\jdk6 instead.
> >
> > I'm surprised your IDE didn't select that one automatically. Mine
> > (Enclojure) did.
>
> My IDE is waterfront, and it just starts java, and in my path the
> first java was jre, I've changed that, problem solved, thanks.
>
> What's intresting, when I run the code in java -server, the difference
> between using global, and using literal map expression in let got
> bigger.
>

That's very odd.

Rich needs to take a look at this. Letting a constant shouldn't have a
performance hit, IMO.

Could you test whether it's faster to use your complex data structure
directly in the function, anonymously at the point of use, or to yank it
from a global var?

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread ajuc

> That's very odd.
>
> Rich needs to take a look at this. Letting a constant shouldn't have a
> performance hit, IMO.
>
> Could you test whether it's faster to use your complex data structure
> directly in the function, anonymously at the point of use, or to yank it
> from a global var?

Code (can you run it on your computer to verify?):
http://clojure.pastebin.com/f508ad31b

My results (I've increased N to 10 and cached random coordinates
in vector, to supply the same points to each version of function):

"Elapsed time: 2990.418336 msecs"
"point-to-hilbert-directly-from-global " nilnil

"Elapsed time: 2488.745357 msecs"
"point-to-hilbert-let-from-global " nilnil

"Elapsed time: 3669.685672 msecs"
"point-to-hilbert-literal-in-let " nilnil

"Elapsed time: 13039.499434 msecs"
"point-to-hilbert-literal-in-place " nilnil

With literal in place it is 10 seconds slower.

-- 
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: swap two elements in an arbitrary collection

2009-11-15 Thread Meikel Brandmeyer

Hi,

Am 13.11.2009 um 17:29 schrieb Lauri Pesonen:


I hope this helps. I don't think I did a particularly good job in
explaining how the macro works...


And there is always macroexpand(-1)...

user=> (macroexpand-1 '(-> foo (bar baz)))
(bar foo baz)

Sincerely
Meikel





smime.p7s
Description: S/MIME cryptographic signature


Re: Map a list of agents to a list of their values

2009-11-15 Thread Meikel Brandmeyer

Hi,

Am 14.11.2009 um 20:31 schrieb John Harrop:

For situations like this, I find it handy to discover what reader- 
macros are expanding to. This works well:


user=>(defmacro expand [arg] (println arg))
#'user/expand
user=>(expand #(@%))
(fn* [p1__6536] ((clojure.core/deref p1__6536)))


user=> (macroexpand-1 '#(@%))
(fn* [p1__13] ((clojure.core/deref p1__13)))

;)

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Datatypes and Protocols - early experience program

2009-11-15 Thread Michael Wood
2009/11/14 John Harrop :
> On Sat, Nov 14, 2009 at 1:42 PM, Richard Newman  wrote:
>>
>> I like CL's package support for this kind of situation, where
>> unexported symbols can still be reached via foo::bar, at the cost of
>> an obvious "code smell".
>
> This suggests an alternate fix for the private functions in macros problem:
> 1. Keep the throw when dereferencing another ns's private vars.
> 2. Add a way to override that throw when dereferencing -- a
>    "deref-private" that always works.
> 3. Add a reader macro, say #!, with the property that #!foo expands
>    to (deref-private #'foo).

Except you'll have to find another reader macro.  #! is already taken.
 It's a comment-to-end-of-line reader macro to support Unix scripts.

A quick search of clojure.org didn't find it, but it's mentioned in
the Clojure Programming wikibook:

http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Shebang_Scripting_in_Clojure

-- 
Michael Wood 

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


Some questions about core.clj implementation

2009-11-15 Thread Angel Java Lopez
Hi people!

I'm working on reimplement core.clj using my own C# interpreter for a
clojure-like language. Browsing in the 1.0.0 source code of core.clj, I have
some questions:

1: this is defn definition:

(def

 #^{:doc "Same as (def name (fn [params* ] exprs*)) or (def
name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
to the var metadata"
:arglists '([name doc-string? attr-map? [params*] body]
[name doc-string? attr-map? ([params*] body)+ attr-map?])}
 defn (fn defn [name & fdecl]
(let [m (if (string? (first fdecl))
  {:doc (first fdecl)}
  {})
  fdecl (if (string? (first fdecl))
  (next fdecl)
  fdecl)
  m (if (map? (first fdecl))
  (conj m (first fdecl))
  m)
  fdecl (if (map? (first fdecl))
  (next fdecl)
  fdecl)
  fdecl (if (vector? (first fdecl))
  (list fdecl)
  fdecl)
  m (if (map? (last fdecl))
  (conj m (last fdecl))
  m)
  fdecl (if (map? (last fdecl))
  (butlast fdecl)
  fdecl)
  m (conj {:arglists (list 'quote (sigs fdecl))} m)]
  (list 'def (with-meta name (conj (if (meta name) (meta name) {})
m))
(cons `fn fdecl)

(. (var defn) (setMacro))

Why the "posponed" setMacro? Why not add the :macro true to inital metadata,
directly?

2) The cond macro is defined:

(defmacro cond
  "Takes a set of test/expr pairs. It evaluates each test one at a
  time.  If a test returns logical true, cond evaluates and returns
  the value of the corresponding expr and doesn't evaluate any of the
  other tests or exprs. (cond) returns nil."
  [& clauses]
(when clauses
  (list 'if (first clauses)
(if (next clauses)
(second clauses)
(throw (IllegalArgumentException.
 "cond requires an even number of forms")))
(cons 'clojure.core/cond (next (next clauses))

Why the need of add the full namespace name in the last cons?

Ok, but the first use of it is in:

(defn spread
  {:private true}
  [arglist]
  (cond
   (nil? arglist) nil
   (nil? (next arglist)) (seq (first arglist))
   :else (cons (first arglist) (spread (next arglist)

Where is defined :else keyword behaviour? I can't find how :else is defined
to be managed in cond/if code

TIA

Angel "Java" Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

-- 
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 Web Libraries

2009-11-15 Thread Stefan Tilkov
On Nov 15, 2009, at 4:58 AM, ngocdaothanh wrote:

> Hi Stuart,
> 
> Can you elaborate on Restlet? After some short investigation I think
> it uses annotation but Clojure does not support it, so Clojure is not
> "Restlet-ready".
> 

Only the JSR-311 (JAX-RS) API uses annotations. Restlet has a lower-level API 
that just uses plain classes.

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

> Thanks
> 
> 
> On Jan 23, 1:44 am, Stuart Sierra  wrote:
>> Hi Frank,
>> I'd also recommend looking atRestlet and
>> the Java Servlets API.
>> -Stuart Sierra
>> 
>> On Jan 21, 4:39 pm, Frank  wrote:
>> 
>>> Hi,
>> 
>>> I am interested in trying to use Clojure to develop web-based
>>> applications.  Can someone point me to any Clojure libraries that have
>>> been written that I can use.  Thanks.
>> 
>>> Frank
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


Re: Some questions about core.clj implementation

2009-11-15 Thread Michael Wood
2009/11/15 Angel Java Lopez :
[...]
> (defn spread
>   {:private true}
>   [arglist]
>   (cond
>    (nil? arglist) nil
>    (nil? (next arglist)) (seq (first arglist))
>    :else (cons (first arglist) (spread (next arglist)
>
> Where is defined :else keyword behaviour? I can't find how :else is defined
> to be managed in cond/if code

I don't know about your other questions, but I believe :else could be
replace by anything that is logically true.  It's just a convention to
use ":else".

user=> (cond (zero? 42) "42 is zero"
:else "42 is not zero")
"42 is not zero"
user=> (cond (zero? 42) "42 is zero"
true "42 is not zero")
"42 is not zero"
user=> (cond (zero? 42) "42 is zero"
:something-that-is-logically-true "42 is not zero")
"42 is not zero"
user=> (cond (zero? 42) "42 is zero"
"otherwise, if the above is not true, then" "42 is not zero")
"42 is not zero"

-- 
Michael Wood 

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


SLIME REPL broken

2009-11-15 Thread Stefan Kamphausen
Hi,

a short discussion on the SLIME mailinglist lead to the result that
the arglist of a backend function in swank did change.

Current checkouts of SLIME do not work with Clojure, at least if you
use autodoc.

http://common-lisp.net/pipermail/slime-devel/2009-November/016919.html

I took a quick look at the relevant function (src/main/clojure/swank/
commands/contrib/swank_arglists.clj) in swank-clojure but it would
need some diving into the code for me to help with this.  Maybe
someone more experienced than me can step in?

Kind regards,
Stefan Kamphausen

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread Michael Wood
2009/11/15 ajuc :
>
>> That's very odd.
>>
>> Rich needs to take a look at this. Letting a constant shouldn't have a
>> performance hit, IMO.
>>
>> Could you test whether it's faster to use your complex data structure
>> directly in the function, anonymously at the point of use, or to yank it
>> from a global var?
>
> Code (can you run it on your computer to verify?):
> http://clojure.pastebin.com/f508ad31b

Here are my results on Linux with the server VM, after fixing the typo
(glocal -> global) and changing pr to println:

http://clojure.pastebin.com/f49f16d71

"Elapsed time: 2110.721659 msecs"
point-to-hilbert-directly-from-global  nil

"Elapsed time: 1197.547328 msecs"
point-to-hilbert-let-from-global  nil

"Elapsed time: 1884.66 msecs"
point-to-hilbert-literal-in-let  nil

"Elapsed time: 4847.630084 msecs"
point-to-hilbert-literal-in-place  nil

$ java -version
java version "1.6.0_0"
OpenJDK Runtime Environment (IcedTea6 1.4.1) (6b14-1.4.1-0ubuntu12)
OpenJDK Client VM (build 14.0-b08, mixed mode, sharing)

Although, running it again now, I get:

"Elapsed time: 3278.709938 msecs"
point-to-hilbert-directly-from-global  nil

"Elapsed time: 1234.739782 msecs"
point-to-hilbert-let-from-global  nil

"Elapsed time: 1945.980422 msecs"
point-to-hilbert-literal-in-let  nil

"Elapsed time: 5737.756701 msecs"
point-to-hilbert-literal-in-place  nil

And after rearranging them, I get:

"Elapsed time: 2506.30872 msecs"
point-to-hilbert-let-from-global  nil

"Elapsed time: 2091.866122 msecs"
point-to-hilbert-literal-in-let  nil

"Elapsed time: 1309.805767 msecs"
point-to-hilbert-directly-from-global  nil

"Elapsed time: 5228.071194 msecs"
point-to-hilbert-literal-in-place  nil

So it seems you need to allow Hotspot to optimise it:

"Elapsed time: 3084.796868 msecs"
point-to-hilbert-literal-in-let  nil

"Elapsed time: 1354.13218 msecs"
point-to-hilbert-literal-in-let  nil

"Elapsed time: 1340.907318 msecs"
point-to-hilbert-literal-in-let  nil

"Elapsed time: 1338.655641 msecs"
point-to-hilbert-literal-in-let  nil

and:

"Elapsed time: 2393.682633 msecs"
point-to-hilbert-let-from-global  nil

"Elapsed time: 990.713252 msecs"
point-to-hilbert-let-from-global  nil

"Elapsed time: 1008.451391 msecs"
point-to-hilbert-let-from-global  nil

"Elapsed time: 985.379787 msecs"
point-to-hilbert-let-from-global  nil

-- 
Michael Wood 

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


Re: SLIME REPL broken

2009-11-15 Thread Cyrus Harmon
Heh: ";; Yeah, I'm lazy -- I'll flesh this out later"

Not sure if that's related to the problem, but it's amusing at least.

Cyrus

On Nov 15, 2009, at 6:21 AM, Stefan Kamphausen wrote:

> Hi,
> 
> a short discussion on the SLIME mailinglist lead to the result that
> the arglist of a backend function in swank did change.
> 
> Current checkouts of SLIME do not work with Clojure, at least if you
> use autodoc.
> 
> http://common-lisp.net/pipermail/slime-devel/2009-November/016919.html
> 
> I took a quick look at the relevant function (src/main/clojure/swank/
> commands/contrib/swank_arglists.clj) in swank-clojure but it would
> need some diving into the code for me to help with this.  Maybe
> someone more experienced than me can step in?
> 
> Kind regards,
> Stefan Kamphausen
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


Re: Some questions about core.clj implementation

2009-11-15 Thread Meikel Brandmeyer

Hi,

Am 15.11.2009 um 14:51 schrieb Angel Java Lopez:


2) The cond macro is defined:

(defmacro cond
  "Takes a set of test/expr pairs. It evaluates each test one at a
  time.  If a test returns logical true, cond evaluates and returns
  the value of the corresponding expr and doesn't evaluate any of the
  other tests or exprs. (cond) returns nil."
  [& clauses]
(when clauses
  (list 'if (first clauses)
(if (next clauses)
(second clauses)
(throw (IllegalArgumentException.
 "cond requires an even number of forms")))
(cons 'clojure.core/cond (next (next clauses))

Why the need of add the full namespace name in the last cons?


If you don't qualify the recursive call, you'll get in trouble if a  
user namespace defines its own cond. clojure.core/cond will then call  
the original cond, but the expansion would call the user defined one.  
And suddenly you are name capture hell. Fully qualifying the recursive  
call is avoiding this issue.


Note, the syntax-quote is not yet available at that point of core.clj!

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Mocking (with EasyMock?) java calls

2009-11-15 Thread ronen
Id recommend using mockito instead:

http://mockito.org/

On Nov 12, 1:55 am, Howard Lewis Ship  wrote:
> Try looking at this:
>
> http://github.com/hlship/cascade/blob/master/src/main/clojure/cascade...
>
>
>
> On Thu, Nov 5, 2009 at 5:00 AM, vanallan  wrote:
>
> > Hi
> > Im trying to convert a couple of Java methods in a Java project to
> > Clojure. The Java methods have test methods that mocks other part of
> > the whole system with EasyMock. Is it possible to something similar in
> > Clojure? I want to call a Java function and get a predetermined value
> > from that function in return to test with. This is because the java
> > method is using a database that I don't reach, and I want to use the
> > correct method call right from the start. Any one got any experience
> > in this?
>
> > :)
> > --~--~-~--~~~---~--~~
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that posts from new members are moderated - please be patient with 
> > your first post.
> > To unsubscribe from this group, send email to
> > clojure+unsubscr...@googlegroups.com
> > For more options, visit this group at
> >http://groups.google.com/group/clojure?hl=en
> > -~--~~~~--~~--~--~---
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210http://howardlewisship.com

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


Re: clojure event handling

2009-11-15 Thread nchubrich
Thanks for posting these examples; I'd never thought of using
multimethods that way.  And thanks for the Swing example.
I'm really interested in functional-reactive programming; hope we
see lots of that stuff in Clojure.  Anyone ever used FrTime in PLT?
Here's the Swing events without the Swing.  Didn't know you could
override deref and invoke like that

  (import
'(java.util.concurrent LinkedBlockingQueue)
'(clojure.lang IDeref IFn))


(defn hydra
  "returns a BlockingQueue, will return a new infinite lazy-seq
wrapped in a delay
  evertime it is deref'ed. all items put in the LinkedBlockingQueue
will be added to
  all the lazy-seqs producded by deref'ing"
  []
  (let [consumers (atom nil)
producer (proxy [LinkedBlockingQueue IDeref IFn] []
   (invoke [& x]
   (doseq [y x] (.put this y)))
   (deref []
  (let [x (LinkedBlockingQueue.)]
(swap! consumers conj x)
(delay (repeatedly #(.take x))]
(future
  (while true
(let [x (.take producer)]
  (doseq [y @consumers]
(.put y x)
producer))

(def queue (hydra))

;see it working
(def results (atom nil))

(def show (fn [] (.start (Thread. (fn [] (doseq [i (force
@queue)] ;derefing the lbq from hydra returns a delay wrapped lazy-seq
  (swap! results conj i)))

-- 
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: idomatic sudoku?

2009-11-15 Thread B Smith-Mannschott
On Sun, Oct 11, 2009 at 22:12, Matt Wilson  wrote:
>
> My approach (which I might upload once I've tidied it up a bit) was to
> use a hash-map of [x y] cell coordinates to a set of all remaining
> numbers. So, something like:
>
> {[0 0] #{1 2 3 4} [0 1] #{5 6 7 8} …}
>
> Then I just made some functions that mapped an [x y] pair to all it's
> peers -- e.g. unit, row, col (which were generated by another
> function.) I memoized those functions.
>
> The only hassle with a map is that iterating over it (in my case, with
> a `for`) turns it into a list of [key value], which makes it a pain to
> turn back into a map once you're done. The magical incantation for
> round-tripping turns out to be:
>
> (apply hash-map (apply concat seq-of-pairs))

I've recently hacked up my own sudoku solver. This is essentially the
representation I've chosen, except that I use integers 0 through 80 to
identify positions on the game board. This allows my to use vectors
where you'd have used a map.

So, I've got a vector which we'll call freedoms, indexed from 0 to 80,
which contains sets of symbols from the solution alphabet, specifying
which symbols are possible at that position.

Additionally, for each position p, I keep a sorted map (could have
used a vector here too, I guess) from (count (freedoms p)) to a set of
all p with that (count (freedoms p)). We'll call it freeranks. This
has two advantages:

1. it's wasy to see when I'm done (= 81 (count (freeranks 1))
2. It's easy to find the position for the next move:
(first
 (apply
  concat
  (for [[nfree positions] freeranks :when (> nfree 1)]
positions)))

It turns out to be *very* beneficial to always choose the move with
the fewest freedoms as the next move.

-- 
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: Datatypes and Protocols - early experience program

2009-11-15 Thread John Harrop
On Sun, Nov 15, 2009 at 8:45 AM, Michael Wood  wrote:

> 2009/11/14 John Harrop :
> > On Sat, Nov 14, 2009 at 1:42 PM, Richard Newman 
> wrote:
> >>
> >> I like CL's package support for this kind of situation, where
> >> unexported symbols can still be reached via foo::bar, at the cost of
> >> an obvious "code smell".
> >
> > This suggests an alternate fix for the private functions in macros
> problem:
> > 1. Keep the throw when dereferencing another ns's private vars.
> > 2. Add a way to override that throw when dereferencing -- a
> >"deref-private" that always works.
> > 3. Add a reader macro, say #!, with the property that #!foo expands
> >to (deref-private #'foo).
>
> Except you'll have to find another reader macro.  #! is already taken.
>  It's a comment-to-end-of-line reader macro to support Unix scripts.


That's weird. It's not documented anywhere on the site. And it seems to hang
the REPL:

user=> nil #!foo

and nothing. Enter doesn't print "nil" and a fresh user=> prompt as it
should and nothing else apparently works either. The REPL is either wedged
or interpreting everything as comment from then on.

Weirdly enough, ; hangs the REPL likewise.

Maybe use @!? That's closer to @ and the ! is still there to suggest
something perilous, as it does with the mutable-state fns.

It would prevent using normal deref-@ with symbols that start with !, but
does anyone actually use symbols that start with ! at this time? Even not=
is not= instead of !=.

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread John Harrop
Interesting. It looks like Clojure's missing a few obvious optimizations,
and is reconstructing the literal structure each time the function is
called, or each time the value is used if the literal is directly at point
of use.

On the other hand, deref of a global is not exactly blindingly fast either,
since it uses Java ThreadLocals under the hood (or equivalent mechanism).

Somewhat surprising performance problems when you consider that a literal
data structure should actually be right there in the code, constructed
already by the Clojure reader at read-time. I guess when class bytecodes are
generated it turns into a set of function calls to vec, list, hash-map &c.

I suggest at least one of these two alternatives be done:

1. Alter the bytecode generator to turn such literals into a static final
field whose initializer generates the structure, plus a reference to that
field; if identical literal structures recur the same static final field can
be referenced for each copy.

2. Add a defconstant* special form: can be redef'd but is otherwise strictly
constant; (binding ...) will not work on it, nor set!. This can therefore be
stored and accessed more efficiently, without going through ThreadLocal or
anything similar and thread-dependent, for higher speed access and greater
JIT potential. Add appropriate defconstant and defconstant- macros to core
that wrap the special form and add docstring and metadata support.

-- 
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: Map a list of agents to a list of their values

2009-11-15 Thread John Harrop
On Sat, Nov 14, 2009 at 6:03 PM, Meikel Brandmeyer  wrote:

> Hi,
>
> Am 14.11.2009 um 20:31 schrieb John Harrop:
>
>
>  For situations like this, I find it handy to discover what reader-macros
>> are expanding to. This works well:
>>
>> user=>(defmacro expand [arg] (println arg))
>> #'user/expand
>> user=>(expand #(@%))
>> (fn* [p1__6536] ((clojure.core/deref p1__6536)))
>>
>
> user=> (macroexpand-1 '#(@%))
> (fn* [p1__13] ((clojure.core/deref p1__13)))


Funny, I get
user=> (macroexpand-1 '#(@%))
(fn* [p1__6540] (@p1__6540))

as apparently the Enclojure REPL turns "(deref foo)" back into "@foo" when
printing it. In fact I fiddled with the macro just because '#(@%) by itself
at my REPL just echoed itself. But this does work:

user=> (prn '#(@%))
(fn* [p1__6544] ((clojure.core/deref p1__6544)))

So does temporarily clicking off pretty-printing at the REPL and just
evaluating '#(@%).

On the other hand, the macro's argument doesn't need to be quoted, so
there's one less awkward-to-type punctuation character. :)

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

Clojure & Terracotta - TIM

2009-11-15 Thread Sergey Didenko
Hi from a Clojure newbie!

I have read the april thread "Clojure + Terracotta Update" and it
looks pretty positive.

A few question for TIM users:

Is there newer version than
http://github.com/pjstadig/tim-clojure-1.0-snapshot ?

Are there still bugs?

Can it be called production ready?

Regards, Sergey.

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread Alex Osborne
ajuc wrote:
> I would like to somehow hide the global hilbert-map into my function,
> but I can't see how to do that.
> 
> Is this possible? I know that I can just inert literal into my let,
> but that degrades performance, when function is called many times.
> 
> I would like to have something like static local variable in C++, or
> just regular constant local variable in my function.

Clojure's name gives a hint as to how do this: use a closure. :-)  Just 
pull the let outside the defn:

(let [hilbert-map {...}]
   (defn point-to-hilbert [...]
 ...))

-- 
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: idomatic sudoku?

2009-11-15 Thread David Brown
On Sun, Nov 15, 2009 at 09:43:38PM +0100, B Smith-Mannschott wrote:
>On Sun, Oct 11, 2009 at 22:12, Matt Wilson  wrote:

>> The only hassle with a map is that iterating over it (in my case, with
>> a `for`) turns it into a list of [key value], which makes it a pain to
>> turn back into a map once you're done. The magical incantation for
>> round-tripping turns out to be:
>>
>> (apply hash-map (apply concat seq-of-pairs))

Why not just

   (into {} seq-of-pairs)

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: Datatypes and Protocols - early experience program

2009-11-15 Thread David Brown
On Sun, Nov 15, 2009 at 04:20:19PM -0500, John Harrop wrote:

>That's weird. It's not documented anywhere on the site. And it seems to hang
>the REPL:
>
>user=> nil #!foo
>
>and nothing. Enter doesn't print "nil" and a fresh user=> prompt as it
>should and nothing else apparently works either. The REPL is either wedged
>or interpreting everything as comment from then on.
>
>Weirdly enough, ; hangs the REPL likewise.

How's the data getting to the REPL?  jline, or ide?  I'm using rlwrap
at the console, and netierh seems to cause problems.  However, #! eats
everything, and doesn't prompt again, but does after the next line.
The ; prints a new prompt, so they are definitely treated differently.

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


A macro for flexible keyword argument handling

2009-11-15 Thread Constantine Vetoshev
A couple of days ago, I finally had enough of manually extracting
function keyword arguments. defnk is cool and all, but it does nothing
for fn, letfn, defmethod, or any other form with a parameter list. Map
destructuring is also cool, but providing defaults requires writing
each symbol twice, once in :keys and once in :or.

The macro I ended up with, fn-keywords, owes much to Common Lisp's
lambda lists. Instead of an outer wrapper for Clojure's various
function forms, it provides a kind of inner wrapper, really a let form
specialized for keyword arguments. Each keyword is defined in a
keyword spec, which allows for an optional default value, and for an
optional symbol to be bound to true if the keyword was actually
provided in the function call.

Note that keywords arguments may be & rest in style, or provided as
either maps or vectors. This should cover all useful cases for keyword
arguments, including their use in functions with multiple arities.


Example:

(defn test1 [req1 req2 & kw-args]
  (fn-keywords [:kw1
[:kw2 "kw2 default"]
[:kw3 "kw3 default" kw3-supplied?]]
  kw-args
;; function body
{:req1 req1 :req2 req2 :kw1 kw1 :kw2 kw2
 :kw3 kw3 :kw3-supplied? kw3-supplied?}))

> (test1 1 2 :kw3 "there")
{:req1 1, :req2 2, :kw1 nil, :kw2 "kw2 default",
 :kw3 "there", :kw3-supplied? true}
> (test1 1 2 :kw1 "there")
{:req1 1, :req2 2, :kw1 "there", :kw2 "kw2 default",
 :kw3 "kw3 default", :kw3-supplied? false}
> (test1 1 2 :kw1 "hello" :kw2 "there")
{:req1 1, :req2 2, :kw1 "hello", :kw2 "there",
 :kw3 "kw3 default", :kw3-supplied? false}


Macro code:

(defmacro fn-keywords
  "Adds flexible keyword handling to any form which has a parameter
list: fn,
   defn, defmethod, letfn, and others. Keywords may be passed to the
surrounding
   form as & rest arguments, lists, or maps. Lists or maps must be
used for
   functions with multiple arities if more than one arity has keyword
   parameters. Keywords are bound inside fn-keywords as symbols, with
default
   values either specified in the keyword spec or nil. Keyword specs
may consist
   of just the bare keyword, which defaults to nil, or may have the
general form
   [:keyword-name keyword-default-value* keyword-bound?*]. keyword-
bound? is an
   optional symbol bound to true if the keyword was supplied, and to
false
   otherwise."
  [kw-spec-raw kw-args & body]
  (let [kw-spec  (map #(if (sequential? %) % [%]) kw-spec-raw)
keywords (map first kw-spec)
symbols  (map (comp symbol name) keywords)
defaults (map second kw-spec)
destrmap {:keys (vec symbols)
  :or (apply hash-map (interleave symbols defaults))}
supplied (reduce (fn [m [k v]] (assoc m k v)) (sorted-map)
 (remove (fn [[_ val]] (nil? val))
 (partition 2
(interleave keywords
(map (comp
second rest)
 kw-
spec)
kw-args-map (gensym)]
`(let [kw-args# ~kw-args
   ~kw-args-map (if (map? kw-args#) kw-args# (apply hash-map
kw-args#))
   ~destrmap ~kw-args-map]
   ~@(if (empty? supplied)
 body
 `((apply (fn [~@(vals supplied)]
~...@body)
  (map (fn [x#] (contains? ~kw-args-map x#))
   [~@(keys supplied)])))


More examples:

(defmulti test2 (fn [x & rest] (class x)))

(defmethod test2 java.lang.Integer [req & kw-args]
  (fn-keywords [[:kw1 "default" kw1-supplied?]] kw-args
{:method "integer"
 :req req
 :kw1 kw1
 :kw1-supplied? kw1-supplied?}))

(defmethod test2 java.lang.String [req & kw-args]
  (fn-keywords [[:kw1 "default"]] kw-args
{:method "string"
 :req req
 :kw1 kw1}))

(defn test3
  ([req1 kw-args]
 (fn-keywords [:kw1 :kw2] kw-args
   {:req1 req1 :kw1 kw1 :kw2 kw2}))
  ([req1 req2 kw-args]
 (fn-keywords [:kw1 :kw2] kw-args
   {:req1 req1 :req2 req2 :kw1 kw1 :kw2 kw2})))

(defn test4 []
  (letfn [(inner [& kw-args]
(fn-keywords [:kw1 :kw2] kw-args
  {:kw1 kw1 :kw2 kw2}))]
(inner :kw1 "hello" :kw2 "world")))


Credit where it's due: I lifted ideas and bits of code from defnk.
Thanks, Meikel!

Comments welcome.

--
Constantine Vetoshev

-- 
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: A macro for flexible keyword argument handling

2009-11-15 Thread Constantine Vetoshev
Looks like Google Groups posting software forced line wraps at less
than 80 columns, breaking the code. Lovely. Here's the fn-keywords
macro reformatted for 72 column wrapping.

(defmacro fn-keywords
  "Adds flexible keyword handling to any form which has a
   parameter list: fn, defn, defmethod, letfn, and
   others. Keywords may be passed to the surrounding form as &
   rest arguments, lists, or maps. Lists or maps must be used for
   functions with multiple arities if more than one arity has
   keyword parameters. Keywords are bound inside fn-keywords as
   symbols, with default values either specified in the keyword
   spec or nil. Keyword specs may consist of just the bare
   keyword, which defaults to nil, or may have the general form
   [:keyword-name keyword-default-value*
   keyword-bound?*]. keyword-bound? is an optional symbol bound
   to true if the keyword was supplied, and to false otherwise."
  [kw-spec-raw kw-args & body]
  (let [kw-spec  (map #(if (sequential? %) % [%]) kw-spec-raw)
keywords (map first kw-spec)
symbols  (map (comp symbol name) keywords)
defaults (map second kw-spec)
destrmap {:keys (vec symbols)
  :or (apply hash-map
(interleave symbols defaults))}
supplied (reduce (fn [m [k v]] (assoc m k v)) (sorted-map)
 (remove (fn [[_ val]] (nil? val))
 (partition 2
(interleave
 keywords
 (map (comp second rest)
  kw-spec)
kw-args-map (gensym)]
`(let [kw-args# ~kw-args
   ~kw-args-map (if (map? kw-args#)
kw-args#
(apply hash-map kw-args#))
   ~destrmap ~kw-args-map]
   ~@(if (empty? supplied)
 body
 `((apply (fn [~@(vals supplied)]
~...@body)
  (map (fn [x#] (contains? ~kw-args-map x#))
   [~@(keys supplied)])))

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread John Harrop
On Sun, Nov 15, 2009 at 7:32 PM, Alex Osborne  wrote:

> ajuc wrote:
> > I would like to somehow hide the global hilbert-map into my function,
> > but I can't see how to do that.
> >
> > Is this possible? I know that I can just inert literal into my let,
> > but that degrades performance, when function is called many times.
> >
> > I would like to have something like static local variable in C++, or
> > just regular constant local variable in my function.
>
> Clojure's name gives a hint as to how do this: use a closure. :-)  Just
> pull the let outside the defn:
>
> (let [hilbert-map {...}]
>   (defn point-to-hilbert [...]
> ...))


Has anyone benchmarked this alternative?

-- 
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: Datatypes and Protocols - early experience program

2009-11-15 Thread John Harrop
On Sun, Nov 15, 2009 at 8:17 PM, David Brown  wrote:

> On Sun, Nov 15, 2009 at 04:20:19PM -0500, John Harrop wrote:
>
> >That's weird. It's not documented anywhere on the site. And it seems to
> hang
> >the REPL:
> >
> >user=> nil #!foo
> >
> >and nothing. Enter doesn't print "nil" and a fresh user=> prompt as it
> >should and nothing else apparently works either. The REPL is either wedged
> >or interpreting everything as comment from then on.
> >
> >Weirdly enough, ; hangs the REPL likewise.
>
> How's the data getting to the REPL?  jline, or ide?


Enclojure IDE.

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread Alex Osborne
John Harrop wrote:
> On Sun, Nov 15, 2009 at 7:32 PM, Alex Osborne  > wrote:
> 
> ajuc wrote:
>  > I would like to somehow hide the global hilbert-map into my function,
>  > but I can't see how to do that.
> 
> Clojure's name gives a hint as to how do this: use a closure. :-)  Just
> pull the let outside the defn:
> 
> (let [hilbert-map {...}]
>   (defn point-to-hilbert [...]
> ...))
> 
> 
> Has anyone benchmarked this alternative? 

On my PC it's indistinguishable from point-to-hilbert-let-from-global 
and point-to-hilbert-directly-from-global.  I get around 750ms +- 20ms 
for all three of them (after letting the JIT warm up by running a few 
times).

-- 
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: local constants in functions or static locals/Hilbert curve in clojure (no images:)

2009-11-15 Thread ajuc


On 16 Lis, 01:32, Alex Osborne  wrote:
> Clojure's name gives a hint as to how do this: use a closure. :-)  Just
> pull the let outside the defn:
>
> (let [hilbert-map {...}]
>    (defn point-to-hilbert [...]
>      ...))

Now it seems so obvious :).
I guess I don't think functional yet.
Thank you, that's exactly what I was trying to achieve.

-- 
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: Datatypes and Protocols - early experience program

2009-11-15 Thread Michael Wood
2009/11/16 John Harrop :
> On Sun, Nov 15, 2009 at 8:17 PM, David Brown  wrote:
>>
>> On Sun, Nov 15, 2009 at 04:20:19PM -0500, John Harrop wrote:
>>
>> >That's weird. It's not documented anywhere on the site. And it seems to
>> > hang
>> >the REPL:
>> >
>> >user=> nil #!foo
>> >
>> >and nothing. Enter doesn't print "nil" and a fresh user=> prompt as it
>> >should and nothing else apparently works either. The REPL is either
>> > wedged
>> >or interpreting everything as comment from then on.
>> >
>> >Weirdly enough, ; hangs the REPL likewise.
>>
>> How's the data getting to the REPL?  jline, or ide?
>
> Enclojure IDE.

This is what I get with or without rlwrap from the command line.  No
IDE or anything like that:

Clojure 1.1.0-alpha-SNAPSHOT
user=> ; some comment
user=> #! something
(println "blah")
blah
nil
user=>

i.e. the same as David.

-- 
Michael Wood 

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