Re: Risks of (over-)using destructuring?

2009-07-25 Thread Laurent PETIT
Hi,

2009/7/25 jan 

>
> Laurent PETIT  writes:
>
> > 2009/7/24 pcda...@gmail.com 
> >
> > On Jul 23, 10:15 pm, Richard Newman  wrote:
> > > > Coming from an OO background which puts a strong focus on data
> > > > encapsulation,
> > > > this makes me a little nervous.
> > >
> > > The same problem exists with OO.
> >
> > Not to the same extent, unless you expose all the internals of your
> > classes (including fields) as public.
> >
> >
> > Java tries hard to hide the detail, yes, but it's still possible to use
> > reflection.
> > So it's just (as you stated) a fact of making it easy or difficult.
> >
> > But you should consider that everything you cannot find in the (doc) of
> > functions is not public API.
>
> While I agree with what you say, I have a couple of problems with
> relying on doc strings to document private fields. Firstly, I don't
> write docs while prototyping. Secondly, docs aren't visible when
> browsing code.


It's not just about map keys one should -or should not- considere as public
API. It's, more generally, about the detail of the structures passed to
functions or returned from functions.
Trying to do some introspection into the structure (even as simple as a
hash-map) seems to me already like the first step of breaking encapsulation
in java by using the reflective APIs.




>
> I've been using the convention of naming private fields with a
> trailing hyphen: {:foo "public" :bar- "private"}
>
> Here's a patch that adds syntax highlighting for this to clojure-mode.
>
> diff --git a/clojure-mode.el b/clojure-mode.el
> index 2d82ab6..7f1c28f 100644
> --- a/clojure-mode.el
> +++ b/clojure-mode.el
> @@ -374,6 +374,8 @@ elements of a def* forms."
> "\\(\\sw+\\)?" )
> (1 font-lock-keyword-face)
> (2 font-lock-function-name-face nil t))
> +  ;; Private keywords :foo-
> +  ("\\<:\\sw+-\\>" 0 font-lock-constant-face)
>   ;; Constant values.
>   ("\\<:\\sw+\\>" 0 font-lock-builtin-face)
>   ;; Meta type annotation #^Type
>
>
> --
> jan
>
> >
>

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



Re: Tests in Clojure source

2009-07-25 Thread ajlopez

Hi people!

Thanks for the answers, Wilson, Richard.

Yesterday, I could clone the CLR branch from github (github hates my
IE7 browser, I switched to FireFox):

http://github.com/richhickey/clojure-clr/tree/master

I found in the code the kind of test I was looking for. Just curious:
any attempt to add that kind of test to Java source code? I guess it
could be a great help in case of minor and major refactors of the base
code.

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


On Jul 20, 2:07 pm, Richard Newman  wrote:
> > yes, it's in clojure.contrib.test-is
>
> I think Angel's asking — based on his context of "Clojure inner guts"  
> — if there are any Java tests for the Clojure core, as opposed to  
> tests written in Clojure. I presume that he wants these to mirror into  
> C#, to get a better handle on the expected behavior of lower-level  
> operations.
>
> I believe the answer to that question is "no, none at all". I  
> certainly don't see any in the Clojure "jvm" tree.
>
> Angel: Clojure's tests are written in Clojure, and are a community-
> driven effort. Rich's position on writing tests is well-known[1].
>
> [1]   >

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



Simple questions from a newbie

2009-07-25 Thread ajlopez

Hi people!

I have some experience with plain-vanilla Lisp (not Common Lisp or
Scheme); I have some questions about minor (or not) design decisions
in Clojure:

1) Why the fn special form receives an array as list of parameters?
That is, why Clojure is using:

(fn [x y]

instead of

(fn (x y) ...

or both

Any rationale behing this decision?

2) I read in core.clj definitions like:

(def
 #^{:arglists '([x])
:doc "Return true if x is a String"}
 string? (fn string? [x] (instance? String x)))

Why not:

