Re: Help Getting Sente to Work

2014-07-26 Thread Bob Hutchison

Hi Tim,

I think I went through this when I was first starting with Sente. You need to 
setup the CSRF handling part, in the example code by including 
ring-anti-forgery/wrap-anti-forgery in your routes. *AND* you have to make sure 
that you are using one of those routes before you try to use Sente's connection 
stuff, otherwise your session won't have certain critical attributes set (e.g. 
__anti-forgery-token). I think the 404s are from the anti-forgery stuff 
rejecting your request. And I think Sente is assuming it's setup. This was a 
while ago so maybe I'm not remembering it quite right.

Cheers,
Bob

On Jul 26, 2014, at 12:33 AM, Timothy Washington  wrote:

> Hi all, 
> 
> I'm using [com.taoensso/sente "0.15.1"], and having trouble connecting the 
> client to the server. I'm sure it's something simple, but not obvious, as 
> this is taken directly from the examples on sente's github page. Anyone seen 
> and fixed the error in fig.1? The clojurescript and clojure code are in fig 2 
> and 3 respectively. 
> 
> 
> WebSocket connection to 'ws://172.28.128.5:58269/chsk' failed: Error during 
> WebSocket handshake: Unexpected response code: 404
> WebSocket error: [object Event] VM1707:1689
> Chsk is closed: will try reconnect (8). VM1707:1689
> 
> fig.1 - Chrome network error message 
> 
> (ns my.ns
>   (:require-macros
>[cljs.core.match.macros :refer (match)] ; Optional, useful
>[cljs.core.async.macros :as asyncm :refer (go go-loop)])
>   (:require
>;;[clojure.browser.repl :as repl]
>[cljs.core.match] ; Optional, useful
>[cljs.core.async :as async :refer (! put! chan)]
>[taoensso.sente :as sente :refer (cb-success?)]))
> 
> 
> (let [{:keys [chsk ch-recv send-fn state]}
>   (sente/make-channel-socket! "/chsk" {:type :auto})]
> 
>   (def chsk   chsk)
>   (def ch-chskch-recv) 
>   (def chsk-send! send-fn) 
>   (def chsk-state state))
> 
> (defn one []
>   (chsk-send! [:some/request-id {:name "Rich Hickey" :type "Awesome"}]))
> 
> fig.2 - my.cljs 
> 
> 
> (ns my.http.ns
>   (:require [compojure.core :refer :all]
> ...
> 
> ;; Sente stuff
> [clojure.core.match :as match :refer (match)] ; Optional, useful
> [clojure.core.async :as async :refer (! >!! put! chan go 
> go-loop)]
> [taoensso.sente :as sente]))
> 
> 
> (let [{:keys [ch-recv send-fn ajax-post-fn ajax-get-or-ws-handshake-fn]}
>   (sente/make-channel-socket! {})]
>   
>   (def ring-ajax-postajax-post-fn)
>   (def ring-ajax-get-or-ws-handshake ajax-get-or-ws-handshake-fn)
>   (def ch-chsk   ch-recv)
>   (def chsk-send!send-fn))
> 
> ...
> 
> (defn create-approutes [project-config browserrepl]
> 
>   (defroutes app-routes
> 
> ;; Sente stuff
> (GET  "/chsk" req (ring-ajax-get-or-ws-handshake req)) ; tried both 
> ring-ajax-get-or-ws-handshake and #'ring-ajax-get-or-ws-handshake
> (POST "/chsk" req (ring-ajax-postreq)); same here 
> for trying both 
> 
> 
> (GET "/" []
>  (-> (ring-resp/response (with-browser-repl "index.html" browserrepl))
>  (ring-resp/content-type "text/html")))
> 
> (route/resources "/" {:root "resources/public/"})
> (route/not-found "Not Found")))
> 
> fig.3 - my.clj 
> 
> 
> Tim Washington 
> Interruptsoftware.com 
> 
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> --- 
> You received this message because you are subscribed to the Google Groups 
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Is this behavior with recur and pre/post a bug?

2014-07-25 Thread Bob Hutchison

On Jul 25, 2014, at 12:27 AM, Michael O'Keefe  
wrote:

> Andy, good advice and I agree. Thanks. I'll think on it then.

Would you want one of your users going though this kind of thought process: I 
won't file a ticked because I don't think it can be fixed? It's a bug, file the 
ticket. At the very least it can be documented.

Cheers,
Bob


-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: unexpected behavior of clojure.core/empty

2014-07-18 Thread Bob Hutchison

On Jul 18, 2014, at 5:45 AM, Brian Craft  wrote:

> => (empty [:foo 5])
> []
> => (first (mapv identity {:foo 5}))
> [:foo 5]
> => (empty (first (mapv identity {:foo 5})))
> nil

=> (class (first (mapv identity {:foo 5})))
clojure.lang.MapEntry
=> (class (first (mapv (fn [[k v]] [k v]) {:foo 5})))
clojure.lang.PersistentVector
=> (empty (first (mapv (fn [[k v]] [k v]) {:foo 5})))
[]

by mapping identity over the map you're returning a vector of MapEntries (which 
print/deconstruct like a two element array).

Cheers,
Bob

> 
> What just happened there? Is this expected? In the second and third cases the 
> type of the vector is clojure.lang.MapEntry, which I expect is the root of 
> the behavior, but this seems very inconsistent. Is there a way to get the 
> behavior one would expect? Should clojure.core/empty be avoided?
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Local variable

2014-07-08 Thread Bob Hutchison

On Jul 8, 2014, at 7:08 PM, Cecil Westerhof  wrote:

> 2014-07-08 23:11 GMT+02:00 Bob Hutchison :
> 
> On Jul 8, 2014, at 9:40 AM, Cecil Westerhof  wrote:
> 
> > In Clojure you can define a local constant with let, but I need a variable 
> > (I think).
> >
> > I want to do the following. I have a function that checks several things. 
> > Every time an error is found I want to set the variable errors to:
> > (concat errors new-error)
> >
> > Is this possible? Or is there a better way to do this?
> 
> Here's a different take on your question, and a few comments about how I'd 
> write that code. I don't think you need the atom -- kinda ugly and the 
> reduce/map/filter family of sequence functions will take you a long way.
> 
> ; This is not a predicate, so don't use the -p suffix (and in Clojure it's a 
> ? normally)
> 
> ​As I understood it (I am rewriting land of lisp to Clojure) that when a 
> function returns a true/false state, that you then use the -p suffix. When 
> returning () there are no errors. But I should use the ? then?

You’re returning a list of errors. You can interpret that as a truthy/falsy 
kind of thing, in which case make sure you’re returning a nil for the no-error 
case. And use the ‘?’ in Clojure.

> 
> ​ 
> ; There's no reason not to pass those two objects into this function, so I do.
> 
> ​Good idea. Makes it easy to test the function also.

it does

> 
> […]​ 
>  
> I hope you can make sense of that :-)
> 
> ​Not immediately. I need to digest it.

Have fun.

> 
> By the way. The current function is only the start of the checks.​  ​After 
> the if I need to do several other checks also. So I think I do need the atom. 
> But maybe I am mistaken. ;-)

I thought maybe your checks would be a little more than that. That’s why I left 
the ‘reduce’ version in there. Just make the function that is applied by reduce 
more powerful, perhaps pull it out into a separate function rather than an 
inline anonymous function. This will work as long as all tests are performed on 
one object at a time.

No matter what, I’d recommend not going using an atom if you can help it.

Cheers,
Bob

> 
> -- 
> Cecil Westerhof
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Local variable

2014-07-08 Thread Bob Hutchison

On Jul 8, 2014, at 9:40 AM, Cecil Westerhof  wrote:

> In Clojure you can define a local constant with let, but I need a variable (I 
> think).
> 
> I want to do the following. I have a function that checks several things. 
> Every time an error is found I want to set the variable errors to:
> (concat errors new-error)
> 
> Is this possible? Or is there a better way to do this?

Here's a different take on your question, and a few comments about how I'd 
write that code. I don't think you need the atom -- kinda ugly and the 
reduce/map/filter family of sequence functions will take you a long way.

; This is not a predicate, so don't use the -p suffix (and in Clojure it's a ? 
normally)
; There's no reason not to pass those two objects into this function, so I do.
(defn errors-in-datastruct [locations objects]
  (if (= (count objects) (count locations))
; 'remove' makes a new sequence containing elements that had a falsey 
; (false or nil) result to the provided function -- that is the objects
; with no location

; the mapv maps a function over a sequence resulting in a vector.
; the function creates a vector pair for each object containing the error
; code and object

; I find vectors more natural to use in Clojure

; I also find keywords more natural (and useful)

; In my mind, finding the errors and reporting them are two separate 
functions. If you want to make
; a nicer error report, then map a reporting function over the error codes.

(mapv #(vector :no-location %) (remove locations objects))

; This reduce does something similar to the mapv/remove combination above, 
but 
; it gives you more flexibility.

#_(reduce (fn [errors obj] 
(if (locations obj) 
  errors 
  (conj errors [:no-location obj]))) [] objects)

[[:counts-differ]]))

; use locally scoped variables if you can
(let [locations {:whiskey :living-room
 :bucket  :living-room
 :chain   :garden
 :frog:garden
 :dummy   :nowhere}]
  (println (errors-in-datastruct locations [:whiskey :bucket :chain :frog 
:dummy]))
  (println (errors-in-datastruct locations [:whiskey :bucket :chain :frog :pole 
:dummy]))
  (println (errors-in-datastruct locations [:whiskey :bucket :chain :frog 
:pole]))
  (println (errors-in-datastruct locations [:whiskey :bucket :chain :frog1 
:pole]))
  (println (errors-in-datastruct locations [:whiskey :whiskey :whiskey :whiskey 
:whiskey])))


; If you need to use the same locations map and don't want to pass it around, 
you can
; partially apply the errors-in-datastruct function to the locations, and use 
that function.
; You probably don't care about this but the technique can be very handy when 
getting
; rid of global variables.
(let [f (partial errors-in-datastruct {:whiskey :living-room
   :bucket  :living-room
   :chain   :garden
   :frog:garden
   :dummy   :nowhere})]
  (println (f [:whiskey :bucket :chain :frog :dummy]))
  (println (f [:whiskey :bucket :chain :frog :pole :dummy]))
  (println (f [:whiskey :bucket :chain :frog :pole]))
  (println (f [:whiskey :bucket :chain :frog1 :pole])))


I hope you can make sense of that :-)

Cheers,
Bob

> 
> -- 
> Cecil Westerhof
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Workflow: cljx, cljsbuild & tdd in one process

2014-06-22 Thread Bob Hutchison
Thanks for the tip, works nicely. I was doing the same thing Michal was doing.

Cheers,
Bob

On Jun 20, 2014, at 11:07 AM, Michael Griffiths  
wrote:

> There's also a Leiningen plugin called lein-pdo that lets you run tasks in 
> parallel: https://github.com/Raynes/lein-pdo
>  
> Example usage for cljx auto & cljsbuild auto: 
> https://github.com/DomKM/omelette/blob/master/project.clj#L59
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Clojure:Lisp :: LSD:Meditation

2014-06-13 Thread Bob Hutchison

On Jun 13, 2014, at 6:58 AM, Jonas  wrote:

> I found this post from 2011 which probably is still relevant: 
> https://groups.google.com/d/msg/clojure/t0pGIuoyB7I/RQtuuAOhes8J

And just for fun, from that thread... Rich Hickey wrote:

"There will be times, yes, when the most considerate thing will be to write 
opinions in a blog post, perhaps putting only a pointer here and following up 
on the blog."


