Re: Simulations in Clojure/Clojurescript

2018-01-12 Thread Bobby Eickhoff
I don't have any examples to provide, but I would highly recommend reading 
through Rich's essay on Identity and State: https://clojure.org/about/state

Bobby

On Thursday, January 11, 2018 at 12:43:00 AM UTC-5, Michael Nardell wrote:
>
> On Wednesday, January 10, 2018 at 4:56:24 PM UTC-8, Christopher Small 
> wrote:
>
> You may be right about an object-oriented approach being the most natural 
>> here. But, I'd encourage you to keep an open mind. Clojure has this 
>> particular way of encouraging you to and rewarding you for describing your 
>> problem domain in terms of pain data, and writing program logic as (mostly) 
>> pure functions around that data. 
>>
>
> Chris :: Thanks, I am hoping that you are foretelling the path I will end 
> up following. That I start with an object approach, because that is what I 
> am familiar with and have used in the past. Then find new ways of thinking 
> about the problem through through functional and Clojure programming. I 
> think a good starting point, is as you recommend, substitute maps for 
> objects in my thinking in the problem domain. I can see that I could 
> actually set-up the simulation just so, and I will have completely captured 
> the model, frozen at time t=0. Then my challenge is to write a set of 
> functions that will transition the model to time t+1. At that point I am 
> done. 
>
> Mike
>

-- 
You 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: [ANN] Git Deps for Clojure!

2018-01-09 Thread Bobby Eickhoff
I find it somewhat ironic given all of the recent discussion of growth vs. 
breakage in the world of Clojure that this latest release of clojure tools 
-- if I understand correctly -- includes, as advertised above, a breaking 
change.  :-P

On Tuesday, January 9, 2018 at 9:44:12 AM UTC-5, Alex Miller wrote:
>
> There is a new version of clojure tools available (1.9.0.302) that changes 
> the attributes for git coordinates:
>
> :rev - removed attribute
> :sha - new required attribute, full sha strongly encouraged (prefix sha 
> support may be removed)
> :tag - new optional attribute, should match the sha (not used by 
> tools.deps.alpha)
>
> This release also fixes the XML warning under JDK 9 for -Spom.
>
> If you are listing git coordinate information in your README, we would 
> strongly encourage publishing a full :sha (40 chars) example.
>
> On Friday, January 5, 2018 at 12:49:15 PM UTC-6, Alex Miller wrote:
>>
>> Pleased to announce some new functionality for clj and tools.deps!
>>
>> https://clojure.org/news/2018/01/05/git-deps
>>
>> Additionally, there have been new releases of:
>> - Brew clojure formula (to get it: brew upgrade clojure)
>> - Linux clojure installer (see https://clojure.org/guides/getting_started 
>> for info)
>> - tools.deps.alpha 
>> - NEW tools.gitlibs 
>>
>> Other than git deps, "clj -Spom" for pom generation has some fixes and an 
>> addition to add Maven repositories if needed.
>>
>

-- 
You 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: How to transform deeply nested map into a series of arrays?

2017-03-11 Thread Bobby Eickhoff
Given the recent discussions about specter, I thought I'd add a spectral 
solution.  Disclaimer: I'm still a specter novice.

An unrolled solution might look like this:

(select [ALL (collect-one FIRST) LAST
 ALL (collect-one FIRST) LAST
 ALL (collect-one FIRST) LAST]
  data)

=> [[30 4 50 43] [30 4 1000 32] [30 6 40 12] [30 6 90 2] [30 8 777 23] [30 8 
9090 1]]


Each repetition in that path starts with a map, navigates to each key-value 
pair (ALL), collects its key (collect-one FIRST), and navigates to its 
value (LAST).  The values are themselves maps, so we repeat.

This obviously lends itself to recursive navigation:

(def TreePaths
  (recursive-path [] p
(if-path map?
  [ALL (collect-one FIRST) LAST p]
  STAY)))

(select [TreePaths] data)

=> [[30 4 50 43] [30 4 1000 32] [30 6 40 12] [30 6 90 2] [30 8 777 23] [30 8 
9090 1]]



