Re: recur rationale?

2008-12-21 Thread verec

 You propose a clever trick, but unfortunately it would require even  
 more cleverness. What if foo, bar, and baz live in different  
 libraries, and you reload one of the libraries as part of a dynamic  
 update at runtime? How would the inline copies know they needed to  
 update?

Annotations?

We all know that a Sufficiently Smart Compiler could do it, innit? :-)
--
JFB
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: *compile-path* hardwired in compiled Clojure core

2008-12-21 Thread Rich Hickey



On Dec 19, 3:45 pm, Stuart Sierra the.stuart.sie...@gmail.com wrote:
 Hi Rich  all,
 While compiling Clojure, It seems that *compile-path* is being set to
 the absolute path to classes within the Clojure source
 distribution.  That is:

 unzip clojure_20081217.zip
 cd clojure
 java -jar clojure.jar
 Clojure
 user= *compile-path*
 /Users/rich/dev/clojure/classes

 And it doesn't obey the system property used by clojure.lang.Compile:

 java -Dclojure.compile.path=/tmp/classes -cp /tmp/
 classes:clojure.jar clojure.main
 Clojure
 user= *compile-path*
 /Users/rich/dev/clojure/classes


Looks like a bug in compile.main, where with-bindings hardwired the
compile-time value of clojure.compile.path.

Fixed (svn 1177) - thanks for the report.

Rich

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



Re: Clojure vs. CL macros question

2008-12-21 Thread Rich Hickey



On Dec 19, 2:05 pm, Stuart Halloway stuart.hallo...@gmail.com wrote:
 According to Paul Graham's On Lisp, macroexpanders should be purely
 functional, and you should not count on how often a macro gets
 expanded. This seems like a reasonable restriction for Clojure too.
 However, Chouser posted an example that shows the expansion of proxy
 does have a side effect [2].

 Should macros written by ordinary mortals follow PG's rule?

Yes.

 If not,
 should this be listed as a difference from other Lisps at [3]?


No. There's no significant difference between CL and Clojure in this
area.

No one should come to rely on the implementation details of proxy or
gen-class.

Rich

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



Re: clojure.lang.Script

2008-12-21 Thread Emeka


 java -cp clojure.jar clojure.lang.Script yourapp.clj


In my SciTe I added  java -cp clojure.jar clojure.lang.Script $(FilePath)
plus others and when I click 'GO' or F5 instead of running the code and
printing result. I have


 java -cp clojure.jar clojure.lang.Script C:\janus\myapp.clj

  exit 0

No other thing comes out. So how do I cause it to print the result of the
code I have written. It works in SciTe, however, it doesn't print result.
Have you used clojure.Lang.Script with SciTe before?

Emeka.

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



class diagram

2008-12-21 Thread Mark Volkmann

Somebody created a class diagram for the Java classes and interfaces
in the Clojure implementation, I believe using GraphViz, and I'm
having trouble finding it now. Can someone share the URL?

Also, is there a Clojure function that outputs all the classes and
interfaces in the inheritance hierarchy of a given class or interface?

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



non-seq collections

2008-12-21 Thread Mark Volkmann

Until this morning I was under the impression that ALL Clojure
collections are sequences. Now I understand (from the screencast
Clojure Data Structures - Part 2) that vectors and maps are not and
that you need to call seq on them to get a sequence representation.
What are some situations where this is necessary? I'm confused because
the following code works.

(def my-map {:a 1 :b 2 :c 3})
(first my-map) - [:b 2]
(rest my-map} - ([:c 3] [:a 1])

-- 
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
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: class diagram

2008-12-21 Thread Lauri Oherd

It was made by Chouser:
http://groups.google.com/group/clojure/browse_thread/thread/c7ae505290cdf59a/742f3b5f740e4592

Lauri


On Sun, Dec 21, 2008 at 5:44 PM, Mark Volkmann
r.mark.volkm...@gmail.com wrote:

 Somebody created a class diagram for the Java classes and interfaces
 in the Clojure implementation, I believe using GraphViz, and I'm
 having trouble finding it now. Can someone share the URL?

 Also, is there a Clojure function that outputs all the classes and
 interfaces in the inheritance hierarchy of a given class or interface?

 --
 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
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: class diagram

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 07:44, Mark Volkmann wrote:
 Somebody created a class diagram for the Java classes and interfaces
 in the Clojure implementation, I believe using GraphViz, and I'm
 having trouble finding it now. Can someone share the URL?

 Also, is there a Clojure function that outputs all the classes and
 interfaces in the inheritance hierarchy of a given class or
 interface?

None I'm aware of as such. Naturally, reflection is available for such 
purpose and Chouser's Clojure code shows one example of doing that.

To answer your first question:

On Sunday 14 December 2008 13:47, Chouser wrote:
 I've updated the Clojure classes graph.  The new version includes the
 newest classes as well as Java interfaces that are applicable.  These
 latter are shown inside diamonds.

 A couple different .svg and .png versions are available here, along
 with the code used to create them:

 http://github.com/Chouser/clojure-classes/tree/master

 For a quick link to the main graphic, you can use:

 http://tinyurl.com/clojure-classes

 I won't be maintaining the chart.png in the file upload area of this
 group, since it's much easier to just push new versions to the github
 repo.  There you can also find older versions, other formats, etc.

 --Chouser


Randall Schulz

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



Re: non-seq collections

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 07:51, Mark Volkmann wrote:
 Until this morning I was under the impression that ALL Clojure
 collections are sequences.

Sequences are views of collections (sequential ones, if you can believe 
it!). All collections can be sequenced, but they are not to be equated.


 Now I understand (from the screencast Clojure Data Structures - Part
 2) that vectors and maps are not and that you need to call seq on
 them to get a sequence representation. What are some situations where
 this is necessary? I'm confused because the following code works.

 (def my-map {:a 1 :b 2 :c 3})
 (first my-map) - [:b 2]
 (rest my-map} - ([:c 3] [:a 1])

In very many (most? all?) cases, library functions will apply (seq ...) 
as necessary, leaving you able to use sequences or collections 
seemingly interchangeably.


Randall Schulz

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



Re: non-seq collections

2008-12-21 Thread Meikel Brandmeyer

Hi Mark,

Am 21.12.2008 um 16:51 schrieb Mark Volkmann:


Until this morning I was under the impression that ALL Clojure
collections are sequences. Now I understand (from the screencast
Clojure Data Structures - Part 2) that vectors and maps are not and
that you need to call seq on them to get a sequence representation.
What are some situations where this is necessary? I'm confused because
the following code works.


It is important to understand the difference between a collection
and a seq. Collections are specific implementations of a container.
Maybe a vector, maybe a map, ...

A seq on the other hand is an abstract view on such a collection.
(In particular a seq is not a collection.)

Note that  a list is still a collection, which just happens to implement
the contract of a seq. So it can act as it's own seq.


(def my-map {:a 1 :b 2 :c 3})
(first my-map) - [:b 2]
(rest my-map} - ([:c 3] [:a 1])



Theoretically the calls would need a seq for the map.

(first (seq my-map))

However, this is very hard on the user. He always has to take
care, that he passes a seq. But since a seq is also it's own seq,
ie. (seq a-seq) == a-seq, we can change the interface from
takes a seq to takes a sequable thing and call seq on that
thing in the function itself.

Then we suddenly save a lot of seq calls on the user side.
Also being more convenient for the user.

Hope this helps.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: class diagram

2008-12-21 Thread Albert Cardona


 Also, is there a Clojure function that outputs all the classes and
 interfaces in the inheritance hierarchy of a given class or interface?
   


Isn't that ancestors?

user= (ancestors String)
#{java.lang.Object java.lang.CharSequence java.io.Serializable 
java.lang.Comparable}


-- 
Albert Cardona
http://albert.rierol.net


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