> 
> On Friday, June 13, 2014 1:05:47 PM UTC+3, David Della Costa wrote:
> You raise a good point, which is that I don't know what the group policy 
> is or where it's posted.  I just see this in the header on the google 
> groups page: 
> 
> "Welcome to the Clojure mailing list. Please note that posts by new 
> members are moderated to prevent spam." 
> 
> Anyone know better than this? 
> 
> (2014/06/13 18:50), Josh Kamau wrote: 
> > If i were to be asked, i would restrict the group to: 
> > 1. Any type of question that is related to clojure 
> > 2. Any type of announcement on clojure core library 
> > 3. Any new library/version 
> > 4. Any link to a narration on real life usages (e.g how we did xyz with 
> > clojure) or benchmarks  (generally hard facts ) 
> > 5. Any link to new book, tutorial, training materials. 
> > 
> > This is just my opinion, I dont know the group policy and may be its all 
> > up to me to choose what i want to read and what i dont want to and 
> > probably keep my feelings to myself ;) 
> > 
> > Josh 
> > 
> > 
> > On Fri, Jun 13, 2014 at 12:34 PM, Dave Della Costa 
> > mailto:ddell...@gmail.com>> wrote: 
> > 
> > I'm not sure what the problem is here.  I've posted personal blog links 
> > before that were Clojure related; I sincerely thought that it was 
> > potentially useful to the group, and I more or less got responses that 
> > supported that. 
> > 
> > That being the case, I'm having a hard time understanding what is so 
> > different about my blog post and Divyansh's; as far as I can tell, this 
> > post is relevant to Clojure, even if it's a bit more...exploratory.  It 
> > has Clojure code examples, it talks about Common Lisp and Python and 
> > metaprogramming.  It's clearly not random spam. 
> > 
> > So it seems to me that some folks simply don't like the content; that's 
> > fine, but I think it's a stretch to say that it's not appropriate for 
> > this list.  Or if it is not appropriate, then even relevant blog posts 
> > should never be appropriate, and arguably stuff like, say, epic 
> > ruminations on the nature of literate programming would arguably be 
> > even 
> > less appropriate for the list. 
> > 
> > DD 
> > 
> > (2014/06/13 11:25), Gary Trakhman wrote: 
> > > To be fair, I actually read the thing, but I hoped to see more 
> > > interesting information on LSD, meditation and Clojure than the 
> > headline 
> > > would suggest :-). 
> > > 
> > > 
> > > On Thu, Jun 12, 2014 at 10:01 PM, Atamert Ölçgen  >  
> > > >> wrote: 
> > > 
> > > There's also Planet Clojure . 
> > > 
> > > @Divyansh 
> > > 
> > > Josh, Hussein and Gary are not the only ones who think this 
> > sort of 
> > > traffic building is uncool. By traffic building I mean; sending a 
> > > message with a link that has no valuable information for the 
> > group 
> > > members. They are probably just nodding their head and 
> > thinking that 
> > > sending another response is not necessary. At least that's what I 
> > > did before I saw your response. 
> > > 
> > > 90% of the messages in this group doesn't interest me. That's 
> > fine. 
> > > Valuable information for someone else. But I certainly 
> > wouldn't want 
> > > everybody to post their blogs here regularly. Because each 
> > message 
> > > is a tiny little distraction. I'm willing to pay the price 
> > because 
> > > when a really cool library is announced for example, I get a big 
> > > reward. Let's keep the benefit/cost ratio, time-wise & 
> > > attention-wise, high. 
> > > 
> > > 
> > > 
> > > 
> > > On Thu, Jun 12, 2014 at 10:05 PM, Gary Trakhman 
> > > mailto:gary.t...@gmail.com> 
> > >> 
> > wrote: 
> > > 
> > > Twitter's a more organic way to do this.  Your followers can 
> > > read it, decide to retweet or not. 
> > > 
> > > 
> > > On Thu, Jun 12, 2014 at 5:37 PM, Divyansh Prakash 
> > >  >  
> > >  > >> wrote: 
> > > 
> > > Sorry if you feel that way. Thought i could share my 
> > > thou

Re: "in Clojure I rarely find myself reaching for something like the state monad, as I would in Haskell"

2014-05-19 Thread Bob Hutchison

On May 19, 2014, at 2:45 PM, Ben Wolfson  wrote:

> On Mon, May 19, 2014 at 11:28 AM, Bob Hutchison  
> wrote:
> 
> I badly miss the Maybe and Either monads, but would want the syntactic 
> support Haskell provides (which I can't see will ever be available in Clojure)
> 
> I've been pretty happy with: 
> https://github.com/bwo/monads/blob/master/src/monads/core.clj#L65
> 

Hmm. I'm going to have to take another look at that. 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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: "in Clojure I rarely find myself reaching for something like the state monad, as I would in Haskell"

2014-05-19 Thread Bob Hutchison

On May 19, 2014, at 1:50 PM, Ben Wolfson  wrote:

> On Mon, May 19, 2014 at 7:48 AM, Bob Hutchison  
> wrote:
> 
> Haskell's STM transactions can be thought of as a form of IO action (like 
> reading a file is an IO action) that modify refs (there are no atoms in 
> Haskell, only refs). A transaction must be started in the IO monad and then, 
> like IO, the STM monad is 'carried' in type signatures through all 
> intervening computations that could take part in the transaction. The STM 
> type/monad 'blocks' the IO type/monad (you can't do other IO actions if you 
> might take part in an STM transaction (IO action), this is an effect of, and 
> enforced by, Haskell's type system (i.e. it's a compilation not a runtime 
> error)). In Clojure the STM isn't part of the IO system, and you can start or 
> take part in a transaction anywhere you want to, even nest dosyncs within a 
> single transaction, and intermingle transactional code with IO (no matter how 
> bad an idea that is).
> 
> You can use regular IO in an STM action with unsafeUItoSTM: 
> <http://hackage.haskell.org/package/base-4.7.0.0/docs/GHC-Conc-Sync.html#v:unsafeIOToSTM>.
>  IMO it's advantageous that you have to explicitly say that you want to do IO 
> inside a transaction, given that (in general) you probably shouldn't be doing 
> it.

You're right. I didn't want to bring that up though. It's well named. I used 
the various unsafe* functions regularly while debugging, and even then only for 
writing to the console. I would be *very* *very* reluctant to use any of them 
in production, and certainly not intentionally design something that required 
their use. So, for the purposes of this discussion, I figured I'd just pretend 
they didn't exist.

Cheers,
Bob

> 
> -- 
> Ben Wolfson
> "Human kind has used its intelligence to vary the flavour of drinks, which 
> may be sweet, aromatic, fermented or spirit-based. ... Family and social life 
> also offer numerous other occasions to consume drinks for pleasure." 
> [Larousse, "Drink" entry]
> 
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: "in Clojure I rarely find myself reaching for something like the state monad, as I would in Haskell"

2014-05-19 Thread Bob Hutchison

On May 19, 2014, at 1:44 PM, Ben Wolfson  wrote:

> I wouldn't say that I *often* find myself reaching for monads, or the state 
> monad in particular, but I certainly have found them useful on occasion (and 
> would have sometimes refrained from using them where I'd naturally lean to 
> doing so solely to avoid creating an dependency). For instance, whenever 
> there's a couple of functions that return either a success value or an error 
> message that have to be threaded together---an error monad to do the plumbing 
> makes this a lot nicer.

I badly miss the Maybe and Either monads, but would want the syntactic support 
Haskell provides (which I can't see will ever be available in Clojure)

> 
> We've got a library at ReadyForZero for walking though json and xml 
> structures and doing transformations based on the values found there, or a 
> bit of configuration, using a combined reader-writer-state monad, and a bunch 
> of code that uses it. The state that's held is actually just a zipper into 
> the structure, the configuration at this point is only a keyword, and the 
> writer log holds reports of unexpected values. This could all be done with 
> other machinery---pass the zipper around directly (or hold it in an atom), 
> pass the log around directly (or hold it in an atom), use a dynamic variable 
> + binding for the configuration (since the reader monad amounts to that 
> anyway). However, I think the monadic code is easier to work with, partly 
> because nothing does need to be managed or passed around explicitly (so it's 
> easier to put together lots of little pieces), and partly because it enables 
> the use of generic tools. Also, traversing the the structures has a fairly 
> imperative feel---go here, go there, do this transformation---with occasional 
> variable binding, and the macro for monadic computations the monad library 
> we're using provides makes expressing that fairly convenient. (Though I may 
> be biased, since I wrote it.)
> 
> It's true that there doesn't seem to be much need for introducing a monad 
> library and using the state monad if you *only* had the state monad, since 
> Clojure has other ways to deal with mutation (incidentally, I don't think 
> it's true to say that Haskell only has refs, not atoms; there are functions 
> to modify IORefs, which live outside the STM system, atomically).

Which is why I didn't call them atoms :-) There's also a ref in the ST monad 
(which is a bells-and-whistles state monad that has fallen into a bit of disuse 
since the IO monad appeared)

> 
> 
> 
> On Fri, May 16, 2014 at 5:49 PM, Julian  wrote:
> A quick shoutout to the Clojure Community - thanks for the way you've all 
> contributed to make my life (mentally) richer. 
> 
> James Reeves (author of Compojure and many other wonderful libraries) made 
> this interesting comment on Hacker News:
> > Clojure has libraries that implement monads, but these aren't often used 
> > for threading state. I can't quite place my finger on why, but in Clojure I 
> > rarely find myself reaching for something like the state monad, as I would 
> > in Haskell.
> >Clojure tends to view mutability as a concurrency problem, and the tools it 
> >provides to deal with mutability, such as atoms, refs, agents, channels and 
> >so forth, are not mechanisms to avoid mutation, as to provide various 
> >guarantees that restrict it in some fashion.
> >It might be that in the cases where I'd use a state monad in Haskell, in 
> >Clojure I might instead use an atom. They're in no way equivalent, but they 
> >have some overlapping use-cases.
> https://news.ycombinator.com/item?id=7751424
> My question is - have other Clojure/Haskell programmers had this experience? 
> (ie "I rarely find myself reaching for something like the state monad"). I'm 
> interested to hear if so, and why. 
> JG
> PS If this post is unhelpful, could be worded better - please let me know. 
> I'm asking out of curiosity, not with intent to troll. 
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
> 
> 
> 
> -- 
> Ben Wolfson
> "Human kind has used its intelligence to vary the flavour of drinks, which 
> may be sweet, aromatic, fermented or spirit-based. ... Family and social life 
> also offer numerous other occasions to consume drinks for pleasure." 
> [Larousse, "Drink" entry

Re: "in Clojure I rarely find myself reaching for something like the state monad, as I would in Haskell"

2014-05-19 Thread Bob Hutchison

On May 16, 2014, at 8:49 PM, Julian  wrote:

> A quick shoutout to the Clojure Community - thanks for the way you've all 
> contributed to make my life (mentally) richer. 
> 
> James Reeves (author of Compojure and many other wonderful libraries) made 
> this interesting comment on Hacker News:
> > Clojure has libraries that implement monads, but these aren't often used 
> > for threading state. I can't quite place my finger on why, but in Clojure I 
> > rarely find myself reaching for something like the state monad, as I would 
> > in Haskell.
> >Clojure tends to view mutability as a concurrency problem, and the tools it 
> >provides to deal with mutability, such as atoms, refs, agents, channels and 
> >so forth, are not mechanisms to avoid mutation, as to provide various 
> >guarantees that restrict it in some fashion.
> >It might be that in the cases where I'd use a state monad in Haskell, in 
> >Clojure I might instead use an atom. They're in no way equivalent, but they 
> >have some overlapping use-cases.
> https://news.ycombinator.com/item?id=7751424
> My question is - have other Clojure/Haskell programmers had this experience? 
> (ie "I rarely find myself reaching for something like the state monad"). I'm 
> interested to hear if so, and why. 
> 

I'm perhaps an atypical specimen (and I'm not what I'd call an expert Haskell 
programmer) but... I've written a fairly substantial prototype in Haskell 
(maybe 25k sloc, whatever that means) that made heavy use of the state monad. 
I've re-written the same application in Clojure and it never, even once, 
occurred to me to use the state monad. As James Reeves pointed out, Clojure 
programmers normally use atoms or refs to manage this kind of state. Looking at 
my two code bases you'd notice that the state monad would have been replaced in 
Clojure by a bunch of refs and atoms. If the state had been less complex and 
the application less concurrent I'd have used a single atom.

In Haskell you'd not be able to use this technique nearly as frequently, if at 
all, and certainly not in the same way. 

Please excuse the imprecision in the following... 

In Haskell, all IO is marked in the type signatures, and so if you want to 
perform any IO you have to carry the IO monad with you (IO appears in your type 
signature) into all 'sub' computations. The IO monad exists at the top level of 
your program, and so must be 'carried' all the way from the top level, you 
can't just suddenly start using IO deep within some computation. And this is 
exactly what you want in Haskell -- it's a *good* thing. In Clojure you can 
perform IO wherever you wish, and in Clojure this is exactly what you want, and 
is also a *good* thing. 

Haskell's STM transactions can be thought of as a form of IO action (like 
reading a file is an IO action) that modify refs (there are no atoms in 
Haskell, only refs). A transaction must be started in the IO monad and then, 
like IO, the STM monad is 'carried' in type signatures through all intervening 
computations that could take part in the transaction. The STM type/monad 
'blocks' the IO type/monad (you can't do other IO actions if you might take 
part in an STM transaction (IO action), this is an effect of, and enforced by, 
Haskell's type system (i.e. it's a compilation not a runtime error)). In 
Clojure the STM isn't part of the IO system, and you can start or take part in 
a transaction anywhere you want to, even nest dosyncs within a single 
transaction, and intermingle transactional code with IO (no matter how bad an 
idea that is).

That's a lot of talk to get to the point that using the STM has an 
insignificant impact on the structure of your Clojure programs, while in 
Haskell the impact is huge (of course, it's possible to argue that that's a 
*good* thing). In Haskell the state monad is pretty flexible, well supported by 
the language, and allows you to sidestep a lot of this impact (for one thing, 
you can introduce it anywhere). In Clojure the state monad would buy you 
nothing (in my opinion) while using it would have an impact on your programs 
structure. In Haskell there are forces pushing you to use the state monad, 
while in Clojure there are forces pushing you away from the state monad.

In my opinion.



I've 'simplified' my explanation, and obscured some of the actual 
issues/powers/advantages of Haskell's type system. For example, I hand-wavingly 
using the phrase 'you can/can't introduce...' -- it isn't quite like that, but 
that's the effect, so, I think, close enough for this discussion.

 

As an aside, a Clojure programmer might get a feel for what Haskell's state 
monad is like by considering the -> and ->> macros. Within the -> macro you 
start by defining your initial state then applying a sequence of operations to 
an updated state. You don't have to mention the state in your code again. The 
functions called in the -> and ->> macros have either their first or last 
argument 'receiving' the state and re

Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Bob Hutchison