(def
 #^{:arglists '([x])
:doc "Return true if x is a String"}
 string? (fn [x] (instance? String x)))

that is, fn WITHOUT the name of the defined function. The name after
fn could be used in a recursive call, but, is it needed in this
context? for debugging purpose?

3) Why the redefs like:

;during bootstrap we don't have destructuring let, loop or fn, will
redefine later
(def
 #^{:macro true}
  let (fn* let [& decl] (cons 'let* decl)))

(def
 #^{:macro true}
 loop (fn* loop [& decl] (cons 'loop* decl)))

(def
 #^{:macro true}
 fn (fn* fn [& decl] (cons 'fn* decl)))

from loop* to loop, let* to let, fn* to fn... Are all *-ended names
special forms?

4) why not a def for macros? In the above fragment, I read that "fn is
a macro" is specified in a metadata tag. Why this decision? I'm
playing with an interpreter written in C# (not a compiler) and the
only metadata I need to process, by now, is the meta tag...

TIA

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



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



Re: Very minor problem in the REPL

2009-07-25 Thread ronen

Iv stumbled this also when using Threads, (http://
javadevelopmentforthemasses.blogspot.com/2009/07/easiest-singleton-
around.html)

user=> (defn singleton-factory []
 (println "creating object")
 (+ 1 2))
user=> (use 'clojure.contrib.singleton)
nil
user=> (def t-singleton (per-thread-singleton singleton-factory))
#'user/t-singleton
user=> (defn use-twice [] (+ 1 (t-singleton)) (+ 1 (t-singleton)))
#'user/use-twice
user=> (. (Thread. use-twice) start)
nil
user=> creating object ; REPL prints on the wrong line
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Simple questions from a newbie

2009-07-25 Thread Meikel Brandmeyer

Hi,

Am 25.07.2009 um 15:08 schrieb ajlopez:


1) Why the fn special form receives an array as list of parameters?
That is, why Clojure is using:

(fn [x y]

instead of

(fn (x y) ...

or both

Any rationale behing this decision?


In Clojure vectors are used everywhere, where
the grouping parentheses are used for in other
Lisps is not a functional call. Examples are let,
binding and - as you said - fn. So whenever
you (something in parentheses), you can be
normally be sure, that something is a kind of
function. (eg. maps and keywords are also
"functions", that is, they implement IFn).


2) I read in core.clj definitions like:

(def
#^{:arglists '([x])
   :doc "Return true if x is a String"}
string? (fn string? [x] (instance? String x)))

Why not:

(def
#^{:arglists '([x])
   :doc "Return true if x is a String"}
string? (fn [x] (instance? String x)))

that is, fn WITHOUT the name of the defined function. The name after
fn could be used in a recursive call, but, is it needed in this
context? for debugging purpose?


A side effect of naming the anonymous fn
is that instead of "fn__34" you can read
"string_QMARK" in a stack trace. This helps
when debugging.

I often do this for multimethods because
it's otherwise difficult to find out which
method exactly was invoked.

(defmethod foo [String Integer]
  foo--string-integer
  [a b]
  ...)


3) Why the redefs like:

;during bootstrap we don't have destructuring let, loop or fn, will
redefine later
(def
#^{:macro true}
 let (fn* let [& decl] (cons 'let* decl)))

(def
#^{:macro true}
loop (fn* loop [& decl] (cons 'loop* decl)))

(def
#^{:macro true}
fn (fn* fn [& decl] (cons 'fn* decl)))

from loop* to loop, let* to let, fn* to fn... Are all *-ended names
special forms?


loop, let and fn are "special" forms. For
convenience however the support a
feature called destructuring.

(let [[a [b c]] [1 [2 3]]] [a b c])
=> [1 2 3]

This works also in loop and in the argument
list of fns. However this feature is implemented
in Clojure, hence it is not available at that point
in time. Later, when the prerequisites are defined
the macros are redefined to use destructuring
and the expand into a call of the corresponding
*-form. The *-forms are the "real" special forms.


4) why not a def for macros? In the above fragment, I read that "fn is
a macro" is specified in a metadata tag. Why this decision? I'm
playing with an interpreter written in C# (not a compiler) and the
only metadata I need to process, by now, is the meta tag...


There is defmacro, which defines a macro.
At this early point it's not defined, yet. Hence
the manual definition with the metadata.

Macros are just functions with the special
macro tag in the metadata of the Var holding
them. This tag is inquired by the compiler to
see whether it's a function or a macro.

Hope this helps.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Very minor problem in the REPL

2009-07-25 Thread Stuart Sierra

That's a general problem with multiple threads printing to the same
stream, and not something that can be easily avoided.
-Stuart


On Jul 25, 12:48 pm, ronen  wrote:
> Iv stumbled this also when using Threads, (http://
> javadevelopmentforthemasses.blogspot.com/2009/07/easiest-singleton-
> around.html)
>
> user=> (defn singleton-factory []
>          (println "creating object")
>          (+ 1 2))
> user=> (use 'clojure.contrib.singleton)
> nil
> user=> (def t-singleton (per-thread-singleton singleton-factory))
> #'user/t-singleton
> user=> (defn use-twice [] (+ 1 (t-singleton)) (+ 1 (t-singleton)))
> #'user/use-twice
> user=> (. (Thread. use-twice) start)
> nil
> user=> creating object ; REPL prints on the wrong line
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



validate inconsistency

2009-07-25 Thread Mark Volkmann

Looking at the source ARef.java, I see that the validate method will
throw an IllegalStateException if the validator function either
returns false or throws a non-RuntimeException. The setValidator
method immediately validates the Ref using the new validator function.
It always throws a RuntimeException when validation fails. Why doesn't
it just allow the exception thrown by the validate function to
propagate out instead of wrapping it in a RuntimeException? That would
make it have the same result as calling validate.

-- 
R. Mark Volkmann
Object Computing, Inc.

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



where to suggestion changes

2009-07-25 Thread Mark Volkmann

Should I use this mailing list to suggest changes to the Clojure
implementation or some other avenue?

Some suggestions I may have are pretty simple.
For example, in LockingTransaction.java I see:

ref.validate(ref.getValidator(), e.getValue());

That could be replaced by:

ref.validate(e.getValue());

because the validate method in ARef.java is overloaded and the version
that just takes the proposed new value uses the same validator
function returned by ref.getValidator().

-- 
R. Mark Volkmann
Object Computing, Inc.

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



Re: where to suggestion changes

2009-07-25 Thread Rich Hickey



On Jul 25, 3:20 pm, Mark Volkmann  wrote:
> Should I use this mailing list to suggest changes to the Clojure
> implementation or some other avenue?
>
> Some suggestions I may have are pretty simple.
> For example, in LockingTransaction.java I see:
>
> ref.validate(ref.getValidator(), e.getValue());
>
> That could be replaced by:
>
> ref.validate(e.getValue());
>
> because the validate method in ARef.java is overloaded and the version
> that just takes the proposed new value uses the same validator
> function returned by ref.getValidator().
>

Unless it substantially improves something, I think any such changes
are just a distraction.

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



Re: where to suggestion changes

2009-07-25 Thread Mark Volkmann

On Sat, Jul 25, 2009 at 2:53 PM, Rich Hickey wrote:
>
> On Jul 25, 3:20 pm, Mark Volkmann  wrote:
>> Should I use this mailing list to suggest changes to the Clojure
>> implementation or some other avenue?
>>
>> Some suggestions I may have are pretty simple.
>> For example, in LockingTransaction.java I see:
>>
>> ref.validate(ref.getValidator(), e.getValue());
>>
>> That could be replaced by:
>>
>> ref.validate(e.getValue());
>>
>> because the validate method in ARef.java is overloaded and the version
>> that just takes the proposed new value uses the same validator
>> function returned by ref.getValidator().
>>
>
> Unless it substantially improves something, I think any such changes
> are just a distraction.

Certainly this example doesn't substantially improve anything. It does
make the code look a small bit cleaner though. Making the code easier
to read/understand (more than my simple suggestion) can increase the
number of people that take the time to read it and that could result
in more significant suggestions. It's your call though whether you
want to act on the suggestions.

Suppose though that I come up with a significant suggestion. What
avenue should I use to share it?

-- 
R. Mark Volkmann
Object Computing, Inc.

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



Re: How to write performant functions in clojure (and other functional languages)

2009-07-25 Thread atucker

I wonder if any of the Clojurians on here might like to describe how
one might write the factorial function as a parallel one?  Taking
advantage of the associativity of multiplication, along the lines of

16! = (((1*2)*(3*4)) * ((5*6)*(7*8))) * (((9*10)*(11*12)) * ((13*14)*
(15*16)))

On Jul 24, 8:38 pm, Daniel Lyons  wrote:
> Jeremy,
>
> On Jul 24, 1:20 pm, Jeremy Gailor  wrote:
>
> > I'm just looking for general optimizations that I should be aware of, the
> > nature of the function itself isn't really important.  I could turn to
> > number theory to get some performance improvement, but from a Clojure
> > oriented perspective, what things might I try?
>
> You are probably already know about this, but a good general
> technique
> is to rephrase your function with accumulators. For
> example,
> factorial, you might try to do it like
> this:
>
> (defn fac
> [n]
>   (* n (recur (- n
> 1
>
> This blows up because the recur isn't in the tail position. If
> you
> just change it to 'fact then your function will consume stack and
> not
> run as quickly as a naive loop. This can be rephrased using
> an
> accumulator like
> so:
>
> (defn
> fac
>   ([n] (fac n
> 1))
>   ([n acc] (if (zero? n)
> acc
>                (recur (dec n) (* acc
> n)
>
> Not quite as pleasing to the eye, but performs much
> better.
>
> You can do this with multiple accumulators too, such as for
> average:
>
> (defn
> avg
>   ([l] (avg l 0
> 0))
>   ([l cnt
> tot]
>      (if (empty? l) (/ tot
> cnt)
>          (recur (rest l) (inc cnt) (+ (first l)
> tot)
>
> There's no need for this in Clojure though, because 'count is O(1),
> so
> this really can't perform any better than
> this:
>
> (defn avg
> [l]
>   (/ (reduce + l) (count
> l)))
>
> Specifically to Clojure I would try and use laziness to my
> advantage
> as much as
> possible.
>
> If you have the ability to turn to number theory I would
> definitely
> recommend
> it. :)
>
> --
> Daniel

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



Re: Simple questions from a newbie

2009-07-25 Thread Michael Wood

Hi

2009/7/25 ajlopez :
[...]
> from loop* to loop, let* to let, fn* to fn... Are all *-ended names
> special forms?
[...]

No, you can name your own functions/macros something* if you want to.
The * at the end normally just means that this function/macro is
similar to the one without the *, but not exactly the same and the one
without the * is the one that would normally be used.

e.g. something* could be a helper function used by a macro called something.

-- 
Michael Wood 

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



Re: How to write performant functions in clojure (and other functional languages)

2009-07-25 Thread Timothy Pratley

The parallel library wraps the ForkJoin library scheduled for
inclusion in JDK 7:
http://gee.cs.oswego.edu/dl/concurrency-interest/index.html
You'll need jsr166y.jar in your classpath in order to use this
library.
(use '(clojure.parallel))
(clojure.parallel/preduce * (range 2 16))

On Jul 26, 6:40 am, atucker  wrote:
> I wonder if any of the Clojurians on here might like to describe how
> one might write the factorial function as a parallel one?  Taking
> advantage of the associativity of multiplication, along the lines of
>
> 16! = (((1*2)*(3*4)) * ((5*6)*(7*8))) * (((9*10)*(11*12)) * ((13*14)*
> (15*16)))

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