Behavior of equals (==) w/r/t keywords

2008-12-21 Thread chris

This is not what I would expect:

user (== :test :test)
false

I am trying to use keywords as enumerations to texture types.  I want
to know if two textures are comparable, thus I would expect
(== :rgba :rgba) to return true.

I may have missed something, but it seems like Rich did away with the
8 different equals you find in CL.  Which is wonderful.

Also, is there a way to get the numeric value from equals?

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



Re: Behavior of equals (==) w/r/t keywords

2008-12-21 Thread chris

Ah,
user (= :float :float)
true

Chris

On Dec 21, 10:33 am, chris cnuern...@gmail.com wrote:
 This is not what I would expect:

 user (== :test :test)
 false

 I am trying to use keywords as enumerations to texture types.  I want
 to know if two textures are comparable, thus I would expect
 (== :rgba :rgba) to return true.

 I may have missed something, but it seems like Rich did away with the
 8 different equals you find in CL.  Which is wonderful.

 Also, is there a way to get the numeric value from equals?

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



Re: Behavior of equals (==) w/r/t keywords

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 09:33, chris wrote:
 This is not what I would expect:

 user (== :test :test)
 false

user= (doc ==)
-
clojure.core/==
([x] [x y] [x y  more])
  Returns non-nil if nums all have the same value, otherwise false


To be clear: == is for numeric values only.


 ...

 Also, is there a way to get the numeric value from equals?

Eh?


 Chris


Randall Schulz

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



SPARQL DSL - a humble request for review and guidance

2008-12-21 Thread Adam Harrison (Clojure)


Hi folks,

First let me say 'Thankyou very much' for Clojure - it has enabled me to 
finally take the plunge into learning a Lisp without feeling like I'm 
abandoning a ten year investment in the Java platform and its libraries. 
I bought 'Practical Common Lisp' about eighteen months ago and read it 
half heartedly, never making it to a REPL; however I now have the luxury 
of working on a project of my own and decided the time was right to 
revisit the promised land of Lisp. I have been aware of Clojure for 
about six months, and, given my experience of Java, it seemed like the 
obvious place to start. I've spent the past couple of weeks devouring 
lots of general Lisp related documentation, Rich's Clojure webcasts and 
Stuart's 'Programming Clojure' book. I am pleased to report that my Lisp 
epiphany occurred yesterday when I found I could understand this macro 
pasted to lisp.org by Rich:

