prog1

2008-11-08 Thread Phlex

Hello,

I was missing the prog1 macro from common lisp, so here it is.

(defmacro prog1 [ body]
   (prog1 forms*)
Evaluates all the forms, returning the result of the first form
  `(let [result# ~(first body)]
 ~@(rest body)
 result#))

user (prog1 a b c)
a
user (prog1)
nil
user (prog1 a)
a

Might be usefull to have this in the language. Maybe it's already there 
but couldn't find it !

Sacha

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Patch and audit: Use vectors for bindings in doseq, et al.

2008-11-08 Thread Rich Hickey



On Nov 8, 8:52 am, Chouser [EMAIL PROTECTED] wrote:
 Attached is an updated patch. Instead of using for in the
 implementation of doseq, this has a doseq that uses loop/recure.
 The interface is the same, but it should run faster.  This also means
 doseq is only defined once (nor redefined as in the earlier patch).

 This patch is against 1089, the Interim checkin - DO NOT USE!! version of 
 SVN.


Patch applied - many thanks!!

Rich


 On Sat, Nov 8, 2008 at 7:42 AM, Rich Hickey [EMAIL PROTECTED] wrote:

  On Nov 7, 5:09 pm, James Reeves [EMAIL PROTECTED] wrote:
  On Nov 7, 9:32 pm, Chouser [EMAIL PROTECTED] wrote:

And in which case, your vector syntax could be misleading, because it
seems to imply you're assigning i to 10:

(dotimes [i 10]
 (prn i))

   Vectors are also used for for:

   (for [i (range 10)]
 (* 2 i))

   Here i is not bound to the seq (range 10) but to each of the numbers
   in turn.

  I'm still not convinced on this one. Currently, you have single
  assignments, where a value is assigned to a symbol as in let and
  binding, and sequence assignments, where each item in the sequence is
  assigned to a symbol. Adding a vector to dotimes would add a third
  type, and I don't think it's obvious what the [i 10] does. I mean, you
  originally put it down as [i (range 10)], so you were thinking in
  terms of [symbol sequence] too.

  The general idea behind this patch is that all macros that introduce
  names will do so in vector syntax. The nature of the bindings is going
  to be open, as is the set of macros - doseq/dotimes/let/loop all have
  different semantics. As it stands, it is confusing for people because
  they don't know if they need a vector or not, for each macro.

Second, with your patch, is the following valid:

(doseq [i (range 10)
   j (range 10)]
 (prn i)
 (prn j))

   It behaves the same as for does, that is with j in an inner loop.
   It also supports :while and :when as for does.

  Well, not that my opinion matters ;) - but you've sold me on this one.
  Consistency with the for macro seems reasonable.

  This is a much-needed enhancement, as so many people use for for side-
  effects and forget dorun. Plus it will be faster for that use.

   My first inclination is to disallow it -- add a check to make sure
   only one binding pair is given.  Alternatively it could act as if it
   were nested, as for (and now doseq) do, in which case it would act
   like an and, and both x and y would be bound to non-false values.

  Hm. A nested if would be consistent with the nested for and doseq
  macros. If this is implemented, nesting ifs would be my preference for
  this.

  I'd like to see this patch limit its enhancements to doseq a la for,
  and otherwise just be a syntax change for all the others.

  Rich



  doseq-vector-2.patch
 27KViewDownload
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Patch and audit: Use vectors for bindings in doseq, et al.

2008-11-08 Thread Rich Hickey



On Nov 7, 5:09 pm, James Reeves [EMAIL PROTECTED] wrote:
 On Nov 7, 9:32 pm, Chouser [EMAIL PROTECTED] wrote:

   And in which case, your vector syntax could be misleading, because it
   seems to imply you're assigning i to 10:

   (dotimes [i 10]
(prn i))

  Vectors are also used for for:

  (for [i (range 10)]
(* 2 i))

  Here i is not bound to the seq (range 10) but to each of the numbers
  in turn.

 I'm still not convinced on this one. Currently, you have single
 assignments, where a value is assigned to a symbol as in let and
 binding, and sequence assignments, where each item in the sequence is
 assigned to a symbol. Adding a vector to dotimes would add a third
 type, and I don't think it's obvious what the [i 10] does. I mean, you
 originally put it down as [i (range 10)], so you were thinking in
 terms of [symbol sequence] too.


The general idea behind this patch is that all macros that introduce
names will do so in vector syntax. The nature of the bindings is going
to be open, as is the set of macros - doseq/dotimes/let/loop all have
different semantics. As it stands, it is confusing for people because
they don't know if they need a vector or not, for each macro.

   Second, with your patch, is the following valid:

   (doseq [i (range 10)
  j (range 10)]
(prn i)
(prn j))

  It behaves the same as for does, that is with j in an inner loop.
  It also supports :while and :when as for does.

 Well, not that my opinion matters ;) - but you've sold me on this one.
 Consistency with the for macro seems reasonable.


This is a much-needed enhancement, as so many people use for for side-
effects and forget dorun. Plus it will be faster for that use.

  My first inclination is to disallow it -- add a check to make sure
  only one binding pair is given.  Alternatively it could act as if it
  were nested, as for (and now doseq) do, in which case it would act
  like an and, and both x and y would be bound to non-false values.

 Hm. A nested if would be consistent with the nested for and doseq
 macros. If this is implemented, nesting ifs would be my preference for
 this.


I'd like to see this patch limit its enhancements to doseq a la for,
and otherwise just be a syntax change for all the others.

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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Robert Pfeiffer

Hello,

Is there a benefit in implementing this as a macro instead of a
function? The function version would be very simple:

(defn returning [returnval  body]
   returnval)

This is just a K combinator with varargs.

Robert Pfeiffer
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



doseq, dotimes loop/recur

2008-11-08 Thread verec

More of an inquiry into the fp mindset as opposed to the procedural
one than anything else ...

If I got this right, there are two forms of iterations: internal and
external.
`map' is an internal iterator, `doseq' is an external iterator.

An internal iterator does the iteration by itself and applies some
provided fn to the collection, possibly resulting into some new
collection.

An external iterator provides you with the closest access to the
collection, allowing you to decide for yourself what you want to do
inline on an element by element basis, possibly deciding on a course
of actions depending on the values seen so far, which would be more
difficult to do with an internal iterator such as `map', because the
fn would need to be passed those previous values of interest as
arguments each time.

Now, if I summarize the set of clojure provided iterations forms I get
the internal ones such as `map' or 'reduce', the external ones such as
`doseq' or `dotimes', plus, via loop/recur the means by which to
implement my own internal iterators in the `map'/`reduce' vein.

The question then is: is this all there is to iteration? And if any
external iterator beyond `doseq' and `dotimes` is missing, what would
they be?
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Stephen C. Gilardi


On Nov 8, 2008, at 5:55 AM, Phlex wrote:

 Hello,

 I was missing the prog1 macro from common lisp, so here it is.

 (defmacro prog1 [ body]
   (prog1 forms*)
 Evaluates all the forms, returning the result of the first form
  `(let [result# ~(first body)]
 ~@(rest body)
 result#))

 user (prog1 a b c)
 a
 user (prog1)
 nil
 user (prog1 a)
 a

 Might be usefull to have this in the language. Maybe it's already  
 there
 but couldn't find it !

I came across a place where it would be useful as well, but worked  
around it manually. do1 would arguably fit better into Clojure's  
naming scheme. I think none of prog1, prog2, or a hypothetical  
do1 have names that really jump out at a beginner with what they  
mean (though of course, one isn't a beginner forever).

A collection of some useful CL macros written in Clojure would  
probably make a nice addition to the wiki.

--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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Meikel Brandmeyer

Hi,

Am 08.11.2008 um 17:10 schrieb Robert Pfeiffer:

Is there a benefit in implementing this as a macro instead of a
function? The function version would be very simple:

(defn returning [returnval  body]
  returnval)


Although I'm a strong proponent of using macros only where they
are really needed, I would make an exception here. The function
might be simple and the use of a K combinator - whatever that is -
might be elegant, but it hides away the intent of the macro/function.
The macro expansion on the other hand is clear: evaluate the first
form, do the rest and return the first thing. The function call
hides away the do the rest step.

I apologise for being a peasant.

Sincerely
Meikel




smime.p7s
Description: S/MIME cryptographic signature


Re: prog1

2008-11-08 Thread Phlex


Robert Pfeiffer wrote:
 Hello,

 Is there a benefit in implementing this as a macro instead of a
 function? The function version would be very simple:

 (defn returning [returnval  body]
returnval)


   

Well no, the forms are evaluated. It's usefull for side effects.

user (def *bleh* (ref nil))
user (prog1
(dosync (ref-set *bleh* 3))
(println (str bleh is now  @*bleh*)))
bleh is now 3
3

A function would work :

(defn progz [return-value do-also-fn]
  (do-also-fn)
  return-value)

user (progz (+ 1 3)
(fn []
  (prn hello)
  (prn i'm evaluated)))
hello
i'm evaluated
4

But it's not as terse.

Sacha

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Print compiled Clojure svn revision?

2008-11-08 Thread Matt Revelle

If marking SVN revisions and/or release versions is something we still  
want and want automated, it now looks like using the build tool is the  
only way to go.  The example I sent earlier to the list includes the  
creation of a versioninfo file from the build script which is then  
read and stored in a version var in boot.clj.

The only problem is that the build script now depends on the  
svnversion command being available and a SVN repository being used  
for building.  For tarball releases of the source, the versioninfo  
file can be generated for the release and the build script modified to  
use the existing file if svnversion isn't working.  As for  
supporting git and other SCMs used to mirror the SVN repos, the build  
script can be made to use the tools available in any of the other SCMs  
to identify the SVN revision and generate the versioninfo file.

Or have we decided this isn't worth it?

-Matt

On Nov 7, 2008, at 2:41 PM, Mike Hinchey wrote:


 Haven't we been through this before?
 http://groups.google.com/group/clojure/browse_thread/thread/1ae7eae292765d40/f49c4ccdaca67a23

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Meikel Brandmeyer

Hi,

Am 08.11.2008 um 17:39 schrieb Meikel Brandmeyer:

(defn returning [returnval  body]
 returnval)


And another question, which a I got when I read the
mail of Phlex: Is the order of evaluation of function
arguments guaranteed to be from the left to the right?

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: prog1

2008-11-08 Thread Meikel Brandmeyer

Hi,

Am 08.11.2008 um 17:58 schrieb Randall R Schulz:

Peasant? Or did you mean pedant?


In german there is the word Banause which translates
according the dictionary to peasant. It means something
like the following:

Artist:  Oh! Look this beautiful picture! It's art!
Banause: It's just a blob of blue color.

Sincerely
Meikel




smime.p7s
Description: S/MIME cryptographic signature


Re: prog1

2008-11-08 Thread Randall R Schulz

On Saturday 08 November 2008 08:39, Meikel Brandmeyer wrote:
 Hi,

 Am 08.11.2008 um 17:10 schrieb Robert Pfeiffer:
  Is there a benefit in implementing this as a macro instead of a
  function? The function version would be very simple:
 
  (defn returning [returnval  body]
returnval)

 Although I'm a strong proponent of using macros only where they
 are really needed, I would make an exception here. The function
 might be simple and the use of a K combinator - whatever that is -
 might be elegant, but it hides away the intent of the macro/function.
 The macro expansion on the other hand is clear: evaluate the first
 form, do the rest and return the first thing. The function call
 hides away the do the rest step.

 I apologise for being a peasant.

Peasant? Or did you mean pedant?


 Sincerely
 Meikel


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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: doseq, dotimes loop/recur

2008-11-08 Thread Graham Fawcett

Hi,

On Sat, Nov 8, 2008 at 11:20 AM, verec
[EMAIL PROTECTED] wrote:

 More of an inquiry into the fp mindset as opposed to the procedural
 one than anything else ...

 If I got this right, there are two forms of iterations: internal and
 external.
 `map' is an internal iterator, `doseq' is an external iterator.

I see where you're going there, but I wouldn't put too fine a point on
the distinction between internal and external. Really they're just
different syntax for expressing the same thing.

The intention behind the do forms isn't about externality but
evaluation strategy. As you know, sequences in Clojure are lazy. The
do forms force evaluation of a sequence's elements to be done
immediately, rather than lazily as needed. A common reason you'd want
to do that is because your do-expression has side-effects (I/O) and
you want the effects to happen now rather than spread out across a
set of future time points (or possibly not at all, if the sequence is
never evaluated to its end).

Ignoring laziness for a moment, all of these iteration constructs can
be expressed in terms of loop/recur, since any iteration form can be
expressed in terms of recursion. They can also be built up from
reduce, which is a form called a fold in other functional languages,
and is the internal equivalent of loop/recur, to borrow your
terminology. Using (doall) in conjunction with either of these would
let you express the non-lazy do forms.

The benefit of map, reduce, filter isn't that they are inherently
different from loop/recur, but that they concisely express a notion of
transforming one sequence into another using a transformation
function. If the expression you're trying to build up naturally fits
that pattern, then map, reduce, filter are a good fit. (Note, reduce
is more general than map/filter, in that it can transform a sequence
into something other than another sequence.)

Since reduce is the internal equivalent to loop/recur, you might
consider writing some expressions in both styles until the equivalence
makes sense. For example, here are two simple functions described
using loop and reduce.

(defn add-up [numbers]
  (loop [nums numbers accumulator 0]
(if (nil? nums)
accumulator
(recur (rest nums) (+ (first nums) accumulator)

(defn add-up-reducing [numbers]
  (reduce + 0 numbers))

(defn sum-and-product [numbers]
  (loop [nums numbers sum 0 product 1]
 (if (nil? nums)
 [sum product]
 (recur (rest nums)
(+ (first nums) sum)
(* (first nums) product)

(defn sum-and-product-reducing [numbers]
  (reduce (fn [[sum prod] frst] [(+ sum frst) (* prod frst)])
  [0 1]
  numbers))

In short, if you can figure out how to write your expression using
reduce rather than a loop, it can lead to more compact code. But more
complex reduce expressions can be hard to follow, and loop will make
for better readability.

Hope this helps,
Graham

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread André Thieme

On 8 Nov., 17:47, Phlex [EMAIL PROTECTED] wrote:
 Robert Pfeiffer wrote:
  Hello,

  Is there a benefit in implementing this as a macro instead of a
  function? The function version would be very simple:

  (defn returning [returnval  body]
     returnval)

 Well no, the forms are evaluated. It's usefull for side effects.

In what way would the forms *not* get evaluated when using
Roberts function returning?


 user (def *bleh* (ref nil))
 user (prog1
         (dosync (ref-set *bleh* 3))
         (println (str bleh is now  @*bleh*)))
 bleh is now 3
 3

user (def *bleh* (ref nil))
#=(var user/*bleh*)
user (returning
(dosync (ref-set *bleh* 3))
(println (str bleh is now  @*bleh*)))
bleh is now 3
3


 A function would work :

 (defn progz [return-value do-also-fn]
   (do-also-fn)
   return-value)

Your function only takes two arguments.
Roberts took an arbitrary number of them.


 user (progz (+ 1 3)
         (fn []
           (prn hello)
           (prn i'm evaluated)))
 hello
 i'm evaluated
 4

 But it's not as terse.

But this is:
user (returning (+ 1 3)
(prn Hello)
(prn I'm evaluated))
Hello
I'm evaluated
4


Macros are much less often needed in a functional language
which also comes with syntactic suger for (λ [args] ...) in form
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread André Thieme

On 8 Nov., 18:32, Meikel Brandmeyer [EMAIL PROTECTED] wrote:
 Hi,

 Am 08.11.2008 um 17:58 schrieb Randall R Schulz:

  Peasant? Or did you mean pedant?

 In german there is the word Banause which translates
 according the dictionary to peasant. It means something
 like the following:

The german word “Banause” is “Philistine” in english.
What you said is, that you are sorry for being a Bauer :-)
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread André Thieme

On 8 Nov., 18:00, Meikel Brandmeyer [EMAIL PROTECTED] wrote:
 Hi,

 Am 08.11.2008 um 17:39 schrieb Meikel Brandmeyer:

  (defn returning [returnval  body]
   returnval)

 And another question, which a I got when I read the
 mail of Phlex: Is the order of evaluation of function
 arguments guaranteed to be from the left to the right?

I am very sure that Clojure guarantees this.
In a pure functional language (like Haskell) this has not
to be the case. As there are no side effects it absolutely
does not matter at all in what order anything is evaluated.
But Clojure is a functional and imperative language, and
for running Java we need this guarantee.

At a first glance I see no need for implementing that in
the core language, and also not as a macro.
This can easily be implemented as a function, as Robert
demonstrated.
I also don’t see how the function hides the “do the rest”
part. Maybe returning is not the best name, but how would
we benefit of a macro, which is more complicated and also
is not first class and can’t be passed around?
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Randall R Schulz

On Saturday 08 November 2008 10:44, André Thieme wrote:
 On 8 Nov., 18:32, Meikel Brandmeyer [EMAIL PROTECTED] wrote:
  Hi,
 
  Am 08.11.2008 um 17:58 schrieb Randall R Schulz:
   Peasant? Or did you mean pedant?
 
  In german there is the word Banause which translates
  according the dictionary to peasant. It means something
  like the following:

 The german word “Banause” is “Philistine” in english.
 What you said is, that you are sorry for being a Bauer :-)

I tried to keep this off the list, but I have recent ancestors whose 
surname is Bauer, so tread carefully, please...


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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Phlex



André Thieme wrote:
 On 8 Nov., 17:47, Phlex [EMAIL PROTECTED] wrote:
   
 Robert Pfeiffer wrote:
 
 Is there a benefit in implementing this as a macro instead of a
 function? The function version would be very simple:
   
 (defn returning [returnval  body]
returnval)
   
 Well no, the forms are evaluated. It's usefull for side effects.
 

 In what way would the forms *not* get evaluated when using
 Roberts function returning?
   
Ah I guess you're right, either way it would be nice to have the 
functionality available in clojure.
There must be some reason for CL to have it as a macro 
(call-argument-limit perhaps ?)
Also there's not function call overhead with a macro. Though that should 
not be a concern.
 Macros are much less often needed in a functional language
 which also comes with syntactic suger for (λ [args] ...) in form
 of #(...).
   
ahwell that's a debate... sure you can do much with lambdas. Some would 
say that's a leaking abstraction.
I often implement some functionality as a higher order function, then 
wrap it around in a macro.
Like a do-trie macro around a map-trie function. it's just prettier !

Sacha


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: prog1

2008-11-08 Thread Michael Wood

On Sat, Nov 8, 2008 at 8:48 PM, André Thieme
[EMAIL PROTECTED] wrote:

 On 8 Nov., 18:00, Meikel Brandmeyer [EMAIL PROTECTED] wrote:
 Hi,

 Am 08.11.2008 um 17:39 schrieb Meikel Brandmeyer:

  (defn returning [returnval  body]
   returnval)
[...]
 I also don't see how the function hides the do the rest
 part. [...]

I agree that it's not obvious, but that's only because body makes no
difference whatsoever, unless it causes side effects.

-- 
Michael Wood [EMAIL PROTECTED]

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: doseq, dotimes loop/recur

2008-11-08 Thread verec

Hmmm.

Thank you for the post.

Questions of laziness apart, I know that recursion has been proven to
be equivalent to iterations (expect to weed out interview candidates,
as per Steve Yege's remarks :-)

But then why would we want any of `doseq', `dotimes' or `doall', and
if we do, is that set complete, and with respect to what design
principle?

For example, CL provides `do-symbols', `do-all-symbols' or `with-
package-iterator' as external iterators.

Clojure decided that anything that could be expressed as a `seq' could
be iterated over using `doseq', so I can express the equivalent of
CL's (do-symbols ...) using clojure (doseq [n all-ns] )

To rephrase the question differently, what could exist that is not a
clojure `seq' that we would want to iterate over?

Clojure already answers this (partially?) by providing (dotimes ...)
(as CL does) to iterate over a zero based consecutive and finite
sequence of numbers. Though the same (dotimes ...) could be _used_ to
iterate over any finite range)

What are the things that one could iterate over, for which clojure
does not, currently, provide special cases à la `doseq' or 'dotimes' ?

I can't think of any, but that's just my poor lack of imagination :-)

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



nth and take-nth argument order

2008-11-08 Thread Michael Wood

Is there any particular reason for the reversal of the order of
arguments between nth and take-nth?  I would have expected something
like:

clojure/nth
([n coll])

clojure/take-nth
([index coll]) ([index coll not-found])

or else:

clojure/nth
([coll n])

clojure/take-nth
([coll index]) ([coll index not-found])

-- 
Michael Wood [EMAIL PROTECTED]

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: nth and take-nth argument order

2008-11-08 Thread Rich Hickey



On Nov 8, 2:44 pm, Michael Wood [EMAIL PROTECTED] wrote:
 Is there any particular reason for the reversal of the order of
 arguments between nth and take-nth?

Short answer - take-nth is more like take.

Longer answer:

http://groups.google.com/group/clojure/browse_frm/thread/8b2c8dc96b39ddd7/a8866d34b601ff43

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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: doseq, dotimes loop/recur

2008-11-08 Thread Graham Fawcett

HI,

On Sat, Nov 8, 2008 at 2:39 PM, verec
[EMAIL PROTECTED] wrote:

 But then why would we want any of `doseq', `dotimes' or `doall', and
 if we do, is that set complete, and with respect to what design
 principle?

Well, given loop/recur as a fundamental iteration form, and doall as a
mechanism for forcing evaluation of the spine of a sequence, I'd say
that loop/recur + doall could be used to build all the other forms.

(I realize I mis-spoke in my earlier message by saying that loop/recur
and reduce could be equated. That's not true, since loop/recur allows
for short-circuiting, and does not require a sequence as one of its
arguments. So loop/recur is more general than reduce. Sorry about
that.)

I think we want a variety of forms for the same reason Common Lispers
want DOTIMES, LOOP, etc. -- pragmatism.

 For example, CL provides `do-symbols', `do-all-symbols' or `with-
 package-iterator' as external iterators.

 Clojure decided that anything that could be expressed as a `seq' could
 be iterated over using `doseq', so I can express the equivalent of
 CL's (do-symbols ...) using clojure (doseq [n all-ns] )

Yes, exactly -- abstract sequences are a super idea, and make a lot of
special-case procedures unnecessary.

 To rephrase the question differently, what could exist that is not a
 clojure `seq' that we would want to iterate over?

 Clojure already answers this (partially?) by providing (dotimes ...)
 (as CL does) to iterate over a zero based consecutive and finite
 sequence of numbers. Though the same (dotimes ...) could be _used_ to
 iterate over any finite range)

I'd argue that dotimes iterates, but doesn't iterate *over* anything
-- there's no Clojure sequence involved.

 What are the things that one could iterate over, for which clojure
 does not, currently, provide special cases à la `doseq' or 'dotimes' ?

Not special cases -- dotimes doesn't traverse a sequence, and doseq
can be thought of as a map that is evaluated immediately, for
side-effects, and which discards the result of the map. (Like for-each
in Scheme, compared with map in Scheme -- the former is for
side-effects, the latter to produce a transformed list.)

Clojure's concept of the 'seq' as the object of traversal, rather than
a literal type (list, vector, etc.) is its fundamental genius, IMHO.

Best,
Graham

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: nth and take-nth argument order

2008-11-08 Thread Michael Wood

On Sat, Nov 8, 2008 at 10:08 PM, Rich Hickey [EMAIL PROTECTED] wrote:

 On Nov 8, 2:44 pm, Michael Wood [EMAIL PROTECTED] wrote:
 Is there any particular reason for the reversal of the order of
 arguments between nth and take-nth?

 Short answer - take-nth is more like take.

 Longer answer:

 http://groups.google.com/group/clojure/browse_frm/thread/8b2c8dc96b39ddd7/a8866d34b601ff43

Ah, thanks.

-- 
Michael Wood [EMAIL PROTECTED]

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: doseq, dotimes loop/recur

2008-11-08 Thread Graham Fawcett

On Sat, Nov 8, 2008 at 4:23 PM, verec
[EMAIL PROTECTED] wrote:
 Everything that can be interpreted as a `seq', clojure's `doseq' takes
 care of it.

 What I am after are the special cases for things one could somehow
 enumerate but are not a `seq'.

 A number range is one such thing, and clojure provides 'dotimes' to
 handle this case.

 What could be the XYZ that are neither a `seq' nor a number range, for
 which we would want a `doXYZ' ?

 In other words, is the set `doseq', `dotimes' and `doall' complete,
 and if not, what is missing?

Of course, dotimes could be implemented in terms of doseq, e.g.

(dotimes i n ...)
(doseq i (take n (iterate inc 0)) ...)

so really there aren't any special cases in Clojure. I can't think of
anything that is sequence-like but couldn't be represented as a seq,
so I think the bases are covered. :-)

Best,
Graham

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



a macro question, this time completely specified :-)

2008-11-08 Thread Stuart Halloway

The defrunonce macro below works, creating a function that runs only  
once and tracking its run status in metadata.

Now, how do I write it without using eval?

(defn runonce
   Create a function that will only run once, given a function. Returns
   a vector containing the function and the reference that tracks  
whether
   the function has been run.
   [function]
   (let [has-run (ref false)]
 [(fn [ args]
(or @has-run
   ; TODO: think through semantics for parallel target invocation
   (do
 (apply function args)
 (dosync (ref-set has-run true)
  has-run]))

(defmacro defrunonce [sym doc  forms]
   Defines a function with runonce semantics. Curren run status
   is kept in a reference under the :has-run metadata key.
   (let [[function has-run] (runonce (eval (concat (list 'fn [])  
forms)))]
 `(def ~(with-meta sym {:has-run has-run}) ~function)))



--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: a macro question, this time completely specified :-)

2008-11-08 Thread Chouser

On Sat, Nov 8, 2008 at 10:23 PM, Stuart Halloway
[EMAIL PROTECTED] wrote:

 How about:

 (defn runonce
   Create a function that will only run its argument once.
   [function]
   (let [call-count (ref 0)]
 (fn [ args]
   (when (= 1 (dosync (alter call-count inc)))
 (apply function args)

Or:

(defn runonce
  Create a function that will only run its argument once.
  [function]
  (let [needed (java.util.concurrent.atomic.AtomicBoolean. true)]
(fn [ args]
  (when (.getAndSet needed false)
(apply function args)

--Chouser

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



Re: a macro question, this time completely specified :-)

2008-11-08 Thread Stephen C. Gilardi


On Nov 8, 2008, at 10:23 PM, Stuart Halloway wrote:


 How about:

 (defn runonce
   Create a function that will only run its argument once.
   [function]
   (let [call-count (ref 0)]
 (fn [ args]
   (when (= 1 (dosync (alter call-count inc)))
 (apply function args)

The counter occurred to me too. I don't think it's necessary though.  
What's important is that one thread know that it was the one that  
cause the false to true transition.

Regarding the value returned by dosync above, I'd believe it if  
someone told me that it could only return 1 to one thread, one time,  
guaranteed, but I've been wrong before in my reasoning about alter vs.  
commute regarding what's possible, so I'll have to give it more  
thought on correctness.

Here's perhaps a more basic one shot building block:

(defn once
   Returns a function that returns v the first time it's called and
   nil every time after that
   [v]
   (let [returned (ref false)]
 (fn []
   (dosync
(when-not (ensure returned)
  (ref-set returned true)
  v)

--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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: a macro question, this time completely specified :-)

2008-11-08 Thread Stuart Halloway

How about:

(defn runonce
   Create a function that will only run its argument once.
   [function]
   (let [call-count (ref 0)]
 (fn [ args]
   (when (= 1 (dosync (alter call-count inc)))
 (apply function args)


 On Nov 8, 2008, at 8:31 PM, Stuart Halloway wrote:


 The defrunonce macro below works, creating a function that runs only
 once and tracking its run status in metadata.

 Now, how do I write it without using eval?

 (defn runonce
  Create a function that will only run once, given a function.
 Returns
  a vector containing the function and the reference that tracks
 whether
  the function has been run.
  [function]
  (let [has-run (ref false)]
[(fn [ args]
   (or @has-run
 ; TODO: think through semantics for parallel target invocation
 (do
   (apply function args)
   (dosync (ref-set has-run true)
 has-run]))

 Since the deref of has-run is outside a transaction, I don't see
 anything here that prevents two threads from running function if
 they're trying to do it at roughly the same time.

 I think the following version accomplishes the core task of running
 just once and could be adapted to return the has-run ref as well:

 (defn runonce
   Create a function that will only run its argument once.
   [function]
   (let [has-run (ref false)]
 (fn [ args]
   (when
   (dosync
(ensure has-run)
(when-not @has-run
  (ref-set has-run true)))
 (apply function args)

 I'd appreciate seeing corrections or simplifications of it.

 --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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: a macro question, this time completely specified :-)

2008-11-08 Thread Chouser

On Sat, Nov 8, 2008 at 8:31 PM, Stuart Halloway
[EMAIL PROTECTED] wrote:

 (defmacro defrunonce [sym doc  forms]
   Defines a function with runonce semantics. Curren run status
   is kept in a reference under the :has-run metadata key.
   (let [[function has-run] (runonce (eval (concat (list 'fn [])
 forms)))]
 `(def ~(with-meta sym {:has-run has-run}) ~function)))

(defmacro defrunonce [sym doc  forms]
  Defines a function with runonce semantics. Curren run status
  is kept in a reference under the :has-run metadata key.
  (let [has-run (gensym)]
`(let [[function# ~has-run] (runonce (fn [] [EMAIL PROTECTED]))]
   (def ~(with-meta sym {:has-run has-run}) function#

--Chouser

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



Re: a macro question, this time completely specified :-)

2008-11-08 Thread Stephen C. Gilardi


On Nov 8, 2008, at 8:31 PM, Stuart Halloway wrote:


 The defrunonce macro below works, creating a function that runs only
 once and tracking its run status in metadata.

 Now, how do I write it without using eval?

 (defn runonce
   Create a function that will only run once, given a function.  
 Returns
   a vector containing the function and the reference that tracks
 whether
   the function has been run.
   [function]
   (let [has-run (ref false)]
 [(fn [ args]
(or @has-run
  ; TODO: think through semantics for parallel target invocation
  (do
(apply function args)
(dosync (ref-set has-run true)
  has-run]))

Since the deref of has-run is outside a transaction, I don't see  
anything here that prevents two threads from running function if  
they're trying to do it at roughly the same time.

I think the following version accomplishes the core task of running  
just once and could be adapted to return the has-run ref as well:

(defn runonce
   Create a function that will only run its argument once.
   [function]
   (let [has-run (ref false)]
 (fn [ args]
   (when
   (dosync
(ensure has-run)
(when-not @has-run
  (ref-set has-run true)))
 (apply function args)

I'd appreciate seeing corrections or simplifications of it.

--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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: (string?) bug

2008-11-08 Thread Luc Prefontaine
A StringBuilder is not a Java String... neither is it a
StringBuffer :)))

user= (string? (.toString (java.lang.StringBuilder. hello)))
true
user= 

because:

user= (.getClass (java.lang.StringBuilder. hello))
java.lang.StringBuilder

and

user= (.getClass (.toString (java.lang.StringBuilder. hello)))
java.lang.String

user= (.getClass ABCDE)
java.lang.String

Clojure uses Java String, not StringBuffer or StringBuilder as it's
String representation.

You can write your own predicate if you need one.

Luc



On Sat, 2008-11-08 at 23:07 -0700, Brian Doyle wrote:

 This seems like a bug returning false for StringBuilder.  
 
 user= (string? (new java.lang.String hello))
 true
 
 user= (string? (new java.lang.StringBuilder hello))
 false
 
 
  

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---