On Wednesday, March 8, 2017 at 12:38:18 PM UTC-5, piast...@gmail.com wrote:
>
>
> Given this: 
>
> {:positive :true {30 {4 {50 43, 1000 32}, 6 {40 12, 90 2}, 8 {777 23, 9090 
> 1}}}
>
> I'd like a series of arrays that I can feed into (reduce) so I can easily 
> sum them:
>
> [ 30 4 50 43 ]
>
> [ 30 4 1000 32 ]
>
> [ 30 6 40 12 ]
>
> [ 30 6 90 2 ]
>
> [ 30 8 777 23 ]
>
> [ 30 8 9090 1 ]
>
> I've been trying to work this out using "walk" recursively, but then I 
> wondered if perhaps I am missing something obvious? Does Clojure offer a 
> straightforward way to do this?
>
>
>
>
>
>

-- 
You 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: What does it mean to say that special forms can't be used as arguments to functions?

2016-12-19 Thread Bobby Eickhoff
Here, "if" is not actually an argument to the + function.  The arguments to 
+ are 10 and 1, i.e. (+ 10 1).  The reason this is true is because, in 
Clojure, the arguments to functions are evaluated before the function call, 
i.e. evaluation is strict.

To see an example of how if (and other special forms) cannot be used as 
arguments to functions, consider the following:

user=> ((partial + 2) 3)
5
user=> ((partial if true) :a :b)

CompilerException java.lang.RuntimeException: Unable to resolve symbol: if 
in this context, compiling:(/private/var/folders/pc/
kdtygcsd50n_35zx7qzhk7w1z9685_/T/form-init4959724850588988177.clj:1:2) 



On Monday, December 19, 2016 at 4:24:51 PM UTC-5, Hugh Jass wrote:
>
> I read this on page 51 of the book 'Clojure for the Brave and True':
>
> Another feature that differentiates special forms is that you can’t use
>> them as arguments to functions.  
>>
>
> So, I expected the following code to fail:
>
> (+ (if (> 2 1) 10 1) 1)
>
> since I used the 'if' special form as an argument to the '+' function. 
> However, the code runs and returns 11.
>
> What does the quote really mean?
>
>

-- 
You 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: recursive bindings not available in let form?

2016-12-02 Thread Bobby Eickhoff
Note that letfn does allow recursive bindings, though I couldn't comment as 
to the implementation details.

On Friday, December 2, 2016 at 3:01:13 PM UTC-5, Paul Gowder wrote:
>
> Hi clojure-world, 
>
> I think maybe this is actually related to the complexities of binding 
> referenced in the previous thread (
> https://groups.google.com/forum/?utm_source=digest_medium=email#!topic/clojure/zBXsrqTN2xs)...
>  
> maybe?  But it would be amazing if some wise person would help explain... 
>
> So for obscure reasons, I found myself trying to use a naive recursive 
> fibonacci function interactively.  So naturally, the first thing my fingers 
> went to was: 
>
> (let [fib (fn [x] 
>   (cond
> (< x 2) x
> :else (+ (fib (- x 2)) (fib (- x 1)]
> (fib 5))
>
> which threw an unable to resolve symbol error because it couldn't resolve 
> the recursive calls to fib inside the let binding. 
>
> But swap out the let for a def and it works just fine:
>
> (def fib (fn [x] 
>   (cond
> (< x 2) x
> :else (+ (fib (- x 2)) (fib (- x 1))
> (fib 5)
>
> Can someone clarify for me what's going on here?  Why can a def binding 
> get access to its own name in the body of a function, but not a let binding?
>
> thanks!
>
> -Paul
>

-- 
You 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: [beginner] idiomatic way to parse lazy sequence

2016-11-08 Thread Bobby Eickhoff
Here are a few thoughts.

This algorithm sounds like a fold, i.e. a reduction.  You're iterating over 
a sequence while accumulating into a collection.  A collection of 
collections, in this case.

You're starting value for the fold might be this:

{:first {}, :second {}}

You're reducing function would consume each line, adding it into the above 
map of maps.  Updating the map-of-maps might be done through something like 
update or update-in:

(update-in maps [:first] add-by-key-and-value line)


Here add-by-key-and-value is a function that I've left undefined.  It takes 
a single map and a line and adds that line by key and value.  (Since the 
definition of key and value were omitted from the example, I've delegated 
them to said function.)

Hence, the whole thing might look like this (untested!):

(defn ___ [lines]
  (let [rf (fn [maps line]
 (condp re-matches line
   #"some-regex"(update-in maps [:first] 
add-by-key-and-value line)
   #"another-regex" (update-in maps [:second] 
add-by-key-and-value key line)))]
(reduce rf {:first {}, :second {}} lines)))


P.S.  I'm using update-in here a bit unnecessarily.  update would work 
perfectly fine, but I thought it would be better to show you the general 
form which can update maps to any depth.

-- 
You 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: comp and partial vs ->>

2016-10-28 Thread Bobby Eickhoff
I agree that forms like (partial > 3) are clearer than #() forms.  However, 
I've been avoiding partial in code bases for a while -- it was measurably 
slower than the alternative.  Is that still the case?  Has anyone else 
observed slowness with partial?

On Thursday, October 27, 2016 at 8:44:14 PM UTC-4, tbc++ wrote:
>
> I use comp all the time, not only for transducers, but also for digging 
> into maps:
>
>
> (map (comp first :pets)
>[{:pets [:fluffy]}
> {:pets [:spot]}])
>
> => (:fluffy, :spot)
>
> Partial is also handy when used with a lot of sequence functions
>
> (->> [1 2 3 4 5]
>(filter (partial > 3)))
>
> Sure I could write that function as #(< 3 %), but I find that syntax 
> harder to mentally parse as I have to remember that the body of the #() is 
> a function context and then I have to look up where the % symbol is. 
> (partial > 3) is just easier to understand. 
>
> Timothy 
>
>
>
> On Thu, Oct 27, 2016 at 6:12 PM, Mark Engelberg  > wrote:
>
>> On Thu, Oct 27, 2016 at 9:39 AM, Alan Thompson > > wrote:
>>
>>> I almost never use either the `comp` or the `partial` functions.  I 
>>> think it is clearer to either compose the functions like Gary showed, or to 
>>> use a threading macro (my favorite is the `it->` macro from the Tupelo 
>>> library ).
>>> Alan
>>>
>>>
>> You need to use comp if you're building a transducer. 
>>
>> -- 
>> 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 unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> “One of the main causes of the fall of the Roman Empire was that–lacking 
> zero–they had no way to indicate successful termination of their C 
> programs.”
> (Robert Firth) 
>

-- 
You 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: 0-arity of transducer in transduce

2016-08-31 Thread Bobby Eickhoff
Mathias, I've never found a satisfactory answer to this question.  It has 
been asked before.

https://groups.google.com/d/msg/clojure/HK9LkmlRyjY/S0U1u2nQCQAJ
https://groups.google.com/d/msg/clojure/uVKP4_0KMwQ/-oUJahvUarIJ

Hoping someone with more insight will comment on this situation.

Bobby

On Wednesday, August 24, 2016 at 4:00:41 AM UTC-4, Mathias De Wachter wrote:
>
> Hi,
>
> I'm trying to use the transducer framework for some sequence processing 
> where I have a core reduction function, but depending on options, extra 
> functionality can be added to the reduction function. I thought that's a 
> good fit for hand-written transducers.
>
> However, I'm running into a problem initializing the optional 
> functionality. I thought I would simply perform it in the 0-arity, like 
> this:
>
> (defn my-tx
>   [rf]
>   (fn
>  ([] (assoc (rf) ::my-ns/my-extra-field my-init-value)
> ...
>
> But that's never called, at least not in transduce:
>
> (defn transduce
> "..." {:added "1.7"}
> ([xform f coll] (transduce xform f *(f)* coll))
> ([xform f init coll]
>   (let [f (xform f)
> ret (if (instance? clojure.lang.IReduceInit coll)
>(.reduce ^clojure.lang.IReduceInit coll f init)
>(clojure.core.protocols/coll-reduce coll f init))]
>   (f ret
>
> So, my question is: why the (f) instead of (xform f)? And what's the use 
> of the 0-arity in transducers if it's not called? I assume it's used in 
> other uses of transducers?
>
> By the way, I understand it's tricky to call (xform f) instead, because 
> then what do you do with a provided init... And I also understand that I 
> can create initial state in the closure of the transducer, so I'm not 
> blocked at all. I'm just very curious :).
>
> Thanks,
> -Mathias
>

-- 
You 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: Having trouble doing what I want using macros, is there a better way?

2016-06-10 Thread Bobby Eickhoff
Having spent quite a bit of time recently dissecting transducers 
, 
I'd tend to agree with Tim: core transducers will probably give you most of 
what you want.  I'd also agree that writing macros should be your last 
resort.  But maybe the core function completing is very close to what 
you're looking for...

clojure.core/completing

([f] [f cf])

  Takes a reducing function f of 2 args and returns a fn suitable for

  transduce by adding an arity-1 signature that calls cf (default -

  identity) on the result argument.


On Friday, June 10, 2016 at 2:07:58 PM UTC-4, Travis Daudelin wrote:
>
> Hi all!
>
> I'm current working on a project where I am ingesting events off a stream 
> and processing them. There are many many steps involved in the processing 
> component, so I am choosing to write the steps as a series of transducers 
> (because, hey, they're super cool!). Here's the problem though, after 
> writing the first 2 processing steps I'm noticing that all of them are 
> going to look very similar:
>
> (defn a-step-transducer
>   []
>   (fn [reducing-fn]
>  (fn
>([] (reducing-fn))
>([result] (reducing-fn result))
>([[guid-state processed-events :as result] event]
> ;; step-specific logic
> 
>
> Given how many steps I am planning to write, this is a ton of boilerplate! 
> So, my first thought was to use a macro to abstract away all this 
> boilerplate. Now, I have to admit that Clojure is my first Lisp, so I'm 
> really not sure I fully understand when or why to use macros to do things. 
> My current understanding is that macros are a kind of "template" for code, 
> so something like this where I don't want to write the same function 
> structure over and over seems like a decent use case for macros (feel free 
> to correct me if I'm totally off on this). Here is my first attempt:
>
> (defmacro deftransducer
> [body]
> `(fn [reducing-fn]
>(fn
>  ([] (reducing-fn))
>  ([result] (reducing-fn result))
>  ([[guid-state processed-events :as result] event]
>   ~@body
>
> The idea here being that in body I can reference the variables defined by 
> the macro like reducing-fn, result, event, etc. Of course, I quickly 
> found out that this doesn't work:
>
> storm-etl.entry-processing> (deftransducer "something")
> CompilerException java.lang.RuntimeException: Can't use qualified name as 
> parameter: storm-etl.entry-processing/reducing-function
>
> Some quick googling tells me that the solution to this is to use gensyms 
> for these variable names, but that would defeat the whole purpose of this 
> because I want to be able to reference those variables from within the code 
> that I pass to my macro. Is this an appropriate use case for macros or am I 
> way off base? Is there an alternative approach that would be recommended?
>

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


Deconstructing Transducers

2016-05-27 Thread Bobby Eickhoff
Precondition:  I didn't really understand transducers
Action:  I spent some time tinkering with them
Postcondition:  I've written a blog post about it: Deconstructing 
Transducers 


Constructive feedback is more than welcome.
Thanks!
Bobby

-- 
You 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: Return from a function

2016-04-14 Thread Bobby Eickhoff
The result of the last expression evaluated is always returned.  Hence, the 
shape of the function is what determines the points of return and the 
returned values.  For example,  if you're entire function is defined as one 
(if ...) statement, there are two possible points of return, each of the 
branches.

But I think you're probably asking if you can return early from a function, 
like in Java or Javascript.  No, there's no return "statement" in Clojure.  
You just have to structure your functions a certain way.

Here's an alternate version of your pyramid function which uses (recur 
...).  This is equivalent to calling pyramid recursively, but the compiler 
is able to optimize this recursive call away.  In other words, it will 
never overflow the stack.

(defn pyramid [n]
  (when (pos? n)
(dotimes [_ n]
  (print "* "))
(println)
(recur (dec n




On Thursday, April 14, 2016 at 9:23:58 PM UTC-4, Varun Kamra wrote:
>
> On Thursday, April 14, 2016 at 5:58:33 PM UTC-7, Varun Kamra wrote:
> > Hey guys I am new to clojure. I was just experimenting by printing a 
> pyramid of stars 5 rows and 5 column. Here's the code:
> > 
> > (defn pyramid [j i]
> > (if (and (= i 0) (neg?
> > (println "There's your pyramid"))
> > (if (= j 0)
> > (do (println)
> > (pyramid (- i 1) (- i 1)))
> > (do (print "* ")
> > (pyramid (- j 1) i
> > 
> > It's working fine till it prints the pyramid, but after printing it, it 
> continues printing a lot of stars and eventually fail with stack overflow. 
> I am guessing that a if I put a negative check I can prevent it but I 
> wanted to know if there's a way to return from the recursive call instead.
>
> I understood now, it was going in the else condition of the if so here'so 
> the modified code
>
> (defn pyramid [j i]
> (if (= i 0)
> (println "There's your pyramid"))
> (if (= j 0)
> (do (println)
> (pyramid (- i 1) (- i 1
> (if (not (neg? j))
> (do (print "* ")
> (pyramid (- j 1) i
>
> But my question still stands if ther's a way to return from function.
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
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: Puzzle solving in Clojure

2016-04-12 Thread Bobby Eickhoff
doall holds on to the head of the seq, "causing the entire seq to reside in 
memory at one time." (https://clojuredocs.org/clojure.core/doall)

Instead, just find the first solution:

(->> (permutations (range 10)) (filter check?) (first) (print-solution))


On Friday, April 8, 2016 at 9:28:55 AM UTC-4, Olivier Scalbert wrote:
>
> Hello everybody !
>
> I just start learning Clojure and I am a complete newbie !
>
> I have tried to solve this classical small puzzle with Clojure.
> Assign one digit from {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} to each letter {o n e 
> t h r l v w y} so that
> one + one + one + three + three + eleven = twenty
>
> Here is the code:
>
> (defn permutations [s]
>   (lazy-seq
>(if (seq (rest s))
>  (apply concat (for [x s]
>  (map #(cons x %) (permutations (remove #{x} s)
>  [s])))
>
> (defn tomap [proposal]
> (zipmap [:o :n :e :t :h :r :l :v :w :y] proposal))
>
> (defn one-value [m]
> (+ (* 100 (:o m))
>(*  10 (:n m))
>   (:e m)))
>
> (defn three-value [m]
> (+ (* 1 (:t m))
>(*  1000 (:h m))
>(*   100 (:r m))
>(*10 (:e m))
> (:e m)))
>
> (defn eleven-value [m]
> (+ (* 10 (:e m))
>(*  1 (:l m))
>(*   1000 (:e m))
>(*100 (:v m))
>(* 10 (:e m))
>  (:n m)))
>
> (defn twenty-value [m]
> (+ (* 10 (:t m))
>(*  1 (:w m))
>(*   1000 (:e m))
>(*100 (:n m))
>(* 10 (:t m))
>  (:y m)))
>
> (defn check? [proposal]
> (let [m (tomap proposal)
>   one (one-value m)
>   three (three-value m)
>   eleven (eleven-value m)
>   twenty (twenty-value m)]
>
> (= (+ one one one three three eleven)
>twenty)))
>
> (defn print-solution [solution]
> (println (tomap solution)))
>
> (doall (map print-solution (filter check? (permutations (range 10)
>
> This program prints the correct solution, but I have some questions !
> It seems to consume lot of memory (around 6GB). Do I miss something with 
> the lazy evaluation ?
> How can I change the code into a more idiomatic one ?
>
> Thanks for your help and time !
>
> Olivier
>
>
>

-- 
You 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: Prismatic Schema - Self-reference in schema definitions

2016-03-05 Thread Bobby Eickhoff
Note also that I'm giving each Zone "object" it's own :type property.  
That's how I'm able to dispatch on the type.  It also plays well with 
multimethods.

On Saturday, March 5, 2016 at 7:26:27 PM UTC-5, Bobby Eickhoff wrote:
>
> It sounds like what you're describing is (structurally) an algebraic data 
> type, i.e. a generic type with specific variants.  I've been able to do 
> something like this in my own projects.  Here I'm considering Zone the 
> general type and each variant is Zone:Hand, Zone:Deck, 
>
> (def Zone:Hand
>   ...)
>
> (def Zone:Deck
>   ...)
>
> (def Zone
>   (s/conditional
> #(= (:type %) :Hand) Zone:Hand
> #(= (:type %) :Deck) Zone:Deck
> ...))
>
> Does that help?
>
> On Saturday, March 5, 2016 at 6:58:31 PM UTC-5, JvJ wrote:
>>
>> I've been using Schema, and there's a kind of type definition that I'm 
>> having trouble with.  I'm not sure exactly how to describe it, so I'll 
>> provide an example.
>>
>> I'm working on a digital card game in which there are numerous zones that 
>> a card may be in.  Each card needs to know which zone it is in, and there 
>> may be additional information depending on the zone.
>>
>> For instance, if a card is in a player's hand, no additional information 
>> is required.  However, if the card is on the board, it needs to understand 
>> its position on the board.
>>
>> I have the following definition for zone types:
>>
>> (def Zone
>>   "A schema for referring to the various game zones."
>>   (s/enum :Hand
>>   :Deck
>>   :Board
>>   :Field
>>   :Discard
>>   :Void))
>>
>> I want to define a different schema type for each of these, and then 
>> define a zone spec:
>>
>> (def ZoneSpec {(required-key :zone-type) Zone
>>:data > specified earlier>
>> })
>>
>> I want to ensure that whichever data is provided specified the schema 
>> associated with the zone type.
>>
>> Is there a way to do this?
>>
>> 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: Prismatic Schema - Self-reference in schema definitions

2016-03-05 Thread Bobby Eickhoff
It sounds like what you're describing is (structurally) an algebraic data 
type, i.e. a generic type with specific variants.  I've been able to do 
something like this in my own projects.  Here I'm considering Zone the 
general type and each variant is Zone:Hand, Zone:Deck, 

(def Zone:Hand
  ...)

(def Zone:Deck
  ...)

(def Zone
  (s/conditional
#(= (:type %) :Hand) Zone:Hand
#(= (:type %) :Deck) Zone:Deck
...))

Does that help?

On Saturday, March 5, 2016 at 6:58:31 PM UTC-5, JvJ wrote:
>
> I've been using Schema, and there's a kind of type definition that I'm 
> having trouble with.  I'm not sure exactly how to describe it, so I'll 
> provide an example.
>
> I'm working on a digital card game in which there are numerous zones that 
> a card may be in.  Each card needs to know which zone it is in, and there 
> may be additional information depending on the zone.
>
> For instance, if a card is in a player's hand, no additional information 
> is required.  However, if the card is on the board, it needs to understand 
> its position on the board.
>
> I have the following definition for zone types:
>
> (def Zone
>   "A schema for referring to the various game zones."
>   (s/enum :Hand
>   :Deck
>   :Board
>   :Field
>   :Discard
>   :Void))
>
> I want to define a different schema type for each of these, and then 
> define a zone spec:
>
> (def ZoneSpec {(required-key :zone-type) Zone
>:data  specified earlier>
> })
>
> I want to ensure that whichever data is provided specified the schema 
> associated with the zone type.
>
> Is there a way to do this?
>
> 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.


clojars down?

2016-01-01 Thread Bobby Eickhoff
Is anyone else having trouble connecting to clojars.org?  Firefox can't 
connect: "The connection has timed out".  Neither can lein:

INFO: I/O exception (java.net.NoRouteToHostException) caught when 
processing request to {s}->https://clojars.org:443: No route to host

-- 
You 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 core eval appears recursive?

2015-07-24 Thread Bobby Eickhoff
eval isn't calling itself, it's calling the method Compiler#eval.  (defn 
eval ...) binds the function to a var named eval, but (. 
clojure.lang.Compiler (eval form)) is invoking a static method.  See the dot 
special form docs http://clojure.org/java_interop#Java Interop-The Dot 
special form.

On Friday, July 24, 2015 at 10:27:52 AM UTC-4, SteveSuehs wrote:

 I am looking at the source for clojure's core eval function.  It appears 
 to recursively call itself.  Is the eval used to call a method on compiler 
 not the same eval? How is this not infinitely recursive?  Is something lazy 
 here?

 Links:
 * Clojure eval 
 https://github.com/clojure/clojure/blob/bdc752a7fefff5e63e0847836ae5e6d95f971c37/src/clj/clojure/core.clj
 * Compiler 
 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java

 Thanks!
 -Steve


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
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: Satisfies? seems strangely slow

2015-01-22 Thread Bobby Eickhoff
Clojure isn't doing the caching.  The JVM is doing the caching.  In this 
case, Clojure just has mechanical sympathy for how the JVM operates.

On Thursday, January 22, 2015 at 11:10:56 PM UTC-5, Michael Blume wrote:

 It sounds like basically dispatch is fast because we bothered to make it 
 fast (by caching) and satisfies? is slow because we didn't. Is it worth 
 throwing caching at satisfies? to make it fast or should satisfies? just 
 not be on the critical path for Clojure code?

 (To give a motivating example, satisfies? is on the critical path for 
 honeysql and will be until this pull is merged: 
 https://github.com/jkk/honeysql/pull/38)


 On Thu Jan 22 2015 at 5:52:13 PM Ghadi Shayban gsha...@gmail.com 
 javascript: wrote:

 Protocol call sites build an inline cache to optimize dispatch.  The 
 benchmark is running many times and reaping benefit from the cache. 
  satisfies? looks up the object's class in the protocol's implementation 
 map [1], and the benchmark is stressing this.  You'll see that code checks 
 if the protocol has the backing interface first, then checks for the 
 object's class, then if necessary walks up the superclass chain.

 [1] 
 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L507-L516



 On Thursday, January 22, 2015 at 8:36:23 PM UTC-5, Michael Blume wrote:

 Extends seems to be defeated by superclassing. ie:

 (extends? my-protocol (class {})) = false

 because my-protocol is extended to IPersistentMap and (class {}) isn't 
 IPersistentMap it's PersistentArrayMap (which implements IPersistentMap but 
 extends? doesn't care)

 On Thu Jan 22 2015 at 5:28:30 PM Timothy Baldridge tbald...@gmail.com 
 wrote:

 The logic of extends? is much simpler, so try that. IIRC it's something 
 like extends? returns true if any method on the protocol is implemented 
 by 
 x, satisfies? returns true if all methods of a protocol are implemented 
 by x. 

 The docs don't seem to give much help here, so play with it in the repl 
 a bit. 

 Timothy

 On Thu, Jan 22, 2015 at 6:14 PM, Michael Blume blume...@gmail.com 
 wrote:

 (defprotocol my-protocol
   (foo [this]))

 (extend-protocol my-protocol
   clojure.lang.IPersistentMap
   (foo [this] hello from map))

 (criterium.core/quick-bench
   (satisfies? my-protocol {}))

 (criterium.core/quick-bench
   (foo {}))

 Simply calling foo on an empty map takes 7 ns,
 but checking whether the map satisfies my-protocol takes 22 µs, 3000 
 times longer.

 It seems like to call foo, some mechanism has to look up an 
 implementation of my-protocol for maps -- how is it we can do that so 
 quickly for a call and so slowly for satisfies?

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


 For more options, visit https://groups.google.com/d/optout.




 -- 
 “One of the main causes of the fall of the Roman Empire was 
 that–lacking zero–they had no way to indicate successful termination of 
 their C programs.”
 (Robert Firth) 

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



-- 
You 

Re: how do you name your protocols?

2014-09-06 Thread Bobby Eickhoff
What might be an advantage to using something like the I-prefix?  At first 
glance, this appears to be unbeneficial hungarian notation.

Aesthetically, this seems backwards (to me).  I want interfaces and 
protocols to have the most readable names.  I'm willing to concede on less 
readable names for concrete implementations.  Many implementations and 
participants will even be anonymous.

On Friday, September 5, 2014 5:52:48 AM UTC-4, Dave Sann wrote:

 I saw a comment on protocol naming here: 
 https://groups.google.com/d/msg/clojure/A4xIitQWloU/6E4xHDTPPaIJ

 there is nothing in the coding standards: 
 http://dev.clojure.org/display/community/Library+Coding+Standards (are 
 these maintained?)

 is there any sensible consensus on good naming convention?

 IBlah
 PBlah
 BlahP
 Blah
 ...other

 ...doesn't matter

 Dave


-- 
You 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 Korma still a good current choice for DB backend?

2014-07-24 Thread Bobby Eickhoff
Slight tangent:  I've never used honeysql, but every time I see the name I 
want it to be pronounced honeysuckle.  Is that the naming intent, or is 
it simply honey s q l?

On Tuesday, July 22, 2014 8:10:16 AM UTC-4, Jonathon McKitrick wrote:

 Development and support seem to have slowed down.  Are there newer or 
 better choices out there with momentum right now?



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

2014-02-26 Thread Bobby Eickhoff
This seems like a reasonable optimization.  I read something similar a few 
years ago 
(http://lorgonblog.wordpress.com/2008/05/24/catamorphisms-part-four/):

What we want is a function which will be smart, and only allocate new data 
structures when necessary.  Indeed, one of the main advantages of immutable 
data structures is the ability to share portions of structure.


Bobby

On Monday, February 24, 2014 4:00:34 PM UTC-5, Brian Craft wrote:

 This is vaguely related to David's posts about om/react, where he talks 
 about optimizing state change tracking by checking object identity on 
 immutable objects: deep compares can be avoided if same identity implies no 
 changes.

 My first thought was that there are many algorithms that will give you a 
 new object every time, even if nothing has changed.  E.g. if your state has 
 an array whose elements must be validated, doing a map over the elements 
 will give you a new array every time, even if it makes no changes.

 Enforcing non-negative values, for instance:

 = (let [x {:a [1 -2 3]}] (update-in x [:a] (fn [y] (mapv #(if ( % 0) 0 
 %) y
 {:a [1 0 3]}

 In the following case the values are already non-negative, but we still 
 get a new object:

 = (let [x {:a [1 2 3]}] (identical? x (update-in x [:a] (fn [y] (mapv 
 #(if ( % 0) 0 %) y)
 false

 One can imagine trying to rewrite this so it passes through the vector if 
 nothing has changed. E.g.

 = (let [x {:a [1 2 3]}] (identical? x (update-in x [:a] (fn [y] (reduce 
 (fn [v i] (if ( (v i) 0) (assoc v i 0) v)) y (range (count y)))
 true

 = (let [x {:a [1 -1 3]}] (identical? x (update-in x [:a] (fn [y] (reduce 
 (fn [v i] (if ( (v i) 0) (assoc v i 0) v)) y (range (count y)))
 false

 I expect many algorithms would need to be reworked like this in order to 
 rely on object identity for change tracking. Is this madness? Am I thinking 
 about this the wrong way?


 An interesting note here is that the next-to-last update-in, above, 
 returned the same object. I didn't know update-in could return the same 
 object. A simpler example:

 = (let [x {a [1 2 3]} y (update-in x [a] (fn [z] z))] [x y 
 (identical? x y)])
 [{a [1 2 3]} {a [1 2 3]} true]

 = (let [x {a [1 2 3]} y (update-in x [a] (fn [z] [1 2 3]))] [x y 
 (identical? x y)])
 [{a [1 2 3]} {a [1 2 3]} false]


 Is this some kind of optimization in update-in, that it doesn't create a 
 new object if the new attribute is identical to the old attribute? Is it 
 peculiar to the data type? Is it documented anywhere?




-- 
You 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 cannot last be fast on vector?

2012-06-29 Thread Bobby Eickhoff
Warren, you're on the right track with your alternative design: Intuitively 
and ideally, last should return the last element of a finite, ordered 
collection.  But Clojure's last operates on sequences, not collections. 
 This is problematic because sequences can be (effectively) infinite. 
 Calling last on an arbitrary sequence is, therefore, dubious at best. 
 It's what Doug Crockford might call an attractive nuisance: sometimes 
useful, but dangerous.  So last isn't a function I would spend alot of 
time trying to fix.

There is historical precedent for Clojure's last function.  For example, 
see Haskell's last function in Data.List.  Historical precedent doesn't 
justify the design, but it helps explain how we got here.

Bobby

On Friday, June 29, 2012 4:34:04 PM UTC-4, Warren Lynn wrote:

 Even not a single action is taken because of this thread, I still would 
 not consider the thread fruitless. It helped me (and maybe others) 
 understand the issue better.

 My point was: you need a clear documentation on a coherent, consistent 
 abstraction, and let the programmer to understand. Just clear documentation 
 is not enough. You can document a very messy system in clear documentation 
 (maybe the US tax code?).

 Here, we are having both peek and last, which is not coherent to me. 
 consider the documentation on an alternative design:

 last: get the last element from an ordered collection. for queues and 
 linked lists, it takes linear time. for vectors, it takes constant time.

 and get rid of peek (we already have first for linked list and queues, 
 right?)

 Which one is cleaner?


-- 
You 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: letrec

2011-12-15 Thread Bobby Eickhoff
'declare' wouldn't be good because of the scope of vars.  There's no sense 
using global (albeit namespaced) variables for what probably only need to 
be local identifiers.

-- 
You 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 Website / Wikispaces

2011-10-07 Thread Bobby Eickhoff
Yes, and I also frequently get the Wikispaces homepage after hitting the 
browser's back button (while surfing through the pages at clojure.org).

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