(defmacro defnk [sym args  body]
 (let [[ps keys] (split-with (complement keyword?) args)
   ks (apply array-map keys)
   gkeys (gensym gkeys__)
   letk (fn [[k v]]
  (let [kname (symbol (name k))]
`(~kname (~gkeys ~k ~v]
   `(defn ~sym [...@ps  k#]
  (let [~gkeys (apply hash-map k#)
~@(mapcat letk ks)]
~...@body

I am now spoiled forever, and although my powers are weak, I realise I 
have become one of those smug Lisp types condemned to look down on all 
other programming languages for the rest of their lives. Thankyou's and 
cliched tales of enlightenment dispensed with, I can now move on to the 
plea for aid :)

My current project involves semantic web technologies, at this point 
specifically SPARQL queries over RDF triple stores (for those unfamiliar 
with SPARQL it will suffice to say that it's a straightforward query 
language modelled after SQL, but operating over graphs rather than 
tables). Like their SQL counterpart, the Java APIs for performing these 
queries are verbose and cumbersome, and I am hoping that they can be 
hidden behind some cunning Lisp macros to provide an expressive and 
tightly integrated semantic query capability (similar to Microsoft's 
LINQ). Unfortunately my ambitions far exceed my skills at this point, 
and I am hoping to garner some gentle mentoring to steer me in the right 
direction from the outset.

My first inclination is to start with the simplest thing which will 
work, which is to create a function which takes a SPARQL query string as 
an argument and returns a list of results:

(sparql 
PREFIX foaf: http://xmlns.com/foaf/0.1
SELECT ?name
WHERE
{
   ?person foaf:mbox \mailto:adam-cloj...@antispin.org\; .
   ?person foaf:name ?name
})

However this style is poor for several reasons: it looks ugly, quotation 
marks have to be escaped manually, and interpolation of variables into 
the query string is a chore which further decreases readability. What I 
really want is a nice DSL:

(let [mbox mailto:adam-cloj...@atispin.org;]
 (sparql
   (with-prefixes [foaf http://xmlns.com/foaf/0.1;]
 (select ?name
   (where
 (?person foaf:mbox mbox)
 (?person foaf:name ?name)

Clearly this is going to require a macro, because for a start I don't 
want the symbols representing SPARQL capture variables (the ones 
starting with '?') to be evaluated - I want to take the name of the 
symbol, '?' and all, and embed it into the query string which this DSL 
will ultimately generate before calling into the Java API. On the other 
hand, I do want some things evaluated - I want to embed the value 
('mailto:adam-clog...@antispin.org') bound to the symbol 'mbox' in the 
query string, not the name of the symbol.

 From my position of total ignorance, I can see two broad approaches to 
tackling this. The first is to implement (sparql ...) as a macro which 
is responsible for interpreting the entire subtree of forms below it, 
building a query string by selectively evaluating some forms whilst 
using others as navigational markers which give context. It would honour 
the grammar which defines SPARQL queries, and either signal an error or 
be guaranteed to generate syntactically correct queries. The macro would 
also have insight into the format of the data which would be returned 
(gleaned from the 'select' part) and so could return something useful 
like a list of maps where the keys are the names of the capture 
variables that appear in the select clause. I have no idea how to do 
this, but it feels like the 'right' way.

The other approach, which is IMO a bit hacky, but within my reach, is to 
define 'with-prefixes', 'select' and 'where' as individual macros whose 
first arguments are expanded into the relevant subcomponent of the query 
string and whose final argument is a string to be appended to the end. 
You then compose these together into the right order to get the compete 
query string:

(with-prefix [foaf http://xmlns.com/foaf/0.1;] ...the select 
statement) would evaluate to PREFIX foaf: 

Re: Behavior of equals (==) w/r/t keywords

2008-12-21 Thread chris

Right, waking up a bit.

I would like, at some point, to serialize a bunch of structures to a
byte stream.

They are the mapped structs (struct :data1 :data2).

Lets say I would like to do this generically, I need a function that
takes a keyword and returns an integer.
I will write out a mapping from integer to name to the file.

Next, on deserialize I need to be able to create the keyword again
from the name.

So I can auto-generate these integers just fine but if there is an
internal mapping I might use that.

Second, exactly what namespace do :keywords go into?  I
know ::keywords go into *ns*, but
I am not super clear about single-colon keywords.  They seem like
global keywords which is
really what I want for enumerations, but I need to be able to take a
string and turn it into
the same keyword.

Is there a keywords namespace that single colon keywords go into?

Chris

On Dec 21, 10:51 am, Randall R Schulz rsch...@sonic.net wrote:
 On Sunday 21 December 2008 09:33, chris wrote:

  This is not what I would expect:

  user (== :test :test)
  false

 user= (doc ==)
 -
 clojure.core/==
 ([x] [x y] [x y  more])
   Returns non-nil if nums all have the same value, otherwise false

 To be clear: == is for numeric values only.

  ...

  Also, is there a way to get the numeric value from equals?

 Eh?

  Chris

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



How to encapsulate local state in closures

2008-12-21 Thread chris

I would like to be able to encapsulate local state in a closure.
Specifically, I would like a function that returns an incrementing
integer, thus:
(test_func)
1
(test_func)
2
What is the best way to go about this?  With local bindings is failing
and I can't figure just why...

(def test_closure
   (with-local-vars [one 1]
 (fn [] (var-get one
#'user/test_closure
user (test_closure)
; Evaluation aborted.
The var is null when I call the closure.

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



Re: Behavior of equals (==) w/r/t keywords

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 10:18, chris wrote:
 Right, waking up a bit.

 I would like, at some point, to serialize a bunch of structures to a
 byte stream.

 They are the mapped structs (struct :data1 :data2).

 Lets say I would like to do this generically, I need a function that
 takes a keyword and returns an integer.
 I will write out a mapping from integer to name to the file.

You should at least consider just using the Clojure printer and reader 
for your serialization / deserialization.


 ...

 Is there a keywords namespace that single colon keywords go into?

Keywords and symbols are the same insofar they they all live in 
namespace. The notation is consistent between the two:

user= (namespace :foo/bar)
foo

user= (name :foo/bar)
bar



 Chris


Randall Schulz

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



Re: Behavior of equals (==) w/r/t keywords

2008-12-21 Thread chris

user (namespace :test)
nil

So it doesn't live in a namespace.  But it is a distinct entity; a
comparable value.

user (= :test :test)
true
user (= :test :bar)
false

user (keyword test)
:test
user (namespace (keyword test))
nil
user (namespace (keyword test user))
test
user (namespace (keyworld user test))
; Evaluation aborted.
user (namespace (keyword user test))
user

That answers my question.  Don't use a namespace, and the keyword is
global.  Pass in a namespace, and the keyword is in that namespace.

I will definitely consider using the clojure printer/reader; that is a
really really good idea, thanks!

I am doing graphics work, so I may have to externalize certain data
(like images and data buffers), but as long as the clojure printer
prints text you have hit upon a really great solution!

Chris

On Dec 21, 12:26 pm, Randall R Schulz rsch...@sonic.net wrote:
 On Sunday 21 December 2008 10:18, chris wrote:

  Right, waking up a bit.

  I would like, at some point, to serialize a bunch of structures to a
  byte stream.

  They are the mapped structs (struct :data1 :data2).

  Lets say I would like to do this generically, I need a function that
  takes a keyword and returns an integer.
  I will write out a mapping from integer to name to the file.

 You should at least consider just using the Clojure printer and reader
 for your serialization / deserialization.

  ...

  Is there a keywords namespace that single colon keywords go into?

 Keywords and symbols are the same insofar they they all live in
 namespace. The notation is consistent between the two:

 user= (namespace :foo/bar)
 foo

 user= (name :foo/bar)
 bar

  Chris

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



(Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Stephen C. Gilardi
The enclosed updated patch: unified-main-2.patch addresses all defects  
I am aware of in its predecessor.


On Dec 17, 2008, at 6:10 PM, Stephen C. Gilardi wrote:


On Dec 17, 2008, at 2:27 PM, Rich Hickey wrote:


In what way is that the right thing to do?



The idea was that the sequence of top level forms may each depend on  
the success of the previous one. It can easily be changed to  
consider them all independent and I'll be happy to do that.


Top level forms are now independently evaluated. As always, only the  
most recent exception is saved in *e so stack trace information can be  
lost in the case of multiple exceptions on the same input line. I  
think that's ok.


I'm quite concerned about compatibility, especially with all the  
read-line stuff. I remember some nightmares:


I know you're talking about unexpected nightmares. I think testing  
by others would be wise and I welcome it. These specific ones came  
up in my own testing I believe the patched code handles them well.





[details]



(read-line) now works in an unsurprising, easy to explain way. All  
kinds of reading from the input stream during eval are now supported  
and they no longer interfere with prompting.


The behavior is that after reading a top level form and before  
evaluating it, if the input stream is pointing at a newline character,  
the repl will consume that newline before evaluating the form. If the  
top level form doesn't end the input line, any reading done by the  
code being eval'd begins right after the form and all subsequent  
characters including whitespace and newlines will be seen.


Without this special handling, (read-line) from the repl would always  
return .


(Alternative special handling would skip whitespace after the top  
level form rather than only a single newline character. I think the  
latter is preferable, but it would be easy to change to the other  
option.)


Here are some examples with notes below:

Clojure
1   user= (read-line)
2   123
3   123
4   user= (read-line)123
5   123
6   user= (read-line) 1 2 3
71 2 3
8   user= [(.read *in*)(.read *in*)(.read *in*)(.read *in*)]
9   1234
10  [49 50 51 52]
11  user= [(.read *in*)(.read *in*)(.read *in*)(.read *in*)]
12  12
13  34
14  [49 50 10 51]
15  4
16  user= [(.read *in*)(.read *in*)(.read *in*)(.read *in*)]1
17  23456
18  [49 10 50 51]
19  456
20  user= (.read *in*)
21  1 2 3
22  49
23  2
24  3
25  user=

Notes:

1. The newline the user entered after ) is eaten. The repl blocks on  
the next line waiting for input. A string containing the entire line  
of input is returned as the value of the (read-line).
4. There is no newline immediately after ), so the rest of the line  
is returned by (read-line)
6. Same situation here. Note that the returned value begins with  
whitespace.
8. Reading 4 character codes into a vector. They are the codes for 1,  
2, 3, and 4.
11. Reading 4 character codes into a vector. They are the codes for 1,  
2, newline, and 3. The subsequent 4 remains on the input stream and is  
read/eval/printed.
16. Reading 4 character codes into a vector. The first comes from  
after the top level form. Then newline, 2, and 3. Then 456 is read/ 
eval/printed.

20. One character code is read, then 2 and 3 are read/eval/printed.


Are these changes compatible with the interactions done via, say,  
emacs inferior lisp mode? It's important to consider the fact that  
the repl can be interacted with by programs, not just people.


In those I've tested, it has worked fine. The prompt only when  
there's nothing left to read/eval/print from the most recent user  
input behavior is now configurable via a :need-prompt (function)  
argument to the repl. There is an opportunity to prompt after each top  
level read/eval/print is complete. If (need-prompt) returns true, the  
prompt will be printed. The default need-prompt function cooperates  
with LineNumberingPushbackReader to determine when we're about to wait  
for the user to type on a new blank line and prompts only then. If  
some software requires prompting for every top level read/eval/print,  
code that launches the associated repl can pass in #(identity true)  
for need-prompt.



Could someone please try it with Gorilla?


It appears nobody has tried this.


Has anyone tried this patch under Windows?


I tried it on Windows and it works fine. I learned something important  
here. LineNumberingPushbackReader wraps a LineNumberReader stream. The  
latter collapses all three supported line terminators: CR, LF, and  
CRLF into a single \n character. We've been running with that all  
along. I've taken advantage of that to simplify clojure.main and my  
modifications to LineNumberingPushbackReader and noted that I'm using  
that behavior in comments and doc strings.


There also seems to be a difference in behavior between  
clojure.main and Repl regarding 

Re: How to encapsulate local state in closures

2008-12-21 Thread Parth Malwankar



On Dec 21, 11:47 pm, chris cnuern...@gmail.com wrote:
 I would like to be able to encapsulate local state in a closure.
 Specifically, I would like a function that returns an incrementing
 integer, thus:
 (test_func)
 1
 (test_func)
 2
 What is the best way to go about this?  With local bindings is failing
 and I can't figure just why...


One way to do this would be to use atom.

(defn mk-counter [start]
  (let [n (atom start)]
(fn [] (swap! n inc

(def counter (mk-counter 0))

user= (counter)
1
user= (counter)
2
user= (counter)
3

Parth
 (def test_closure
            (with-local-vars [one 1]
              (fn [] (var-get one
 #'user/test_closure
 user (test_closure)
 ; Evaluation aborted.
 The var is null when I call the closure.

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



Re: clojure.lang.Script

2008-12-21 Thread Parth Malwankar



On Dec 21, 8:21 pm, Emeka emekami...@gmail.com wrote:
  java -cp clojure.jar clojure.lang.Script yourapp.clj

 In my SciTe I added  java -cp clojure.jar clojure.lang.Script $(FilePath)
 plus others and when I click 'GO' or F5 instead of running the code and
 printing result. I have



  java -cp clojure.jar clojure.lang.Script C:\janus\myapp.clj

   exit 0

 No other thing comes out. So how do I cause it to print the result of the
 code I have written. It works in SciTe, however, it doesn't print result.
 Have you used clojure.Lang.Script with SciTe before?

If you are using the latest Clojure you can probably try:
java -cp clojure.jar clojure.main filename.clj

I haven't used SciTe but this is what I do in my clojure launch
script.

Parth


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



gen-class from REPL

2008-12-21 Thread .Bill Smith

Is this a valid thing to do from the REPL?

$ java -jar clojure.jar
Clojure
user= (ns clojure.examples.hello
(:gen-class))

(defn -main
  [greetee]
  (println (str Hello  greetee !)))

nil
clojure.examples.hello= #'clojure.examples.hello/-main
clojure.examples.hello= (compile 'clojure.examples.hello)
java.io.FileNotFoundException: Could not locate clojure/examples/
hello__init.class or clojure/examples/hello.clj on classpath:
(NO_SOURCE_FILE:0)
clojure.examples.hello=


I'm running rev 1180 of clojure and rev 320 of clojure-contrib.


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



Re: Behavior of equals (==) w/r/t keywords

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 11:33, chris wrote:
 ...

 That answers my question.  Don't use a namespace, and the keyword is
 global.  Pass in a namespace, and the keyword is in that namespace.

Yes, the default namespace for keywords is different than for symbols, 
which is why the ::keyword form exists.


 I will definitely consider using the clojure printer/reader; that is
 a really really good idea, thanks!

 I am doing graphics work, so I may have to externalize certain data
 (like images and data buffers), but as long as the clojure printer
 prints text you have hit upon a really great solution!

It's not a universal replacement for persistent data storage along the 
lines of a Hibernate-style) object-relational system, an O-O database 
or even an eXist-style XML database.

But it's a handy option for data that is essential symbolic, not 
tremendously voluminous and for which and all-or-none externalization / 
internalization model that doesn't require selective query / retrieval 
and update is adequate.


 Chris


Randall Schulz

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



Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Mark McGranaghan

Hi Steve,

Thanks for your work on polishing up Clojure's entry point situation.

I've applied your patch and tried a series of typical entry point
scenarios; all but one of them worked for me. Just for the record,
here is what did work:
- Using -h to get help
- Using no options to boot into a repl
- Running the repl with jLine
- Using - to read from stdin
- Running a script located based on a filesystem path
- Running a script located relative to classpath
- Using -i to load files before running a script
- Using set! in one of these init files
- Accessing *command-line-args* from a script

The one that didn't work was booting into a line-numbered repl, which
is the setup I use now with trunk Clojure and Clojure-Contrib:
java -cp clojure.jar:/Users/mmcgrana/Clojure/jars/clojure-contrib.jar
clojure.main -e (use 'clojure.contrib.repl-ln) -e (repl)

This just hangs without giving a prompt, and then when I press enter
it goes into an infinite loop of error messages.
Perhaps I'm just using the wrong approach to booting in the line-numbering repl?

- Mark

On Sun, Dec 21, 2008 at 2:42 PM, Stephen C. Gilardi squee...@mac.com wrote:
 The enclosed updated patch: unified-main-2.patch addresses all defects I am
 aware of in its predecessor.

 On Dec 17, 2008, at 6:10 PM, Stephen C. Gilardi wrote:

 On Dec 17, 2008, at 2:27 PM, Rich Hickey wrote:

 In what way is that the right thing to do?


 The idea was that the sequence of top level forms may each depend on the
 success of the previous one. It can easily be changed to consider them all
 independent and I'll be happy to do that.

 Top level forms are now independently evaluated. As always, only the most
 recent exception is saved in *e so stack trace information can be lost in
 the case of multiple exceptions on the same input line. I think that's ok.

 I'm quite concerned about compatibility, especially with all the
 read-line stuff. I remember some nightmares:

 I know you're talking about unexpected nightmares. I think testing by
 others would be wise and I welcome it. These specific ones came up in my own
 testing I believe the patched code handles them well.


 [details]


 (read-line) now works in an unsurprising, easy to explain way. All kinds of
 reading from the input stream during eval are now supported and they no
 longer interfere with prompting.

 The behavior is that after reading a top level form and before evaluating
 it, if the input stream is pointing at a newline character, the repl will
 consume that newline before evaluating the form. If the top level form
 doesn't end the input line, any reading done by the code being eval'd begins
 right after the form and all subsequent characters including whitespace and
 newlines will be seen.

 Without this special handling, (read-line) from the repl would always return
 .

 (Alternative special handling would skip whitespace after the top level form
 rather than only a single newline character. I think the latter is
 preferable, but it would be easy to change to the other option.)

 Here are some examples with notes below:

Clojure
 1   user= (read-line)
 2   123
 3   123
 4   user= (read-line)123
 5   123
 6   user= (read-line) 1 2 3
 71 2 3
 8   user= [(.read *in*)(.read *in*)(.read *in*)(.read *in*)]
 9   1234
 10  [49 50 51 52]
 11  user= [(.read *in*)(.read *in*)(.read *in*)(.read *in*)]
 12  12
 13  34
 14  [49 50 10 51]
 15  4
 16  user= [(.read *in*)(.read *in*)(.read *in*)(.read *in*)]1
 17  23456
 18  [49 10 50 51]
 19  456
 20  user= (.read *in*)
 21  1 2 3
 22  49
 23  2
 24  3
 25  user=

 Notes:

 1. The newline the user entered after ) is eaten. The repl blocks on the
 next line waiting for input. A string containing the entire line of input is
 returned as the value of the (read-line).
 4. There is no newline immediately after ), so the rest of the line is
 returned by (read-line)
 6. Same situation here. Note that the returned value begins with whitespace.
 8. Reading 4 character codes into a vector. They are the codes for 1, 2, 3,
 and 4.
 11. Reading 4 character codes into a vector. They are the codes for 1, 2,
 newline, and 3. The subsequent 4 remains on the input stream and is
 read/eval/printed.
 16. Reading 4 character codes into a vector. The first comes from after the
 top level form. Then newline, 2, and 3. Then 456 is read/eval/printed.
 20. One character code is read, then 2 and 3 are read/eval/printed.


 Are these changes compatible with the interactions done via, say, emacs
 inferior lisp mode? It's important to consider the fact that the repl can be
 interacted with by programs, not just people.

 In those I've tested, it has worked fine. The prompt only when there's
 nothing left to read/eval/print from the most recent user input behavior is
 now configurable via a :need-prompt (function) argument to the repl. There
 is an opportunity to prompt after each top 

Lazy inconsistency between map and mapcat; lazy concatenation

2008-12-21 Thread Jason

Hi,

I noticed that while map produces a fully lazy result, mapcat always
evaluates the first three terms when it is called, and is lazy
thereafter.  This can be confusing, and is sometimes not desired
behavior.  For example, I'm trying to generate a lazy infinite seq
corresponding to a tree traversal by interleaving mapcat and recursive
calls, and these extra evaluations cause a stack overflow before a
single element is produced.

In addition to a lazy mapcat, it might be nice to have a truly lazy
variant of concat itself built-in.  I know lazy-cat exists, but it is
a macro so the number of seqs must be known at compile-time
(correct?).  Perhaps most useful would be a function that takes a lazy
seq of lazy seqs, and returns their supremely lazy concatenation.

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



Re: clojure.contrib.enum Exception

2008-12-21 Thread Stuart Sierra

Whoops, looks like contrib.enum doesn't work with the new AOT-
compilation.  I wrote it, so I'll take a look, but for the mean
time... don't use it. :)

-Stuart Sierra


On Dec 21, 12:56 am, Andrew Baine andrew.ba...@gmail.com wrote:
 Any help is much appreciated:

 user (require :verbose 'clojure.contrib.enum)
 (clojure.core/load /clojure/contrib/enum)
 ; Evaluation aborted.

 java.lang.Exception: Unable to resolve symbol: gen-and-load-class in
 this context (enum.clj:42)
   [Thrown class clojure.lang.Compiler$CompilerException]

 I'm using the latest version of clojure and clojure-contrib:

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



Re: gen-class from REPL

2008-12-21 Thread Stuart Sierra

Hi Bill,

I think compile calls load-lib, or something like that, so it
assumes there's a source file somewhere.

-Stuart Sierra


On Dec 21, 3:19 pm, .Bill Smith william.m.sm...@gmail.com wrote:
 Is this a valid thing to do from the REPL?

 $ java -jar clojure.jar
 Clojure
 user= (ns clojure.examples.hello
     (:gen-class))

 (defn -main
   [greetee]
   (println (str Hello  greetee !)))

 nil
 clojure.examples.hello= #'clojure.examples.hello/-main
 clojure.examples.hello= (compile 'clojure.examples.hello)
 java.io.FileNotFoundException: Could not locate clojure/examples/
 hello__init.class or clojure/examples/hello.clj on classpath:
 (NO_SOURCE_FILE:0)
 clojure.examples.hello=

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



Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Mark McGranaghan

Steve,

Your version of repl_ln.clj works for me:

1:1 user= (+ 1 2)
3
1:2 user= (throw (Exception. test))
java.lang.Exception: test (repl-1:2)

Thanks again,
- Mark

On Sun, Dec 21, 2008 at 3:47 PM, Stephen C. Gilardi squee...@mac.com wrote:
 Hi Mark,

 Thanks for your work on polishing up Clojure's entry point situation.

 You're welcome. Thanks very much for the feedback.

 I've applied your patch and tried a series of typical entry point
 scenarios; all but one of them worked for me. Just for the record,
 here is what did work:
 - Using -h to get help
 - Using no options to boot into a repl
 - Running the repl with jLine
 - Using - to read from stdin
 - Running a script located based on a filesystem path
 - Running a script located relative to classpath
 - Using -i to load files before running a script
 - Using set! in one of these init files
 - Accessing *command-line-args* from a script

 Excellent, that's some fine coverage. I appreciate it!

 The one that didn't work was booting into a line-numbered repl, which
 is the setup I use now with trunk Clojure and Clojure-Contrib:
 java -cp clojure.jar:/Users/mmcgrana/Clojure/jars/clojure-contrib.jar
 clojure.main -e (use 'clojure.contrib.repl-ln) -e (repl)

 clojure.contrib.repl-ln will need an update if my patch is made part of
 Clojure. I'm attaching the copy I'm currently using (which has not gone
 through my usual pre-patch testing process, but is working for me.)
 Please let me know whether it works for you.
 Thanks!
 --Steve




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



Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Mark McGranaghan

I have another quick observation:

The (System/exit 0) bit at the end of the main function changes the
behavior of some scripts I have for starting Jetty servers. The
scripts basically end with (.start server), were server is a Jetty
Server instance, and previously would run until control-C'd from the
command line. I see in the linked thread above that this change in
behavior is required by other aspects of Clojure, which makes senes to
me. Do you know of any straiforward change I could make to these
scripts to keep the servers running? Perhaps this is a matter of the
Jetty APIs and not Clojure.

I'm not using Compujre here, but looking quickly at Compojure it seems
like it uses (.start server) as well from scripts.

- Mark

On Sun, Dec 21, 2008 at 3:59 PM, Mark McGranaghan mmcgr...@gmail.com wrote:
 Steve,

 Your version of repl_ln.clj works for me:

 1:1 user= (+ 1 2)
 3
 1:2 user= (throw (Exception. test))
 java.lang.Exception: test (repl-1:2)

 Thanks again,
 - Mark

 On Sun, Dec 21, 2008 at 3:47 PM, Stephen C. Gilardi squee...@mac.com wrote:
 Hi Mark,

 Thanks for your work on polishing up Clojure's entry point situation.

 You're welcome. Thanks very much for the feedback.

 I've applied your patch and tried a series of typical entry point
 scenarios; all but one of them worked for me. Just for the record,
 here is what did work:
 - Using -h to get help
 - Using no options to boot into a repl
 - Running the repl with jLine
 - Using - to read from stdin
 - Running a script located based on a filesystem path
 - Running a script located relative to classpath
 - Using -i to load files before running a script
 - Using set! in one of these init files
 - Accessing *command-line-args* from a script

 Excellent, that's some fine coverage. I appreciate it!

 The one that didn't work was booting into a line-numbered repl, which
 is the setup I use now with trunk Clojure and Clojure-Contrib:
 java -cp clojure.jar:/Users/mmcgrana/Clojure/jars/clojure-contrib.jar
 clojure.main -e (use 'clojure.contrib.repl-ln) -e (repl)

 clojure.contrib.repl-ln will need an update if my patch is made part of
 Clojure. I'm attaching the copy I'm currently using (which has not gone
 through my usual pre-patch testing process, but is working for me.)
 Please let me know whether it works for you.
 Thanks!
 --Steve





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



Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Stephen C. Gilardi

Based on the bottom of the ruby code example on this page:

http://rjack.rubyforge.org/jetty/classes/Jetty/ServerFactory.html

A first guess is that this would work:

(.start server)
(.join server)

Join will wait for the thread to exit before continuing. That code  
makes sense if server is an instance of Thread.


--Steve

On Dec 21, 2008, at 4:16 PM, Mark McGranaghan wrote:



I have another quick observation:

The (System/exit 0) bit at the end of the main function changes the
behavior of some scripts I have for starting Jetty servers. The
scripts basically end with (.start server), were server is a Jetty
Server instance, and previously would run until control-C'd from the
command line. I see in the linked thread above that this change in
behavior is required by other aspects of Clojure, which makes senes to
me. Do you know of any straiforward change I could make to these
scripts to keep the servers running? Perhaps this is a matter of the
Jetty APIs and not Clojure.

I'm not using Compujre here, but looking quickly at Compojure it seems
like it uses (.start server) as well from scripts.

- Mark

On Sun, Dec 21, 2008 at 3:59 PM, Mark McGranaghan  
mmcgr...@gmail.com wrote:

Steve,

Your version of repl_ln.clj works for me:

1:1 user= (+ 1 2)
3
1:2 user= (throw (Exception. test))
java.lang.Exception: test (repl-1:2)

Thanks again,
- Mark

On Sun, Dec 21, 2008 at 3:47 PM, Stephen C. Gilardi  
squee...@mac.com wrote:

Hi Mark,

Thanks for your work on polishing up Clojure's entry point  
situation.


You're welcome. Thanks very much for the feedback.

I've applied your patch and tried a series of typical entry point
scenarios; all but one of them worked for me. Just for the record,
here is what did work:
- Using -h to get help
- Using no options to boot into a repl
- Running the repl with jLine
- Using - to read from stdin
- Running a script located based on a filesystem path
- Running a script located relative to classpath
- Using -i to load files before running a script
- Using set! in one of these init files
- Accessing *command-line-args* from a script

Excellent, that's some fine coverage. I appreciate it!

The one that didn't work was booting into a line-numbered repl,  
which

is the setup I use now with trunk Clojure and Clojure-Contrib:
java -cp clojure.jar:/Users/mmcgrana/Clojure/jars/clojure- 
contrib.jar

clojure.main -e (use 'clojure.contrib.repl-ln) -e (repl)

clojure.contrib.repl-ln will need an update if my patch is made  
part of
Clojure. I'm attaching the copy I'm currently using (which has not  
gone

through my usual pre-patch testing process, but is working for me.)
Please let me know whether it works for you.
Thanks!
--Steve







--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google  
Groups Clojure group.

To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---





smime.p7s
Description: S/MIME cryptographic signature


Re: SPARQL DSL - a humble request for review and guidance

2008-12-21 Thread Daniel E. Renfer

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 12/21/2008 12:03 PM, Adam Harrison (Clojure) wrote:
 
 Hi folks,
 
 First let me say 'Thankyou very much' for Clojure - it has enabled me to 
 finally take the plunge into learning a Lisp without feeling like I'm 
 abandoning a ten year investment in the Java platform and its libraries. 
 I bought 'Practical Common Lisp' about eighteen months ago and read it 
 half heartedly, never making it to a REPL; however I now have the luxury 
 of working on a project of my own and decided the time was right to 
 revisit the promised land of Lisp. I have been aware of Clojure for 
 about six months, and, given my experience of Java, it seemed like the 
 obvious place to start. I've spent the past couple of weeks devouring 
 lots of general Lisp related documentation, Rich's Clojure webcasts and 
 Stuart's 'Programming Clojure' book. I am pleased to report that my Lisp 
 epiphany occurred yesterday when I found I could understand this macro 
 pasted to lisp.org by Rich:
 
 (defmacro defnk [sym args  body]
  (let [[ps keys] (split-with (complement keyword?) args)
ks (apply array-map keys)
gkeys (gensym gkeys__)
letk (fn [[k v]]
   (let [kname (symbol (name k))]
 `(~kname (~gkeys ~k ~v]
`(defn ~sym [...@ps  k#]
   (let [~gkeys (apply hash-map k#)
 ~@(mapcat letk ks)]
 ~...@body
 
 I am now spoiled forever, and although my powers are weak, I realise I 
 have become one of those smug Lisp types condemned to look down on all 
 other programming languages for the rest of their lives. Thankyou's and 
 cliched tales of enlightenment dispensed with, I can now move on to the 
 plea for aid :)
 
 My current project involves semantic web technologies, at this point 
 specifically SPARQL queries over RDF triple stores (for those unfamiliar 
 with SPARQL it will suffice to say that it's a straightforward query 
 language modelled after SQL, but operating over graphs rather than 
 tables). Like their SQL counterpart, the Java APIs for performing these 
 queries are verbose and cumbersome, and I am hoping that they can be 
 hidden behind some cunning Lisp macros to provide an expressive and 
 tightly integrated semantic query capability (similar to Microsoft's 
 LINQ). Unfortunately my ambitions far exceed my skills at this point, 
 and I am hoping to garner some gentle mentoring to steer me in the right 
 direction from the outset.
 
 My first inclination is to start with the simplest thing which will 
 work, which is to create a function which takes a SPARQL query string as 
 an argument and returns a list of results:
 
 (sparql 
 PREFIX foaf: http://xmlns.com/foaf/0.1
 SELECT ?name
 WHERE
 {
?person foaf:mbox \mailto:adam-cloj...@antispin.org\; .
?person foaf:name ?name
 })
 
 However this style is poor for several reasons: it looks ugly, quotation 
 marks have to be escaped manually, and interpolation of variables into 
 the query string is a chore which further decreases readability. What I 
 really want is a nice DSL:
 
 (let [mbox mailto:adam-cloj...@atispin.org;]
  (sparql
(with-prefixes [foaf http://xmlns.com/foaf/0.1;]
  (select ?name
(where
  (?person foaf:mbox mbox)
  (?person foaf:name ?name)
 
 Clearly this is going to require a macro, because for a start I don't 
 want the symbols representing SPARQL capture variables (the ones 
 starting with '?') to be evaluated - I want to take the name of the 
 symbol, '?' and all, and embed it into the query string which this DSL 
 will ultimately generate before calling into the Java API. On the other 
 hand, I do want some things evaluated - I want to embed the value 
 ('mailto:adam-clog...@antispin.org') bound to the symbol 'mbox' in the 
 query string, not the name of the symbol.
 
  From my position of total ignorance, I can see two broad approaches to 
 tackling this. The first is to implement (sparql ...) as a macro which 
 is responsible for interpreting the entire subtree of forms below it, 
 building a query string by selectively evaluating some forms whilst 
 using others as navigational markers which give context. It would honour 
 the grammar which defines SPARQL queries, and either signal an error or 
 be guaranteed to generate syntactically correct queries. The macro would 
 also have insight into the format of the data which would be returned 
 (gleaned from the 'select' part) and so could return something useful 
 like a list of maps where the keys are the names of the capture 
 variables that appear in the select clause. I have no idea how to do 
 this, but it feels like the 'right' way.
 
 The other approach, which is IMO a bit hacky, but within my reach, is to 
 define 'with-prefixes', 'select' and 'where' as individual macros whose 
 first arguments are expanded into the relevant subcomponent of the query 
 string and whose final argument is a string to be appended to the end. 
 

Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Rich Hickey

If main doesn't match the behavior of Repl and Script in this area  
when run in repl or script modes respectively, it needs to.  Repl  
calls exit, Script does not.

Rich

On Dec 21, 2008, at 4:30 PM, Stephen C. Gilardi wrote:

 Based on the bottom of the ruby code example on this page:

 http://rjack.rubyforge.org/jetty/classes/Jetty/ServerFactory.html

 A first guess is that this would work:

   (.start server)
   (.join server)

 Join will wait for the thread to exit before continuing. That code  
 makes sense if server is an instance of Thread.

 --Steve

 On Dec 21, 2008, at 4:16 PM, Mark McGranaghan wrote:


 I have another quick observation:

 The (System/exit 0) bit at the end of the main function changes the
 behavior of some scripts I have for starting Jetty servers. The
 scripts basically end with (.start server), were server is a Jetty
 Server instance, and previously would run until control-C'd from the
 command line. I see in the linked thread above that this change in
 behavior is required by other aspects of Clojure, which makes senes  
 to
 me. Do you know of any straiforward change I could make to these
 scripts to keep the servers running? Perhaps this is a matter of the
 Jetty APIs and not Clojure.

 I'm not using Compujre here, but looking quickly at Compojure it  
 seems
 like it uses (.start server) as well from scripts.

 - Mark

 On Sun, Dec 21, 2008 at 3:59 PM, Mark McGranaghan  
 mmcgr...@gmail.com wrote:
 Steve,

 Your version of repl_ln.clj works for me:

 1:1 user= (+ 1 2)
 3
 1:2 user= (throw (Exception. test))
 java.lang.Exception: test (repl-1:2)

 Thanks again,
 - Mark

 On Sun, Dec 21, 2008 at 3:47 PM, Stephen C. Gilardi squee...@mac.com 
  wrote:
 Hi Mark,

 Thanks for your work on polishing up Clojure's entry point  
 situation.

 You're welcome. Thanks very much for the feedback.

 I've applied your patch and tried a series of typical entry point
 scenarios; all but one of them worked for me. Just for the record,
 here is what did work:
 - Using -h to get help
 - Using no options to boot into a repl
 - Running the repl with jLine
 - Using - to read from stdin
 - Running a script located based on a filesystem path
 - Running a script located relative to classpath
 - Using -i to load files before running a script
 - Using set! in one of these init files
 - Accessing *command-line-args* from a script

 Excellent, that's some fine coverage. I appreciate it!

 The one that didn't work was booting into a line-numbered repl,  
 which
 is the setup I use now with trunk Clojure and Clojure-Contrib:
 java -cp clojure.jar:/Users/mmcgrana/Clojure/jars/clojure- 
 contrib.jar
 clojure.main -e (use 'clojure.contrib.repl-ln) -e (repl)

 clojure.contrib.repl-ln will need an update if my patch is made  
 part of
 Clojure. I'm attaching the copy I'm currently using (which has  
 not gone
 through my usual pre-patch testing process, but is working for me.)
 Please let me know whether it works for you.
 Thanks!
 --Steve





 



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



Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Stephen C. Gilardi


On Dec 21, 2008, at 4:40 PM, Rich Hickey wrote:


If main doesn't match the behavior of Repl and Script in this area
when run in repl or script modes respectively, it needs to.  Repl
calls exit, Script does not.


OK, I'll fix that.

--Steve



smime.p7s
Description: S/MIME cryptographic signature


namespace function

2008-12-21 Thread Mark Volkmann

Why do I get an IncompatibleClassChangeError below?  I'm using revision 1180.

(def my-map {:a 1 :b 2})
(namespace my-map)
java.lang.IncompatibleClassChangeError (NO_SOURCE_FILE:0)

-- 
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
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: namespace function

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 13:35, Mark Volkmann wrote:
 Why do I get an IncompatibleClassChangeError below?  I'm using
 revision 1180.

 (def my-map {:a 1 :b 2})
 (namespace my-map)
 java.lang.IncompatibleClassChangeError (NO_SOURCE_FILE:0)

I'm not sure about that specific error, though I've seen it several 
times myself.

However, asking for the namespace of a map is nonsensical. Perhaps you 
want to know the namespace of the Var associated with my-map?

user= ^#'my-map
{:ns #Namespace user, :name my-map, :file repl-1, :line 17}


Randall Schulz

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



Re: Lazy inconsistency between map and mapcat; lazy concatenation

2008-12-21 Thread Jason

Also, on a related note, lazy-cat always evaluates its first argument:

user (do (lazy-cat (do (prn 1) (list 1)) nil) nil)
1
nil
user (do (lazy-cons (do (prn 1) (list 1)) nil) nil)
nil

which is confusing given its documentation:

user (doc lazy-cat)
-
clojure.core/lazy-cat
([coll] [coll  colls])
Macro
  Expands to code which yields a lazy sequence of the concatenation
  of the supplied colls.  Each coll expr is not evaluated until it is
  needed.

If this is the desired behavior, the docs should probably be updated
to explain that the first coll is always needed right away.  If so,
I'm also curious why this is the case.

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



Re: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar

2008-12-21 Thread Stephen C. Gilardi

On Dec 21, 2008, at 4:43 PM, Stephen C. Gilardi wrote:

On Dec 21, 2008, at 4:40 PM, Rich Hickey wrote:

If main doesn't match the behavior of Repl and Script in this area
when run in repl or script modes respectively, it needs to.  Repl
calls exit, Script does not.


OK, I'll fix that.


This is fixed in the enclosed unified-main-3.patch .

--Steve



unified-main-3.patch
Description: Binary data






smime.p7s
Description: S/MIME cryptographic signature


Re: SPARQL DSL - a humble request for review and guidance

2008-12-21 Thread Brian Sletten

Adam, I just joined the list, but I am very interested in working with  
you on the SPARQL DSL. Let me catch up on what you've written and  
we'll muddle through it together.

Glad to see there are other Clojure-loving SemWeb nerds around here. :)

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



bit-and, bit-or arity question

2008-12-21 Thread ntu...@googlemail.com

Why do bit-or and bit-and only accept 2 arguments? or and and
accept an arbitrary number and I think it is useful to modifiy bit-
or and bit-and to accept 2 or more, for example:

(defn my-bit-or [x y  rest]
  (reduce #(clojure.lang.Numbers/or %1 %2) (list* x y rest)))

What does the group 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
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: SPARQL DSL - a humble request for review and guidance

2008-12-21 Thread Michael Wood

On Sun, Dec 21, 2008 at 7:03 PM, Adam Harrison (Clojure)
adam-cloj...@antispin.org wrote:
[...]
 (defmacro where [ triples]
 `(let [encode# (fn [x#] (cond (and (symbol? x#) (= (first (name x#))
 \?)) (name x#)
  (integer? x#) (str \ x# \^^xsd:integer)
  (float? x#) (str \ x# \^^xsd:decimal)
  (string? x#) (str \ x# \)))]
  (apply str
   (interpose  .\n
 (for [triple# '~triples]
   (apply str
 (interpose  
   (map encode# triple#

 As you can see, so far it correctly encodes SPARQL capture variables,
 and literal strings, integers and floats:

 user= (print (where (?a ?b 1) (?a ?b 2.0) (?a ?b string)))
 ?a ?b 1^^xsd:integer .
 ?a ?b 2.0^^xsd:decimal .
 ?a ?b string

 I tried adding '(list? x#) (eval x#)' to the encode cond to make it cope
 with expressions like this:

 (where (?a ?b (+ 1 2)))

 Unfortunately that results in an unencoded literal '3' in the query
 string instead of the '3^^xsd:integer' I was looking for. I tried

Here's my poor excuse for a nudge in what may or may not be the right direction:

user= (defn encode-symbol [x] (if (= (first (name x))) (name x)))
#'user/encode-symbol
user= (defn encode-other [x]
 (cond (integer? x) (str \ x \ ^^xsd:integer)
   (float? x) (str \ x \ ^^xsd:decimal)
   (string? x) (str \ x \)))
#'user/encode-other
user= (defmacro encode [x]
 (if (symbol? x)
  (encode-symbol x)
  `(encode-other ~x)))
nil
user= (encode ?a)
?a
user= (encode 1)
\1\^^xsd:integer
user= (encode 2.0)
\2.0\^^xsd:decimal
user= (encode string)
\string\
user= (encode (+ 1 2))
\3\^^xsd:integer
user=

(Disclaimer: I don't know what I am doing, but this at least seems to work.)

-- 
Michael Wood esiot...@gmail.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
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: bit-and, bit-or arity question

2008-12-21 Thread Randall R Schulz

On Sunday 21 December 2008 15:14, ntu...@googlemail.com wrote:
 Why do bit-or and bit-and only accept 2 arguments? or and and
 accept an arbitrary number and I think it is useful to modifiy bit-
 or and bit-and to accept 2 or more, for example:

 (defn my-bit-or [x y  rest]
   (reduce #(clojure.lang.Numbers/or %1 %2) (list* x y rest)))

 What does the group think?

The group thinks only in group-think, and hence is meaningless...

But I (the individual) agree, modulo a proper overloading pattern to 
afford minimal overhead for the two-argument form.


RRS

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



Curiosity: why doesn't (count (doall (range 1000000000))) exhaust memory?

2008-12-21 Thread Jason

Yet another question, this time just a curiosity.  Sorry for the
plethora of posts, but I'm trying to make sure I understand lazy seqs
properly.

Why doesn't (count (doall (range 100))) cause an out-of memory
error?  doall says it causes the entire seq to reside in memory at one
time, yet:

user (count (range 1))  ; uses no memory, as expected
1
user (count (doall (range 1))) ; still uses no memory!?
1
user (count (doall (range 5))) ; even bigger, still no heap
growth
5
user (count (doall (map identity (range 1 ; now as
expected
; Out of memory

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



Re: Curiosity: why doesn't (count (doall (range 1000000000))) exhaust memory?

2008-12-21 Thread Stephen C. Gilardi


On Dec 21, 2008, at 6:44 PM, Jason wrote:


Why doesn't (count (doall (range 100))) cause an out-of memory
error?  doall says it causes the entire seq to reside in memory at one
time, yet:


(range n) produces an object that is a seq, not just one that's seq- 
able. Its rest operation is not implemented using lazy-cons, instead  
it returns an object that implements the rest seq in a self-contained  
way: a Range object that starts one increment higher. (see  
clojure.lang.Range, implementation of first and rest)


Holding onto the head in this case, does not keep a realized chain of  
objects in memory. Instead it holds the first one only. Subsequent  
rests are generated one by one during the doall and then discarded.


Your map example turns this into a chain of lazy-cons objects with the  
associated much greater memory use.


The doc for doall should probably be updated to say something along  
the lines of it may cause the sequence to reside in memory all at  
once.


--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: How to encapsulate local state in closures

2008-12-21 Thread Brian Doyle
I haven't been following the new atom stuff, so I was wondering why atom
would be best in this
situation, vs a ref?  Thanks.

On Sun, Dec 21, 2008 at 1:03 PM, Parth Malwankar
parth.malwan...@gmail.comwrote:




 On Dec 21, 11:47 pm, chris cnuern...@gmail.com wrote:
  I would like to be able to encapsulate local state in a closure.
  Specifically, I would like a function that returns an incrementing
  integer, thus:
  (test_func)
  1
  (test_func)
  2
  What is the best way to go about this?  With local bindings is failing
  and I can't figure just why...
 

 One way to do this would be to use atom.

 (defn mk-counter [start]
  (let [n (atom start)]
(fn [] (swap! n inc

 (def counter (mk-counter 0))

 user= (counter)
 1
 user= (counter)
 2
 user= (counter)
 3

 Parth
  (def test_closure
 (with-local-vars [one 1]
   (fn [] (var-get one
  #'user/test_closure
  user (test_closure)
  ; Evaluation aborted.
  The var is null when I call the closure.
 
  Thanks,
  Chris
 


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



Re: How to encapsulate local state in closures

2008-12-21 Thread Mark Engelberg

But if mk-counter is called twice because it's retried in part of a
transaction, then you're in big trouble when you use atom.  Better to
use a ref here.  atom needs to be reserved for the very few cases when
retries don't matter (like a cache).

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



Re: How to encapsulate local state in closures

2008-12-21 Thread Stephen C. Gilardi


On Dec 21, 2008, at 7:24 PM, Brian Doyle wrote:

I haven't been following the new atom stuff, so I was wondering why  
atom would be best in this

situation, vs a ref?  Thanks.



The implementation of atoms is supported by the JVM typically using a  
processor hardware instruction that accomplishes thread safety for a  
single location in a very focused, fast way.


From http://clojure.org/atoms :

Atoms are an efficient way to represent some state that will never  
need to be coordinated with any other, and for which you wish to make  
synchronous changes (unlike agents, which are similarly independent  
but asynchronous).


See also: http://www.ibm.com/developerworks/java/library/j-jtp11234/

--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: How to encapsulate local state in closures

2008-12-21 Thread Parth Malwankar



On Dec 22, 5:24 am, Brian Doyle brianpdo...@gmail.com wrote:
 I haven't been following the new atom stuff, so I was wondering why atom
 would be best in this
 situation, vs a ref?  Thanks.

Rich discusses the use of atoms, refs and agents in good detail
in this thread:
http://groups.google.com/group/clojure/msg/fd0371eb7238e933

In case you don't want multiple counters but just one,
the following can also be done.

user= (let [n (atom 0)] (defn counter [] (swap! n inc)))
#'user/counter
user= (counter)
1
user= (counter)
2
user= (counter)
3

Parth



 On Sun, Dec 21, 2008 at 1:03 PM, Parth Malwankar
 parth.malwan...@gmail.comwrote:



  On Dec 21, 11:47 pm, chris cnuern...@gmail.com wrote:
   I would like to be able to encapsulate local state in a closure.
   Specifically, I would like a function that returns an incrementing
   integer, thus:
   (test_func)
   1
   (test_func)
   2
   What is the best way to go about this?  With local bindings is failing
   and I can't figure just why...

  One way to do this would be to use atom.

  (defn mk-counter [start]
   (let [n (atom start)]
     (fn [] (swap! n inc

  (def counter (mk-counter 0))

  user= (counter)
  1
  user= (counter)
  2
  user= (counter)
  3

  Parth
   (def test_closure
              (with-local-vars [one 1]
                (fn [] (var-get one
   #'user/test_closure
   user (test_closure)
   ; Evaluation aborted.
   The var is null when I call the closure.

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



Re: How to encapsulate local state in closures

2008-12-21 Thread Parth Malwankar



On Dec 22, 5:45 am, Mark Engelberg mark.engelb...@gmail.com wrote:
 But if mk-counter is called twice because it's retried in part of a
 transaction, then you're in big trouble when you use atom.  Better to
 use a ref here.  atom needs to be reserved for the very few cases when
 retries don't matter (like a cache).

If I understand it right, as long as the counter is used
within a single thread and not across threads there shouldn't
be any issues. Same as a cache.

If the idea is to use one counter across multiple threads
then refs can be used.

I don't think I follow why mk-counter would be retried. There
is not reason for it to fail as it simply creates a new counter
and returns it and doesn't need to block or be blocked.

Parth



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



Re: How to encapsulate local state in closures

2008-12-21 Thread Mark Engelberg

I misspoke; it's the call to counter that's the problem.  Let's say
you want to use a counter to count the number of times a ref is set,
something like this:

(dosync (counter) (ref-set r 1))

If your var-set causes the transaction to retry, an atom-based counter
will increment twice.  As I understand it, atoms are one of the most
dangerous things in Clojure, and should be avoided unless you're
completely sure it will not change the semantics of your program if it
gets executed multiple times.  Aside from the memoization example for
which it was invented, I am hard-pressed to think of a good use for
atoms.  For something like a counter, you really have to use ref, and
that should remain people's default when dealing with mutability.

I haven't done much with atoms yet, so if I've misunderstood Rich's
posts, feel free to explain my mistake.

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



A Common Lisp format function for Clojure now up

2008-12-21 Thread Tom Faulhaber

Good Evening Clojurians,

I have been working on a Clojure implementation of the format function
from Common Lisp and it's coming along well enough that I thought I'd
share.

You can see/download the current state of it in its github project:
http://github.com/tomfaulhaber/cl-format/

It's currently about 2/3 complete including iteration, conditionals,
and floating point in all their various flavors. I'm finding that it's
already a lot more useful than the Java format, but that might just be
my bias :-). The README on github has a detailed implementation status
that I keep up-to-date.

If you don't know about Common Lisp's super-powerful format function,
you can check it out here, in Practical Common Lisp,
http://www.gigamonkeys.com/book/a-few-format-recipes.html or here, in
Common Lisp the Language,
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/clm/node200.html.

I'm definitely interested in feedback on it in terms of style, on what
you're using it for, and on what features you'd like to see next. I
also want to hear about bugs. I'm sure there are plenty!

You can add feedback here, via github or find me as replaca on
#clojure.

Enjoy!

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



Re: December monads

2008-12-21 Thread Konrad Hinsen

On 20.12.2008, at 22:50, jim wrote:

 I also think this would be a great addition to clojure-contrib.

Me too. But who decides what goes into clojure-contrib? Rich?

 Because of the way most monad tutorials are written, monads seem to be
 pretty hard to get your head around.  Also, many of the reasons for
 the standard monads in Haskell don't exist in impure functional
 languages like Clojure.  So there's less motivation to understand
 them.  But I found that once I understood them, they are a powerful
 addition to my conceptual toolbox.

I agree. I see monads as the functional equivalent to aspect-oriented  
programming: a way to implement separation of concerns.

I also think that some aspects of monads are clearer in Clojure than  
they are in Haskell. Haskell's way to implement monads as data types  
has some practical advantages, but it also obscures the algorithmic  
nature of monads a bit. Moreover, it makes some things impossible,  
for example executing a single piece of code under different monads  
(easy in Clojure by having the monad as a variable), which is quite  
handy sometimes, e.g. for debugging. I also prefer monad transformers  
implemented as functions to monad transformers implemented as pretty  
complicated abstract data types with boilerplate code to get data in  
and out. In the long run, we should have a monad tutorial for  
Clojure, rather then let everyone learn Haskell first.

Konrad.




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