Newbie question - Functional programming & special cases

2010-02-01 Thread ka
Hi clojure folk,

I'm reading up on clojure from the book 'Programming clojure'.  In
chapter 2 there is a statement -

"The imperative indexOfAny must deal with several special cases:
null or empty strings, a null or empty set of search characters,
and the absence of a match. These special cases add branches
and exits to the method. With a functional approach, most of these
kinds of special cases just work without any explicit code."

I'm not quite sure if I understand this properly. How is it that with
a functional approach, most of these special cases like null checks or
empty checks get handled automatically?  I mean isn't that a property
of the language / api rather than the programming approach per se?
Please explain with some examples!

On a similar note, following is the definition of the function index-
filter given in the book :-

(defn index-filter [pred coll]
  (when pred
(for [[idx elt] (indexed coll) :when (pred elt)] idx)))

Why is the 'when pred' check necessary?

Thanks!

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


Re: Newbie question - Functional programming & special cases

2010-02-10 Thread ka
Thanks, that answers my questions.

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


Clojure binding for Open CL

2010-02-10 Thread ka
Hi,

I was just wondering if (by now) Open CL has been 'wrapped' by higher
level languages. I came across these from the Khronos site (http://
www.khronos.org/developers/resources/opencl/#timplementations) -
1. http://ruby-opencl.rubyforge.org/
2. http://planet.plt-scheme.org/display.ss?package=opencl.plt&owner=jaymccarthy
3. http://mathema.tician.de/software/pyopencl

Wondering if anyone is already working on a Open CL binding.  I would
love if I can code in clojure and it runs through Open CL drivers :)
on my Radeon!

Thanks!

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


Permutations of n things

2010-02-14 Thread ka
I'm trying to make a function which gives the n! permutations of a
vector of n things. Here is my first attempt :