On May 3, 2014, at 9:45 AM, Dave Tenny  wrote:

> I'm still struggling with how to write the most readable, simple clojure code
> to deal with dynamically bindings.
> 
> What is the graceful clojure equivalent of common lisp special variables for 
> the following scenario.
> 
> If I were writing common lisp I'd just do something like (pardon if my lisp 
> is rusty here):
> 
> (defvar *x* 1)
> ... do stuff with *x* ...
> (setq *x* 2)
> ... do stuff with *x* ...
> (let ((*x* 3))  (do stuff with *x*...)
> ;; do stuff with *x* that's currently at 2
> 
> 
> The way I'm tempted to do this in clojure is
> 
> (def ^{:dynamic true} *x* (atom 1))
> ... do stuff with @*x* ...
> (reset! *x* 2)
> ... do stuff with @*x* ...
> (binding [*x* (atom 3)] (do stuff with @*x*))

Inside the binding you can call set! if you must.

You can also just use 'def' to redefine the global binding. It says this:

"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. Consider either using binding to provide a thread-local 
value for the var, or putting a ref or agent in the var and using transactions 
or actions for mutation." in the docs at http://clojure.org/special_forms#def 
which is roughly what you did with the atom. But it'll work.

You can also just write it:

(def ^:dynamic *x* (atom 1))

which is a little less verbose.

Cheers,
Bob

> 
> 
> Is that the simplest way to map between the two language scenarios?
> Or is there something simpler, perhaps using some var-* apis or what have you?
> 
> 
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Do not understand why loop takes 3 arguments who are all the same

2014-05-03 Thread Bob Hutchison

On May 3, 2014, at 6:42 AM, Roelof Wobben  wrote:

> 
> (fn [default initial-keys]
>   (loop [remaining-keys initial-keys
>  result-map {}]
>  (if (empty? remaining-keys)
>result-map
>(let [key (first remaining-keys)
>  remaining-keys' (rest remaining-keys)
>  result-map' (assoc result-map key default)]
>  (recur remaining-keys' result-map')
> 
> This also passes the unit tests.
> 
> Maybe that's a bit clearer as to what's going on. Maybe the new names help a 
> bit. Notice the ticks on some of the names (the ' characters). This is just a 
> convention some programmers use. The ticks are part of the name, nothing 
> magic, and are used to indicate that the value of the name is derived from 
> the value of the name with one less tick. Some programmers use numbers 
> instead. Other programmers don't care and just use the same name.
> 
> When you've understood the solution you've come up with, you might want to 
> try using reduce to do this. It'll be both shorter and much easier to 
> understand. If you look carefully at your code the only part that isn't 
> boiler-plate is the (assoc result-map key default) -- the boiler-plate 
> corresponds closely to what reduce does.
> 
> 
> Thanks,
> 
> Now It more clearer what loop does.
> I can look at a reduce solution but then I have to look which reduce I have 
> to use.
> I know  reduce + and reduce - which does calculations on the collection.

This reduce: http://clojuredocs.org/clojure_core/clojure.core/reduce is what 
you need.

Cheers,
Bob

> 
> Roelof
>  
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Do not understand why loop takes 3 arguments who are all the same

2014-05-03 Thread Bob Hutchison
Hi Roelof,

On May 3, 2014, at 3:09 AM, Roelof Wobben  wrote:

> Hello, 
> 
> Im now at the last exercise of the beginners exercise of 4clojure.

nice!

> 
> I figured out that this solution works.
> 
> (fn [default lijst1]
>   (loop [lijst lijst1 d {}]
>  (if (empty? lijst)
>d
>(recur (rest lijst) (assoc d (first lijst) default)

Yes, it passes the unit tests.

> 
> But as I see it lijst lijst 1 and d are all the same. They all contains the 
> collection which has to fill in the end collection.
> As a example I mean  default = 0 lijst 1 [:a :b: :c] 
> then lijst1 and d also contains [:a :b:c]  so what is then the point of using 
> 3 arguments.

There's only two arguments (to the loop and to the function). I re-wrote your 
code changing the names of variables and adding a few line breaks as:

(fn [default initial-keys]
  (loop [remaining-keys initial-keys
 result-map {}]
 (if (empty? remaining-keys)
   result-map
   (let [key (first remaining-keys)
 remaining-keys' (rest remaining-keys)
 result-map' (assoc result-map key default)]
 (recur remaining-keys' result-map')

This also passes the unit tests.

Maybe that's a bit clearer as to what's going on. Maybe the new names help a 
bit. Notice the ticks on some of the names (the ' characters). This is just a 
convention some programmers use. The ticks are part of the name, nothing magic, 
and are used to indicate that the value of the name is derived from the value 
of the name with one less tick. Some programmers use numbers instead. Other 
programmers don't care and just use the same name.

When you've understood the solution you've come up with, you might want to try 
using reduce to do this. It'll be both shorter and much easier to understand. 
If you look carefully at your code the only part that isn't boiler-plate is the 
(assoc result-map key default) -- the boiler-plate corresponds closely to what 
reduce does.

I hope this doesn't confuse you even more.

Cheers,
Bob
 
> 
> Roelof
> 
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: My experiments with concurrent programming

2014-04-13 Thread Bob Hutchison
Hi Cecil,

On Apr 12, 2014, at 3:18 PM, Cecil Westerhof  wrote:

> 
> I just started playing with Clojure a few days ago, so I am a tabula rasa. I 
> attached what I have until now. If it can be improved, I like to know it.

I had a look at your code and it's not clear to me what you are trying to 
experiment with. Possibly benchmark using futures to run the do-sequential 
function concurrently. I'll assume that for the moment and make a couple of 
observations...

You are using atoms to store two values (max-diff and max-factor) that are used 
and changed in main-function. Did you really intend to share these across all 
the calculations? The code you've provided will have concurrency errors as a 
result. You might consider writing this as something like (the *completely* 
untested and so only good as a sketch):

(def max-diff (ref 0.0))
(def max-factor (ref 0.0))

(defn init [type]
  (give-message (format "Start %s" type))
  (dosync
(ref-set max-diff   0.0)
(ref-set max-factor 0.0)))
   
(defn main-function [i diff]
  (dosync
(ensure max-diff)
(ensure max-factor)
(when (> diff @max-diff)
   (give-message (format "Different for %12d (%e, %e)" i diff (/ diff i)))
   (alter max-diff max diff)
   (when (> (/ diff i) @max-factor)
 (alter max-factor max (/ diff i)

The 'ensures' are there because max-diff and max-factor aren't really 
independent and some interaction between concurrent threads in the outer when 
could lead to some strange situations (like testing for max-diff (or 
max-factor) then finding that some other thread ran and changed max-diff (or 
max-factor) out from under you.

Your concurrency will likely be restricted to (some subset) of your cores since 
there's no IO in there (you're dumping the actual logging off to an agent). 
This isn't a bug, just mentioning it, but there's something to think about 
below.

There's a problem in your calculation of diff... it's always 0.0 which means 
that there's nothing being done in main-function. I changed it to something 
arbitrary (and *completely* untested and so only good as a sketch):

  (let [v (int (Math/sqrt i))
diff (Math/abs (- (Math/pow v 2) i))]

No idea if that's reasonable, but at least main-function does something now.

With the hacked up calculation of diff, I was able to demonstrate the 
concurrency problem in main-function by simply running (the *completely* 
untested and so only good as a sketch):

(defn main-function [i diff]
  (swap! iterations0 inc)
  (when (> diff @max-diff)
(swap! iterations1 inc)
#_(give-message (format "Different for %12d (%e, %e)" i diff (/ diff i)))
(swap! max-diff max diff)
(when (> (/ diff i) @max-factor)
  (swap! iterations2 inc)
  (swap! max-factor max (/ diff i)

and printing the values of iterations* -- with your swap algorithm you get 
different values for iterations1 and sometimes iterations2 for successive run.

If you didn't intend to share max-diff and max-factor, then you'd likely be 
better off if do-sequential passed local values into main-function, something 
like (the *completely* untested and so only good as a sketch):

(defn main-function [[max-diff max-factor] i]
  (let [v (int (Math/sqrt i))
diff (Math/abs (- (Math/pow v 2) i))]
(if (> diff max-diff)
  (do
#_(give-message (format "Different for %12d (%e, %e)" i diff (/ diff 
i)))
[(max max-diff diff) (max max-factor (/ diff i))])
  [max-diff max-factor])))

(defn do-sequential [start stop step]
  (reduce main-function [0.0 0.0] (range start stop step)))


You've decided to use futures for concurrency. Maybe that's the whole point, 
but if you're just trying to get a feel for concurrency in Clojure then there 
are some options. I find I directly use futures and promises, at most, rarely 
(I can't remember ever using them directly, maybe in the very early days of 
Clojure). What I find handy for this sort of thing is something like pmap, and 
if you really want this asynchronous then have a look at core.async. Anyway, 
with pmap (the *completely* untested and so only good as a sketch):

(defn check-concurrent [number]
  (doall
(pmap #(do-sequential % check-until number) (range 1 (inc number)

The shutdown-agents call is likely not what you want, you don't need it.

You're using agents for the logging. This gets the IO out of your code being 
tested, but there's still a lot of formatting work happening there (not much of 
a problem). But you don't know the impact of the agent thread pool on your 
benchmark. It's possible that it acts as a throttle. You can avoid this easily 
by not logging anything in main-function (I've commented it out in the example 
above).

Benchmarking is tricky to do. It's a lot easier to use something like 
criterium, kind of like this (I added the *verbose* dynamic variable for fun to 
the *completely* untested and so only good as a sketch):

(def ^:dynamic *verbose* true)
(defn give-message [mes

Re: [ANN] durable-queue: an in-process disk-backed queue

2014-02-07 Thread Bob Hutchison

On Feb 6, 2014, at 6:45 PM, Zach Tellman  wrote:

> At Factual we get a lot of data thrown at us, and often don't have control 
> over the rate at which it comes in.  As such, it's preferable that our buffer 
> isn't bounded by the process' memory, since a temporary blip in throughput 
> may cause GC pauses, OOM exceptions, and other things that will only 
> exacerbate the problem.  It's also preferable that if the process dies, we 
> won't lose any data which hasn't yet escaped the process.  A disk-backed 
> queue satisfies both of these requirements.
> 
> As such, I'm happy to announce that we're open sourcing 'durable-queue': 
> https://github.com/Factual/durable-queue.  It's a small, fast, pure-Clojure 
> implementation that in our production systems is responsible for processing 
> billions of entries daily.  We believe it has broad applications, and are 
> excited to see how others will use it.

What excellent timing! I've been looking at ZeroMQ, RabbitMQ, and Kafka for the 
last week or so. ZMQ is awfully attractive for what I'm trying to do, but there 
are a few things it doesn't do that I need done. I had begun thinking of 
building something similar on top of Redis.

You mention the idea of batching to reduce the impact of fsync. Is there an API 
for batching puts? Is there a way to batch a complete! and put! new tasks to 
the queue?

One pattern that keeps coming up is:
   - take a single task from the queue
   - execute the task, which might generate a set of new tasks to be queued on 
the same queue (and likely on other queues too)
   - signal completion, and put the new tasks

Cheers,
Bob

> 
> Zach
> 
> P.S. If this sort of work is interesting to you, Factual is hiring: 
> https://groups.google.com/forum/#!searchin/clojure/factual/clojure/8bPIEnNpfyQ/lvv-9gkVozAJ
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: core.async count in a channel

2014-01-21 Thread Bob Hutchison

On Jan 21, 2014, at 11:56 AM, Paul Viola  wrote:

> I think this is all well and good for a particular use of channel.
> 
> So perhaps I am misusing channels??  
> 
> To repeat: in one case I have workers pulling from a channel of real work. 
> For various reasons this channel might get filled rather deeply. In this case 
> I would want to add additional workers or get a bigger machine. I was 
> wondering if monitoring the channel for things like average depth (or 99 
> percentile) would give me the information I needed.
> 
> 

Often queue length isn’t a particularly good measure of what’s happening, nor a 
particularly good indicator of how to solve a problem, or even if there is a 
problem. You might consider measuring service time more directly by tracking 
how long requests take to be served. Then you might measure the utilisation of 
the workers, maybe by measuring how long they wait for a new job and how long 
it takes to complete a task. These measurements are pretty straightforward to 
implement in core.async (though it’d be more ‘efficient’ to build them right 
into channels). What to do in response to these numbers isn’t necessarily 
obvious (more workers? *fewer* workers? split the queue? faster CPU? More CPUs?)

Core.async introduces it’s own problem by banning unbound queues. The strategy 
of blocking clients as a consequence of maxing out a queue can be bad. So 
there’s a new problem that you have to deal with, making sure the channel size 
is big enough to handle any normal situation (which implies you to know what 
normal actually is, and sometimes you don’t know beforehand). To deal with this 
problem a channel count would be very helpful.

> 
> I could of course "just skip the channel business, and use a java queue" is a 
> fine proposal.

Well…

>  
> 
> But since the producers of this work are truly asynchronous (attached to the 
> real world) I thought it best to keep the channel methodology.
> 
> 
> 
> 
> 
> 
> On Tue, Jan 21, 2014 at 5:11 AM, Aaron France  
> wrote:
> On 21/01/14 14:09, Moritz Ulrich wrote:
> On Tue, Jan 21, 2014 at 9:43 AM, Aaron France  
> wrote:
> Since channels yield nil when they are devoid of items, surely this is enough 
> to know when the channel is empty?
> That's not correct. Take-Operations block on empty channels. They
> yield nil when they're closed. You could add a timeout to the take
> operation to see if no item arrived in a specific time.
> 
> Much appreciated for the clarification. It's the same in Go.
> 
> I can imagine this pattern (take on a possibly closed channel being useful) 
> being useful but I'm not convinced knowing the count of channel is a safe 
> thing to know/care about.
> 
> My $0.02, perhaps Clojure does this differently.
> 
> 
> -- 
> -- 
> 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 a topic in the 
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/clojure/zD2jl-bIFXI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to 
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
> 
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https

Re: Effects of diving into Clojure

2014-01-14 Thread Bob Hutchison

On Jan 14, 2014, at 3:46 PM, gvim  wrote:

> No, you're probably right. It's just that there never seem to be enough hours 
> in a day/life :(

You’re not alone there either :-)

Cheers,
Bob

> 
> gvim
> 
> 
> On 14/01/2014 20:26, Bob Hutchison wrote:
> 
>> No it’s not just you. Hardly! However, I’d caution you against allowing this 
>> situation to continue. Preference is one thing. Isolating yourself from 
>> demonstrably successful ideas is another. Not to mention abandoning 
>> everything you’ve attained through the learning of Ruby. Keep going back and 
>> forth until all that’s left is preference.
>> 
>> Sorry for the pontificating :-)
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Effects of diving into Clojure

2014-01-14 Thread Bob Hutchison

On Jan 14, 2014, at 2:01 PM, gvim  wrote:

> I recently took the plunge into learning Clojure and love it. Since I tend to 
> be single-minded/all-or-nothing about these things I'm now finding it very 
> difficult to switch mindset when I have to work with Ruby. Anyone else 
> experienced this?

I think everyone who makes the attempt to learn more than one different 
programming language experiences this at some early point (like their second 
major language :-), and then suffers unpredictably recurring bouts over time.

> If you get deeply into a programming language it alters the way you think and 
> approach design/solutions which is one reason I've never understood the 
> advice to try to learn many programming languages.

You’ve described one of the most important reasons behind that advice. Do you 
really think your Ruby experience has not informed your Clojure experience? And 
when you go back to Ruby do you really forget what you learned from Clojure? 
Even the most ‘useless’ of languages have something interesting to say about 
the problem they're designed to address (and for me, that’d be COBOL).

> With Clojure the functional/Lisp structure is so radically different and 
> elegant that switching to standard OO/mutable state/infix approaches starts 
> to feel alien. Maybe it's just me.

No it’s not just you. Hardly! However, I’d caution you against allowing this 
situation to continue. Preference is one thing. Isolating yourself from 
demonstrably successful ideas is another. Not to mention abandoning everything 
you’ve attained through the learning of Ruby. Keep going back and forth until 
all that’s left is preference.

Sorry for the pontificating :-)

Cheers,
Bob

> 
> gvim
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: library development

2013-12-20 Thread Bob Hutchison

On Dec 20, 2013, at 9:22 AM, Daniel Higginbotham  wrote:

> "lein install" actually installs your library ~/.m2/repository in addition to 
> creating the pom and jar. That should be all you need to do.

[message was bounced earlier…]

Thank you. You’re right. As it happens, I just discovered that myself. I nice 
cup of tea and thinking “there’s no way these leiningen guys didn’t do 
something so obvious” led be to suck it up and poke around my maven repository 
to see what I could see. Maven’s getting pretty quick isn’t it?

Cheers,
Bob

> 
> On Friday, December 20, 2013 9:09:32 AM UTC-5, Bob Hutchison wrote:
> Hi, 
> 
> I’m missing something. And it’s annoying me. 
> 
> Let’s say I’m working on three or four projects and there’s some code that 
> really should be developed as a library and used by each of the projects. A 
> similar thing happens if I fork a library from github. I don’t want to make 
> any of this code public so clojars is not an option. It’s clear enough that 
> the solution to this will involve a local maven repository somehow. 
> 
> Now, I don’t know maven. I like it that way. I *do* *not* want to know maven. 
> It’s so low on my priority list that reviewing the new C++ standard is 
> higher. Basically it’ll never get to the top of the list. 
> 
> Furthermore I think requiring someone to know maven to do any non-trivial 
> Clojure development is a bad plan. This is surely one of the founding goals 
> of Leiningen. 
> 
> I’ve found some documentation and blog posts that, as soon as they get 
> interesting, pretty much all end up assuming you know maven. I’ve found 
> lein-localrepo plugin, which is was hopeful until you read it’s docs and see 
> that it describes itself in maven terminology (why do I care what the maven 
> coordinates of a file are? *WHY* do I have to know? Is this about Clojure or 
> Java jar files? Are they different?) 
> 
> Lein install makes a jar file and a pom file. So what? Is there something you 
> do with these? There must be. But since I don’t know maven I’ve not got a 
> clue what that might be. 
> 
> What I’d like to do is type something no more complex than “lein 
> local-install” and be done with it. I do not care if every developer on my 
> team has to execute that command. I don’t care about sharing. I don’t care 
> about naming. I just want to work on my library, install it, and use it in my 
> other four projects. 
> 
> Running “cp -r” will do it, but it’s a bit crude. 
> 
> Thanks, 
> Bob
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


library development

2013-12-20 Thread Bob Hutchison
Hi,

I’m missing something. And it’s annoying me.

Let’s say I’m working on three or four projects and there’s some code that 
really should be developed as a library and used by each of the projects. A 
similar thing happens if I fork a library from github. I don’t want to make any 
of this code public so clojars is not an option. It’s clear enough that the 
solution to this will involve a local maven repository somehow.

Now, I don’t know maven. I like it that way. I *do* *not* want to know maven. 
It’s so low on my priority list that reviewing the new C++ standard is higher. 
Basically it’ll never get to the top of the list.

Furthermore I think requiring someone to know maven to do any non-trivial 
Clojure development is a bad plan. This is surely one of the founding goals of 
Leiningen.

I’ve found some documentation and blog posts that, as soon as they get 
interesting, pretty much all end up assuming you know maven. I’ve found 
lein-localrepo plugin, which is was hopeful until you read it’s docs and see 
that it describes itself in maven terminology (why do I care what the maven 
coordinates of a file are? *WHY* do I have to know? Is this about Clojure or 
Java jar files? Are they different?)

Lein install makes a jar file and a pom file. So what? Is there something you 
do with these? There must be. But since I don’t know maven I’ve not got a clue 
what that might be.

What I’d like to do is type something no more complex than “lein local-install” 
and be done with it. I do not care if every developer on my team has to execute 
that command. I don’t care about sharing. I don’t care about naming. I just 
want to work on my library, install it, and use it in my other four projects.

Running “cp -r” will do it, but it’s a bit crude.

Thanks,
Bob

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Slamhound 1.5.0 + screencast + Vim plugin

2013-11-30 Thread Bob Hutchison

On Nov 30, 2013, at 10:59 AM, guns  wrote:

> On Sat 30 Nov 2013 at 09:29:30AM -0500, Bob Hutchison wrote:
> 
>> This is a great idea… but I’m having an awful time getting it to work.
> 
> Hello Bob,
> 
> I'm sorry to hear that setup is problematic. If it's trouble for you,
> it's bound to be trouble for others. Would you be willing to open a new
> issue on the bug tracker?
> 
> https://github.com/technomancy/slamhound/issues/new

I’ve split my email into two and have created issues 58 and 59.

> 
> Just copying and pasting your email would be very helpful. I suspect
> there are a couple of hidden problems that are general to all users, so
> I am eager to help you.

The next week or so will be busy, but I’ll do what I can to help.

> 
>> However, the changes it makes to the namespaces are excellent!
> 
> I'm glad to hear there is some good news!

Certainly was :-)

> 
>guns

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Slamhound 1.5.0 + screencast + Vim plugin

2013-11-30 Thread Bob Hutchison

On Nov 29, 2013, at 11:14 PM, guns  wrote:

> Hello,
> 
> I am happy to announce version 1.5.0 of Slamhound, technomancy's amazing
> ns rewriting tool.
> 
>;; ~/.lein/profiles.clj
>{:user {:dependencies [[slamhound "1.5.0"]]}}
> 
> This is a *major* bugfix release. If you've tried Slamhound in the past
> and felt frustrated, now is a great time to give it another try.
> 

This is a great idea… but I’m having an awful time getting it to work.

Two problems:

1) if I try it on junky experimental clojure programs, files that execute when 
loaded and don’t do anything serious but explore some feature of clojure, I’m 
getting this error when running from vim:

Error detected while processing function 
slamhound#reconstruct..fireplace#eval..fireplace#session_eval..37_eval..86:
line   38:
E605: Exception not caught: Error running Clojure: Error: Could not 
find or load main class clojure.main^@

   And from the command line it silently does nothing.

2) most of my real code, maybe all since I can’t find anything else, uses 
ring/compojure and midge. Midje is used in-line (the facts are in the source 
file not in the test directory).
  — from inside vim, again since Slamhound never terminates, I’ve got to 
Control-C out of it, and consequently the buffer is never updated.
  — when I run Slamhound from the command line:
  — it never terminates
  — despite not terminating, it does update all but one of the files 
properly
  — it does not handle the file(s) that start ring servers and complains:
 Failed to reconstruct: #
 Address already in use
 This is even if the address really isn’t in use, I think it’s trying 
to ‘run’ server.clj a second time. And it doesn’t terminate either.

However, the changes it makes to the namespaces are excellent!

I tried updating both fireplace and clojure-static but that made no difference.

Cheers,
Bob

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] overload-middleware 0.1.1

2013-11-17 Thread Bob Hutchison
Hi Rob,

Nice! Thanks for releasing this. I’m not sure when I’ll use this but I can 
pretty much guarantee that I will give it a go sooner or later. I’ve written a 
few of these in the past, it’s good to see someone make a library out of it.

BTW, things like AngularJS and EmberJS should/could know about 503 errors and 
what they mean. There’s actually a project, that I’ve *not* used (yet), 
https://github.com/kkolstad/angular-servicestack that will re-try on a 503 
after a random delay. Here’s the line from their source code (it’s 
coffeescript):

sleepTime = Math.min (Math.random() * (Math.pow(4, response.collisionCount() - 
1) * 100)), serviceStackRestConfig.maxDelayBetweenRetries

Cheers,
Bob

On Nov 16, 2013, at 1:21 PM, Rob Day  wrote:

> Hi all,
> 
> I've just published the first working version of a Ring middleware that some 
> of you might find useful. It's designed for web apps where, if you're 
> overloaded, it's better to serve some requests quickly and fail the others 
> than to try and serve all the requests   and do it slowly. (My background 
> is in telecoms, where that's often the best approach.)
> 
> Specifically, you specify a target latency that you want 90% of requests to 
> try and meet, and it applies the algorithm from 
> http://www.eecs.harvard.edu/%7Emdw/papers/control-usits03.pdf to try and keep 
> your latency below that threshold. The exact parameters of the algorithm are 
> tunable, and different URLs or groups of URLs can have different targets and 
> parameters.
> 
> It still needs a bit of tidying - docstrings, cleaning up some of the Midje 
> tests, and so on - but it works and I think the documentation is usable, so 
> I'm announcing it now.
> 
> Github (w/ docs): https://github.com/rkday/overload-middleware
> Clojars: https://clojars.org/overload-middleware
> 
> Let me know if you have any feedback!
> Rob

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: is PG's "imperative outside-in" advice any good?

2013-10-15 Thread Bob Hutchison

On 2013-10-15, at 8:29 AM, Daniel Higginbotham  wrote:

> I've been going through On Lisp by Paul Graham and on page 33 he recommends 
> against performing "intermediate" bindings. Does this advice hold for 
> Clojure? Here are a couple examples:
> 
> ;; Common Lisp (from the book)
> (defun bad (x)
> (let (y sqr)
>   (setq y (car x))
>   (setq sqr (expt y 2))
>   (list 'a sqr)))
> 
> (defun good (x)
> (list 'a (expt (car x) 2)))
> 
> ;; Clojure
> (defn bad [x]
> (let [y (first x)
>   sqr (expt y 2)]
>   (list 'a sqr)))
> 
> (defn good [x]
> (list 'a (expt (first x) 2)))

The closest I can think of to the bad CL code in Clojure would be something 
like:

(defn bad-clojure [x]
  (let [v (first x)
v (Math/pow v 2)
v (list 'a v)]
v))   

I don't think anyone at all would find either the bad CL or Clojure code okay. 
This is more of an admonition to not be an idiot :-)

Your Clojure code is equivalent to the following CL code:

(defun good2 (x)
  (let* ((y (car x))
 (sqr (expt y 2)))
(list 'a sqr)))

There's nothing wrong with writing code that way, it's functional and clear. 
What you're doing with this style of writing is introducing intermediate named 
values. Sometimes those just clutter up the code, sometimes they clarify. Use 
your own good taste. You'd do the same thing in Haskell, but I'd use a where 
clause.

> 
> Paul Graham explains:
> 
> "The final result is shorter than what we began with, and easier to 
> understand. In the original code, we’re faced with the final expression (list 
> 'a sqr), and it’s not immediately clear where the value of sqr comes from. 
> Now the source of the return value is laid out for us like a road map.
> 
> The example in this section was a short one, but the technique scales up. 
> Indeed, it becomes more valuable as it is applied to larger functions."

Yes, in the bad CL code you don't know where the value of sqr comes from and 
the problem gets much worse as the code gets longer. This is the problem with 
imperative code in general.

You don't have that problem in either Clojure or the 'good2' CL program.

> 
> In clojure you can't do setq of course but I find myself going against this 
> advice all the time

He's not talking about intermediate names for values, he's talking about 
imperative assignments using setq, setf, and friends. Clojure's nearest 
equivalent, that I can think of, is shadowing in a let statement, and I think 
you'll find this is frowned upon.

> So, is PG's advice any good?

Yup.

Cheers,
Bob

> 
> Thanks!
> Daniel
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Sequential conditional transforms of an argument

2013-07-08 Thread Bob Hutchison

On 2013-07-08, at 2:40 AM, Laurent PETIT  wrote:

> thank you all for your answer.
> 
> So to go back to my original concern, there does not seem to be a way
> to do this as I intended by just combining the existing features in
> core.
> 

I'm not sure what you're asking for here. Do you mean *in-line* with only core 
features? I suppose that's the same as asking if core already deals with this 
somehow? I don't think it does. And, for what it's worth, I see this pattern 
regularly as well, and I've used something somewhere between Thomas' and 
Y.Kohyama's techniques.

Cheers,
Bob

> Cheers,
> 
> --
> Laurent
> 
> 2013/7/8 Yoshinori Kohyama :
>> Hi Laurent,
>> 
>> How about a macro like below?
>> 
>>  (defmacro tt
>>([x] x)
>>([x ts tr & more] `(tt (if (~ts ~x) (~tr ~x) ~x) ~@more)))
>> 
>> To use this,
>> 
>>  (tt x test1 transform1 test2 transform2 test3 transform3)
>> 
>> This doesn't work even number of arguments as you see.
>> 
>> HTH,
>> Y.Kohyama
>> 
>> --
>> --
>> 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 unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.
>> 
>> 
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
> 
> 

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: What's the point of -> ?

2013-03-11 Thread Bob Hutchison

On 2013-03-11, at 6:58 AM, edw...@kenworthy.info wrote:

> So I understand that:
> 
> (-> foo bar wibble)
> 
> is equivalent to
> 
> (wibble (bar (foo)))
> 
> With the advantage that the latter version is better, in the sense that it's 
> clearer what the final result is (the result of the call to wobble).
> 
> What I don't understand is the need for -> the only thing it seems to do is 
> make something Lispy appear to be imperative.
> 
> Is that it?

Consider:

  (-> foo
  (f1 p1 p2 p3)
  (f2 p4 p5 p6)
  (f3 p7 p8 p9))

vs

(f3 (f2 (f1 foo p1 p2 p3) p4 p5 p6) p7 p8 p9)

(assuming I cut and pasted correctly) and you can see a little better where 
this is going, especially if you tried putting real names in there.

Is it imperative? Is it declarative? Who cares?

Cheers,
Bob


> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>  
>  

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: how would you implement sending out a verification email?

2013-02-21 Thread Bob Hutchison

On 2013-02-20, at 9:46 PM, James Reichley  wrote:

> I can't find the reference now, but either in a screencast or a discussion I 
> read it was mentioned that if you have a single thing that performs 
> side-effects, you can perform this function last in the transaction without 
> worrying about any issues. The reasoning here is that if anything before it 
> fails, the side-effect action was never attempted and if the side-effect 
> action itself fails then the transaction rolls back like always.


Since you say 'side-effect' I'm assuming you're talking about STM transactions. 
If so, I don't see how this can be true. If some other thread can run while the 
side-effect is being created then that other thread has the ability to do 
something that causes your transaction to retry. Being the last thing done 
doesn't change this other than perhaps reducing its likelihood. The Clojure 
documentation is pretty clear about this: no side-effects. The Haskell version 
of STM is clear both in its documentation and it's STM implementation and type: 
no side-effects.

If you're talking about database transactions, just guessing but I'd think it 
depends on when/if locks are set.

Cheers,
Bob

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: how would you implement sending out a verification email?

2013-02-21 Thread Bob Hutchison

On 2013-02-20, at 9:32 AM, Balint Erdi  wrote:

> In the languages I come from (e.g Ruby) I'd use a library that handles the 
> queueing and consumption of tasks. Is this how you'd do it in Clojure or it's 
> one of these cases where Clojure itself suffices where other languages are 
> lacking?

This is how I've done it.

I know this is largely a theoretical question about side-effects and STM in 
Clojure, but… In the end, there's always the chance that you'll send duplicate 
emails, all you can do is try to minimize that. There's also the chance that 
you never actually successfully send the email, if for no other reason than 
there's no way to ensure the email is received or to know if it was received. 
Not to mention spam filters. Using specialist email services is something to 
seriously consider, it'll make your job much easier, all you have to do is make 
sure the email request is received by the service -- there's a protocol for 
that. A decent service will do much better than you can do at making sure the 
email is sent.

Cheers,
Bob

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Why is this so difficult?

2013-02-15 Thread Bob Hutchison

On 2013-02-15, at 4:16 AM, BJG145  wrote:

> I don't know anything about build managers so I think my next step will be to 
> pick up a book on Maven to get the background…)

Don't. Just don't. All you really need to know about maven, and it's role, is 
what you can get from wikipedia. Seriously. Then click around on related 
articles. If you need more than that then lein will have failed (miserably) -- 
but my experience with lein is pretty good. When you know that lein cannot do 
what you need (which may well be never) then it'll be time to look into maven.

http://en.wikipedia.org/wiki/Build_automation
http://en.wikipedia.org/wiki/Apache_Maven

The trick is to get lein installed the first time. This might take a bit of 
work if you haven't already got a machine setup for command line based 
development. (That's important by the way: *command line* -- even if you intend 
to always use IntelliJ or some other IDE)

I completely sympathize with your situation. I've seen this a lot, and 
experienced it myself when starting from a fresh machine. It's very difficult 
to give instructions because of the wildly differing starting points.

Good luck, but you'll get there :-)

Cheers,
Bob

> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>  
>  

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Clojure + Web Services + Web Sockets

2013-02-11 Thread Bob Hutchison

On 2013-02-11, at 6:12 PM, Ryan T.  wrote:

> Unless someone has to suggest something better, it seems that the best way to 
> achieve what i want is to use aleph which allows you to initialize it with a 
> wrapped ring handler. 

You might have a look at http://http-kit.org/ 

Cheers,
Bob

> 
> If you have more details on the issue or alternatives I would love to hear 
> about them.
> 
> On Tuesday, February 12, 2013 12:54:53 AM UTC+2, Ryan T. wrote:
> Hello,
> 
> I am trying to figure out how to setup my clojure project in order to be able 
> to serve both normal http requests which will return json and also handle 
> requests over websockets. Is it possible to do both and listen on same port? 
> or do i need two separate projects? or ?
> 
> I did find this but from what I read Webbit is not the best solution for what 
> I need. I was hoping to be able to build my clojure project and use jetty in 
> development and tomcat on production.
> 
> Thank you for your time
> 
> -- 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>  
>  

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Clojure web server benchmarks

2013-01-25 Thread Bob Hutchison

On 2013-01-25, at 6:24 AM, Peter Taoussanis  wrote:

> I'd consider adding a graph if folks think these numbers are sufficiently 
> interesting?
> 

That would be great! This is very important information for me. And, unless 
things have improved markedly over that last year or so (I hope so), I think 
you'll be 'amused' by what you see.

Cheers,
Bob

-- 
-- 
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: [ANN] Formative - render, parse, and validate web forms

2013-01-16 Thread Bob Hutchison

On 2013-01-16, at 11:31 AM, Justin Kramer  wrote:

> So I went ahead and implemented the first solution I mentioned: the default 
> renderer now groups fields into fieldsets, split by :heading and :submit 
> fields. Each fieldset has a class that you can target with css/js. You can 
> see the result in the demo - http://formative-demo.herokuapp.com/.

Heh, that was quick :-) Thanks!

I don't suppose you've thought much about this situation: I've got a couple of 
standard (what I'll call) mixin-forms that have fields and validations that I 
'mixin' to a form (once or not at all). They aren't forms on their own, just a 
bunch of fields and validation rules. For example, I have a standard way of 
describing an entity (name, title, abbreviated description, full description, 
and a few other things). It's possible to think of tabs this way as well. 
Dropdowns in a nav bar is similar too, maybe. It's pretty clear how to get 
started on implementing something like this, but I'm wondering if you've 
considered anything in this regard.

I've also got groups of several controls that operate together. The bootstrap 
prepended and appended inputs are simple examples. These are to some degree 
like the 'mixin' things I mentioned, but there can be more than one of them and 
they need to be distinguished, and the validation might be different for each 
or need to be extended for each instance. It looks to be easy enough to do this 
by adding new field types (extending the render-field and parse-input 
multimethods). Is that how you'd approach the problem?

While I think of it, do you provide a way to validate that a value corresponds 
to one of the :options?

Cheers,
Bob

> 
> Justin
> 
> On Wednesday, January 16, 2013 8:35:54 AM UTC-5, hutch wrote:
> 
> This is *really* interesting! I'll have a look at this more closely over the 
> next couple of days, but, really, the timing could not be better… you might 
> have just tipped a project I'm working on over to Clojure :-)
> 
> It looks as though you've not put any kind of 'structure' on the fields… they 
> are 'flat'. For example, I don't see fieldsets. One of my projects has its 
> forms in two parts, the input fields which scroll (and have fieldsets) and a 
> second part that consists of things like the submit and cancel buttons. The 
> second part is pulled into a sidebar and fixed on the page (doesn't scroll 
> with the rest of the fields). These forms can be a bit long (but they are a 
> lot more usable than you'd think), so there's also an index in the sidebar 
> that on click moves the scrollable part to make the corresponding fields come 
> into view. In my current project these indexed things aren't fieldsets but 
> they could be. Alternatively, some other kind of grouping structure could be 
> used. Or possibly just a new field type that created an index entry… I'll 
> have a muck about and see what I can come up with.
> 
> Cheers,
> Bob
> 
>> 
>> Justin
>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@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+u...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
> 
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
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: [ANN] Formative - render, parse, and validate web forms

2013-01-16 Thread Bob Hutchison

On 2013-01-15, at 5:00 PM, Justin Kramer  wrote:

> Formative is a library for dealing with web forms. Features:
> Describe forms using simple data
> Render forms via pluggable renderers (comes with Bootstrap and other 
> renderers built-in)
> Parse submitted form data from Ring params
> Validate parsed data using Verily (another new but less interesting lib)
> A live demo can be seen at http://formative-demo.herokuapp.com/. Demo source: 
> https://github.com/jkk/formative-demo
> 
> See the README for a usage guide and quick reference:
> 
> https://github.com/jkk/formative
> 
> It has seem some real-world usage, and I consider the API stable.
> 
> Feedback and contributions welcome.

This is *really* interesting! I'll have a look at this more closely over the 
next couple of days, but, really, the timing could not be better… you might 
have just tipped a project I'm working on over to Clojure :-)

It looks as though you've not put any kind of 'structure' on the fields… they 
are 'flat'. For example, I don't see fieldsets. One of my projects has its 
forms in two parts, the input fields which scroll (and have fieldsets) and a 
second part that consists of things like the submit and cancel buttons. The 
second part is pulled into a sidebar and fixed on the page (doesn't scroll with 
the rest of the fields). These forms can be a bit long (but they are a lot more 
usable than you'd think), so there's also an index in the sidebar that on click 
moves the scrollable part to make the corresponding fields come into view. In 
my current project these indexed things aren't fieldsets but they could be. 
Alternatively, some other kind of grouping structure could be used. Or possibly 
just a new field type that created an index entry… I'll have a muck about and 
see what I can come up with.

Cheers,
Bob

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

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

Re: [ANN] nrepl-transcript

2013-01-15 Thread Bob Hutchison

On 2013-01-14, at 3:58 PM, Jonas  wrote:

> Hi
> 
> I created a middleware for nrepl that saves a transcript of your repl 
> interactions so you can go back and see what you did. 
> 
> https://github.com/jonase/nrepl-transcript
> 
> Feedback welcome!

Oh! Thank you!

Bob

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

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

Re: [ANN] sublime-lispindent, clojure indenting for sublime text 2

2012-11-25 Thread Bob Hutchison

On 2012-11-25, at 12:45 AM, Anthony Grimes  wrote:

> I just took a shot at it. I put it in Pristine Packages as described, but it 
> disappears when I restart ST2 and try to use it.


I imagine you tried to put it in:

  ~/Library/Application Support/Sublime Text 2/Pristine Packages

I did that too. You need to put it in:

  /Applications/Sublime Text 2.app/Contents/MacOS/Pristine Packages

Cheers,
Bob

> 
> Also, will this work with the built in 'reindent' command? If not, will it 
> work with vintage mode (you can reindent blocks with =ab from Vim)? I really 
> wish the Clojure mode just didn't suck so bad.
> 
> On Monday, November 12, 2012 10:25:38 AM UTC-6, Jonathan Fischer Friberg 
> wrote:
> Dear clojure mailing list,
> 
> As the indenting for clojure (and lisp in general) was very lacking
> in sublime, I decided to make a plugin:
> 
> https://github.com/odyssomay/sublime-lispindent
> 
> I hope someone finds this useful.
> 
> By the way, if someone with a mac could try the keyboard shortcuts that would 
> be great.
> I don't own a mac so I cannot test them.
> 
> Sincerely,
> Jonathan
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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

Re: Replacing nested let statements with assignments

2012-10-19 Thread Bob Hutchison

On 2012-10-18, at 2:11 PM, Evan Gamble  wrote:

> For the situation where the lets are nested because you're checking the 
> values in some way after each binding, I wrote a macro called let?. I find it 
> very useful and use it in nearly all my code. 
> https://github.com/egamble/let-else

Hmmm, I can see how that might be very handy… like having guards on each 
binding. Thanks.

Cheers,
Bob

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

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

Re: Modelling for DAG with identity map - or not?

2012-09-18 Thread Bob Hutchison

On 2012-09-16, at 3:21 PM, Patrik Sundberg  wrote:

> I'm asking myself though if there's a more functional design for 
> accomplishing the same goals? My main goals are to do things consistently so 
> that changing a value X propagates properly, and being able to find 
> dependencies of a given value. A DAG+identity map is my first take, but there 
> may be something more natural for FP I'm completely missing.

Sounds like a reasonable approach to me. There's nothing wrong with state, just 
how you manipulate it. The STM in Clojure is really nice in this regard. You 
might want to have a look at Functional Reactive Programming (FRP). There's a 
lot of stuff available about that in the Haskell community, but usually for UIs 
and things like that. They sometimes use spread sheets as an example (spread 
sheets can be thought of as a DAG with values and computations in cells… you 
can see the mapping between them in your application (where the mapping doesn't 
work or is hard might be pointing at something quite interesting). There's also 
something called 'Cells' in Common Lisp that might be interesting. I'm not sure 
what's been done in Clojure.

Cheers,
Bob

> 
> Thanks,
> Patrik
> 

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

2011-01-17 Thread Bob Hutchison
Hi Stuart,

On 2011-01-15, at 4:06 PM, Stuart Halloway wrote:

>> In my experience, errors are the problem and we should be avoiding them, 
>> almost at all costs. 
> 
> This debate always starts by conflating three things into two, and then goes 
> downhill from there. :-( It isn't 
> 
> (a) safe/slow vs. 
> (b) unsafe/fast. 

That's how us outsiders are left to look at it.

> 
> It is 
> 
> (a) unsafe/incorrect value on overflow/fastest/unifiable* vs. 
> (b) safe/error on overflow/fast/unifiable vs. 
> (c) safe/promoting on overflow/slow/not-unifiable
> 
> *unifiable: able to deliver same semantics for primitives and objects

This doesn't really help me understand your argument.

It looks to me as though Clojure is trying to steer itself through the middle 
of something. The trouble is that I don't know where the edges of the middle 
are.

Maybe it is just a documentation problem. But I'd also suggest that there's a 
bit of a sales job necessary here.

> 
> We have thought about this quite a bit,

Nobody doubts that, certainly I don't. And I'm not trying to minimise or 
dismiss what you've done. And I'm not claiming that I've thought about it 
better or more or deeper. But I do have concerns and I don't see them being 
addressed, and I'd like it if they weren't minimised either. Maybe my concerns 
are completely addressed. Maybe not. I don't know, and I'd like to be convinced.

> and an argument from one axis only (e.g safe/unsafe) that doesn't even 
> mention some of  the other axes is not likely to be persuasive. Would be more 
> interesting to see a new axis we haven't thought of...

Numerical correctness, for some of us, is an overwhelming issue. This is purely 
from experience... bad experience... 30+ years of bad experience in my case :-) 
From my point of view, the approach Clojure is taking isn't persuasive, not to 
say it couldn't be made persuasive.

I think I did add what might be considered an additional axis. Syntax. 
Specifically what annotations are needed and for what purpose. I don't think 
this should be dismissed out of hand.

Cheers,
Bob

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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




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

2011-01-15 Thread Bob Hutchison
I'm going to re-organise this a bit…

> On Jan 14, 2:40 pm, Stuart Sierra  wrote:
>> Debatable it is, endlessly. ;)  So Clojure committers made a choice.
>>  Hopefully, they have made a choice that has:

I agree that they've made a choice, and I really don't want to be too critical 
here. However, since Clojure 1.3 is still in an alpha stage, maybe this 
discussion can still contribute something. Maybe what I'm saying is that I want 
to stay constructive and that there's maybe still time to be constructive.

>> 
>> * a small positive effect (better performance with less effort) on a
>> majority of users
>> 
>> * a small negative effect (worse performance, extra effort) on a minority

These goals are good, but I don't know that the approach taken achieves them.

In my experience, errors are the problem and we should be avoiding them, almost 
at all costs. Numbers are confusing to people. Numbers approximated on a 
computer are far more confusing. How many times do you see threads discussing 
how a compiler is buggy because it can't divide two numbers and get the right 
answer? I've been doing this stuff for years and I can come up with an awful 
lot of amusing and/or horribly nasty examples. But I don't think this needs to 
be re-established.

Given my experience I *strongly* lean towards not making a 'mistake' due to 
compiler optimisations. In other words, I'd be very annoyed, and I'd expect 
others to be annoyed too, if a numerical error was introduced to one of my 
programs because of an unexpected, silent, compiler optimisation.

Secondly, Clojure has already established that we will use type annotations to 
signal to the compiler what's what. When we annotate, we are relaxing our 
requirements on the compiler to not make a mistake by assuming that 
responsibility ourselves.

I would suggest the following:

1) if there's type annotation on both values of, say, an addition, then the 
optimised version can be used. If there isn't, or the compiler isn't sure, then 
use safe operations.

2) if the compiler isn't cooperating (because it isn't sure what's going on) we 
should be helping it by again assuming the responsibility of being right and 
marking the operator, say with a tick.

And yes, this likely has problems too. I'm not saying that this is an issue 
with easy solutions.

We're heading for a hodgepodge of annotation purposes, some for optimisation, 
some for correctness (and one of these days I'll mention what I think of the 
@/deref thing :-) And now we're pretty much guaranteed ugly code no matter 
what. Though I'd prefer no ugliness, I'd trade ugly code for speed, but I'd 
rather not for correctness.

And there's a practical problem with mixed annotation purposes. If you want to 
track down a bug you can't just remove all annotations temporarily. You'd have 
to remove some and add others. Not looking forward to that. Maybe a macro: 
make-this-safe could be written. Hmm. Maybe a 'defn-safe' would be something to 
think about???

This is also the kind of thing that you just can't fix later. Imagine how we'll 
feel in ten or twenty years about this decision.


>> 
>> -S
> 
On 2011-01-14, at 8:40 PM, Armando Blancas wrote:

> They used to give you compile switches for that kind of stuff, not
> hope and wholesome wishes. Seems like every performance improvements
> makes the language more complex, uglier or both.
> 


Compiler switches were/are problematic too, but at least they are explicit and 
have to be *added*.

Cheers,
Bob


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




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


Re: How do I find implemented protocols in Clojure object?

2011-01-12 Thread Bob Hutchison

On 2011-01-12, at 8:38 AM, Stuart Sierra wrote:

> One way:
> 
> (ancestors (type the-object))
> 
> This will include every interface implemented by the object, including 
> protocols.

This seems to only work if the protocol is mentioned in the defrecord. If it's 
applied using the extend function it doesn't seem to show the protocol.

The functions bases and supers work similarly.

Unless I'm doing something really stupid, which is a distinct possibility.

Any idea how to tell which of the classes returned by ancestors/bases/supers 
are protocols? I copied a function from the source that can tell if something 
is a protocol if written directly in clojure, but does not work on the results 
from those methods.

(defn protocol?
  [maybe-p]
  (boolean (:on-interface maybe-p)))


Cheers,
Bob


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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




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

help to improve a multimethod with a vaguely interesting dispatch function

2010-11-15 Thread Bob Hutchison

Hi,

I'm trying to work out a way to define a multimethod dispatch function that 
will allow me to make a decision based on two values. In the example below I'm 
using symbols for the values of the major and minor values, mostly for 
convenience. What I'm trying to do is dispatch a multifunction on both values 
if the method exists, on the major value alone if it exists, and to the default 
if there's still no method.

Can anyone see a better way of doing this?

Thanks,
Bob

(declare can-we-not-do-better-dispatcher)

(defmulti can-we-not-do-better (fn [major minor] 
(can-we-not-do-better-dispatcher major minor)))
(remove-all-methods can-we-not-do-better)
(defmethod can-we-not-do-better :default [major minor](str "default-default 
-> " major minor))
(defmethod can-we-not-do-better :one [major minor](str "one-default 
-> " major minor))
(defmethod can-we-not-do-better [:one :two] [major minor] (str "one-two 
-> " major minor))

(defn can-we-not-do-better-dispatcher [major minor]
  (let [method-map (methods can-we-not-do-better)]
(or (and (get method-map [major minor]) [major minor])
(and (get method-map major) major)
:default)))

(defn play []
  (println (can-we-not-do-better :zero :zero))
  (println (can-we-not-do-better :one :two))
  (println (can-we-not-do-better :one :three)))

(play)
default-default -> :zero:zero
one-two -> :one:two
one-default -> :one:three


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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: ANN: Programothesis screencast series on Clojure, Emacs, etc

2010-11-12 Thread Bob Hutchison

On 2010-11-12, at 4:25 PM, Scott Jaderholm wrote:

> Hey Clojurians,
> 
> I don't think there are any great new movies in the theater this weekend so 
> if you're looking to kick back and relax and watch the tube a bit you might 
> checkout the first few episodes of my new screencast series on Clojure, 
> Emacs, Slime, etc.
> 
> http://youtube.com/emailataskcom

Thanks Scott. Nice idea, short to the point demonstrations of how things work. 
I am new to emacs so these are pretty handy.

Cheers,
Bob

-- 
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: Python is way faster than Clojure on this task

2010-11-06 Thread Bob Hutchison

On 2010-11-06, at 10:22 AM, Peter Schuller wrote:

>>> I increased the heap space a lot, but I'm just bordering on the edge
>>> of my real memory, so it's not helping much.
>> 
>> Did you try pushing the minimum heap space up. I'm usually lazy and set them 
>> to the same. I've had serious trouble caused by the way the JVM increases 
>> the heap space. Setting min to max (and max big) pretty much took care of 
>> that issue.
> 
> People keep making claims like this in various situations but I don't
> tend to hear details. Exactly what problems are you having that would
> plausibly apply in this situation?
> 
> Not that there is no reason to set ms=mx (there are reasons), but the
> need to do so tends to be over-stated in my opinion. But if I'm
> missing something I'd like to know about it :)

I understand your scepticism but, even applaud it, but, in my case, it comes 
from actually trying it and measuring the difference (again in my case you 
didn't need anything fancy it was huge and highly visible). It happened often 
enough on different projects that I just do it routinely now. Anyway, if I 
*ever* see something that might be a GC-like problem I first eliminate heap 
growth from the picture (and, this is all I was suggesting here). Perhaps a 
hold over from earlier versions of the JVM but I don't personally care that 
much with my servers -- I have a machine dedicated to the application, it's got 
a lot of memory, use it. Might have a different attitude for a desktop app :-)

Cheers,
Bob

> 
> -- 
> / Peter Schuller
> 
> -- 
> 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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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: Python is way faster than Clojure on this task

2010-11-06 Thread Bob Hutchison

On 2010-11-06, at 9:08 AM, pepijn (aka fliebel) wrote:

> I increased the heap space a lot, but I'm just bordering on the edge
> of my real memory, so it's not helping much.

Did you try pushing the minimum heap space up. I'm usually lazy and set them to 
the same. I've had serious trouble caused by the way the JVM increases the heap 
space. Setting min to max (and max big) pretty much took care of that issue.

Cheers,
Bob


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




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

2010-10-30 Thread Bob Hutchison

On 2010-10-30, at 12:32 AM, Michael Gardner wrote:

> On Oct 29, 2010, at 11:09 PM, David Nolen wrote:
> 
>> JS brought me to Lisp, I would love to see the Clojure community bring Lisp 
>> back to JS. However I fail to see what advantage JS gives on the server 
>> side. From what I've seen the V8 GC and Node.js have a considerable number 
>> of years to go before they are serious contenders against the JVM for 
>> non-trivial projects, evented or no.
> 
> Agreed. What is the point of Javascript on the server side? Familiarity? 
> Consistency with client-side code?

The point isn't entirely Javascript on the server side...

- there are an awful lot of non-non-trivial *web* projects :-)
- it is (very) fast
- websockets/comet based applications absurdly easily set up
- this is the kind of thing the entire node.js community is interested in (it 
isn't a javascript-the-language focused community)

Aleph is extremely interesting. How many in the Clojure community know *of* it, 
let alone *know* it, or have actually *used* it? Know about integrating it with 
Ring? I'm just pointing out a difference in focus the two communities might 
have, this is not a criticism of either.

Aleph isn't the only thing happening out 'there'. What does the Clojure 
community know about Mongrel2 and ZeroMQ?

It is ridiculously easy to set up a quick prototype of a fancy web app using 
node.js, and it seems a lot of people aren't seeing a reason to move away from 
it when they start getting 'serious' about the app.

Like I said, it isn't "Javascript on the server" that's going on with node.js

> 
>> More interesting would be something along the lines of CoffeeScript (like 
>> ClojureScript) that takes a reasonable subset Clojure and compiles into 
>> efficient JS, allowing Clojure programmers to send Clojure code to clients.
> 
> Yes! Writing Javascript makes me want to throw things. Client-side Clojure 
> would be fantastic.

Certainly I'd kinda like this too. But being in wet-blanket-mode... it's gotta 
be more. To me the real problem in programming the browser is the DOM, it's 
*not* a language thing[1]. That has to be dealt with or Clojure on the browser 
will make you want to throw things too :-) You've also got to deal with the 
environment: how is Clojure's immutability of data going to fit into an 
environment where the whole purpose is mucking about with a huge hunk of state 
(the DOM)?

In the short term it seems to me that an "absurdly easy" way to get 
websocket/comet based servers running in Clojure would be good. At least I'd be 
happy. This problem is staring me in the face and I've got to do something next 
week. What do I do? node.js (done in 5 minutes) or somehow get 
Aleph/Ring/Clojure working? or Mongrel2/Ring/Clojure? or ZeroMQ/Ring/Clojure? 
or what? That's the kind of problem *I* am having to deal with.

I should probably bring this up on the Clojure web dev mailing list.

Cheers,
Bob

[1] and mootools and Google's Closure are making real progress with dealing 
with the DOM *and* making Javascript more uniform (so is jQuery for that matter)

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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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: Fighting with Emacs ;-)

2010-10-05 Thread Bob Hutchison

On 2010-10-05, at 3:51 PM, Phil Hagelberg wrote:

> On Tue, Oct 5, 2010 at 11:57 AM, Bob Hutchison  
> wrote:
>> What do you mean by 'switch to the repl', in fact, how do you do that?
>> 
>> I'm using lein swank, I can connect to it, I can evaluate expressions and 
>> get the correct results, I can see the communication going between emacs and 
>> lein swank in the *slime-events* buffer. I switched the mode of the 
>> *scratch* buffer to Clojure and I can ^X^E stuff in there and get the 
>> results.
> 
> The slime project (upstream) foolishly split out slime-repl into a
> separate package from slime itself, so it's a separate elisp package.
> Do M-x package-list-packages and mark slime-repl with i, then press x.
> 
> If it fails to install be sure you're using the latest package.el from
> http://github.com/technomancy/package.el since there are some bug
> fixes I've submitted that *still* haven't been accepted upstream. (You
> might get compilation warnings either way; don't worry about those.)
> 
> -Phil

Thank you!!

I have a repl now that works quite nicely.

I've updated my package.el as well.

Cheers,
Bob

-- 
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: Fighting with Emacs ;-)

2010-10-05 Thread Bob Hutchison

On 2010-10-05, at 3:13 PM, Alan wrote:

> Hm. How are you connecting to swank? I use M-x slime-connect (then hit
> yes/ a few times); as soon as that's done, a new buffer with the
> clojure REPL appears. Then I can switch to it just as with any buffer;
> C-x C-o or similar. The buffer it creates is called *slime-repl
> clojure*. That should be all you have to do. I'm curious what you're
> doing, to cause swank to "work", but not give you a REPL.

I'm connecting exactly that way, a couple of questions about host and port, 
then complaints about version incompatibilities which are answered by me with a 
'y', then a success message. The only buffer created is *slime-events*. I'm on 
OSX with three versions of emacs that I can use, all three do exactly the same 
thing.

That version incompatibility thing I've googled, nobody seems to think it 
matters.

Cheers,
Bob

> 
> On Oct 5, 11:57 am, Bob Hutchison  wrote:
>> Hi,
>> 
>> I've been using Clojure & Leiningen for a while, but never reliably with 
>> emacs. To make things worse I really don't know emacs (vi since 1978 or 
>> something, but not emacs, and now I think emacs hates me). Questions below.
>> 
>> On 2010-09-28, at 7:37 AM, Mike Meyer wrote:
>> 
>> 
>> 
>>> Actually, this sounds like standard behavior for an integrated
>>> EMACS/REPL to me: "sending" code from the edited file to the REPL
>>> evaluates them in the REPL, but doesn't print them: you either get a
>>> message in the minibuffer or a short note in the buffer. Normal usage
>>> is to edit a function, send it to the REPL, then switch to the repl
>>> and test the newly defined function(s) (usually just M-p to recall the
>>> just failed test).
>> 
>> Okay. I'm feeling like a total idiot here.
>> 
>> What do you mean by 'switch to the repl', in fact, how do you do that?
>> 
>> I'm using lein swank, I can connect to it, I can evaluate expressions and 
>> get the correct results, I can see the communication going between emacs and 
>> lein swank in the *slime-events* buffer. I switched the mode of the 
>> *scratch* buffer to Clojure and I can ^X^E stuff in there and get the 
>> results.
>> 
>> What I cannot do is open up a repl. If I us ^C^Z it'll try to run a program 
>> called 'lisp', and if it isn't there emacs will moan. If I make a shell 
>> script called 'lisp' and put 'lien repl' in it, emacs will start the script 
>> start up a new repl and show the prompt... but it'll be running from the 
>> wrong place.
>> 
>> What is this lisp program? How do I bring up a repl that uses the swank I'm 
>> connected to? Is this even possible?
>> 
>> Thanks *so* much in advance.
>> 
>> Cheers,
>> Bob
>> 
>> 
>> 
>>> In particular, SWANK/SLIME prints the value of the last expression in
>>> the evaluate region in the minibuffer. At least, that's what' it's
>>> always done for me.
>> 
>>>   >> --
>>> Mike Meyer http://www.mired.org/consulting.html
>>> Independent Network/Unix/Perforce consultant, email for more information.
>> 
>> 
>> Bob Hutchison
>> Recursive Design Inc.http://www.recursive.ca/
>> weblog:http://xampl.com/so
> 
> -- 
> 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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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: Fighting with Emacs ;-)

2010-10-05 Thread Bob Hutchison
Hi,

I've been using Clojure & Leiningen for a while, but never reliably with emacs. 
To make things worse I really don't know emacs (vi since 1978 or something, but 
not emacs, and now I think emacs hates me). Questions below.

On 2010-09-28, at 7:37 AM, Mike Meyer wrote:
> 
> Actually, this sounds like standard behavior for an integrated
> EMACS/REPL to me: "sending" code from the edited file to the REPL
> evaluates them in the REPL, but doesn't print them: you either get a
> message in the minibuffer or a short note in the buffer. Normal usage
> is to edit a function, send it to the REPL, then switch to the repl
> and test the newly defined function(s) (usually just M-p to recall the
> just failed test).

Okay. I'm feeling like a total idiot here.

What do you mean by 'switch to the repl', in fact, how do you do that?

I'm using lein swank, I can connect to it, I can evaluate expressions and get 
the correct results, I can see the communication going between emacs and lein 
swank in the *slime-events* buffer. I switched the mode of the *scratch* buffer 
to Clojure and I can ^X^E stuff in there and get the results.

What I cannot do is open up a repl. If I us ^C^Z it'll try to run a program 
called 'lisp', and if it isn't there emacs will moan. If I make a shell script 
called 'lisp' and put 'lien repl' in it, emacs will start the script start up a 
new repl and show the prompt... but it'll be running from the wrong place.

What is this lisp program? How do I bring up a repl that uses the swank I'm 
connected to? Is this even possible?

Thanks *so* much in advance.

Cheers,
Bob


> 
> In particular, SWANK/SLIME prints the value of the last expression in
> the evaluate region in the minibuffer. At least, that's what' it's
> always done for me.
> 
>    -- 
> Mike Meyerhttp://www.mired.org/consulting.html
> Independent Network/Unix/Perforce consultant, email for more information.



Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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: Thinking in Clojure

2010-09-03 Thread Bob Hutchison

On 2010-09-02, at 10:02 PM, HB wrote:

> So in idiomatic Clojure applications, maps are considered like
> objects?
> And to operate on them we pass them to functions?

I think that considering maps as a state representation is reasonable. There 
are alternatives, but that's fine-tuning I think.

There's a lot you're going to have to take in, but I suspect the biggest 
sticking point will be around values/immutable-state, references to that state, 
and when/how the reference changes. When you get this, you'll be able to see 
how state/reference/time relate to the OO concepts you already know. At which 
point you'll be laughing.

I don't remember anybody I've worked with that has had any difficulty with 
picking up functional programming (aside from the immutability thing). It's one 
of those things that changes how you work forever -- you are going to feel pain 
when working with Java :-)

I strongly second the recommendation of the book "Joy Of Clojure" as a next 
thing to read (it's from Manning and you can get from their MEAP in pdf/epub 
formats)

Cheers,
Bob

> 
> On Sep 3, 4:55 am, David Nolen  wrote:
>> On Thu, Sep 2, 2010 at 9:29 PM, HB  wrote:
>>> Hey,
>>> I finished reading "Programming Clojure" and "Practical Clojure" and
>>> I'm hooked :)
>>> Please count me in the Clojure club.
>>> But I failed how to think in Clojure.
>>> My main career is around Java web applications (Hibernate, Spring,
>>> Lucene) and Web services.
>>> Lets not talk about Java web frameworks neither Clojure ones, I want
>>> to talk in general.
>>> Usually we create some domain entities, map them with Hibernate/
>>> iBatis.
>>> I don't know how a Clojure application would be build without objects.
>>> I think Scala really shines here, this OOP/FP is really powerful
>>> approach (please note I'm not saying Clojure isn't good, I don't seel
>>> flame war)
>>> How to think in Clojure? how to achieve this shift?
>> 
>> It does require a significant shift in thinking. I think you'll be surprised
>> how far maps and functions will take you if you're used to thinking in OOP.
>> 
>> And contrary to popular belief Clojure is also a hybrid OOP/FP approach:
>> multimethods, protocols, deftype, defrecord, definterface, etc. will let you
>> utilize the better aspects of OOP design. However you should be cautious to
>> reach for these. They are easily misapplied. Stick with the core
>> datastructures (maps, vectors, sets, lists) and fns and you'll do just fine.
>> 
>> David
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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 'chains' of derefs a request for better ideas

2010-04-05 Thread Bob Hutchison

On 2010-04-04, at 2:47 PM, Mark Engelberg wrote:

> I don't understand why you need to "get rid of the delay" once it has been
> updated.  Delays are cheap; why not just be consistent about having your
> data be a ref of a delay?  It will keep your code simpler, and that's well
> worth it.

That's one of the possibilities I considered. But after the first change the 
delay would always have to be forced (it cannot be left as a delay, see the 
example I've posted below). I also didn't want to expose the delay to the 
users/programmers trying to use the stuff (too ugly). The approach of defining 
a type similar to lazy-ref that can initially have a delay but later have just 
a ref is very attractive since there's a ref-like interface for the user and it 
avoids the problem shown below.

Here's a bit of code using Per's example code:

(defn bad-thing [n]
 (let [not-lazy (ref 0)
   lazy (lazy-ref 0)
   counter  (ref 0)]

   (dotimes [i n]
 (dosync
   (ref-set counter i)
   (lazy-alter lazy (fn [x] (+ x @counter)))
   (alter not-lazy (fn [x] (+ x @counter)

   (println "counter: " @counter "lazy:" @lazy "not-lazy:" @not-lazy)
   (println "(* n @counter)  :" (* n @counter))
   (println "(/ (* n (- n 1)) 2) :" (/ (* n (- n 1)) 2

With output:

lazy-ref=> (bad-thing 200)
counter:  199 lazy: 39800 not-lazy: 19900
(* n @counter)  : 39800
(/ (* n (- n 1)) 2) : 19900
nil

You can see the (very) bad situation of the lazy-ref that depends on other refs 
whose values change. This is not just a problem with the lazy-ref, it would be 
easy to have the same effect by setting up delays that don't force previous 
values.


> 
> -- 
> 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
> 
> To unsubscribe, reply using "remove me" as the subject.


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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 'chains' of derefs a request for better ideas

2010-04-04 Thread Bob Hutchison

On 2010-04-04, at 11:15 AM, Per Vognsen wrote:

> Interesting question. Here's something I whipped up in response:
> 
> http://gist.github.com/355456
> 
> I intentionally provide only lazy-alter and no lazy-ref-set. The
> reason is that lazy-alter can be coded so that all the unwrapping and
> rewrapping of delays can be abstracted away from the user-provided
> transformation function. A lazy-ref-set function would impose a much
> stricter discipline on the user in order to maintain laziness.
> 
> All the usual caveats about full laziness apply: beware of space
> leaks, delayed side effects, etc.

Okay, I've had a closer look at what you've done. Thanks again.

I don't need the delay after the alter. This makes lazy-ref-set pretty easy to 
use. So I defined that function and modified your lazy-alter implementation.

This is beginning to look like a single type that is the combination of a ref 
wrapping a delay, and it seems to work. I can also do some interesting things 
when the alter/ref-set happens. So this is getting even better.

Still this isn't quite 'in the language'. The user has to know that it's a lazy 
ref: the functions lazy-alter/lazy-ref-set have to be used rather than 
alter/ref-set. This is unfortunate I think. So I tried using defmethod, along 
the lines of the the contrib libraries generic.arithmetic and 
generic.comparison. Anyway, I've managed to define methods for alter and 
ref-set that will dispatch properly, and so only alter/ref-set are needed (it's 
an illusion maybe, but useful)

Anyway, looks like this'll work well.

Cheers,
Bob

> 
> -Per
> 
> On Sun, Apr 4, 2010 at 9:35 PM, Bob Hutchison  
> wrote:
>> 
>> Hi,
>> 
>> I have a situation where:
>>  1) I have a lot of 'values' that are both expensive to compute and quite 
>> large (they aren't all going to fit into memory) and most of which will not 
>> be needed (this time, but maybe later)
>>  2) I may have a need to update several of them them (in a transaction)
>> 
>> The first case looks to be perfectly suited to delays. The second to refs. 
>> The values are going to be deftypes.
>> 
>> So what I've come up with is a ref -> a delay -> a deftype.
>> 
>> This is fine but it gets troublesome fast.
>> 
>> The first time you try to get the deftype you have to write something like 
>> @@my-thing, and you keep writing that until the value is updated. The update 
>> will make the 'path' a ref -> a deftype (the delay is gone). This is bad I 
>> think because you now have to write @my-thing to get the value.
>> 
>> The best that I've come up with is to update the ref with another delay, 
>> kind of like: (dosync (ref-set my-thing (delay my-updated-thing)))
>> 
>> Is the the way to do it? Is there something better I could be doing? 
>> Something deref-able that I'm missing that is better suited than delay? Some 
>> kind of deref-all-the-way function?
>> 
>> Thanks,
>> Bob
>> 
>> 
>> 
>> Bob Hutchison
>> Recursive Design Inc.
>> http://www.recursive.ca/
>> weblog: http://xampl.com/so
>> 
>> 
>> 
>> 
>> --
>> 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
>> 
>> To unsubscribe, reply using "remove me" as the subject.
>> 
> 
> -- 
> 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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




-- 
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 'chains' of derefs a request for better ideas

2010-04-04 Thread Bob Hutchison

On 2010-04-04, at 11:15 AM, Per Vognsen wrote:

> Interesting question. Here's something I whipped up in response:
> 
> http://gist.github.com/355456
> 
> I intentionally provide only lazy-alter and no lazy-ref-set. The
> reason is that lazy-alter can be coded so that all the unwrapping and
> rewrapping of delays can be abstracted away from the user-provided
> transformation function. A lazy-ref-set function would impose a much
> stricter discipline on the user in order to maintain laziness.
> 
> All the usual caveats about full laziness apply: beware of space
> leaks, delayed side effects, etc.

That's really interesting. Thanks so much! Now I'll go think about it some more 
:-)

Cheers,
Bob

> 
> -Per
> 
> On Sun, Apr 4, 2010 at 9:35 PM, Bob Hutchison  
> wrote:
>> 
>> Hi,
>> 
>> I have a situation where:
>>  1) I have a lot of 'values' that are both expensive to compute and quite 
>> large (they aren't all going to fit into memory) and most of which will not 
>> be needed (this time, but maybe later)
>>  2) I may have a need to update several of them them (in a transaction)
>> 
>> The first case looks to be perfectly suited to delays. The second to refs. 
>> The values are going to be deftypes.
>> 
>> So what I've come up with is a ref -> a delay -> a deftype.
>> 
>> This is fine but it gets troublesome fast.
>> 
>> The first time you try to get the deftype you have to write something like 
>> @@my-thing, and you keep writing that until the value is updated. The update 
>> will make the 'path' a ref -> a deftype (the delay is gone). This is bad I 
>> think because you now have to write @my-thing to get the value.
>> 
>> The best that I've come up with is to update the ref with another delay, 
>> kind of like: (dosync (ref-set my-thing (delay my-updated-thing)))
>> 
>> Is the the way to do it? Is there something better I could be doing? 
>> Something deref-able that I'm missing that is better suited than delay? Some 
>> kind of deref-all-the-way function?
>> 
>> Thanks,
>> Bob
>> 
>> 
>> 
>> Bob Hutchison
>> Recursive Design Inc.
>> http://www.recursive.ca/
>> weblog: http://xampl.com/so
>> 
>> 
>> 
>> 
>> --
>> 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
>> 
>> To unsubscribe, reply using "remove me" as the subject.
>> 
> 
> -- 
> 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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




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


Question about 'chains' of derefs a request for better ideas

2010-04-04 Thread Bob Hutchison

Hi,

I have a situation where:
  1) I have a lot of 'values' that are both expensive to compute and quite 
large (they aren't all going to fit into memory) and most of which will not be 
needed (this time, but maybe later)
  2) I may have a need to update several of them them (in a transaction)

The first case looks to be perfectly suited to delays. The second to refs. The 
values are going to be deftypes.

So what I've come up with is a ref -> a delay -> a deftype.

This is fine but it gets troublesome fast.

The first time you try to get the deftype you have to write something like 
@@my-thing, and you keep writing that until the value is updated. The update 
will make the 'path' a ref -> a deftype (the delay is gone). This is bad I 
think because you now have to write @my-thing to get the value.

The best that I've come up with is to update the ref with another delay, kind 
of like: (dosync (ref-set my-thing (delay my-updated-thing)))

Is the the way to do it? Is there something better I could be doing? Something 
deref-able that I'm missing that is better suited than delay? Some kind of 
deref-all-the-way function?

Thanks,
Bob



Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://xampl.com/so




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

To unsubscribe, reply using "remove me" as the subject.


Re: The new deftype and multimethod dispatching

2009-12-07 Thread Bob Hutchison

On 7-Dec-09, at 4:05 PM, Meikel Brandmeyer wrote:

> Hi,
>
> Am 07.12.2009 um 21:37 schrieb Bob Hutchison:
>
>>> Please note that in clojure, it's the dispatch on the class that's  
>>> the
>>> "trick", not on the type ;-)
>>
>> Sorry, I don't understand what you mean. Could you expand on that a  
>> bit?
>
> Dispatch on the class (or interface) is sometimes the "trick" in  
> clojure. That means a special case, which solves the problem. Eg.  
> the print-method which causes things to be printed by print  
> dispatches on type. Now, type recognises any type tag on the  
> metadata of a thing. But when there is no method defined for this  
> type, print would barf. So the default print-method simply dissocs  
> the type tag from the metadata and retries causing basically a  
> dispatch on the class of the underlying container. Most likely some  
> Map or so. So dispatching on the class is here the trick.  
> Dispatching on type the usual case.

Thanks.

BTW, I'm thinking that my use of the word 'trick' might have been a  
mistake. Where I come from 'does the trick', 'that's the trick' and so  
on mean something along the line of 'that's how you get the required  
result', and that's what I hoped to say... I didn't mean to imply any  
kind of trickiness existed that would fool me into write 'class'  
rather than 'type'... ignorance explains that quite nicely :-)

Cheers,
Bob

>
> Sincerely
> Meikel
>


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://www.recursive.ca/hutch



-- 
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: The new deftype and multimethod dispatching

2009-12-07 Thread Bob Hutchison

On 7-Dec-09, at 4:16 PM, ataggart wrote:
> On Dec 7, 12:37 pm, Bob Hutchison  wrote:
>> On 7-Dec-09, at 12:17 PM, Laurent PETIT wrote:
>>> 2009/12/6 Bob Hutchison 
>>
>>>> Yes! Thanks! The dispatch on type rather than class is the trick. I
>>>> actually ended up writing a macro, this is *much* better.
>>
>>> Please note that in clojure, it's the dispatch on the class that's  
>>> the
>>> "trick", not on the type ;-)
>>
>> Sorry, I don't understand what you mean. Could you expand on that a  
>> bit?
>>
>
> I think Laurent means that type should be the preferred/standard
> mechanism, and class reserved for sneaking over to java-land.


Okay, that makes sense. Maybe I wasn't paying attention but it seems  
to me that the examples I've seen all use class. But, what I thought  
doesn't matter... type certainly works nicely.

Cheers,
Bob


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://www.recursive.ca/hutch



-- 
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: The new deftype and multimethod dispatching

2009-12-07 Thread Bob Hutchison

On 7-Dec-09, at 12:17 PM, Laurent PETIT wrote:

> 2009/12/6 Bob Hutchison 
>
>>
>> On 6-Dec-09, at 3:46 PM, Meikel Brandmeyer wrote:
>>
>>> Hi,
>>>
>>> Am 06.12.2009 um 21:29 schrieb Bob Hutchison:
>>>
>>>> It turns out that dispatching on play.foo.Foo is the only way that
>>>> works. I was hoping ::f/Foo or f/Foo would work too (maybe my alias
>>>> is
>>>> wrong??). Especially since, with aliasing in the user namespace, I
>>>> can
>>>> create a play.foo.Foo using f/Foo
>>>
>>> Does the following work?
>>>
>>> (ns play.foo)
>>> (deftype Foo [])
>>> (defmulti my-print type)
>>> (defmethod my-print ::Foo [x] (println "Got a foo"))
>>>
>>> (in-ns 'user)
>>> ; Note: normally written as (require [play.foo :as f])
>>> (alias 'f 'play.foo)
>>> (def x (f/Foo))
>>> (f/my-print x)
>>
>>
>> Yes! Thanks! The dispatch on type rather than class is the trick. I
>> actually ended up writing a macro, this is *much* better.
>>
>
> Please note that in clojure, it's the dispatch on the class that's the
> "trick", not on the type ;-)

Sorry, I don't understand what you mean. Could you expand on that a bit?

Thanks,
Bob

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


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://www.recursive.ca/hutch



-- 
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: The new deftype and multimethod dispatching

2009-12-06 Thread Bob Hutchison

On 6-Dec-09, at 3:46 PM, Meikel Brandmeyer wrote:

> Hi,
>
> Am 06.12.2009 um 21:29 schrieb Bob Hutchison:
>
>> It turns out that dispatching on play.foo.Foo is the only way that
>> works. I was hoping ::f/Foo or f/Foo would work too (maybe my alias  
>> is
>> wrong??). Especially since, with aliasing in the user namespace, I  
>> can
>> create a play.foo.Foo using f/Foo
>
> Does the following work?
>
> (ns play.foo)
> (deftype Foo [])
> (defmulti my-print type)
> (defmethod my-print ::Foo [x] (println "Got a foo"))
>
> (in-ns 'user)
> ; Note: normally written as (require [play.foo :as f])
> (alias 'f 'play.foo)
> (def x (f/Foo))
> (f/my-print x)


Yes! Thanks! The dispatch on type rather than class is the trick. I  
actually ended up writing a macro, this is *much* better.

Cheers,
Bob

>
> Sincerely
> Meikel
>


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://www.recursive.ca/hutch



-- 
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: The new deftype and multimethod dispatching

2009-12-06 Thread Bob Hutchison

On 6-Dec-09, at 3:46 PM, ataggart wrote:

> While there may be a way to work around it, if you're just dispatching
> on the type of the first arg, you might want to use defprotocol
> instead of defmulti.

True, and I likely will for most situations. In what I hope to do,  
I've got a common situation where I'd like to dispatch on two  
arguments. In something like Ruby this requires a double dispatch, but  
in CL it doesn't.

Cheers,
Bob


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://www.recursive.ca/hutch



-- 
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 new deftype and multimethod dispatching

2009-12-06 Thread Bob Hutchison

Hi,

I'm new to Clojure, not new to lisp (CL and scheme), and having a  
thoroughly good time. I've been having a go at the new deftype stuff  
and using a clone of the new branch from the git repository (up-to- 
date as of this message being posted). So far everything I've tried  
has worked very nicely, except for one thing.

I've put three files up as a gist: http://gist.github.com/250364 that  
illustrate (I hope) my question.

So. I've defined a type 'Foo -- inevitably foo, sorry -- and I want to  
define a very simple multimethod that dispatches on the class of its  
single argument. I understand that defmethod needs a fully ns  
qualified name to dispatch properly. I was hoping there was a shorter  
way of doing this than play.foo.Foo, maybe using some sort of alias- 
based technique like those in Stuary Halloway's book (p233 and  
thereabout).

I've got six variations in there, and I know full well that most of  
these should not work, but I put them in anyway.

I believe that I'm AOT compiling everything (I'm compiling the ./src/ 
play/foo.clj file and the class files are on disk, so...)

It turns out that dispatching on play.foo.Foo is the only way that  
works. I was hoping ::f/Foo or f/Foo would work too (maybe my alias is  
wrong??). Especially since, with aliasing in the user namespace, I can  
create a play.foo.Foo using f/Foo

Obviously, I have a workaround, but that's going to get ugly fast with  
a real namespace name, not to mention making re-naming the namespace  
harder than it should be.

If someone could help me out I'd appreciate it.

Thanks,
Bob


Bob Hutchison
Recursive Design Inc.
http://www.recursive.ca/
weblog: http://www.recursive.ca/hutch



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