(defn permute
  "Gives the n! permuations of the input vector of things"
  [v]
  (if (= 1 (count v)) (list [(v 0)])
(loop [i 0 perm '()]
  (if (= i (count v))
perm
(let [s-v (into [] (concat (subvec v 0 i) (subvec v (inc i
  perm-s-v (permute s-v)
  new-perms (map #(conj % (v i)) perm-s-v)]
  (recur (inc i) (into perm new-perms)))

1:160 user=> (permute [1 2 3])
([2 1 3] [1 2 3] [3 1 2] [1 3 2] [3 2 1] [2 3 1])

How can I write this in a better fashion? In particular how do I make
this lazy?

Thnx

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


Try + finally question

2010-04-21 Thread ka
Hi,

I'm using an API to connect to a server which does not provide
constructors, just static methods to get & close connections.

How can I do something like ...

(try
  (let [conn (API/getConnection ..)]
())
  (catch ..)
  (finally (if conn (API/closeConnection conn

Problem is that conn is unavailable in the finally context.

Is there any easy workaround which doesn't involve defing a global
conn.

- Thanks

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


Re: Try + finally question

2010-04-21 Thread ka
Thanks for the reply Alex,

I thought of 2 try blocks, but seems over engineering doesn't it ?  I
actually need to open 2 connections simultaneously, which would amount
to 3 nested try blocks. The whole code gets cluttered with all these
try finally (and one catch) statements.

  (try
(let [conn1 (API1/getConnection ..)]
  (try
(let [conn2 (API2/getConnection ..)]
  (try
( ... Do something with conn1 conn2 )
(finally
  (API2/closeConnection conn2
(finally
  (API1/closeConnection conn1
(catch Exception ex (.printStackTrace ex)))

The macro solution looks good.  But with 2 different APIs for 2
connections, I would need to write 2 macros right?

(defmacro with-api1-connection [conn-sym arg1 arg2 & body]
  `(let [~conn-sym (API1/getConnection ~arg1 ~arg2)]
 (try
  ~...@body
  (finally (API1/closeConnection ~conn-sym)

(defmacro with-api2-connection [conn-sym arg1 arg2 arg3 & body]
  `(let [~conn-sym (API2/getConnection ~arg1 ~arg2 ~arg3)]
 (try
  ~...@body
  (finally (API2/closeConnection ~conn-sym)

Also coming back to the original requirement, wanted to know what are
the problems with providing support (somehow) for something like -

(try
  (let [conn1 (API1/getConnection ..)
 conn2 (API2/getConnection ..)]
())
  (catch ..)
  (finally
(if conn1 (API1/closeConnection conn1))
(if conn2 (API2/closeConnection conn2


Coming from Java, this would be implemented as -

Connection1 conn1 = null;
Connection2 conn2 = null;
try {
  conn1 = API1.getConnection ..;
  conn2 = API2.getConnection ..;
  ...
}
catch (){}
finally {
  if (conn1 != null)
API1.closeConnection(conn1);
  if (conn2 != null)
API2.closeConnection(conn2);
}

I agree that this code doesn't look good from a purist pov, but any
issues besides that?

- Thanks!

On Apr 21, 4:58 pm, Alex Osborne  wrote:
> ka  writes:
> > How can I do something like ...
>
> > (try
> >   (let [conn (API/getConnection ..)]
> >     ())
> >   (catch ..)
> >   (finally (if conn (API/closeConnection conn
>
> > Problem is that conn is unavailable in the finally context.
>
> Why not just have two try blocks?
>
> (try
>  (let [conn (API/getConnection ..)]
>    (try
>     ()
>     (finally (API/closeConnection conn
>  (catch ...))
>
> For these sorts of things I usually try to use with-open, or if
> with-open is not applicable do my own similar macro:
>
> (defmacro with-api-connection [conn-sym arg1 arg2 & body]
>   `(let [~conn-sym (API/getConnection ~arg1 ~arg2)]
>      (try
>       ~...@body
>       (finally (API/closeConnection ~conn-sym)
>
> So then you never forget to close the connection:
>
> (try
>  (with-api-connection conn ...
>    (... do something with conn ...))
>  (catch ...))
>
> --
> 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 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Try + finally question

2010-04-21 Thread ka
Thanks all for replies.

Laurent, Alex you guys are right, the problem is only with aesthetics
of nesting / boilerplate.  The nesting implementation semantically
expresses exactly what is required.

The with-cleanup macro seems really neat.  Guess I'll learn macros
first and try to implement one.

One more interesting perspective to exceptional handling is the way
Perl 6 is doing it - http://feather.perl6.nl/syn/S04.html#Exception_handlers

See this -

{
my $s = '';
die 3;
CATCH {
when 1 {$s ~= 'a';}
when 2 {$s ~= 'b';}
when 3 {$s ~= 'c';}
when 4 {$s ~= 'd';}
default {$s ~= 'z';}
}

is $s, 'c', 'Caught number';
};

Thanks!

On Apr 21, 7:05 pm, Alex Osborne  wrote:
> ka  writes:
> > The whole code gets cluttered with all these try finally (and one
> > catch) statements.
>
> >   (try
> >     (let [conn1 (API1/getConnection ..)]
> >       (try
> >         (let [conn2 (API2/getConnection ..)]
> >           (try
> >             ( ... Do something with conn1 conn2 )
> >             (finally
> >               (API2/closeConnection conn2
> >         (finally
> >           (API1/closeConnection conn1
> >     (catch Exception ex (.printStackTrace ex)))
>
> I guess the main difference in this compared to your java example is the
> levels of nesting.  This may look messy but it's semantically exactly
> what you're trying to express.
>
> > The macro solution looks good.  But with 2 different APIs for 2
> > connections, I would need to write 2 macros right?
>
> > (defmacro with-api1-connection [conn-sym arg1 arg2 & body]
> >   `(let [~conn-sym (API1/getConnection ~arg1 ~arg2)]
> >      (try
> >       ~...@body
> >       (finally (API1/closeConnection ~conn-sym)
>
> > (defmacro with-api2-connection [conn-sym arg1 arg2 arg3 & body]
> >   `(let [~conn-sym (API2/getConnection ~arg1 ~arg2 ~arg3)]
> >      (try
> >       ~...@body
> >       (finally (API2/closeConnection ~conn-sym)
>
> You could make things more general:
>
> (with-cleanup [conn1 (API1/getConnection ...) API1/closeConnection
>                conn2 (API2/openConnection ...) #(.disconnect %)]
>  ...)
>
> I'll leave implementation as an exercise, it's not much more complicated
> than the previous ones, the main trick would just be to make the macro
> recursive, have it expand into:
>
> (let [conn1 (API1/getConnection ...)]
>   (try
>     (with-cleanup [conn2 (API2/openConnection ...) #(.disconnect %)]
>       ...)
>     (finally
>       (API1/closeConnection conn1
>
> I'd probably start with a signature like this:
>
> (defmacro with-cleanup [[sym create cleanup & more] & body]
>   ...)
>
> Take a look at the source for with-open if you get stuck.
>
>
>
> > Coming from Java, this would be implemented as -
>
> > Connection1 conn1 = null;
> > Connection2 conn2 = null;
> > try {
> >   conn1 = API1.getConnection ..;
> >   conn2 = API2.getConnection ..;
> >   ...
> > }
> > catch (){}
> > finally {
> >   if (conn1 != null)
> >     API1.closeConnection(conn1);
> >   if (conn2 != null)
> >     API2.closeConnection(conn2);
> > }
>
> > I agree that this code doesn't look good from a purist pov, but any
> > issues besides that?
>
> The problem here is that this breaks lexical scope, conn1 and
> conn2 aren't defined outside their let block.  The Java example dodges
> this with mutation.  Python/Ruby/JavaScript etc dodge it by having
> special scoping rules: variables are scoped to functions rather than the
> enclosing block.
>
> Clojure's opinion, as I understand it, is that it's not worthwhile
> introducing mutation or special scoping rules simply to avoid some
> nesting, when we have perfectly good tools (macros) for doing purely
> syntactic transformations and removing boilerplate.
>
> There's nothing semantically wrong with nesting, it's just harder
> to read.  The Clojure idiom for reducing nesting is usually to use a
> macro like ->, ->> or with-open to flatten it.  In this case those
> aren't applicable, so I suggest defining your own.
>
> I'm not sure I phrased that clearly, please let me know if I'm not
> making sense. :-)
>
> Alex
>
> --
> 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 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Try + finally question

2010-04-23 Thread ka
Hi all,

I've written my first macro: with-open-flexi!

(defmacro with-open-flexi!
  " Just like with-open except it takes closing expression instead
of assuming it to be .close

Macro definition :
(with-open-flexi! [] body) expands to -
  (do body)

(with-open-flexi! [obj1 init1 close1 more] body)) expands to
  (let [obj1 init1]
(try
  (with-open-flexi! [more] body)
  (finally close1)))

Note: It is your responsibility to ensure -
  1. Count of elements in the bindings is a multiple of 3
  2. 0th, 3rd, 6th, 9th ... index of binding is a symbol

example usage -
(with-open-flexi! [conn1 (API1/Conn args) (API1/Disconn conn1
args)
 conn2 (API2. args) (API2/Disconn
args conn2)
 conn3 (API3. args) (.disconn
conn3)]
  (... use conn1, conn2, conn3 ...)
  42)
  "
  [bindings & body]
  (if (= 0 (count bindings))
`(do ~...@body)
(let [[o i c & more] bindings]
  `(let [~o ~i]
 (try
   (with-open-flexi! [...@more] ~...@body)
   (finally ~c))


Tested it :

=> (with-open-flexi! [o1 (println "i1") (println o1 "c1")
   o2 (println "i2") (println o2 "c2")]
  (println "body1") (println "body2") 42)
i1
i2
body1
body2
nil c2
nil c1
42

Please let me know if there are any bugs / gotchas / improvements etc.

- Thanks

On Apr 21, 8:04 pm, "Mark J. Reed"  wrote:
> The main thing about Perl6 in this case is that the catch/finally blocks are
> inside the same scope as the try.   But that's true in Clojure as well!
> The difference is that Clojure's try is not itself a lexical binding scope;
> you have to wrap one around it or within it via let.  That's why I thought a
> combination of try and let would be useful, if only as syntactic sugar.
>
>
>
> On Wed, Apr 21, 2010 at 10:43 AM, ka  wrote:
> > Thanks all for replies.
>
> > Laurent, Alex you guys are right, the problem is only with aesthetics
> > of nesting / boilerplate.  The nesting implementation semantically
> > expresses exactly what is required.
>
> > The with-cleanup macro seems really neat.  Guess I'll learn macros
> > first and try to implement one.
>
> > One more interesting perspective to exceptional handling is the way
> > Perl 6 is doing it -
> >http://feather.perl6.nl/syn/S04.html#Exception_handlers
>
> > See this -
>
> > {
> >    my $s = '';
> >    die 3;
> >    CATCH {
> >        when 1 {$s ~= 'a';}
> >        when 2 {$s ~= 'b';}
> >        when 3 {$s ~= 'c';}
> >        when 4 {$s ~= 'd';}
> >        default {$s ~= 'z';}
> >    }
>
> >    is $s, 'c', 'Caught number';
> > };
>
> > Thanks!
>
> > On Apr 21, 7:05 pm, Alex Osborne  wrote:
> > > ka  writes:
> > > > The whole code gets cluttered with all these try finally (and one
> > > > catch) statements.
>
> > > >   (try
> > > >     (let [conn1 (API1/getConnection ..)]
> > > >       (try
> > > >         (let [conn2 (API2/getConnection ..)]
> > > >           (try
> > > >             ( ... Do something with conn1 conn2 )
> > > >             (finally
> > > >               (API2/closeConnection conn2
> > > >         (finally
> > > >           (API1/closeConnection conn1
> > > >     (catch Exception ex (.printStackTrace ex)))
>
> > > I guess the main difference in this compared to your java example is the
> > > levels of nesting.  This may look messy but it's semantically exactly
> > > what you're trying to express.
>
> > > > The macro solution looks good.  But with 2 different APIs for 2
> > > > connections, I would need to write 2 macros right?
>
> > > > (defmacro with-api1-connection [conn-sym arg1 arg2 & body]
> > > >   `(let [~conn-sym (API1/getConnection ~arg1 ~arg2)]
> > > >      (try
> > > >       ~...@body
> > > >       (finally (API1/closeConnection ~conn-sym)
>
> > > > (defmacro with-api2-connection [conn-sym arg1 arg2 arg3 & body]
> > > >   `(let [~conn-sym (API2/getConnection ~arg1 ~arg2 ~arg3)]
> > > >      (try
> > > >       ~...@body
> > > >       (finally (API2/closeConnection ~conn-sym)
>
> > > You could make things more general:
>
> > > (with-cleanup [conn1 (API1/getConnection ...) API1/closeCo

Re: Try + finally question

2010-04-29 Thread ka
Hi ppl,

Above I wrote a macro with-open-flexi! ... which I'm planning to use
in my app's API . .. please let me know if there are any bugs /
gotchas / improvements etc...

I didn't get any responses, so does it means there is something so
obviously wrong that you can't even begin where to start :) (I doubt
so) or does it looks OK ..?

(See the above post for detailed comments & usage)

(defmacro with-open-flexi!
  [bindings & body]
  (if (= 0 (count bindings))
`(do ~...@body)
(let [[o i c & more] bindings]
  `(let [~o ~i]
 (try
   (with-open-flexi! [...@more] ~...@body)
   (finally ~c))

- Thanks

On Apr 24, 4:07 am, ataggart  wrote:
> I wrote this, which seems to solve the problem being discussed:
>
> http://gist.github.com/377278
>
> Thoughts?
>
> On Apr 23, 8:10 am, Armando Blancas  wrote:
>
>
>
> > > Is there any easy workaround which doesn't involve defing a global
> > > conn.
>
> > To do all in a single place you'll have to mimic the Java idiom.
>
> > (let [conn (atom nil)]
> >   (try
> >     (reset! conn (API/getConnection ...) ...
> >     (catch ...)
> >     (finally(if @conn (API/closeConnection @conn)
>
> > As it's been explained, a better way would be a variant of with-open,
> > maybe within atryform if you want to handle open errors locally.
>
> > --
> > 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 
> > athttp://groups.google.com/group/clojure?hl=en
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Try + finally question

2010-05-01 Thread ka
Hmm .. makes sense .. my thinking was its just a more flexible with-
open ... but from user's pov with-open-close is better...

Thanx

On Apr 29, 2:24 pm, Laurent PETIT  wrote:
> Maybe juste the name ?
>
> wouldn't with-open-close be a better reminder of how the bindings are
> constructed ?
>
> 2010/4/29 Alex Osborne :
>
>
>
> > ka  writes:
>
> >> Above I wrote a macro with-open-flexi! ... which I'm planning to use
> >> in my app's API . .. please let me know if there are any bugs /
> >> gotchas / improvements etc...
>
> >> I didn't get any responses, so does it means there is something so
> >> obviously wrong that you can't even begin where to start :) (I doubt
> >> so) or does it looks OK ..?
>
> > It looks okay to me, nothing obviously stands out as wrong with it. :-)
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that posts from new members are moderated - please be patient with 
> > your first post.
> > To unsubscribe from this group, send email to
> > clojure+unsubscr...@googlegroups.com
> > For more options, visit this group at
> >http://groups.google.com/group/clojure?hl=en
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Annoying auto-signature

2010-05-09 Thread ka
+1

On May 7, 2:13 am, Mibu  wrote:
> Am I the only one driven mad by the new auto-appended signature to
> every message in this group ("You received this message because you
> are subscribed...")? It started on April 16th. Is there a way a
> moderator can stop it?
>
> --
> 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 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Why Clojure rocks..

2010-05-09 Thread ka
Not wanting to become an uninvited guest to your party :-) ... but do
you mind elaborating .. ?

On May 9, 2:31 am, Base  wrote:
> I just replaced 443 lines of java with 61 lines of Clojure.
>
> THANK YOU 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 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Adding docstrings to def?

2010-05-14 Thread ka
> I think def should support docstrings, as ^{:doc "foo"} is 8
> characters longer then "foo" - not to mention consistency across
> definers as well as readability.

I agree that there should be consistency across definers and that the
default def should be the best.  Removes unnecessary complexity out of
the language too (I shouldn't have to remember two different way to
write doc strings .. one for def, another for defn, etc.).

> I would love a clojure without any (visible for the programmer) special 
> operators at
> all, such that even def, . etc. could be redefined if necessary

I don't feel this is such a great idea. There should be some (but few)
constant primitive elements so I can understand someone else's code
too.  Consider a situation that someone has modified the 'if' special
form! For one I can miss out that 'if' was redefined, even if that can
be worked around, unless i read and grasp the new 'if' i can't begin
to read other persons code.  Its best to use special forms or
functions made out of special forms unless some other macro etc is
much more suitable and read-able.  Would you like to read my code if I
never use any special forms except to define my own wrappers of them -
my-def, my-if, my-let ...?

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


Re: Block on structure until some data appear

2010-05-14 Thread ka
If add-watch is not what you want because you want the consumers to
have a life of their own, then does something like this work? -

(def my-hash (ref {}))
(def new-keys (ref #{}))

(defn produce  []
  (let [new-key (rand-int 10)
new-val "P"]
(Thread/sleep 100)
(dosync
  (alter my-hash assoc new-key new-val)
  (alter new-keys conj new-key

(defn consum  []
  (loop []
(let [done? (dosync
  (if (> (count @new-keys) 0)
(let [new-key (first @new-keys)
  my-new-val "C"]
  (alter new-keys disj new-key)
  (alter my-hash assoc new-key my-new-val)
  true)
false))]
  (when-not done?
(Thread/sleep 100)
(recur
  (Thread/sleep 100))

(defn producer [] (dorun (repeatedly produce)))

(defn consumer [] (dorun (repeatedly consume)))

(defn report-status  []
  (dosync
(ensure my-hash)
(ensure new-keys)
(println @my-hash)
(println @new-keys)
))

-- 
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: Block on structure until some data appear

2010-05-14 Thread ka
Few notes -
1. report status is not particularly good as it has io in a dosync.
2. Spelling of consume fn.
3. The consumers are not at all fair as they always take the first of
the set.

Please let me know if anyone sees some issues with the above code or
how to make it better.

On May 14, 10:59 pm, ka  wrote:
> If add-watch is not what you want because you want the consumers to
> have a life of their own, then does something like this work? -
>
> (def my-hash (ref {}))
> (def new-keys (ref #{}))
>
> (defn produce  []
>   (let [new-key (rand-int 10)
>         new-val "P"]
>     (Thread/sleep 100)
>     (dosync
>       (alter my-hash assoc new-key new-val)
>       (alter new-keys conj new-key
>
> (defn consum  []
>   (loop []
>     (let [done? (dosync
>                   (if (> (count @new-keys) 0)
>                     (let [new-key (first @new-keys)
>                           my-new-val "C"]
>                       (alter new-keys disj new-key)
>                       (alter my-hash assoc new-key my-new-val)
>                       true)
>                     false))]
>       (when-not done?
>         (Thread/sleep 100)
>         (recur
>   (Thread/sleep 100))
>
> (defn producer [] (dorun (repeatedly produce)))
>
> (defn consumer [] (dorun (repeatedly consume)))
>
> (defn report-status  []
>   (dosync
>     (ensure my-hash)
>     (ensure new-keys)
>     (println @my-hash)
>     (println @new-keys)
>     ))
>
> --
> 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 
> athttp://groups.google.com/group/clojure?hl=en

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


Re: Block on structure until some data appear

2010-05-14 Thread ka
> You can get rid of the I/O in the transaction and still see a consistent
> snapshot by simply return the contents of the refs.
>
> (defn report-status
>   []
>   (apply println (dosync [...@my-hash @new-keys])))
>
> Sincerely
> Meikel
>
> --

Isn't ensure necessary?  Because http://clojure.org/refs says that -
"No changes will have been made by any other transactions to any Refs
that have been ref-set/altered/ensured by this transaction."  It
doesn't guarantee that a ref 'r' will not change if we have (dosync
(..bunch of stuff not involving r..) @r (..bunch of stuff not
involving r..)).

So shouldn't we have to do -

(defn report-status
  []
  (apply println (dosync [(ensure my-hash) (ensure new-keys)])))

- Thanx

-- 
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: Block on structure until some data appear

2010-05-14 Thread ka
@Michael,
There is already a monitor mechanism available in Clojure via the
'locking' macro or more primitive monitor-enter, monitor-exit.  So in
your case all you have to implement is the blocking behavior, I'm not
sure if it can be already done somehow using just Clojure elements.
The above code you gave might just as well be written in Java?

@Meikel
Hmm, thanks for the explanation, I get it now.

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


API in Clojure for Java folklore

2010-05-21 Thread ka
Hi all,

I've written an API in Clojure to be consumed by people working in the
Java world.  Now most of these people haven't even heard of Clojure;
but all they care about is 1) a working API and 2) with nice
documentation.

1) Something about the API - I tried out various things, types,
records, protocols (from the master).  But finally I've decided to
stick with 2-3 defrecords + gen-class.  The API is just a bunch of
static methods with zero state (earlier I was thinking fancy stuff
like OO, and keeping state for each object ... but didn't like any of
it).  Anyway, so now I've a working API.

2) The problem I have now is how to put Javadocs in all my static
methods?  I don't want to create documentation that is detached from
the code.

For example, if I declare a method in gen-class as -
#^{:static true} [myCoolFn [int int] clojure.lang.LazySeq]

and definition of the function-
(defn -myCoolFn
  "My cool documentation"
  [a b]
  ...
)

The .class file generated and hence the API -
2.1) Doesn't have the parameters named int a, int b :(.  They are
named as int arg0, int arg1.
2.2) "My cool documentation" doesn't come up in the Javadocs.

I'm not much familiar with Java so please advise.
Thanks!

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


Re: finding combinations given a coll and selection of n

2010-05-22 Thread ka
As Steve said, better look at the combinatorics-api.

As for your original code, the idea you have gives all permutations
not combinations!  Few changes will make it functioning -

(defn permutations [n coll]
(if (= n 1)
  (map #(vector %) coll)
  (for [el coll nlis (permutations (- n 1) (k-filter el coll))]
(conj nlis el

Thanks

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


Re: reducing multiple sets

2010-05-22 Thread ka
1:6 user=> (use '[clojure.set])
nil
1:7 user=> (reduce union #{} #{#{[3 2] [5 4] [3 3] } #{[4 3] [5 4] [3
3] } #{[3 2] [2 2] [3 3] } } )
#{[3 2] [4 3] [5 4] [2 2] [3 3]}
1:8 user=>

Thx

-- 
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: API in Clojure for Java folklore

2010-05-22 Thread ka
Hi, any responses?

-- 
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: Dividing list by predicate

2010-05-24 Thread ka
You may use reduce, as follows:

(let [r (java.util.Random.)
  f (fn [el] (.nextBoolean r))]
  (def pred f))

(reduce (fn [m el]
(let [k (pred el)]
  (assoc-in m [k] (conj (m k) el
  {true [] false []}
  (range 10))

Thanks

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


Re: do clojure and la(tex) have something in common ?

2010-05-24 Thread ka
Tim,

I don't know much about either lisp or latex :).  But it looks like a
really neat idea at a first thought to me.  Have two remarks-
1. From the developer's pov - I'm not sure how the developer, who is
accustomed to looking at just code + some comments, will manage
working with the book.  But your "tangle" step might help here.
2. From the user's pov - Users will still look for small snippets of
docs like - http://clojure.org/reader; not everyone will have to
patience to go through an entire "chapter".  How do you think we can
extract just these small snippets from the whole book?

- Thanks

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


Re: API in Clojure for Java folklore

2010-05-26 Thread ka
Hi all,

Inspired by Erik above, I've written a macro: gen-class+javadoc
(http://gist.github.com/415269).

It works quite well for me on Windows XP.  For *nix, I think people
will have to make at least one change - the shell command (at line
57).

What it does -
1. Generates a javadoc for your API made using gen-class.

How to use -
1. Just use gen-class+javadoc macro instead of the gen-class macro.
_No other changes are required by the coder_.

Functioning -
1. It calls gen-class first as usual with the args.
2. Generates a .java file containing the javadoc.
3. Runs the javadoc command and generates docs in the doc/ directory.
4. Deletes the .java file created above.

Few points to note -
1. It is by no means complete.  For eg. it doesn't handle interface
related stuff yet.
2. It uses macroexpand inside a macro, but some people on Clojure#
pointed out that this is not recommended.  I'm very new to macro-foo,
so please let me know of the alternatives.
3. The macro itself contains a lot of side effects, dunno if this is a
very big issue.

Try it out if you expose an API through gen-class.

Any comments / suggestions / critiques are welcome.

- Thanks


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


Re: Todo item annotation in Clojure.

2010-05-27 Thread ka
This looks cool.  I'll definitely give it a try in my next project.
Any chance to get it integrated somehow with eclipse ccw?

- Thanks

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


Re: do clojure and la(tex) have something in common ?

2010-05-27 Thread ka
Hi Tim,

Thanks! for such a detailed response.  Really got things in
perspective for me, my thinking yet isn't of such large scale.

So you say literate programming is for those who are writing code that
will live for decades to come and that writing literate programs takes
~3x resources.

Is there a stripped down version of literate programming that will
benefit the majority of programmers who are just average coders,
writing a few APIs etc. that would probably take say ~1.5x resources?
I'm just curious as the concept seems really good.  I'm not sure how
many people are willing to do 3x work for writing their APIs.  I
absolutely agree with your point of documenting (with the goal of
communicating to people) design decisions; and comments are not enough
for the same.

Very recently I started to get interested in code formalism (i.e.
mathematically proving programs), although literate programming is not
geared in this direction, it might play its part.

- Thanks

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


Re: Comparing Cycle

2010-05-27 Thread ka
It would be voodoo magic :) and totally awesome might I say if (= a
(drop 4 a)) returned true immediately!

- Thanks

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


Re: Some suggestions for transients

2010-05-27 Thread ka
My 2 cents,  I read about transients for the first time (why is the
page not linked from clojure.org?) and they seem very promising at a
first glance.

I'm not sure if I agree with Michael's idea of having the same
functions for transients and persistents both.  Functions should have
easy, reproducible semantics imo.  If I take a look at a function call
in isolation of its environment, I should be able to predict its
semantics exactly, not in 90% cases, but 100% (maybe ideal, given my
inexperience).

But I do agree with his concern about the multitude of functions for
persistents and very few for transients.  If I want my bottleneck
function to use transients, it should be straightforward.  Else most
of the energy would be spent to re write things like foo-in etc.  But
maybe that's a deliberate design decision take by Rich not to make
transients popular?

On the transients page Rich has given a very simple benchmark -

(time (def v (vrange 100)))
"Elapsed time: 297.444 msecs"

(time (def v2 (vrange2 100)))
"Elapsed time: 34.428 msecs"

But on my system I don't get a ~9x performance boost, it mostly get a
~3x performance boost (1.2).  Have there been some changes?  What do
other people get?

(time (def v (vrange 100)))
"Elapsed time: 261.82 msecs"

(time (def v2 (vrange2 100)))
"Elapsed time: 87.3 msecs"

Michael: "bash in place" means in-place memory writing, for example in
Java we have a Collections.sort(list) method which uses in-place merge
sort.  That method doesn't return a sorted list, it just changes the
original list in place (which is more memory efficient).  Hope I've
been successful in conveying to you.

- Thanks

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


Re: promoting contrib.string to clojure, feedback requested

2010-05-27 Thread ka
> Stefan Kamphausen writes:
> sorry, I'm a little late.  However, to me it is not clear what the
> trim functions shall do.  If they become a replacement for chomp they
> are clearly misnamed.  In many applications and languages (like Excel,
> several SQL variants, oh, and Java, ...) "trim" means stripping of
> whitespace characters, including but not limited to \n and \r.  In
> contrast to that chomp stands for the removal of the system-specific
> linebreak.

> Mark Engelberg   writes:
>> If you're developing a trio, like ltrim, trim, rtrim, wouldn't it be
>> better to call them triml, trim, trimr so that they show up next to
>> each other in the alphabetized documentation?

+1.  Please keep all chop, chomp, trim* :D

> Therefore I have a little doubt with the implementation of join. It is
> a beautiful implementation but not really efficient. Some (nasty
> looking) implementation directly using a stringbuilder is more
> efficient. (about 2.5 times according to my measureements)

+1 functions in core libs should be efficient first, then beautiful.
Thats the price to pay for the limelight :).

> More generally, i would like to see some overall design principles -
> does the library accept nil in place of string arguments? - some
> functions do / some not. When are characters acceptable in place of
> strings, etc

+1 this seems really important.

-- 
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: API in Clojure for Java folklore

2010-05-28 Thread ka
I've also added a :class-doc key to the macro -

(gen-class+javadoc
  :class-doc "Class Docs
   One   Two  
 "
  :name "a.b.c.MyCoolClass"
  :methods [
  #^{:static true} [method1
[clojure.lang.PersistentArrayMap] int]
  #^{:static true} [method2 [int int float]
clojure.lang.LazySeq]
  #^{:static true} [method3 [] Object]
  ])

Thanks

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


Re: Some suggestions for transients

2010-05-28 Thread ka
Oops didn't know that Rich had already answered.  Google seems to
think that our posts are commutative :/ (often they're not, or are
they? I can't take a stand on this) and just uses the commute fn
instead of using alter and failing the transaction (informing us); but
it does allow for more concurrency as Rich mentions in the docs of
commute :P.

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


Understanding sequence abstraction

2010-05-30 Thread ka
Hi Clojurians,

I have some conceptual questions on the sequence abstraction.  I
understand that (seq coll) will give me a "sequence".
coll maybe be a list, vector, map, set, LazySeq or nil.

1. In case coll is a LazySeq why does (seq coll) realize its first
element?  I thought seq just did a type conversion and all of list,
vector .. etc implemented Seqable or something.

2. Why is there no other way to determine an empty coll except (not
(seq coll)).

- Thanks


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


Re: Understanding sequence abstraction

2010-05-31 Thread ka
@Richard

>> 1. In case coll is a LazySeq why does (seq coll) realize its first
>> element?  I thought seq just did a type conversion and all of list,
>> vector .. etc implemented Seqable or something.

> Because seq is defined as returning nil for an empty sequence. The
> only way to find that out for a lazy sequence is to realize the first
> element.

I'm not sure if that answers why seq should realize the first
element.  Even by what you say, only if I wanted to find if my LazySeq
was nil should I realize its first element.
My understanding of seq is - restricting some Collection type
abstraction to the Sequence abstraction (but maybe my thinking is
wrong).  When I say (seq coll) I don't mean - 1) convert it into a
sequence abstraction + 2) go and find out if the coll is empty by
realizing its first element.

For example suppose I've produce a lazy sequence none of whose
elements are realized yet.  Then I need to call an API which takes a
sequence as input.  I just want to give the sequence abstraction of my
LazySeq by calling (seq coll), but that realizes the first element
(which takes 10 mins say), even if the API were not to use my LazySeq
at all (based on its needs) !  How to solve this - i.e. how do I not
waste 10 mins if not needed?

In fact I'm not even sure why I would need to realize the first
element (completely?) (which takes 10 mins) to find out if the LazySeq
is not empty ?  Can you please explain this further?

>> 2. Why is there no other way to determine an empty coll except (not
>> (seq coll)).

>user=> (empty? [])
>true

1:291 user=> (source empty?)
(defn empty?
  "Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))"
  {:added "1.0"}
  [coll] (not (seq coll)))
nil

Which brings it back to my original question.

Thanks

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


Re: Having trouble getting full performance from a quad-core with trivial code

2010-06-01 Thread ka
Hi Zak,

I tried your example on my i7 (4 physical cores, 8 logical); here are
the results -

1:298 user=> (time (do (doall (map fac (take 10 (repeat 5
nil))
"Elapsed time: 54166.665145 msecs"

1:300 user=> (time (do (doall (pmap fac (take 10 (repeat 5
nil))
"Elapsed time: 27418.26344 msecs"

With map CPU usage ~12.5%, with pmap (10 threads) ~50% average.

But when I change the fac function to say -

(defn fac
  [n]
  (let [n (* n 1000)]
(loop [i 0]
  (when (< i n)
(* 2 2)
(recur (inc i))

1:308 user=> (time (do (doall (map fac (take 10 (repeat 5
nil))
"Elapsed time: 48507.220449 msecs"

1:309 user=> (time (do (doall (pmap fac (take 10 (repeat 5
nil))
"Elapsed time: 9320.92417 msecs"

With map CPU usage ~12.5%, with pmap (10 threads) ~95% average.

So I think it may be something to do with really BigIntegers in your
original fac, but I can't be sure.  The point is that the original fac
somehow doesn't consume the entire CPU even with 10 threads ?!  If you
find out the reason why let me know.

Also I didn't spend much time with your npmap function, but it seems
like a nice idea.  One observation - partition-all is not very good at
dividing up work to be done.  For example suppose you want to divide
up a coll of length 9 into 4 threads, there is no way to do that with
the partition-all directly -

(1:335 user=> (clojure.core/partition-all 2 (range 9))
((0 1) (2 3) (4 5) (6 7) (8))
1:336 user=> (clojure.core/partition-all 3 (range 9))
((0 1 2) (3 4 5) (6 7 8))

Something like this might be better suited (https://gist.github.com/
54313ab02d570204393b) -
1:338 user=> (partition-work 4 (range 9))
((0 1) (2 3) (4 5) (6 7 8))

The above partition-work is based on ideas which I got from MPI
programming a while back.

- Thanks

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


Re: Having trouble getting full performance from a quad-core with trivial code

2010-06-03 Thread ka
Hi Zak,

It seems very weird that my version of fac changes performance
characteristics on my machine and not yours (OS/hardware dependent?).
Can you tell your hardware configuration, esp. number of physical and
logical cores? I am planning next to leave out using pmap and just try
to run the thing using threads directly.  Also write up the same
implementation in Java and compare.  Will do that next when I have
some time to spend on it.

Reg. partitioning -

You won't see any appreciable difference between partition-all and
partition-work in a few examples.  But I'm quite sure that overall on
an average partition-work will divide up the work in a much more
balanced fashion than partition-all.  Imo partition-all is intended
for a different purpose than dividing a coll "equally".

partition-work guarantees (prove it!) that the number of elements in
each sub-coll is bounded above by ceil(n/p) and bounded below by
floor(n/p). n=count of coll, p=num of sub colls to divide into.

Example - suppose need to partition 13 tasks (taking roughly equal
amount of time) onto 4 CPUs.

1:345 user=> (partition-work 4 (range 13))
((0 1 2) (3 4 5) (6 7 8) (9 10 11 12))

1:346 user=> (clojure.core/partition-all 4 (range 13))
((0 1 2 3) (4 5 6 7) (8 9 10 11) (12))

If we just use partition-all (w/o any modifications) it puts 4 tasks
each on 3 CPUs and only 1 task on the last CPU.  But partition-work
will divide - 3 tasks on the first 3 CPUs and 4 tasks on the last CPU;
leading to a more balanced work division.

Also as stated above you cannot use partition-all (directly in its
current form) to divide up 9 tasks among 4 cores -

(1:335 user=> (clojure.core/partition-all 2 (range 9))
((0 1) (2 3) (4 5) (6 7) (8))
1:336 user=> (clojure.core/partition-all 3 (range 9))
((0 1 2) (3 4 5) (6 7 8))

1:338 user=> (partition-work 4 (range 9))
((0 1) (2 3) (4 5) (6 7 8))

- Thanks

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


Re: API in Clojure for Java folklore

2010-06-04 Thread ka
@Jason

I'm supplying a Java API (implemented in Clojure) so needed a solution
quickly which just worked w/o me having to do special things.

Hence the gen-class+javadoc macro (http://gist.github.com/415269).
But I feel there should be something like this available in contrib
which handles the whole jing-bang of gen-class !

Currently I'm using the strategy of generating .class files from gen-
class, then generating java-stubs as required, running javadoc and
just deleting the java-stubs (as they provide no value in their own).

Why do you think keeping the java-stubs is necessary?

- Thanks


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


Re: API in Clojure for Java folklore

2010-06-05 Thread ka
On Jun 5, 1:33 am, Jason Smith  wrote:
> The Java stubs are, ideally, a temporary thing.  They don't need to be
> around forever.  However, I know of no way at present to generate them
> automatically.
>
> Also, you are solving half the problem.  Generating the stubs and
> class files at the same time does not solve the compile-time
> dependency problem.  Consider:
>
> Clojure A references Java class B references Clojure class C
> references Java class D.  A, B, C, D are in a single project.
>
> You *must* run either gen-class or Javac first.  Without some kind of
> stubbing, the compile-time references are unknown, either way.  Either
> Java does not know about the Clojure gen-class classes that are to
> come, or Clojure does not yet know about the Java classes in the
> project.
>
> So, treating Java as the least-common-denominator, you run:
> * gen-stubs
> * Javac
> * gen-class
>
> Since the stubs are around, you can also run JavaDoc.
>
> The stubs don't need to be saved. In the Maven world, they are part of
> the build, not source files.
>
> On Jun 4, 8:03 am, ka  wrote:
>
> > @Jason
>
> > I'm supplying a Java API (implemented in Clojure) so needed a solution
> > quickly which just worked w/o me having to do special things.
>
> > Hence the gen-class+javadoc macro (http://gist.github.com/415269).
> > But I feel there should be something like this available in contrib
> > which handles the whole jing-bang of gen-class !
>
> > Currently I'm using the strategy of generating .class files from gen-
> > class, then generating java-stubs as required, running javadoc and
> > just deleting the java-stubs (as they provide no value in their own).
>
> > Why do you think keeping the java-stubs is necessary?
>
> > - Thanks

Oh, now I understand fully your last post!  I hadn't considered the
cyclic dependencies situation, thanks for pointing that out.  Though I
can't see why right now; in future I might write some code (of mine)
in Java to be used from Clojure (maybe performance).  In that
situation you are right we should -

1) Generate Java-stubs for Clojure gen-class, gen-interface.
 My macro is a half-assed attempt to generate stubs automatically
using the gen-class args.  One complexity is to choose return values
if return type is primitive.

2) Run javac to compile all java sources properly.

3) Run gen-class to replace stubbed .class files by Clojure
generated .class files.

4) Run javadoc to get the seamless documentation.

I'm sure I'm not qualified enough to try to code this up, given that I
haven't used maven or ant ever myself.  But I'd like to give it a shot
given some guidance.

Do you think the right place for this is leiningen?

- Thanks

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


Re: Enhanced Primitive Support

2010-06-21 Thread ka
> My favorite option of those proposed is:
> +, *, -, inc, dec auto-promote.
> loop/recur is changed so that primitive bindings are boxed.
> +',*',-',inc',dec' give error upon overflow.
> A new construct, loop', is introduced that doesn't box primitives and
> enforces recur with primitive upon penalty of error.

+ 1.  This seems the least of all evils.  Think 15 years down the line
when we have 1024 procs to program on.

Is it time for a vote? :)

-- 
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: Transform columnar data into a tree?

2010-06-23 Thread ka
How about this (using only map, reduce) -

user=> (def data1 [[:a1 :b1 :c1]
[:a1 :b1 :c2]
[:a1 :b2 :c3]
[:a1 :b2 :c4]
[:a2 :b3 :c5]
[:a2 :b3 :c6]
[:a2 :b4 :c7]
[:a2 :b4 :c8]])

user=> (pprint
(reduce
  (fn f [tree row]
(if (seq row)
  (let [r (first row)
[idx sub-tree] (some
 (fn [[i v]] (if (= r (:data v)) [i
(:children v)] false))
 (map vector (range) tree))
entry (if (next row)
{:data r :children (f (or sub-tree []) (rest
row))}
{:data r})]
(if idx
  (assoc tree idx entry)
  (conj tree entry)
  []
  data1))

[{:data :a1,
  :children
  [{:data :b1, :children [{:data :c1} {:data :c2}]}
   {:data :b2, :children [{:data :c3} {:data :c4}]}]}
 {:data :a2,
  :children
  [{:data :b3, :children [{:data :c5} {:data :c6}]}
   {:data :b4, :children [{:data :c7} {:data :c8}]}]}]


- Thanks

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


Re: clojure.contrib.logging in "side-effect free" functions?

2010-06-24 Thread ka
To my naive inexperienced eyes, there doesn't seem to be something
obviously wrong with your code.

> Since FOR returns a lazy sequence of the results, is this function
> safe?  (Seeing that it is not side-effect free?)

I'm not getting this, do you foresee any safety issues?  I think that
the logs will be created as you're writing to the out.csv.  If you
want the logs be written before you start writing to out.csv, you may
realize the lazy-seq for returns.

> BTW:
>   clojure.contrib.logging indicates that it can use an agent for
>   logging. Is my assumption that invoking the logger (with or without
>   an agent) within a function would still mean that the function has
>   side-effects correct?

Yes, any change in state or IO means side effect.

- Thanks

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


Re: Can't send from agent error handler?

2010-06-24 Thread ka
I'm also facing the same problem -

(let [handler (agent 50)
a (agent 42
:error-handler
(fn [_ ex]
  (do
(println "Inside agent a error handler fn" (Thread/
currentThread))
(send handler
  (fn [_] (do (println ex (Thread/currentThread)))
60))
(println "Inside agent a error handler fn - after
sending to the handler agent")
(await handler)
(println "CODE DOESN'T REACH HERE ??")
(println "State of handler agent:" @handler]
(send a (fn [_]
  (println "Inside agent a function" (Thread/
currentThread))
  (throw (Exception. "bad news"
(Thread/sleep 1000)
;(println "Errors with a:" (agent-error a))
;(println "Errors with handler:" (agent-error handler))
(shutdown-agents)
(println "Errors with a:" (agent-error a))
(println "Errors with handler:" (agent-error handler))
(println @a)
(println @handler))

- Thanks

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


Re: alter atom while iterating

2010-07-15 Thread ka
>(for [a (r 2), b (r 3)] [a b])
>; produces:
>
>(
>[0 0] [0 1] 
>[0 2] [1 0] [1 1] [1 2])

Why does (r 2) get evaluated before the seq is needed ?

=> (def k (for [a (r 2), b (r 3)] [a b]) )

#'a/k

- Thanks

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


Re: Leiningen 1.2.0 released!

2010-07-20 Thread ka
Awesome awesome new features !!

Yes, when does windows support stop being experimental ?

Even though one of the new features is -
* Added experimental Windows support.

Has anyone tried lein 1.2 on windows (with the lein.bat on
http://github.com/technomancy/leiningen) ?



-- 
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: alter atom while iterating

2010-07-20 Thread ka
@Chouser

Sorry, my above post was directed as a question to you.  Have to stop
being lazy while posting atleast :) !

-- 
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: alter atom while iterating

2010-07-21 Thread ka
@Meikal,

Hi, I get what you mean. Consider the following func -

(defn r
  [n lazy?]
  (.println System/out (str "Called (r " n ")"))
  (let [r-lazy-seq (fn r-lazy-seq [i n]
 (lazy-seq
   (when (< i n)
 (.println System/out (str "Realizing elem "
i))
 (cons :a (r-lazy-seq (inc i) n)
zzz (r-lazy-seq 0 n)]
(if lazy? zzz (doall zzz


1:13 user=> (def k (for [a (r 2 true)] a) )
Called (r 2)
#'user/k

1:14 user=> (def k (for [a (r 2 false)] a) )
Called (r 2)
Realizing elem 0
Realizing elem 1
#'user/k

Why do you think for doesn't have 'lazy-for' semantics already?

Also this thread has given me the insight that 'for' is not meant for
Cartesian products of two seqs (contrary to what I thought) -

1:40 user=> (use '[clojure.contrib.combinatorics])
nil
1:41 user=> (cartesian-product (r 2 true) (r 3 true))
Called (r 2)
Called (r 3)
Realizing elem 0
Realizing elem 0
Realizing elem 1
Realizing elem 2
Realizing elem 1
((:a :a) (:a :a) (:a :a) (:a :a) (:a :a) (:a :a))

1:42 user=> (for [a (r 2 true) b (r 3 true)] [a b])
Called (r 2)
Realizing elem 0
Called (r 3)
Realizing elem 0
Realizing elem 1
Realizing elem 2
Realizing elem 1
Called (r 3)
Realizing elem 0
Realizing elem 1
Realizing elem 2
([:a :a] [:a :a] [:a :a] [:a :a] [:a :a] [:a :a])

- Thanks

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


Re: Efficiency of reduce function for lists.

2010-07-25 Thread ka
> For the program, I know that when processing a character, I do not
> need the previous result. All I need is the current character, and I
> can return a function that acts on the result. I'm not sure if this is
> simple to implement in a functional way.

Actually my understanding says that you need the whole list as this
cannot be implemented as lazy ? (you might have any number of
backspaces ahead so you need all the result)

See also: http://kotka.de/blog/2009/11/Stopping%20Times%20and%20Laziness.html

Thanks

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


Re: Small problem in CCW IDE

2010-07-25 Thread ka
> So, it appears the (read-line) consumes the Clojure form (in-ns
> 'test.readln) probably stacked by CCW (at least I didn't type that!)

Yup you're right, CCW "typed" that, you may disable that feature from
the Windows > Preferences > Clojure > Editor.

Thanks

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


Performance of ensure

2010-08-29 Thread ka
Hi,

I have two refs a1, a2.  One thread modifies a1, another modifies a2.

Sample code: http://gist.github.com/556679

If I don't ensure any ref in the transaction, the code runs in ~ 0.2
ms.

$ java -cp lib/clojure-1.2.0.jar\;src clojure.main -e "(require 'tt)
(tt/transaction-simul {:ensure2 false :ensure1 false}) (System/exit
0)"
Amounts=[-100,-100]
"Elapsed time: 0.248209 msecs"

If I ensure the non-modifying ref - the code takes variable amount of
time - ranging from 1 second to 15 seconds (10 runs).

$ java -cp lib/clojure-1.2.0.jar\;src clojure.main -e "(require 'tt)
(tt/transaction-simul {:ensure2 true :ensure1 false}) (System/exit 0)"
Amounts=[100,-100]
"Elapsed time: 7545.406736 msecs"

If I ensure both refs - the code takes even more time (on average).

$ java -cp lib/clojure-1.2.0.jar\;src clojure.main -e "(require 'tt)
(tt/transaction-simul {:ensure2 true :ensure1 true}) (System/exit 0)"
Amounts=[-100,100]
"Elapsed time: 10705.949317 msecs"

Can someone explain to me what ensure exactly does (implementation
wise)? and why its taking so much time?

Thanks!

PS: If someone is interested in the context - my first blog entry:
http://ka133.blogspot.com/2010/08/serializable-concurrency-sql-clojure.html

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


Re: RFC: updated c.c.logging with some breaking changes

2010-09-07 Thread ka
These seem like good changes to me!  Any plans to push?

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


Re: Clojure ensure

2010-10-02 Thread ka
I follow this thread, but haven't read Clojure's source. I have a
similar question - 
http://groups.google.com/group/clojure/browse_thread/thread/46415b89c7b311f6,
but haven't got any responses yet.

-- 
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: Cross-referencing objects?

2010-10-06 Thread ka
@Alan

I'm trying to understand why you find the solution you gave "gross"

> I could construct all the objects and have a single "global" map, with
> mappings for both set-id=>[objects] and object=>set-id, but this seems
> kinda gross and obscures what is actually meant (objects belong to
> sets) with implementation (integers/keywords mapping to groups of
> objects, and objects mapping to integers).

But you say:

> In an imperative language this would be fairly simple: create some
> empty sets, then iterate over all objects; at each step add the object
> to a set, and adjust the object's "parent" pointer to point at the set
> it's in.

Aren't these two same?

add object to a set _v/s_ set-id => #{objects}
adjust the object's "parent" pointer _v/s_ object => set-id

Only differences for me are:
1. In the imperative case you don't have to create a 'set-id'.  But
'set-id' would naturally come from the way you're partitioning in the
first place.
2. In the functional case you don't have to create a parent pointer
inside the object (which looks ugly to me - what is object's business
to know where it is lying? Tomorrow if you put the object in a second
set, will you add a parent2 or create a parents array or perhaps a map
of parent-id to parent itself).

Note that I may be totally misplaced or missing several things - just
trying to understand.

-- 
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: Idiomatic Way to Keep a Variable Private to a Namespace

2010-10-16 Thread ka
I've been wondering about having let over defn, I have the following
concerns -

1. Not recommended in the docs
http://clojure.org/special_forms#Special%20Forms--%28def%20symbol%20init?%29
says - Using def to modify the root value of a var at other than the
top level is usually an indication that you are using the var as a
mutable global, and is considered bad style.

2. Source is required again:
(ns a)

(println "a---1")

(let [b (atom 0)]
  (println "a---2")
  (defn op1 [] (swap! b inc))
  (defn op2 [] (swap! b dec)))

user=> (require 'a)
a---1
a---2
nil
user=> (a/op1)
1
user=> (require 'a :reload)
a---1
a---2
nil
user=> (a/op1)
1
user=>

But this is a more generic problem - do solve this you can -

(defonce ___
  (let [b (atom 0)]
(println "a---2")
(defn op1 [] (swap! b inc))
(defn op2 [] (swap! b dec

user=> (require 'a)
a---1
a---2
nil
user=>
user=> (a/op1)
1
user=> (a/op1)
2
user=> (require 'a :reload)
a---1
nil
user=> (a/op1)
3
user=>

But as you can see the code doesn't look too pretty.

-- 
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: Reference Menu sans Transients

2010-10-23 Thread ka
+1, besides adding transients, protocols 1.2 features, can we also
have a "Future" section after the Reference section?

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


Re: Clojure 1.3 Alpha 2

2010-10-27 Thread ka
Hi,

Please explain this!

> code path for using vars is now *much* faster for the common case, and you 
> must explicitly ask for :dynamic bindability

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


Clojure namespace dependencies - cdeps

2010-10-31 Thread ka
Few months back I started working on a project which already had 10k
lines of Clojure code.  There were already ~75 namespaces (not
including tests).  I was searching for a tool which would quickly give
me a high level overview of the code - how do the packages depend on
each other, which namespaces are high level and which ones low level
etc. In short I wanted a pretty graph of namespace dependencies for my
project.

Somebody pointed me to http://github.com/hugoduncan/lein-namespace-depends,
but I couldn't get it to work.

So thinking it a good exercise, I wrote a little utility which
generates namespace (and package) dependency graphs at various levels
- complete src, single ns, single package.  Additionally the graph
itself is available in many forms - Clojure map, .xml, .dot, .png

The code itself is a bit ugly & old but it works on both unix and
windows - http://github.com/na-ka-na/cdeps.  Checkout the examples/
directory to see some images.

Hopefully someone finds it useful.

Thanks

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


Re: a function to list the namespaces that a namespace refers to ...

2010-10-31 Thread ka
Hi, not sure if this is useful for you - http://github.com/na-ka-na/cdeps.

-- 
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: REQUEST for feedback on http://clojure.org

2010-11-02 Thread ka
Hi Alex,  Can we have a section: Clojure - What's next? Dishes out
some details & links for the next versions and ideas.

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


Some questions about Clojure Protocols

2010-11-03 Thread ka
1.  How to combine protocols?

For example I have protocols walks, talks, sleeps, now how might I
come up with an abstraction which walks-talks-and-sleeps ?  In Java
one might create an interface which extends multiple interfaces.
Although getting an instance which walks-talks-and-sleeps is made easy
with deftype.

On a related note if I have a protocol P how can I create a protocol
with is a union of P and java.lang.Comparable ?


2. Does it make sense to have "static" fns as part of Clojure
protocols?

For example a fn such as can-walk? could make sense as part of the
walks protocol.

I realize I can create a (defn can-walk? ...) in the protocol ns and
its the same from caller's pov .. (proto-ns/can-walk? ...).  But how
about having can-I-walk? as part of the walks protocol itself (somehow
to me it gives a more complete feeling).

Thanks.

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


Bug with instance? inside deftypes

2010-11-03 Thread ka
Clojure 1.2.0
1:1 user=>
1:2 user=>
1:3 user=> (deftype T [] Object (equals [this o] (if (instance? T o)
true false)))
user.T
1:4 user=> (def t (T.))
#'user/t
1:5 user=> (.equals t t)
false
1:6 user=> (deftype T [] Object (equals [this o] (if (= T (class o))
true false)))
user.T
1:7 user=> (def t (T.))
#'user/t
1:8 user=> (.equals t t)
true
1:9 user=>

(doc deftype) especially says:
> In the method bodies, the (unqualified) name can be used to name the class 
> (for calls to new, instance? etc).

Somebody on the IRC pointed out:
>> while compiling the deftype, T resolves to a different class object (a 
>> compiler-generated stub class) which might conflict with the special 
>> inlining of instance?

Thanks

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


Re: Bug with instance? inside deftypes

2010-11-03 Thread ka
>> I would guess the problem is referring to T inside the deftype.

This also works:

(deftype T [] Object (equals [this o] (if (= T (class o)) true
false)))

But as Meikel said hope that this is not the end of the story.

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


Re: Some questions about Clojure Protocols

2010-11-03 Thread ka
> AFAIK, it is not possible. You must implement all the different protocols.
> It might look desapointing, but on the other hand it is not necessary.
> (As there is no static typing in Clojure)
> What is your use-case?

Current use case is that I want an abstraction which comprises of a
set of operations I want + Comparable + Serializable

> Just define types that extend all the protocols.
> You can't. But you can define a type that extends both P and Comparable.

Currently I'm struggling with the following problem - Suppose I
consider something satisfying 'Coolness' property if it does x, y, z +
is comparable + serializes.

To do this I create a protocol 'OnlyHalfCoolness':
(defprotocol OnlyHalfCooless x y z)

and two deftypes Cool1, Cool2:
(deftype Cool1 ... OnlyHalfCoolness .. Comparable .. Serializable)
(deftype Cool2 ... OnlyHalfCoolness .. Comparable .. Serializable)

Now I need to write a function: is-this-cool?

Instead of
(defn is-this-cool? [o] (satisfies? Coolness o))

I need to now write:
(defn is-this-cool? [o] (or (instance? Cool1 o) (instance? Cool2 o))
or, (even worse)
(defn is-this-cool? [o] (and (satisfies? OnlyHalfCoolness o)
(instance? Comparable o) (instance? Serializable o))

A type hierarchy is not required - but I think a way to compose
(atleast union) abstractions would be nice.

Are there some fundamental problems with - (defprotocol Coolness ..
Comparable .. Serializable .. x y z) ?

> What do you mean by "static" functions?

Normal functions which do not dispatch based on the type of their
first argument. Forget about this - thinking more about it - they
don't really make too much sense in protocols.


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


Re: Some questions about Clojure Protocols

2010-11-04 Thread ka
> May I ask a heretic question: Why don't you specify the contract in the 
> docstring of the protocol?

Yes Meikel that is exactly what I have right now. Just trying to learn
and stir up a discussion here :)

Most times you'll just do fine by passing 'something' to Coolness
functions and expect them to work - they'll just blow up on runtime
(no .compareTo) if that 'something' isn't cool. But imagine certain
scary situations where that 'something' is really 'HalfCool' and still
some 'Coolness' functions work (type dispatch) behind your back!.

(defprotocol Coolness
  "Yadddayaddablablablubber.
  Cool things have to be Comparable and Serializable."
  (x .. "Since 'this' is cool i assume it is Serializable and
Comparable and so logically I can safely do this cool x thing!")
  (y ...))

(deftype ReallyCool ... Coolness .. Comparable .. Serializable)
(deftype SneakyCool .. Coolness)

(x (ReallyCool.)) ;yay rocket launches and reaches moon!
(x (SneakyCool.)) ;rocket launches alright (no exception thrown), but
blows mid air

I know you might argue its a code bug and caller's problem etc. - but
you just allowed a rocket to blow up.

Other times it might be necessary to know if something is 'Cool':

static public ISeq seq(Object coll){
  if(coll instanceof ASeq)
return (ASeq) coll;
  else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
  else
return seqFrom(coll);
}

@Laurent,
> * first, when I see calls to (instance?) (satisifies?), it rings a bell in my 
> head. "design problem".
Do you see the above seq method as a design problem? - or if you don't
care about Java, consider clojure.walk.

If I understand you correctly (probability of which is less) you don't
really see protocols as defining abstractions - but just as a
convenient tool for polymorphism. Like:

(extend ReallyCool clojure.contrib.json/Write-JSON
  {:write-json ...})

But all of this discussion is kind of bypassing my original question,
Meikel you say:

> A protocol comprises functions which act on data in a certain abstract way.

I simply asked - is there anything fundamentally wrong with the notion
of those protocols being composable. Protocol P is a set of abstract
functions, can we have a convenient way of saying P = union(P1, P2) ?

On a related note how is this:

(defn dispatch-fn [this ..]
  (if (and (comparable? this) (serializable? this))
 :green-signal :red-signal)

(defmulti x dispatch-fn)
(defmulti y dispatch-fn)
(defmulti z dispatch-fn)

-- 
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: Bug with instance? inside deftypes

2010-11-04 Thread ka
Christophe, Is it reasonable to assume that atleast the documentation
should be modified to reflect the situation?

-- 
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: Meta-circular STM for teaching purposes

2010-11-04 Thread ka
Hi Tom,

I might not be even remotely qualified but since I'm interested and
find the idea cool, so here's my take:

> - has anyone already experimented with a toy STM in Clojure for didactic 
> purposes?

No idea :)

> - what would be a good resource to start such a design from? (my current plan 
> is to start from )

I would think a good place to start is to define the primitives and
goals:
Primitives: assume existence of monitors in Clojure
Goals: Implement dosync in Clojure (hefty goal :))

I would love to help out in any capacity since I myself want to get
started with understand the STM in more detail. If you need a
volunteer you may contact me personally.

Thanks

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


Re: record serialization

2010-11-23 Thread ka
Hi Islon,

Records already implement java.io.Serializable. So this is working:

(ns record-serialization)

(defrecord R [x y])

(defn test-serialization
  []
  (with-open [oos (java.io.ObjectOutputStream.
(java.io.FileOutputStream. "tmp"))]
(.writeObject oos (R. 12 42)))
  (with-open [ois (java.io.ObjectInputStream.
(java.io.FileInputStream. "tmp"))]
(let [r (.readObject ois)]
  [r (:x r) (:y r)])))

user=> (record-serialization/test-serialization)
[#:record-serialization.R{:x 12, :y 42} 12 42]

-- 
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: dosync style

2010-12-03 Thread ka
> (defn dec-or-dissoc! [key]
>   (dosync
>(let [n (@*counts* key)]
>  (if (< 1 n)
>(alter *counts* assoc key (dec n))
>(alter *counts* dissoc key)

> Is it true that in that case, one would have to use "ensure" to make the 
> operation correct?

I don't think ensure is necessary here, coz the *counts* gets altered
in all cases.

Whereas consider this:

(defn dec-or-dissoc! [key]
  (dosync
   (let [n (@*counts* key)]
 (when (< 1 n)
   (alter *counts* assoc key (dec n))

In this case I think ensure is necessary.

Now consider this,

(defn dec-or-dissoc! [key]
  (dosync
   (alter *counts*
  (fn [m]
(let [n (m key)]
  (when (< 1 n)
(assoc m key (dec n

In this case ensure is not necessary.

-- 
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: why not change > < type compare functions do a compare on strings as well?

2010-12-03 Thread ka
Hi Tim,

How about compare?

user=> (compare "a" "b")
-1
user=> (compare "b" "b")
0
user=> (compare "b" "a")
1
user=> (compare 1 2)
-1
user=> (compare 2 2)
0
user=> (compare 2 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


Re: when to use io! macro?

2010-12-03 Thread ka
This is a good question and I'm not sure of the right answer or if
there is one. Personally, if I were exposing an API I would use the
io! macro for sure. Even otherwise its a good convention to follow.

On Nov 30, 9:06 am, Alex Baranosky 
wrote:
> Hi guys,
>
> I've recently discovered the io! macro.  Is this something to try to use all
> the time.. or only in certain situations?
>
> Alex

-- 
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: functional thinking

2010-12-03 Thread ka
Hi Michael,

We're in a very similar situation to yours. Here's what we did:

1. 2 back end storage impls rah.storage1, rah.storage2 - these are
"private" nses.
2. a single storage interface rah.storage for the rest of the business
code. At runtime this decides which of storage1 or 2 to call.
3. Now you can implement 2. in many ways, protocol, multimethods,
global vars etc. We chose multimethods + macros to generate defmethod
calls automatically.

@ Laurent, Ken,
Why not wrap the entry point in bound-fn ? Convenience?

-- 
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: resultset-seq improvement: mapping column names

2010-12-03 Thread ka
I'm also stuck with the same issues: 1. no option to get string keys
2. I don't understand, why do libs go through the trouble of
downcasing ?

Having said that I totally agree with the point Ryan makes: >> A
greater feature of clojure is its extensibility.  What I am after is a
generalization of the function in question, for greater
interoperability with Java's SQL libraries.

-- 
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: Getting strange behavior when stubbing

2010-12-10 Thread ka
Hi Brian,

Can you explain this in more detail :

>> I didn't have the laziness problem. I don't know if that was by accident or 
>> because Midje applies an #'eagerly function before checking.

Because it seems that if code has a laziness problem, Midje will
actually hide it in tests?

Thanks.

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


The 'in' family

2010-12-14 Thread ka
The functions get-in, assoc-in, update-in are really useful. Just
wanted to share a thoughts.

user=> (def m {:a {:b {:c 10 :c1 20} :b1 90} :a1 100})
#'user/m

1. Lets see the behavior of these functions in the corner case of
empty keyseq:

user=> (get-in m [])
{:a {:b {:c 10, :c1 20}, :b1 90}, :a1 100}

user=> (assoc-in m [] 42)
{nil 42, :a {:b {:c 10, :c1 20}, :b1 90}, :a1 100}

user=> (update-in m [] assoc :a2 42)
{nil {:a2 42}, :a {:b {:c 10, :c1 20}, :b1 90}, :a1 100}

get-in, assoc-in pretty much behave the way I would expect them to but
update-in is wierd especially considering get-in's output.

How about this:

user=> (update-in-2 m [] assoc :a2 42)
{:a2 42, :a {:b {:c 10, :c1 20}, :b1 90}, :a1 100}

(defn update-in-2
  [m ks f & args]
  (if (= 0 (count ks))
(apply f m args)
(let [[k & ks] ks]
  (assoc m k
(apply update-in-2 (get m k) ks f args)

2. There's no dissoc-in ! With the above definition of update-in-2,
dissoc-in is simply:

(defn dissoc-in [m ks] (update-in-2 m (butlast ks) dissoc (last ks)))

Even assoc-in is simply:

(defn assoc-in [m ks v] (update-in-2 m (butlast ks) assoc (last ks)
v))

Can we please have dissoc-in in core.

- Thanks

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


Re: currying in clojure for fixed number of arg functions

2010-12-20 Thread ka
+1 on partial with no args !

I have a doubt: using partial conveys the intent, but with automatic
currying one may get confused between "partial application" &
"function call", no?

-- 
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: which IDEs are you all using?

2011-01-11 Thread ka
Here's one way to use eclipse + ccw + lein

1. Download latest eclipse helios. Go to market place and search for
counter clockwise plugin. Install the latest stable.
2. Create a new Clojure project. Delete the 4 jars it provides :) (yes
that's right delete them).
3. Install lein (https://github.com/technomancy/leiningen).
4. Create a new project.clj (top level of your project) with clojure
1.2 & clojure-contrib 1.2 dep (or even 1.3-alpha4).
5. Open up a cmd and cd to your project and do >lein deps. (It will
add jars to the lib directory in your project folder).
6. Right click on your project in eclipse, go to properties > java
build path. Remove the 4 jar entries already present. Then 'Add jars'
by selecting your lib folder. This will amend a a file '.classpath' in
your project, you can directly amend that and refresh your project too
(its the same). The entries present in .classpath are used as the -cp
argument (along with some more dirs) to launch the clojure REPL
(there's no magic).
7. Done! Right click on project and Run As Clojure REPL.

For adding any new deps, just add the entry in project.clj and repeat
steps 5., 6. above.

-- 
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: running just one test

2011-01-11 Thread ka
@Bill,

If you have a REPL open you can just run the test as a zero arg
function.

(ns 'abc)

(detest xyz ...)

user=> (abc/xyz)

-- 
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: Question about sorted-sets

2011-01-11 Thread ka
Yes that compareTo doesn't define a total order on your class. I think
you are missing a clause in cond:

(cond
(= sr sr2) 0
(= (.lik sr) (.lik s2)) return something based on quasi-isomorphic
(> (.lik sr) (.lik sr2)) -1
:default 1)

I think you should implement quasi-isomorphic as a compare function
(Comparator), then:

equals:
(and (= lik (.lik other)) (= 0 (compare-quasi-isomorphism tree (.tree
other

compareTo:
(let [l (- (.lik sr) (.lik sr2))
   q (compare-quasi-isomorphism (.tree sr) (.tree sr2))]
  (cond
(and (= l 0) (= q 0)) 0
(not= l 0) l
(not= q 0) q
:default 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


Re: Euler 14

2011-01-19 Thread ka
To me this looks totally fine, max-key should keep at most two
sequences in memory. I don't think there should be any difference
between the non-lazy and lazy versions as the depth of cseq is ~500.

The non-lazy version works for me (no heap error) for inputs 1M, 2M,
4M, but for 4M the java process did start to consume very large amount
of memory.

I did some tests with the original non-lazy cseq and (apply max-key
count (map cseq (take 400 (iterate inc 1 [Free of chunking I
think]

Running in VisualVM suggests that % of Used Heap is actually very
less. So the problem is that GC isn't running often enough, so the JVM
has to keep allocating more memory.

Running with -Xmx200M -XX:+UseParallelGC, did keep heap upto 200MB and
produces results for 4M, 10M (ans=686) w/o any problems. It will
consume much CPU and time though.



-- 
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: Euler 14

2011-01-20 Thread ka
>> Running in VisualVM suggests that % of Used Heap is actually very
>> less. So the problem is that GC isn't running often enough, so the JVM
>> has to keep allocating more memory.

By problem I meant, in my case, of too much memory consumption.

> Odd.  I'd expect the JVM to run a GC immediately before reporting that
> the heap has been exhausted.

That certainly is odd, I would expect the same. But quick googling
doesn't turn up any references of the JVM which mention this.

Can you take a heap dump of the chunked and non-chunked versions (-XX:-
HeapDumpOnOutOfMemoryError)?

-- 
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: Euler 14

2011-01-20 Thread ka
Andreas, How are you running that? Also what do you see in the heap
dump and what is the jvm heap size?

-- 
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: Getting started with Counterclockwise

2011-01-20 Thread ka
I've been using ccw for a while now and it works perfectly as
advertised. Plus the new 0.2.0 version looks to be really promising. I
invite all ccw users to give their inputs.

What's bugging is not that you faced a problem or that ccw didn't work
as you expected, what's disturbing is how you reacted to it. What
follows is that the developers working on the project get discouraged,
some new users may just read your post and decide not to try out ccw.

You should give a thought before posting something like this. Do you
really want to end up like this: 
http://en.wikipedia.org/wiki/The_Boy_Who_Cried_Wolf.

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