Re: slackpocalypse? next steps?

2017-05-25 Thread Oliver George

Purely technical feature comparison seems good for shortlisting options.

How about making a selection criteria that the solution has been proven 
itself as a primary platform by one of the communities we admire.  

Possible benefits:
* Subtle features inherent in platforms will have played a role in shaping 
the community.  It'd be hard to identify/list/value them otherwise.
* Empirical way to break a tie where feature comparison is inconclusive

On Thursday, 25 May 2017 09:18:41 UTC+10, Sean Corfield wrote:
>
> I agree. There’s been a lot of hand-wringing about the potential impending 
> “Slackpocalypse” and it seems like some people think this is a problem that 
> needs to be “solved” (by consensus) – but, despite a lot of conversations 
> (in the #community-development channel on the Clojurians Slack primarily), 
> no “perfect solution” has yet been agreed… and to be honest that’s very 
> unlikely to happen: different people have different criteria for what is 
> acceptable.
>
>  
>
> Putting on my Clojurians Admin Hat, what I’d like to see happen here is 
> for each proposed “solution”:
>
>  
>
> Post a new thread on this mailing list with a subject “Slack alternative? 
> ” – with a brief overview of what the system 
> is, what platforms it runs on (including native mobile if available) and, 
> *most 
> importantly*, how to sign up and try it out for Clojure-related chatter. 
> Please include links to the service/product and other stuff you think is 
> relevant ☺
>
>  
>
> Until folks actually go and sign up and try out each service, we’re not 
> going to make progress.
>
>  
>
> As folks try each service, they can provide feedback in the relevant 
> thread – both *positive* as well as negative (constructively) please!
>
>  
>
> We’re almost certainly not going to find a *replacement* for Slack (or 
> any other communications medium) but we may find several *new, additional* 
> ways to communicate as a community.
>
>  
>
> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>  
>
> On 5/23/17, 6:22 PM, "Colin Yates"  
> on behalf of colin...@gmail.com > wrote:
>
>  
>
> I've only been skimming this but "analysis paralysis" comes to mind :-). 
> What is the harm in establishing a presence in matrix (bagsy the "neo" 
> handle) and letting people know? As has been said, people will vote with 
> their feet so if in a months time matrix is a Clojure ghost town then 
> lesson learned. 
>
>  
>
> Or, if I have missed some pertinent fact then by all means, sigh, tut and 
> mutter "sheesh, these drive by commenters are annoying" :-).
>
> On Wednesday, 24 May 2017, Herwig Hochleitner  > wrote:
>
> 2017-05-23 23:04 GMT+02:00 Colin Fleming :
>
> On 24 May 2017 at 00:13, Herwig Hochleitner  > wrote:
>
> I doubt the whole community would want to move anywhere from Slack.
>
>  
>
> Perhaps this will have to wait until Slack inevitably throws us off, then.
>
>  
>
>  
>
> What I'm saying is, that the whole community isn't in a single place 
> anyway. Slack happens to be most popular, right now, but we are spread 
> across IRC, gitter / github, slack, mailing lists, discord, stack overflow, 
> reddit and probably many more.
>
>  
>
> IMO trying to move everybody to one thing is an exercise in futility, but 
> consuming / producing to / from all those places through a generic protocol 
> is a realistic hope, as matrix is proving right now. 
>
>  
>
> It's a far cry from searching for "cursive" from anywhere in Clojurians, 
> though. Searching for channels based on some vague criteria seemed 
> difficult, and searching for Clojure related content across channels is 
> also a pretty bad experience.
>
>  
>
> Granted, matrix' search facilities are far from optimal, as of now. But 
> unlike the alternatives, just about everybody could be (and somebody 
> probably is) improving on that.
>
>  
>
> There has been some talk of making a Clojure-related room directory in an 
> external webpage or something but it's still a kludge. I'm not sure to what 
> extent this would be fixed if we ran our own room server, but then someone 
> has to maintain that.
>
>  
>
> Same. This is currently being worked on: 
> https://github.com/vector-im/riot-web/issues/2454
>
>  
>
> I'd just like to mention, that in the year or so, that I've been using 
> matrix, the stream of improvements has been pretty steady. So while it 
> might not currently do everything we need, it's the best hope for bridging 
> the community across all the various services that (will continue to) exist.
>
>  
>
> 2017-05-23 23:31 GMT+02:00 Alan Moore :
>
> I watched the matrix video linked above and it seems there is a Slack 
> bridge that would allow Slack fans to stay put and others to choose their 
> own client or even go back to IRC. What am I missing?
>
>  
>
> The slack bridge is working fine, but slack has a nagging limitation of 
> o

How do I set up database in the context of a web application ?

2016-11-02 Thread 'George' via Clojure
I'd like to use datomic, but my question applies to any database.

When I used a framework in another language it was easy, the config file 
and ORM did setup the connection. I only installed an adapter and wrote the 
URI of the database..
Now as I want to use a minimal framework or to totally get rid of the 
framework,  I dont know what is the righ way to set up the connection.

I tried to write the connection details (such as URI, conn and db) in the 
route-handler file and it works.
But I know that I'm doing something wrong, because I've read that some 
setup is done by leiningen, 
for example in the examples I found about SQL. I searched and couldn't find 
examples for datomic and luminus.

I guess my routes handler file should only require something to import and 
than in each function
 queries using datomic.api. But datomic.api/q needs a db value, to be 
imported from somewhere.

-- 
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: Two suggestions re: core.spec, `ns`, and clojure 1.9alpha11

2016-08-22 Thread Oliver George

I'm interested to see any discussion regarding this point.  No doubt 
translating spec data into more friendly formats has been discussed.

Getting the data right is clojure's problem.  That's the concrete 
foundation and building blocks required for tooling.  Seems like Rich has 
done spectacularly there.

Potentially it's up to tooling to do more with that data.  I'd love to hear 
Bruce (figwheel), Collin's (cursive) and Bozhidar (cider) opinions about 
that.  


On Tuesday, 23 August 2016 08:11:27 UTC+10, Brian Marick wrote:
>
>
> On Aug 22, 2016, at 11:23 AM, Leon Grapenthin  > wrote:
>
> Still the error messages are simply far from good enough and that is what 
> appears to me as the main problem OP has. 
>
>
> This is important. Will the new, stricter error messages be improved 
> before 1.9 is finalized? 
>
>
>

-- 
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: Thoughts on clojure.spec

2016-07-18 Thread Oliver George
Here's the commit removing that aspect of instrument-all.  Not a big change.

https://github.com/clojure/clojure/commit/30dd3d8554ff96f1acda7cbe31470d92df2f565a

As an aside, I also love the idea of the Clojure community fostering a
culture of gen testing each chunk of well defined functionality.  If it's
truly achievable the Clojure community could become known as an unstoppable
force of robust code.

It would be something of a challenge for many of us... especially those
wanting this particular feature!


On 19 July 2016 at 10:36, Beau Fabry  wrote:

> > Do you find it frustrating that there's no way to turn on
> instrumentation of function outputs for manual testing?
>
> Yes. I've mentioned this elsewhere but I think being able to turn on
> output checking in lower environments (dev, test, master, staging) is
> getting extra values from specs basically for free. Being able to do it
> seems pragmatic. I'm hoping it won't be too difficult to write an
> `overinstrument-all` that gives me that when I want it.
>
> On Tuesday, July 12, 2016 at 5:36:39 PM UTC+10, Maarten Truyens wrote:
>>
>> I would also truly appreciate instrumentation of function outputs for
>> manual outputs. I understand the rationale for not having it as the
>> default, but could it perhaps be specified as an option s/instrument?
>> (Considering that it was present in the first alphas, I would assume that
>> such option should not be far-fetched.)
>>
> --
> 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/jcVnjk1MOWY/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/d/optout.
>



-- 
Oliver George
Director, Condense
0428 740 978

-- 
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: Thoughts on clojure.spec

2016-07-11 Thread Oliver George


> Do you find it frustrating that there's no way to turn on instrumentation 
> of function outputs for manual testing?


Yes.  

In particular when I'm refactoring code and want to know when I'm returning 
something surprising.  

I haven't yet had much success with spec generators for CLJS / UI code. 
 Too many non-clojure types to deal with - my gen-fu is limited.

I suspect the argument for reading an instrument flag to turn on return 
value testing is just that: 

   1. to help those who aren't able to leverage generators in their problem 
   domain.
   2. informal exploration testing

I see that spec/assert would give me the same results.  That's a fantastic 
addition but is also a code intrusion.

Final though: I suspect you can have it for the cost of a small helper 
function.  The instrument-all code doesn't seem complex but there may be a 
few private vars between you and happiness.


On Sunday, 10 July 2016 20:04:39 UTC+10, puzzler wrote:
>
> I've played around now with implementing specs for a couple of my projects.
>
> What I'm finding is that writing specs to check the inputs of a function 
> is easy-ish, but building useful random generators is very hard -- in my 
> projects, this seems too hard to do with any reasonable amount of effort.
>
> This isn't due to anything inherent in clojure.spec, it's just that for 
> non-trivial functions, coming up with relevant random input is a very hard 
> problem.  For example, let's say I have a function that takes two 
> integers.  Odds are that not any two randomly chosen integers will work.  
> Some combinations of integers are non-sensical and could trigger an error, 
> other combinations may cause the function to run way too long.  As a 
> concrete example, I just tried to spec out a SAT solver (which tries to 
> solve NP-complete problems).  The input should be a vector of vectors of 
> ints, but many combinations of inputs will just run forever.  How to 
> generate "good" SAT problems?  I have no idea.
>
> So for the most part, I've ignored the generation aspect of specs because 
> it just feels like too much work.  But without the generators, 
> clojure.spec's utility is significantly diminished.
>
> 1. No way to test function output specs.  For documentation purposes, I 
> want to have an output spec on my function.  However, as far as I know, 
> after instrumentation-triggered checking of output specs was removed a 
> couple of alphas ago, the only way remaining to check against output specs 
> is to use randomly generated tests.  So if I can't make good generators, I 
> have no way to confirm that my output spec works the way I think it does.  
> My documentation could be totally out of touch with reality, and that 
> displeases me.
>
> 2. Limited ability for testing that functions take and receive what you 
> expect.  Whereas a static type system can prove certain properties about 
> whether functions are called with valid inputs, with spec, you only get 
> those guarantees if you pump a function with enough valid random data to 
> trigger the function calling all its callees with interesting combinations 
> of data.  But if I use the naive generators, the function will never even 
> complete with most of the randomly generated input, let alone call other 
> functions in a useful way.  And in many cases I don't see how to generate 
> something of better quality.
>
> So looking back at my experiments, my preliminary impression is that by 
> adding specs to my public APIs, I've gained some useful documentation, and 
> I've given users the ability to instrument functions in order to get 
> high-quality assertion-checking of the inputs.  In some cases, the error 
> messages for bad input when instrumented are also more useful than I would 
> have otherwise gotten, but in some cases they aren't.  Overall, I've 
> struggled to write generators, and without them, the value proposition 
> isn't as great.
>
> One other issue I've had, unrelated to generators, is that I'm struggling 
> to express higher-order type constraints, for example, this function takes 
> a vector v1 of anything and a vector v2 of anything, but the type of the 
> things in vector v1 better match the type of the things in vector v2.
>
> What are other people finding?  Do you find it easy/hard to write 
> generators?  (If you think it's easy, I'd love to know your tricks).  Do 
> you find it easy/hard to read specs as a form of documentation about the 
> contract of a function?  Do you find it frustrating that there's no way to 
> turn on instrumentation of function outputs for manual testing?  Do you 
> feel your generators are providing sufficient code coverage when exercising 
> callee functions?
>

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

Re: clojure.spec

2016-05-23 Thread George Singer
Rich Hickey  gmail.com> writes:

> 
> I did most of the design of spec in a (paper) notebook.
> 
> The rationale tries to capture the salient driving forces.
> 
> If there is a specific question you have I’d be happy to answer.
> 
> Rich
> 
> > On May 23, 2016, at 4:11 PM, Ivan Reese  gmail.com> 
wrote:
> > 
> > Is there anywhere we can read anything about the design process behind 
clojure.spec? I took a look at
> dev.clojure.org / JIRA, but I haven't yet found anything on the topic.
> > 
> > -- 
> > 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+unsubscribe  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+unsubscribe  googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
> 

I'd love to hear Rich give a talk about this (the design process, his 
rationale, and so forth) -- especially how it relates to static type 
systems. I know that there's write-up already on the clojure website, but 
this would be a great talk also.

Can't wait to use 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: [ANN] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-04-04 Thread Oliver George
I like the idea of DB convention interfaces but that wasn't what I was 
thinking about specifically.

For tables, fields and relations in an application there may be conventions 
established by a framework but there are also likely to be exceptions on a 
table-by-table basis.  An schema interface provides a mechanism to default 
to a convention but also make an exception when necessary.  (Another case 
this supports is querying the database schema tables dynamically rather 
than hard coding)

I have some old code lying around from when I was experimenting with this a 
few weeks bacl, not saying it's perfect but perhaps it'll explain better. 
 In this case, pk defaults to :Id but in the case of the user table it is 
:UserId.


(defrecord SimpleSchema [pks rels]  IDBSchema  (pk [_ table-name](get pks 
table-name :Id))  (rel [_ from-table rel-name](if-let [[to-table 
field-mapping] (get-in rels [from-table rel-name])]  {:from from-table  
 :to   to-table   :on   field-mapping}))  (has-many?[db-schema 
table-name rel-name](if-let [{:keys [on]} (rel db-schema table-name 
rel-name)]  (not= [(pk db-schema table-name)] (vals on)



(let [test-schema  (map->TestSchema{:pks  {:Races :Id :Meetings :Id 
:Users :UserId} :rels {:Races{:Meeting [:Meetings {:MeetingId 
:Id}]}:Meetings {:Races [:Races {:Id :MeetingId}]}}})]

  ...)




On Monday, 4 April 2016 19:25:16 UTC+10, Krzysiek Herod wrote:
>
> Thanks :-)
>
> I was thinking about using protocols for defining interfaces of different 
> types of databases (e.g. MySQL, PostgreSQL), but with conventions I'm not 
> sure. 
> Most of the time conventions would not change, and once in a while 
> somebody will want to change only one of them (probably foreign-key). I 
> wouldn't want him to need to define a new record with all the conventions 
> (foreign-key, private-key) in such case. Or did I get it wrong?  
>
> On Thursday, March 31, 2016 at 2:59:56 AM UTC+2, Oliver George wrote:
>>
>> Fantastic.  Keep up the good work.
>>
>> Schema conventions could be made flexible with a protocol.
>>
>> (defprotocol IDBSchema  (pk [_ table-name])  (rel [_ table-name rel-name])  
>> (has-many? [_ table-name rel-name]))
>>
>>
>>
>>
>> On Thursday, 31 March 2016 09:23:00 UTC+11, Krzysiek Herod wrote:
>>>
>>> I just released version 0.3.0 of Relational Mapper. Customization of 
>>> keys and foreign keys is done now, as well as possibility to specify 
>>> relation with a different name than the corresponding table (
>>> https://github.com/netizer/relational_mapper#different-name-of-an-association-than-a-table-name).
>>>  
>>>
>>>
>>> @Oliver George: your example with SupervisorId, AnalystId would work 
>>> now, but have in mind that postgreSQL by default lowercases column names, 
>>> so I'd still recommend supervisor_id and analyst_id. 
>>>
>>> Cheers,
>>> Krzysiek 
>>>
>>> On Tuesday, March 1, 2016 at 11:35:46 PM UTC+1, Oliver George wrote:
>>>>
>>>>
>>>> Both those ideas seem sensible to me.  Look foward to hearing more.
>>>>
>>>> On Tuesday, 1 March 2016 23:38:43 UTC+11, Krzysiek Herod wrote:
>>>>>
>>>>> I went through the paper very briefly, so I might be wrong, but from 
>>>>> the first look it seems like the algorithm would generate the actual SQL 
>>>>> queries . If so, although the idea seems interesting, I wouldn't go in 
>>>>> this 
>>>>> direction because of the loss of flexibility for the user of the library. 
>>>>> For example sometimes it happens, that the slowest SQL query called by 
>>>>> the 
>>>>> application is the one where database picked a sub-optimal index, or 
>>>>> sometimes combining data by adding one more join has a great performance 
>>>>> impact. 
>>>>>
>>>>> Actually I was thinking about giving the programmer more flexibility, 
>>>>> and maybe splitting the whole code into query part and stitch part, so 
>>>>> the 
>>>>> developer would choose the most efficient queries, but the stitching part 
>>>>> would put all those data together (with deep result structure). I'm 
>>>>> curious 
>>>>> what do you think about this direction. I'll comment on your issue (
>>>>> https://github.com/netizer/relational_mapper/issues/3) with more 
>>>>> details about the idea.
>>>>>
>>>>> Cheers,
>>>>&

Re: Reworking :pre condition to add an error message

2016-03-30 Thread Oliver George
I look forward to pre/post conditions becoming more helpful.  Truss is a 
good example of how things can improve.  I think part of the challenge is 
not making the code too messy.

Here's a proof of concept of how metadata in the pre/post/assert expression 
could be used to craft nice messages:

(defn get-highlander [hs] 

  {:pre [^{:msg "There can be only one"} (= 1 (count ^:var hs))]} 

  (first hs))


And the error messages can be presented as:

user=> (get-highlander ["asdf" "ss"])

AssertionError Assert failed: There can be only one

(= 1 (count hs))

where hs is ["asdf" "ss"]  user/get-highlander (NO_SOURCE_FILE:4)


This works by modifying the assert macro so it works for general asserts too

(assert (test (complex (form (with (a ^:var varible) "bad variable")


The modifications to assert seem quite modest but I'm unsure if this is an 
approach which is considered to be the correct solution.

(declare tree-seq)

(defn pr-vars [form env]
  (let [var? (fn [x] (-> x meta :var))]
(for [var (filter var? (tree-seq seq? identity form))]
  `(str "\n where " '~var " is " (pr-str ~var)

(defmacro assert
  "Evaluates expr and throws an exception if it does not evaluate to
  logical tru"
  {:added "1.0"}
  ([x]
   (when *assert*
 `(when-not ~x
(throw (new AssertionError (str "Assert failed: " ~(or (-> x meta :msg) 
"")
"\n" (pr-str '~x)
~@(pr-vars x &env)))
  ([x message]
 (when *assert*
   `(when-not ~x
  (throw (new AssertionError (str "Assert failed: " ~message
  "\n" (pr-str '~x)
  ~@(pr-vars x &env



On Thursday, 31 March 2016 03:09:03 UTC+11, Niels van Klaveren wrote:
>
> Truss also has good support for :pre 
> and :post conditions 
> 
>
> On Monday, July 11, 2011 at 7:40:48 PM UTC+2, frye wrote:
>>
>> Note: This message was originally posted by ' Shantanu' on the "*Re: 
>> Clojure for large programs*" thread. 
>>
>> I took a look at  Shantanu's macros, and I like the concept a lot. But I 
>> would prefer something baked into the :pre condition itself. The reason is 
>> that it just removes a layer of indirection. If you dig into '
>> *clj/clojure/core.clj*', you can see that the 'fn' macro is using 
>> 'assert' to test these conditions. Assert allows error messages to be 
>> applied, ie: 
>>
>> *user => (assert false) *
>>
>> *user => (assert false "fubar") *
>>
>>
>>
>> However, (defmacro fn ...) assumes that just the boolean condition is 
>> being passed in, A). But I'd like to have the option to pass in a message 
>> B). 
>>
>>
>> *A) *
>>
>> *(def fubar *
>>
>> *  (fn []*
>>
>> *{:pre [ (true? false) ] }*
>>
>> *(println "Hello World")))*
>>
>> *(fubar)*
>>
>>
>> *B) *
>>
>> *(def thing *
>>
>> *  (fn []*
>>
>> *{:pre [ [(true? false) "A false message"] ] }*
>>
>> *(println "Hello World")))*
>>
>> *(thing)*
>>
>>
>>
>> I reworked the 'fn' macro, only for the :pre condition, as a 
>> demonstration (see here ). The calling 
>> semantics don't change that much. Is there any interest in putting this 
>> into core? I'd use Shantanu's workaround otherwise, or in the interim. 
>>
>> Thanks 
>>
>> Tim Washington 
>> twas...@gmail.com 
>> 416.843.9060 
>>
>>
>>
>> On Sun, Jul 3, 2011 at 11:42 AM, Shantanu Kumar  
>> wrote:
>>
>>>
>>>
>>> On Jul 3, 7:39 pm, Timothy Washington  wrote:
>>> > I'm using pre / post assertions quite a bit in a project I'm building. 
>>> And I
>>> > too would love to see better or custom error messages for each 
>>> assertion.
>>>
>>> That should be possible with a macro. For example, I use this:
>>>
>>> https://bitbucket.org/kumarshantanu/clj-miscutil/src/acfb97c662d9/src/main/clj/org/bituf/clj_miscutil.clj#cl-1009
>>>
>>> Maybe you need something like this(?):
>>>
>>> (defmacro verify-my-arg
>>>  "Like assert, except for the following differences:
>>>  1. does not check for *assert* flag
>>>  2. throws IllegalArgumentException"
>>>  [err-msg arg]
>>>  `(if ~arg true
>>> (throw (IllegalArgumentException. ~err-msg
>>>
>>> Then use it thus:
>>>
>>> (defn foo [m]
>>>  {:pre [(verify-my-arg "m must be a map" (map? m))]}
>>>  (println m))
>>>
>>> Regards,
>>> Shantanu
>>>
>>> --
>>> 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" grou

Re: [ANN] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-03-30 Thread Oliver George
Fantastic.  Keep up the good work.

Schema conventions could be made flexible with a protocol.

(defprotocol IDBSchema  (pk [_ table-name])  (rel [_ table-name rel-name])  
(has-many? [_ table-name rel-name]))




On Thursday, 31 March 2016 09:23:00 UTC+11, Krzysiek Herod wrote:
>
> I just released version 0.3.0 of Relational Mapper. Customization of keys 
> and foreign keys is done now, as well as possibility to specify relation 
> with a different name than the corresponding table (
> https://github.com/netizer/relational_mapper#different-name-of-an-association-than-a-table-name).
>  
>
>
> @Oliver George: your example with SupervisorId, AnalystId would work now, 
> but have in mind that postgreSQL by default lowercases column names, so I'd 
> still recommend supervisor_id and analyst_id. 
>
> Cheers,
> Krzysiek 
>
> On Tuesday, March 1, 2016 at 11:35:46 PM UTC+1, Oliver George wrote:
>>
>>
>> Both those ideas seem sensible to me.  Look foward to hearing more.
>>
>> On Tuesday, 1 March 2016 23:38:43 UTC+11, Krzysiek Herod wrote:
>>>
>>> I went through the paper very briefly, so I might be wrong, but from the 
>>> first look it seems like the algorithm would generate the actual SQL 
>>> queries . If so, although the idea seems interesting, I wouldn't go in this 
>>> direction because of the loss of flexibility for the user of the library. 
>>> For example sometimes it happens, that the slowest SQL query called by the 
>>> application is the one where database picked a sub-optimal index, or 
>>> sometimes combining data by adding one more join has a great performance 
>>> impact. 
>>>
>>> Actually I was thinking about giving the programmer more flexibility, 
>>> and maybe splitting the whole code into query part and stitch part, so the 
>>> developer would choose the most efficient queries, but the stitching part 
>>> would put all those data together (with deep result structure). I'm curious 
>>> what do you think about this direction. I'll comment on your issue (
>>> https://github.com/netizer/relational_mapper/issues/3) with more 
>>> details about the idea.
>>>
>>> Cheers,
>>> Krzysiek
>>>
>>> On Tue, Mar 1, 2016 at 6:03 AM, Oliver George  
>>> wrote:
>>>
>>>> Awesome, thanks.
>>>>
>>>> I did a little research last night looking for techniques for turning 
>>>> recursive queries into efficient SQL queries.  I came across an 
>>>> interesting 
>>>> paper:
>>>>
>>>> Cheney, James, Sam Lindley, and Philip Wadler. "Query shredding: 
>>>> Efficient relational evaluation of queries over nested multisets (extended 
>>>> version)."*arXiv preprint arXiv:1404.7078* (2014).
>>>>
>>>>
>>>> The details are obscured behind some intimidating equations but the 
>>>> concept seems pretty simple: The nested query gets normalised and then 
>>>> shredded into a set of sql queries and the results of those queries are 
>>>> stitched back together.
>>>>
>>>> There seem to be two version 
>>>> <https://scholar.google.com.au/scholar?hl=en&q=Query+shredding%3A+Efficient+relational+evaluation+of+queries+over+nested+multisets+%28extended+version%29&btnG=&as_sdt=1%2C5&as_sdtp=>
>>>>  
>>>> of the paper.  This one looks to be more detailed  (26 pages):
>>>>
>>>> https://scholar.google.com/citations?view_op=view_citation&hl=en&user=Iz-3VFQJ&sortby=pubdate&citation_for_view=Iz-3VFQJ:9pM33mqn1YgC
>>>>
>>>>
>>>>
>>>>
>>>> On Monday, 29 February 2016 21:06:23 UTC+11, Krzysiek Herod wrote:
>>>>>
>>>>> Thanks a lot for detailed notes.
>>>>>
>>>>> The problem with customization of foreign keys is on my TODO list. I 
>>>>> hope to fix that before releasing version 1.0. That would solve the 
>>>>> problem 
>>>>> with SupervisorId and AnalystId. 
>>>>>
>>>>> What you said about deeper result structure (race -> meeting -> venue) 
>>>>> is very inspiring. You can't do that with this library (you can fetch 
>>>>> records with their - potentially indirect - relations, but those 
>>>>> relations 
>>>>> won't have own relations included), but definitely it's something worth 
>>>>> considering. I added it to my TODO list in the R

Nicer assert by replacing the macro

2016-03-29 Thread Oliver George
Hi All

This is a little script to producing nicer errors from asserts and pre/post 
conditions in your clojure code.  Examples below, gist includes a readme 
with some notes.  I think the pre/post conditions are the biggest win.

Can anyone tell me how to do a similar "assert patch" technique for my 
clojurescript projects while debugging.

https://gist.github.com/olivergeorge/386ff4a559197dd794c1



(let [a 111] (assert (= 1 a)))

*AssertionError Assert failed: (= 1 a) => false*
* where a is 111*
  user/eval28652 (figwheel.clj:1)



(let [heart 1 diamond 2] (assert (> heart diamond) "Hearts should trump 
diamonds"))

*AssertionError Assert failed: Hearts should trump diamonds*
*(> heart diamond) => false*
* where heart is 1*
* where diamond is 2*
  user/eval28778 (figwheel.clj:1)



(let [x 1 y 2 z (range 1000)] (assert (> x 1)))

*AssertionError Assert failed: (> x 1) => false*
* where x is 1*
  user/eval28842 (figwheel.clj:1)



(defn pos-adder [a b]
  {:pre [(pos? a) (number? b)]
   :post [(pos? %)]}
  (+ a b))
=> #'user/pos-adder

(pos-adder 1 2)
=> 3

(pos-adder -1 2)

*AssertionError Assert failed: (pos? a) => false*
* where a is -1*
  user/pos-adder (figwheel.clj:1)


(pos-adder 1 -2)

*AssertionError Assert failed: (pos? %) => false*
* where % is -1*
  user/pos-adder (figwheel.clj:1)


(pos-adder 1 "notnum")

*AssertionError Assert failed: (number? b) => false*
* where b is notnum*
  user/pos-adder (figwheel.clj:1)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-03-01 Thread Oliver George

Both those ideas seem sensible to me.  Look foward to hearing more.

On Tuesday, 1 March 2016 23:38:43 UTC+11, Krzysiek Herod wrote:
>
> I went through the paper very briefly, so I might be wrong, but from the 
> first look it seems like the algorithm would generate the actual SQL 
> queries . If so, although the idea seems interesting, I wouldn't go in this 
> direction because of the loss of flexibility for the user of the library. 
> For example sometimes it happens, that the slowest SQL query called by the 
> application is the one where database picked a sub-optimal index, or 
> sometimes combining data by adding one more join has a great performance 
> impact. 
>
> Actually I was thinking about giving the programmer more flexibility, and 
> maybe splitting the whole code into query part and stitch part, so the 
> developer would choose the most efficient queries, but the stitching part 
> would put all those data together (with deep result structure). I'm curious 
> what do you think about this direction. I'll comment on your issue (
> https://github.com/netizer/relational_mapper/issues/3) with more details 
> about the idea.
>
> Cheers,
> Krzysiek
>
> On Tue, Mar 1, 2016 at 6:03 AM, Oliver George  > wrote:
>
>> Awesome, thanks.
>>
>> I did a little research last night looking for techniques for turning 
>> recursive queries into efficient SQL queries.  I came across an interesting 
>> paper:
>>
>> Cheney, James, Sam Lindley, and Philip Wadler. "Query shredding: 
>> Efficient relational evaluation of queries over nested multisets (extended 
>> version)."*arXiv preprint arXiv:1404.7078* (2014).
>>
>>
>> The details are obscured behind some intimidating equations but the 
>> concept seems pretty simple: The nested query gets normalised and then 
>> shredded into a set of sql queries and the results of those queries are 
>> stitched back together.
>>
>> There seem to be two version 
>> <https://scholar.google.com.au/scholar?hl=en&q=Query+shredding%3A+Efficient+relational+evaluation+of+queries+over+nested+multisets+%28extended+version%29&btnG=&as_sdt=1%2C5&as_sdtp=>
>>  
>> of the paper.  This one looks to be more detailed  (26 pages):
>>
>> https://scholar.google.com/citations?view_op=view_citation&hl=en&user=Iz-3VFQJ&sortby=pubdate&citation_for_view=Iz-3VFQJ:9pM33mqn1YgC
>>
>>
>>
>>
>> On Monday, 29 February 2016 21:06:23 UTC+11, Krzysiek Herod wrote:
>>>
>>> Thanks a lot for detailed notes.
>>>
>>> The problem with customization of foreign keys is on my TODO list. I 
>>> hope to fix that before releasing version 1.0. That would solve the problem 
>>> with SupervisorId and AnalystId. 
>>>
>>> What you said about deeper result structure (race -> meeting -> venue) 
>>> is very inspiring. You can't do that with this library (you can fetch 
>>> records with their - potentially indirect - relations, but those relations 
>>> won't have own relations included), but definitely it's something worth 
>>> considering. I added it to my TODO list in the README but I don't have a 
>>> clear idea about how to do it well yet. 
>>>
>>> Cheers, 
>>> Krzysiek
>>>
>>> On Monday, February 29, 2016 at 12:54:31 PM UTC+8, Oliver George wrote:
>>>>
>>>> Oops, one more.
>>>>
>>>> There was also a Users table (Id, Username, ...)
>>>>
>>>> I didn't see a way to handle join from Races to Users based on 
>>>> SupervisorId and AnalystId.  
>>>>
>>>>
>>>> On Monday, 29 February 2016 15:52:48 UTC+11, Oliver George wrote:
>>>>>
>>>>> Thanks for the details.
>>>>>
>>>>> I did a little experimenting and it works as advertised.  Notes below 
>>>>> show what I did and found.
>>>>>
>>>>> I was interested to see if this might be suitable as a simple om.next 
>>>>> remote for a relational database.  Potentially fanciful but it's a topic 
>>>>> of 
>>>>> interest for me at the moment.
>>>>>
>>>>> I used an existing database so I had a semi interesting dataset to 
>>>>> play with.  
>>>>>
>>>>> Races (Id, RaceNumber, RaceTime, MeetingId, SupervisorId, AnalystId...)
>>>>> Meetings (Id, MeetingDate, MeetingTypeId, VenueId, JurisdictionId, ...)
>>>>> Venues (Id, Name)
>>>&g

Re: [ANN] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-02-29 Thread Oliver George
Awesome, thanks.

I did a little research last night looking for techniques for turning 
recursive queries into efficient SQL queries.  I came across an interesting 
paper:

Cheney, James, Sam Lindley, and Philip Wadler. "Query shredding: Efficient 
relational evaluation of queries over nested multisets (extended 
version)."*arXiv 
preprint arXiv:1404.7078* (2014).


The details are obscured behind some intimidating equations but the concept 
seems pretty simple: The nested query gets normalised and then shredded 
into a set of sql queries and the results of those queries are stitched 
back together.

There seem to be two version 
<https://scholar.google.com.au/scholar?hl=en&q=Query+shredding%3A+Efficient+relational+evaluation+of+queries+over+nested+multisets+%28extended+version%29&btnG=&as_sdt=1%2C5&as_sdtp=>
 
of the paper.  This one looks to be more detailed  (26 pages):
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=Iz-3VFQJ&sortby=pubdate&citation_for_view=Iz-3VFQJ:9pM33mqn1YgC




On Monday, 29 February 2016 21:06:23 UTC+11, Krzysiek Herod wrote:
>
> Thanks a lot for detailed notes.
>
> The problem with customization of foreign keys is on my TODO list. I hope 
> to fix that before releasing version 1.0. That would solve the problem with 
> SupervisorId and AnalystId. 
>
> What you said about deeper result structure (race -> meeting -> venue) is 
> very inspiring. You can't do that with this library (you can fetch records 
> with their - potentially indirect - relations, but those relations won't 
> have own relations included), but definitely it's something worth 
> considering. I added it to my TODO list in the README but I don't have a 
> clear idea about how to do it well yet. 
>
> Cheers, 
> Krzysiek
>
> On Monday, February 29, 2016 at 12:54:31 PM UTC+8, Oliver George wrote:
>>
>> Oops, one more.
>>
>> There was also a Users table (Id, Username, ...)
>>
>> I didn't see a way to handle join from Races to Users based on 
>> SupervisorId and AnalystId.  
>>
>>
>> On Monday, 29 February 2016 15:52:48 UTC+11, Oliver George wrote:
>>>
>>> Thanks for the details.
>>>
>>> I did a little experimenting and it works as advertised.  Notes below 
>>> show what I did and found.
>>>
>>> I was interested to see if this might be suitable as a simple om.next 
>>> remote for a relational database.  Potentially fanciful but it's a topic of 
>>> interest for me at the moment.
>>>
>>> I used an existing database so I had a semi interesting dataset to play 
>>> with.  
>>>
>>> Races (Id, RaceNumber, RaceTime, MeetingId, SupervisorId, AnalystId...)
>>> Meetings (Id, MeetingDate, MeetingTypeId, VenueId, JurisdictionId, ...)
>>> Venues (Id, Name)
>>> Jurisdiction (Id, Name, Code)
>>>
>>>
>>> The table and foreign key naming conventions didn't match so I created 
>>> views for each table.  If that was configurable then you'd open yourself to 
>>> a wider audience.  (e.g. MeetingId vs meetings_id)
>>>
>>> It was easy to setup some associations
>>>
>>> (def associations
>>>   {:meeting {:race :has-many
>>>  :jurisdiction :belongs-to
>>>  :venue:belongs-to}
>>>:race{:meeting  :belongs-to
>>>  :jurisdiction [:through :meeting :belongs-to]}
>>>:venue   {}})
>>>
>>> My queries all worked as expected.  
>>>
>>> (find-one db-state :meeting #{:race} [[:= :meeting.id 5617]])
>>> (find-one db-state :meeting #{:venue} [[:= :meeting.id 5617]])
>>> (find-one db-state :race #{:meeting :jurisdiction} [[:= :race.id 
>>> 42792]])
>>>
>>> I couldn't see how I might pull data which requires three levels of 
>>> information (e.g. race -> meeting -> venue).  I didn't dig deep enough to 
>>> be sure.
>>>
>>> Incidentally, in case you haven't come across the datomic pull inspired 
>>> om.next remote pull syntax this is what it might look like:
>>>
>>> [{:meeting [:race]}]
>>> (find-one db-state :meeting #{:race} [])
>>>
>>> [({:meeting [:race]} [:= :meeting.id 5617])]
>>> (find-one db-state :meeting #{:race} [[:= :meeting.id 5617]])
>>>
>>> [{:meeting [:venue]}]
>>> (find-one db-state :meeting #{:venue} [[:= :meeting.id 5617]])
>>>
>>> [{:race [{:meeting [{:venue :jurisdiction}]}]}]
>>>
>>> Not prettier

Re: [ANN] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-02-28 Thread Oliver George
Oops, one more.

There was also a Users table (Id, Username, ...)

I didn't see a way to handle join from Races to Users based on SupervisorId 
and AnalystId.  


On Monday, 29 February 2016 15:52:48 UTC+11, Oliver George wrote:
>
> Thanks for the details.
>
> I did a little experimenting and it works as advertised.  Notes below show 
> what I did and found.
>
> I was interested to see if this might be suitable as a simple om.next 
> remote for a relational database.  Potentially fanciful but it's a topic of 
> interest for me at the moment.
>
> I used an existing database so I had a semi interesting dataset to play 
> with.  
>
> Races (Id, RaceNumber, RaceTime, MeetingId, SupervisorId, AnalystId...)
> Meetings (Id, MeetingDate, MeetingTypeId, VenueId, JurisdictionId, ...)
> Venues (Id, Name)
> Jurisdiction (Id, Name, Code)
>
>
> The table and foreign key naming conventions didn't match so I created 
> views for each table.  If that was configurable then you'd open yourself to 
> a wider audience.  (e.g. MeetingId vs meetings_id)
>
> It was easy to setup some associations
>
> (def associations
>   {:meeting {:race :has-many
>  :jurisdiction :belongs-to
>  :venue:belongs-to}
>:race{:meeting  :belongs-to
>  :jurisdiction [:through :meeting :belongs-to]}
>:venue   {}})
>
> My queries all worked as expected.  
>
> (find-one db-state :meeting #{:race} [[:= :meeting.id 5617]])
> (find-one db-state :meeting #{:venue} [[:= :meeting.id 5617]])
> (find-one db-state :race #{:meeting :jurisdiction} [[:= :race.id 42792]])
>
> I couldn't see how I might pull data which requires three levels of 
> information (e.g. race -> meeting -> venue).  I didn't dig deep enough to 
> be sure.
>
> Incidentally, in case you haven't come across the datomic pull inspired 
> om.next remote pull syntax this is what it might look like:
>
> [{:meeting [:race]}]
> (find-one db-state :meeting #{:race} [])
>
> [({:meeting [:race]} [:= :meeting.id 5617])]
> (find-one db-state :meeting #{:race} [[:= :meeting.id 5617]])
>
> [{:meeting [:venue]}]
> (find-one db-state :meeting #{:venue} [[:= :meeting.id 5617]])
>
> [{:race [{:meeting [{:venue :jurisdiction}]}]}]
>
> Not prettier necessarily but allows for composing multiple queries into a 
> request and for drilling deeper into available data.  
>
> cheers, Oliver
>  
>
>
>
>
>
>
> On Sunday, 28 February 2016 20:02:15 UTC+11, Krzysiek Herod wrote:
>>
>> Thanks Oliver for the feedback, 
>>
>> actually I came up with the idea of relational_mapper while working on a 
>> project in which I had one "data-model" that contained all the database 
>> related information, but the database related code contained a lot of 
>> features, and I really like working with small, focused clojure libraries, 
>> so in the end relational_mapper is as small as I could think of it. 
>>
>> Also as you can see in this commit: 
>> https://github.com/netizer/relational_mapper/commit/6b4d79f92570bf723e4092d329978d484c01d2ab#diff-2b44df73d826687086fd1972295f8bd0L8
>>  
>> I actually was storing both: relations and fields in the same structure, 
>> but I changed that because I needed "fields" only for migrations that I 
>> used in tests, and because the whole structure was unnecessarily complex 
>> (it was much easier to make mistake modifying the fields/associations 
>> structure). 
>>
>> Relational Mapper is meant only for reading data because whenever I tried 
>> to use complex structures to write data, I was unhappy with the result 
>> (often you have to update indexes of related records after one of them - 
>> with auto-increment field - is created, and there is a problem of 
>> determining if the related record has to be created or updated).
>>
>> I didn't write compare/contrast points because I couldn't find similar 
>> libraries in clojure. I mentioned ActiveRecord in README mostly because of 
>> the wording in types of relations, but even ActiveRecord is very far from 
>> Relational Mapper (it's much bigger, and has features that go way beyond 
>> simple relational mapping). 
>>
>> Thanks again, 
>> Krzysiek
>>
>> On Sunday, February 28, 2016 at 10:54:57 AM UTC+8, Oliver George wrote:
>>>
>>>
>>> Seems pretty nice to me.  Like a light weight version of the Django's 
>>> migrate and queryset features which build on model definitions.
>>>
>>> It seems like this would allow me to define a database schema (tab

Re: [ANN] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-02-28 Thread Oliver George
Thanks for the details.

I did a little experimenting and it works as advertised.  Notes below show 
what I did and found.

I was interested to see if this might be suitable as a simple om.next 
remote for a relational database.  Potentially fanciful but it's a topic of 
interest for me at the moment.

I used an existing database so I had a semi interesting dataset to play 
with.  

Races (Id, RaceNumber, RaceTime, MeetingId, SupervisorId, AnalystId...)
Meetings (Id, MeetingDate, MeetingTypeId, VenueId, JurisdictionId, ...)
Venues (Id, Name)
Jurisdiction (Id, Name, Code)


The table and foreign key naming conventions didn't match so I created 
views for each table.  If that was configurable then you'd open yourself to 
a wider audience.  (e.g. MeetingId vs meetings_id)

It was easy to setup some associations

(def associations
  {:meeting {:race :has-many
 :jurisdiction :belongs-to
 :venue:belongs-to}
   :race{:meeting  :belongs-to
 :jurisdiction [:through :meeting :belongs-to]}
   :venue   {}})

My queries all worked as expected.  

(find-one db-state :meeting #{:race} [[:= :meeting.id 5617]])
(find-one db-state :meeting #{:venue} [[:= :meeting.id 5617]])
(find-one db-state :race #{:meeting :jurisdiction} [[:= :race.id 42792]])

I couldn't see how I might pull data which requires three levels of 
information (e.g. race -> meeting -> venue).  I didn't dig deep enough to 
be sure.

Incidentally, in case you haven't come across the datomic pull inspired 
om.next remote pull syntax this is what it might look like:

[{:meeting [:race]}]
(find-one db-state :meeting #{:race} [])

[({:meeting [:race]} [:= :meeting.id 5617])]
(find-one db-state :meeting #{:race} [[:= :meeting.id 5617]])

[{:meeting [:venue]}]
(find-one db-state :meeting #{:venue} [[:= :meeting.id 5617]])

[{:race [{:meeting [{:venue :jurisdiction}]}]}]

Not prettier necessarily but allows for composing multiple queries into a 
request and for drilling deeper into available data.  

cheers, Oliver
 






On Sunday, 28 February 2016 20:02:15 UTC+11, Krzysiek Herod wrote:
>
> Thanks Oliver for the feedback, 
>
> actually I came up with the idea of relational_mapper while working on a 
> project in which I had one "data-model" that contained all the database 
> related information, but the database related code contained a lot of 
> features, and I really like working with small, focused clojure libraries, 
> so in the end relational_mapper is as small as I could think of it. 
>
> Also as you can see in this commit: 
> https://github.com/netizer/relational_mapper/commit/6b4d79f92570bf723e4092d329978d484c01d2ab#diff-2b44df73d826687086fd1972295f8bd0L8
>  
> I actually was storing both: relations and fields in the same structure, 
> but I changed that because I needed "fields" only for migrations that I 
> used in tests, and because the whole structure was unnecessarily complex 
> (it was much easier to make mistake modifying the fields/associations 
> structure). 
>
> Relational Mapper is meant only for reading data because whenever I tried 
> to use complex structures to write data, I was unhappy with the result 
> (often you have to update indexes of related records after one of them - 
> with auto-increment field - is created, and there is a problem of 
> determining if the related record has to be created or updated).
>
> I didn't write compare/contrast points because I couldn't find similar 
> libraries in clojure. I mentioned ActiveRecord in README mostly because of 
> the wording in types of relations, but even ActiveRecord is very far from 
> Relational Mapper (it's much bigger, and has features that go way beyond 
> simple relational mapping). 
>
> Thanks again, 
> Krzysiek
>
> On Sunday, February 28, 2016 at 10:54:57 AM UTC+8, Oliver George wrote:
>>
>>
>> Seems pretty nice to me.  Like a light weight version of the Django's 
>> migrate and queryset features which build on model definitions.
>>
>> It seems like this would allow me to define a database schema (tables, 
>> relations and fields) as data and use it to both create the database and 
>> run select/insert/update/delete queries against it.  
>>
>> Is that your intention for the library?
>>
>> I've not explored the options in this space before.  It might be good to 
>> have a section in the README pointing out to other related tools with some 
>> compare/contrast points.
>>
>> Thanks.
>>
>>
>> On Friday, 26 February 2016 17:51:10 UTC+11, Krzysiek Herod wrote:
>>>
>>> I created Relational Mapper, for situations where there is a relational 
>>> database with certain amount of relations between tables and 

Re: [ANN] As I was missing this kind of library in clojure I created relational_mapper for dealing with querying relational databases

2016-02-27 Thread Oliver George

Seems pretty nice to me.  Like a light weight version of the Django's 
migrate and queryset features which build on model definitions.

It seems like this would allow me to define a database schema (tables, 
relations and fields) as data and use it to both create the database and 
run select/insert/update/delete queries against it.  

Is that your intention for the library?

I've not explored the options in this space before.  It might be good to 
have a section in the README pointing out to other related tools with some 
compare/contrast points.

Thanks.


On Friday, 26 February 2016 17:51:10 UTC+11, Krzysiek Herod wrote:
>
> I created Relational Mapper, for situations where there is a relational 
> database with certain amount of relations between tables and it's just not 
> cool to fetch data from each table separately nor to write custom code for 
> each such project so, with this library, you can just call: 
>
> (find_all db-state :posts #{:authors :attachments} [:= post.id 1])
>
> and assuming you have appropriate relations between these tables, you'll get:
>
> {:posts {:title "Christmas"
>  :body "Merry Christmas!"
>  :id 1
>  :authors_id 10
>  :authors {:name "Rudolf" :id 10}
>  :attachments [{:name "rudolf.png" :id 100 :posts_id 1}
>{:name "santa.png" :id 101 :posts_id 1}]
>
>
> The code is here: https://github.com/netizer/relational_mapper
>
> Please, guys, let me know what do you think, and if you have any ideas 
> about improvements. If somebody would be so kind to take a look at the 
> code, it would be awesome to read some feedback.
>
> Krzysiek Heród
>

-- 
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 tell buffy which file to read?

2015-10-23 Thread Amith George
Hi Alex,

> first one is to slice the buffer and then feed it to buffy, which means 
that you have to implement streaming yourself.

Is this the same as say manually skipping till byte position X, read in 1MB 
(as described by the size bytes) of data into a buffer and pass that buffer 
(and a corresponding spec for that buffer) to buffy for deserialization? 

I didn't really understand what you meant by the second option. I am bit 
confused by which code (my custom read/skip code or buffy) would be 
responsible for populating the buffer and which code is being passed the 
callback and what exactly is happening inside the callback. 

On Thursday, 22 October 2015 14:37:46 UTC+5:30, Alex P wrote:
>
> Hi Amith, 
>
> Alex from clojurewerkz/buffy here. 
>
> There are actually 2 options: first one is to slice the buffer and then 
> feed it to buffy, which means that you have to implement streaming yourself.
>
> The other option is something I really wanted to implement for quite some 
> time already is continuation-passing style reading for larger byte buffers: 
> you streamline your file and can "dereference" the state on any point, or 
> continue reading until everything is read. Although I've never got to do 
> it. If you want, we could catch up on IRC and talk about it, I could help 
> to get that up and running. In my imagination that should be relatively 
> simple. 
>
> But you've got it right: dynamic frames will only work when buffer is 
> already contained in memory, which definitely isnt' any good of an idea for 
> larger files.
>

-- 
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 tell buffy which file to read?

2015-10-21 Thread Amith George
I seem to have misunderstood what buffy is meant to do. I thought I could 
create a spec (using its dynamic frames feature) for the entire file and 
pass to buffy this spec and the file name. When I query for a certain 
field, it would skip the required number of bytes and load into memory only 
those bytes that comprise the field I queried. I thought this would be an 
efficient way to read only a part of the file in a structured manner. 

That however seems to be incorrect. If I create the spec for the entire 
file, then the buffer passed to buffy has to contain the data for the 
entire file. In the case of a 500MB file, I would have to read the entire 
500MB into a buffer and pass that to buffy. That kinda seems inefficient 
when I only wish to query certain fields from the spec. 

The binary file has its data stored in a custom format. A lot of data is 
stored as a pair representing size of data (1 to 4 bytes of data is used to 
store the size) and actual bytes of data. Existing code is littered with 
custom `readInt(), readShort()` method to read the size of data and 
`skip(size)` to skip over it. This is done many times till it reaches the 
beginning of the interesting data. I was hoping to somehow avoid that using 
buffy and its spec. 


On Wednesday, 21 October 2015 20:09:58 UTC+5:30, Amith George wrote:
>
> I am interested in using buffy[1] to read data from multiple binary files. 
> The files have sizes varying from 10MB to 500MB. From the documenation, 
> buffy seems to work directly on a buffer and not a file. It can either 
> create a heap or off-heap buffer of size equaling the size of the spec or 
> it can wrap a passed in buffer. *With the former, how does it know which 
> file to read from? *
>
> If we choose the latter, ie pass in an existing buffer, how do we go about 
> creating that buffer? I am new to Java, so what should I take into account? 
> Reading blog posts, the general trend seems to be to create a buffer from 
> the inchannel of a RandomAccessFile opened in read mode. The size of the 
> buffer can either match the file size or be a fixed size. Depending on the 
> size of the buffer, `buffer.flip()` is called once or once for each 
> iteration of the read loop. The other alternative seems to be to create a 
> memory mapped buffer, either of size equalling file size or of a fixed 
> size. Since my file size won't go beyond 500MB and I can create a direct 
> buffer using standard allocation code, do I need to use a memory mapped 
> buffer? If I am not using a memory mapped buffer, do I need to call 
> buffer.flip() before passing it to buffy? 
>
> Also, how does buffy handle reading in data that is of size larger than 
> the fixed size buffer? In this specific scenario, I would be interested in 
> only about 5-10MB of data, located somewhere in the middle of the 500MB 
> sized file. I don't see the value in creating a buffer of size 500MB. Can I 
> create a 1MB fixed size buffer and tell buffy to read in a dynamic type 
> field whose size in that file happens to be 2.5MB? 
>
> I looked at other binary file reading libraries and their documentation 
> also don't mention how to create the buffer. I feel like I am overlooking 
> something basic. 
>
> [1] - https://github.com/clojurewerkz/buffy
>

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


How to tell buffy which file to read?

2015-10-21 Thread Amith George
I am interested in using buffy[1] to read data from multiple binary files. 
The files have sizes varying from 10MB to 500MB. From the documenation, 
buffy seems to work directly on a buffer and not a file. It can either 
create a heap or off-heap buffer of size equaling the size of the spec or 
it can wrap a passed in buffer. *With the former, how does it know which 
file to read from? *

If we choose the latter, ie pass in an existing buffer, how do we go about 
creating that buffer? I am new to Java, so what should I take into account? 
Reading blog posts, the general trend seems to be to create a buffer from 
the inchannel of a RandomAccessFile opened in read mode. The size of the 
buffer can either match the file size or be a fixed size. Depending on the 
size of the buffer, `buffer.flip()` is called once or once for each 
iteration of the read loop. The other alternative seems to be to create a 
memory mapped buffer, either of size equalling file size or of a fixed 
size. Since my file size won't go beyond 500MB and I can create a direct 
buffer using standard allocation code, do I need to use a memory mapped 
buffer? If I am not using a memory mapped buffer, do I need to call 
buffer.flip() before passing it to buffy? 

Also, how does buffy handle reading in data that is of size larger than the 
fixed size buffer? In this specific scenario, I would be interested in only 
about 5-10MB of data, located somewhere in the middle of the 500MB sized 
file. I don't see the value in creating a buffer of size 500MB. Can I 
create a 1MB fixed size buffer and tell buffy to read in a dynamic type 
field whose size in that file happens to be 2.5MB? 

I looked at other binary file reading libraries and their documentation 
also don't mention how to create the buffer. I feel like I am overlooking 
something basic. 

[1] - https://github.com/clojurewerkz/buffy

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-07 Thread Amith George
>> I probably wouldn't use protocols since I doubt there is a function 
signature that is exactly identical for all branches. Each branch probably 
needs access to different parts of your system (eg. database) and always 
passing everything to everything is not ideal.

>> Multi-Method is great if you want something openly extensible but that 
again seems unlikely here and also assumes that everything requires the 
same arguments.

I had the same concerns and wanted to use a simple function with 
pattern/condition matching to dispatch to the appropriate function. I had 
considered using Records as synonymous with using polymorphic calls (multi 
methods, protocols). Its good to know the alarm bells ringing in my head 
had merit :). Thanks for that.  

Thinking out loud, if we are not using Records for polymorphism, are we 
using it to guarantee structure? If you could indulge me a little more, 
consider the following two implementations. 


(def OneOff [(s/one s/Str 'name) (s/one s/Str 'email)])

(defn send-one-off
  [something thing [name email :as data]]
  {:pre [(s/validate OneOff data)]}
  ,,,)

(defn send 
  [app thing recipient]
  (match [recipient]
[[:one-off & data]] (send-one-off (:something app) thing data)))




Individual schema are created for each variant case and are checked against 
by the respective functions. The dispatch function only needs to know how 
to check for individual cases of the variant. 


(def OneOffMap {:type (s/eq :one-off) :name s/Str :email s/Str})
(def ExistingContactMap {:type (s/eq :existing) :contact-id s/Int})

(def Recipient (s/either ExistingContactMap OneOffMap))
;; s/either is deprecated and s/cond-pre is recommended
;; however, validating valid OneOffMap data using the following 
;; still throws an error.
;; (def Recipient (s/cond-pre ExistingContactMap OneOffMap))

(defn send-one-off
  [something thing {:keys [name email] :as data}]
  ,,,)

(defn send 
  [app thing recipient]
  {:pre [(s/validate Recipient recipient)]}
  (match [(:type recipient)]
[:one-off] (send-one-off (:something app) thing recipient)))

This reverts to using a map with a :type key. Individuals schema for each 
:type value. A combined schema to represent a recipient. The dispatch 
function only needs to know about the existence of the :type key and the 
values it can handle.


Whether we use records or maps or variants, the dispatch function needs to 
know what contract is implemented by recipient. Whether it will be an 
instance of something, or a variant or a map with type keys. Neither 
versions care for any other data present in recipient or its structure.

At this point I am confused, what makes one version better than the other. 
Creating schema definitions for the records seemed a lot easier than for 
the other two. Also I am assuming that if records are created using 
s/defrecord, the factory functions (->, map->) will automatically validate 
them?

I really appreciate you taking the time to clarify things for me.

--
Amith


On Monday, 7 September 2015 20:57:46 UTC+5:30, Thomas Heller wrote:
>
>
>> (def Recipient
>>>   (s/either PlaceHolder
>>> Existing
>>> OneOff))
>>>
>>
>> This looks interesting. Where would I actually use this? I mean, if I 
>> have created three records, I may as well implement multi methods or 
>> protocols, right? Even if I don't do those, I will still need to use 
>> `(condp instance? obj ...)` or equivalent to select the appropriate branch 
>> for processing. Is there a way I can use Recipient to select a branch? 
>>
>
> I probably wouldn't use protocols since I doubt there is a function 
> signature that is exactly identical for all branches. Each branch probably 
> needs access to different parts of your system (eg. database) and always 
> passing everything to everything is not ideal.
>
> Multi-Method is great if you want something openly extensible but that 
> again seems unlikely here and also assumes that everything requires the 
> same arguments.
>
> cond(p) sounds perfect for this case. I tend to write each branch as a 
> single function and keep the dispatch as compact as possible.
>
> (defn send-placeholder [thing {:keys [text]}]
>   ...)
>
> (defn send-existing [db thing {:keys [contact-id]}]
>   ...)
>
> (defn send-one-off [something thing {:keys [name email]}]
>   ...)
>
> (defn send [app thing recipient]
>   (condp instance? recipient
> PlaceHolder
> (send-placeholder thing recipient)
> Existing
> (send-existing (:db app) thing recipient)
> OneOff
> (send-one-off (:something app) thing recipient)))
>
>
> That greatly reduces the cognitive load when looking at each separate 
> implementation and also keeps the actual internal structure of the 
> Recipient out of the dispatch. The conpd does not need to know how many 
> fields are in OneOff, the tuple/vector/variant match versions must know 
> that. 
>
> /thomas
>
>
>
>
>
>
>

-- 
You received this message because you are subscribed to the 

Re: Just found out about Elixirs function argument pattern matching...

2015-09-07 Thread Amith George

>
> Looking at the "(defn register [...])" example. Where is the problem with 
> the first solution? It doesn't have the bugs the other implementations have 
> and is extremely simple to reason about? The other two solutions do the 
> exact same thing just slower with absolutely no gain. If you need the 
> "status" abstraction use a real state machine. Don't write a recursive 
> function when you don't have to. The code should never be at a point where 
> it can be called with forged data and directly skip over the :create and 
> :check-unqiue states which is possible in 2 of the 3 solutions.
>

It bothered me as well that register could skip states. I couldn't figure 
out how to deal with that and resorted to making the function private :( . 
I was originally thinking - the sum of the all steps being the 
variant/sum-type and each step being one of the cases of the variant. 
However as you said, a state machine might be a better representation. 
Maybe this was a bad use case for variants. The output of the state machine 
steps could be a variant over :ok, :err. Either way lets ignore this usage. 


(def Recipient
>   (s/either PlaceHolder
> Existing
> OneOff))
>

This looks interesting. Where would I actually use this? I mean, if I have 
created three records, I may as well implement multi methods or protocols, 
right? Even if I don't do those, I will still need to use `(condp instance? 
obj ...)` or equivalent to select the appropriate branch for processing. Is 
there a way I can use Recipient to select a branch? 

I am not proposing the variant vector to be used in place of records. I am 
looking at it as an improvement over using a hashmap containing a :type 
key. For some reason I am wary of records. The variant vector seemed like a 
good intermediate solution. 

On Monday, 7 September 2015 17:13:53 UTC+5:30, Thomas Heller wrote:
>
>
>
>>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-06 Thread Amith George
In a possible messaging system, a user could denote a recipient using one 
of three ways - 1) select an existing user id, 2) enter a new name and 
email, 3) pick a placeholder "all my team mates". 

 
Possible F# (might not compipe!!)

Recipient = | Placeholder of string
   | Existing of ContactId
   | OneoffRecipient of string * string


Possible options in Clojure

{:type :placeholder ; or :existing :one-off
 :placeholder-text :all-my-team-mates
 :name nil
 :email nil
 :contact-id nil
}

;; or

(defrecord PlaceholdRecipient [placeholder-text])
(defrecord ExistingReceipient [contact-id])
(defrecord OneoffReceipient [name email])

;; or 

[:one-off name email]
[:existing contact-id]
[:placeholder text]
;; [:self]

The variant needed not be a two element vector. It is a 1 or more element 
vector. We could just as easily have a fourth variant [:self] with no data 
to indicate send message to self. 

To actually use the above data structures and get the actual email 
addresses from them, we need atleast three methods - 1) fetch the emails of 
all the users team mates, 2) fetch the email for a contact in the 
datastore, 3) return the email as is. We could implement these using a 
multi method or implement some protocol or use a pattern matched method. 
Each choice has a different extensibility story and are all equally valid. 
We don't always replace every hashmap with a record. Variants are a viable 
alternative over using a map like the one shown in the first Clojure 
choice. 

>> As much as possible I try to build my apps in such a way that the 
program can self-explore the data you give it to self-optimize, 
self-extend, or otherwise provide flexibility to the programmer. You can't 
do that with a variant as a vector. Hand a vector to a function and the 
logic has to be something like "If this is a two element vector and the 
first thing is a keyword, then this might be a variant, but I'm not sure 
because it could also just be a vector". While if you pass in a record, 
type, or even a variant type, it's trivial to have a program recognize that 
value and act upon it. 

I have no experience writing apps that had to operate on any arbitrary data 
with any arbitrary structure. Pretty much all the functions in my apps 
could rely on data arriving in a particular format in a particular order 
(positional destructuring). 

More importantly we are pretty much agreeing that [:tagged vectors with 
some data] are only a representation of a variant. One chosen out of 
convenience and existing feature set. We could have a defrecord Variant 
with two fields, a type keyword and value hashmap. If core.match was able 
to easily pattern match over a record as well as easily destructure the 
values in the value hashmap, we would use it. From what I have seen of 
core.match, it is nowhere near as easy/clean as pattern matching a vector.

>> As far as performance goes, this is normally the sort of thing that gets 
baked into an app at a pretty low level, that's why I suggest it should be 
as fast as possible. If you're going to be processing millions of these 
things during the life of an app, and transforming them from one format to 
another, a little tweaking here and there may save you some pain in the 
end. 

Pattern matching itself is too slow for it to be viable in any performance 
sensitive context. That said, I feel optimize first for 
readability/maintainability, if profiling shows a bottleneck, then and only 
then optimize that area for performance. 

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-06 Thread Amith George
TIL that "tagged literals" have an existing meaning in clojure. In my mind, 
the terms "tagged vector" and "tagged literal" were interchangeable. From a 
quick Google search there doesn't seem to be an existing meaning for 
"tagged vector". I think we can agree that it a representation of variants 
in Clojure.

So given that, if we want to represent a single key/value pair, the 
> most natural way to do it would be:
>
> [:foreground #color/rgb "ff"]
>
> Variants fulfil the same purpose as key/value pairs in a map. The key 
> denotes a context-sensitive purpose for the data, rather than its type.
>


Could you elaborate on what you mean by variants being like a key value 
pair? Also, for the purposes of discussing variants, we can ignore reader 
tags right? I understand they serve a different purpose. The example in her 
talk had the map

{:type :pickup :store-id 123
 :address nil
 :email nil}

and the equivalent variant was `[:pickup 123]`

If the map was instead

{:pickup {:store-id 123}
 :digital nil
 :delivery nil}

then yes, a variant could be thought of as a key value pair. Is this what 
you meant?


On Sunday, 6 September 2015 13:29:05 UTC+5:30, James Reeves wrote:
>
> On 6 September 2015 at 02:31, Timothy Baldridge  > wrote:
>
>> >> Thanks, it helps to know using a tagged vector is a real pattern :) 
>>
>> I don't know that it's a "real pattern". If I saw code like this in 
>> production I would probably raise quite a stink about it during code 
>> reviews. It's a cute hack, but it is also an abuse of a data structure. Now 
>> when I see [:foo 42] I don't know if I have a vector of data or a tagged 
>> value. It's a better idea IMO to use something like deftype or defrecord to 
>> communicate the type of something. I'd much rather see #foo.bar.Age{:val 
>> 42} than [:foo.bar/age 42]. At least then when I do (type val) I don't get 
>> clojure.lang.PersistentVector.
>>
>
> I'll have to disagree with you here. To my mind, tagged literals don't 
> quite have the same purpose as variants do.
>
> For example, consider a map:
>
> {:foreground #color/rgb "ff"
>  :background #color/rgb "ff"}
>
> The hex strings are given a tag to indicate the type of data they contain, 
> while the keys in the map tell us the purpose of that data.
>
> We clearly wouldn't write something like:
>
> #{#foreground {:val #color/rgb "ff"}
>   #background {:val #color/rgb "ff"}}
>
> So given that, if we want to represent a single key/value pair, the most 
> natural way to do it would be:
>
> [:foreground #color/rgb "ff"]
>
> Variants fulfil the same purpose as key/value pairs in a map. The key 
> denotes a context-sensitive purpose for the data, rather than its type.
>
> - James
>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
defun, core.match, tagged vectors - seems like I can emulate Elixir 
function pattern match behaviour. I took some simple code I found online 
(https://twitter.com/Xzilend/status/640282621042233344) and rewrote it to 
1) use only tagged vectors (not quite) and 2) use defun and tagged vectors. 
I am eager to hear your thoughts on the rewrite.

Original 
(defn- register
  [db mailer email password]
  (if (users/valid? email password)
(if (users/taken? db email)
  (response/bad-request {:errors [{:message "That email is taken."}]})
  (do (users/do-create! db email password)
  (users/notify mailer email activate-subject activate-text)
  (response/ok (auth/authenticate email
(response/bad-request {:errors [{:message errors/invalid-creds}]})))

Lets ignore the possible concurrency issues for now.

Rewrite without using core.match

(defn register
  ([db mailer email password]
   (register [:start {:db db :mailer mailer :email email :password password
}]))
  ([status {:keys [db mailer email password] :as args}]
   (cond 
 (= status :start) 
 (if (users/valid? email password) 
   (register [:check-unique args])
   (register [:err {:res "Invalid credentials"}]))

 (= status :check-unique)
 (if (users/taken? db email)
   (register [:create args])
   (register [:err {:res "User already exisits"}]))

 (= status :create)
 (do (users/do-create! db email password)
 (users/notify mailer email activate-subject activate-text)
 (register [:ok {:res (auth/authenticate email)}]))

 (= status :ok) (response/ok (:res args))

 (= status :err) (response/bad-request {:errors [{:message (:res args
)}]}


With no pattern matching I had to wrap the actual arguments into a map so 
that all recursive calls hit the two argument arity. 

Using defun and tagged vectors,

(defn register [& args] (register' (into [:start] args)))

(defun- register'
  ([:start db mailer email password] 
   (if (users/valid? email password) 
 (register' [:check-unique db mailer email password])
 (register' [:err "Invalid credentials"])))
  ([:check-unique db mailer email password]
   (if (users/taken? db email)
 (register' [:create db mailer email password])
 (register' [:err "User already exists"])))
  ([:create db mailer email password]
   (do (users/do-create! db email password)
   (users/notify mailer email activate-subject activate-text)
   (register' [:ok (auth/authenticate email)])))
  ([:ok res] (response/ok (:res args)))
  ([:err msg] (response/bad-request {:errors [{:message (:res args)}]})))

I couldn't find a way to refer to the arguments vector from within the body 
of a case. I would have preferred writing the :start case like this,

  ([:start _ _ email password] 
   (if (users/valid? email password) 
 (register' (into [:check-unique] it)
 (register' [:err "Invalid credentials"])))



I find the defun version better compared to the plain if else version. Step 
transitions are explicit. Early exit is a transition to err state. The 
`response/bad-request` call occurs only once as opposed to at each early 
exit point. 

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
In Elixir, tuples are used where in the first element is the tag. A similar 
thing can be done in Clojure using vectors. That much was clear. What 
bothered me and prompted me to start this thread was I wasn't sure "what" 
it is I was doing by creating that vector. Was it purely a convention 
thing? What did the convention mean? It looked weird. 

The "aha" moment for me came while watching her talk. The tagged vector is 
simply a way to represent one case of an open discriminated union. 
Discriminated unions are a common approach in a language like F#. A 
function could return an union type Result, with cases Success and Error. 
And it gels very nicely with pattern matching. 

In that light, I can acknowledge tagged vectors as a real pattern. Creating 
records for all these cases wouldn't be worth it in my opinion. Infact one 
would usually just return a map of values. The caller would branch 
depending on the presence of an `:err` key. Each branch would have access 
to the entire map and its not evident which keys are branch specific. The 
pattern matching approach on the other hand makes explicit the values for 
each branch. 

On Sunday, 6 September 2015 07:01:40 UTC+5:30, tbc++ wrote:
>
> >> Thanks, it helps to know using a tagged vector is a real pattern :) 
>
> I don't know that it's a "real pattern". If I saw code like this in 
> production I would probably raise quite a stink about it during code 
> reviews. It's a cute hack, but it is also an abuse of a data structure. Now 
> when I see [:foo 42] I don't know if I have a vector of data or a tagged 
> value. It's a better idea IMO to use something like deftype or defrecord to 
> communicate the type of something. I'd much rather see #foo.bar.Age{:val 
> 42} than [:foo.bar/age 42]. At least then when I do (type val) I don't get 
> clojure.lang.PersistentVector.
>
> Timothy
>
>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George

>
> * Elixir and the BEAM VM are awesome at many things, but I suspect (from 
> experience not evidence) that the defun version is still faster than the 
> elixir version.


In Clojure, the defun version is not the default or idiomatic way to write 
functions. I kind of expected it to be slower. Maybe if the core team felt 
it was good enough to be the default, they could make internal changes to 
the core to optimize stuff (pure speculation here). 

On the other hand, skimming through the elixir documentation gives me the 
feeling that pattern matched functions is the default way to write. As a 
first class language feature, I find it hard to believe it is slower 
(compared to what in Elixir?).   Or do you mean the Beam VM in general is 
slower than the JVM? 

On Sunday, 6 September 2015 02:04:17 UTC+5:30, Rob Lally wrote:
>
> Out of interest, I ran the benchmarks as is, and got more or less the same 
> results - 15x. Then I tried upgrading the defun dependencies - clojure, 
> core.match and tools.macro - all of which have newer versions, and then 
> running the benchmarks without leiningen’s jvm-opts and in a trampolined 
> repl. The results are better (see below). Still not great - but down from 
> 15x to 10x. 
>
> That said:
>
> * I’m not sure I’d care: for most applications the overhead of function 
> dispatch is probably not the bottleneck.
> * Elixir and the BEAM VM are awesome at many things, but I suspect (from 
> experience not evidence) that the defun version is still faster than the 
> elixir version.
>
>
> Rob
>
> ---
>
> user=> (bench (accum-defn 1))
> WARNING: Final GC required 2.590098761776679 % of runtime
> Evaluation count : 429360 in 60 samples of 7156 calls.
>  Execution time mean : 139.664539 µs
> Execution time std-deviation : 4.701755 µs
>Execution time lower quantile : 134.451108 µs ( 2.5%)
>Execution time upper quantile : 150.214646 µs (97.5%)
>Overhead used : 1.565276 ns
>
> Found 5 outliers in 60 samples (8. %)
> low-severe   5 (8. %)
>  Variance from outliers : 20.5880 % Variance is moderately inflated by 
> outliers
>
> user=> (bench (accum-defun 1))
> Evaluation count : 44940 in 60 samples of 749 calls.
>  Execution time mean : 1.361631 ms
> Execution time std-deviation : 40.489537 µs
>Execution time lower quantile : 1.333474 ms ( 2.5%)
>Execution time upper quantile : 1.465123 ms (97.5%)
>Overhead used : 1.565276 ns
>
> Found 9 outliers in 60 samples (15. %)
> low-severe   1 (1.6667 %)
> low-mild     8 (13. %)
>  Variance from outliers : 17.3434 % Variance is moderately inflated by 
> outliers
>
> ---
>
>
> On 5 Sep 2015, at 05:16, Amith George > 
> wrote:
>
> Nice. Hadn't heard of it before. It looks interesting. The criterium 
> benchmark is kinda disappointing though. The pattern matched function took 
> nearly 15x the time of the normal 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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
Thanks, it helps to know using a tagged vector is a real pattern :) Gives 
the confidence to explore this further for my own code. 

On Saturday, 5 September 2015 22:37:33 UTC+5:30, Gary Verhaegen wrote:
>
> It won't really help for the library/ecosystem problem, but for your own 
> code I'd recommend watching Jeanine Atkinson's Conj talk from last year:
>
> http://m.youtube.com/watch?v=ZQkIWWTygio
>
>>
>>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
Nice. Hadn't heard of it before. It looks interesting. The criterium 
benchmark is kinda disappointing though. The pattern matched function took 
nearly 15x the time of the normal function.

Performance aside, in Elixir, there seems to be an established convention 
for creating the function argument tuple. Every function can expect to be 
pattern matched against both :ok and :err. NodeJS callbacks also have 
follow a convention, error first, which would make it trivial to pattern 
match against. Goodbye to all those mundane `if (err) {} else {}` checks. I 
can't quite think of any similar conventions in Clojure. 



On Saturday, 5 September 2015 14:05:02 UTC+5:30, James Reeves wrote:
>
> You might want to take a look at defun: 
> https://github.com/killme2008/defun
>
> - James
>
>

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


Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
Hi,

I just read a blog post [1] talking about Elixir pattern matching. I was 
thoroughly impressed with the way its handled in Elixir. I am posting this 
here cuz I got rather excited and wanted to discuss this with you all. 

My experience with pattern matching is limited to the basics of F# and 
reading the docs of core.match. I think its a great idea, but I also feel 
unless its supported by language at the fundamental level, it remains as 
syntactic sugar. 

All pattern matching code I had read previously, involve matching on a 
specific argument, often inside a function. From what I see in the blog 
post, in Elixir its taken one step further and pattern matching is done at 
the function declaration/invocation level. Normally one would create one 
outer public function and multiple private (?) functions to handle each 
branch. The outer function would only have the pattern matching code. At 
the very least, I find the Elixir version easier to read. It seems to be 
idiomatic for Elixir libraries, functions to return a tuple whose first 
(few?) elements are purely used for pattern matching. 

Consider the following code samples from that blog post,

def to_registration_result({:ok, res}) do
  {:ok, %Membership.RegistrationResult{
success: res["success"],
message: res["message"],
new_id: res["new_id"],
validation_token: res["validation_token"],
authentication_token: res["authentication_token"]
  }}
end

def to_registration_result({:error, err}) do
  {:error, err}
end

Normally, I would have one function with an if condition to check for an 
error value in the args and then call respective functions to handle each 
branch. I could also do

(defmulti to-registration-result first)

(defmethod to-registration-result :ok
  [[_ email password]]
  (println email password))

(defmethod to-registration-result :err
  [[_ err]]
  (println "err: " err))

But this wouldn't be idiomatic Clojure. This would also require all 
libraries and functions to return data in a certain form, one where in the 
first element is some kind of status. 

He has another example where pattern matching is used with recursive 
functions to handle transition from one state/step to another and handle 
terminating conditions. This specific example is a very poor choice, but it 
does demonstrate the possibilities.

def map_single({:ok, res}) do
  cols = res.columns
  [first_row | _] = res.rows
  map_single {:cols_and_first, cols, first_row}
end

def map_single({:cols_and_first, cols, first_row}) do
  zipped = List.zip([cols,first_row])
  map_single {:zipped, zipped}
end

def map_single({:zipped, list}) do
  {:ok, Enum.into(list, %{})}
end

def map_single({:error, err}) do
  {:error, err}
end

Interesting stuff. 

[1] - 
http://rob.conery.io/2015/09/04/using-recursion-in-elixir-to-break-your-oo-brain/

-- 
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: feedback about solutions

2015-09-01 Thread Amith George
Forgot to add, there is a community written clojure style guide [1] that 
you may skim through. I had read it a long time ago. My impression was that 
a lot of the guidelines aligned with my own preferences. 

[1] - https://github.com/bbatsov/clojure-style-guide

-- 
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: feedback about solutions

2015-09-01 Thread Amith George
Hi,

I am not an expert :)

I haven't heard of this repo or even understand what the exercises are. 
Nonetheless, based on what you wrote, some simple changes (to possibly make 
it more idiomatic?),

(< x 0)

 
use (neg? x)

(if (= (mod n  divisor)0) 
>   true
>   false))

 
use (= (mod n divisor) 0) ... `=` returns a boolean value.

(defn abs [x]


I don't understand what the point of this function is. If one can use a 
built-in function `mod` to test divisibility, why can't one use the Java 
function `Math/abs` to implement `abs`?

(not (teen? age ))

 
`((complement teen?) age)` ... I personally find `complement` forms easier 
to read than `not`. And its better than doing `((comp not teen?) age)`

(divides? 5 n )


Maybe it's just me, but it reads like I am checking whether 5 is divisible 
by n. I rather prefer `(divisible? n d)`. Creating a standalone 
`divisible-by-5` function is just as easy. Anyway,

(defn leap-year? [year]
>   (cond
>   (not(divides?  4 year ))   false
>   (not(divides? 100 year)) true
>   (not(divides? 400 year)) false
>   :elsetrue
>   ))


It took me a while to mentally verify the logic. I feel the code becomes 
easier to grok, if you invert the predicates, ie instead of checking for 
negation of a condition, just check for the condition.
(defn leap-year? [x] (cond (divisible? x 400) true (divisible? x 100) false 
(divisible? x 4) true :else false))
 or
(defn leap-year? 
  [x] 
  (cond (divisible? x 400) true 
(and (divisible? x 4) 
 ((complement divisible?) x 100)) true 
:else false))

Can a year be negative or zero? If not, then maybe a pre-condition check 
for positive numbers? 

(defn generic-doublificate [x] ...


Without understanding what this function is supposed to do, I can't comment 
on it. As such, one rarely needs to check if an argument is a list or a 
vector. In this case maybe a better check would be `sequential?`. Maybe, 
you were supposed to implement it using multi methods. One method for 
`number?`, one for `coll?` and a default implementation. The `coll?` 
implementation handles the cases for empty collection, sequential 
collection and any other case. That said, what does this method have to do 
with booleans? 


On Monday, 31 August 2015 23:59:21 UTC+5:30, r/ Wobben wrote:

> Hello, 
>
> I did solve the boolean chapter of the ilovehorses git repo.
> My solutions can be found here: 
> https://github.com/rwobben/i-am-a-horse-in-the-land-of-booleans/blob/master/src/i_am_a_horse_in_the_land_of_booleans.clj
>
> Any experts who can give me feedback about the solutions so I can learn 
> from it.
>
> 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.


Re: Function syntax

2015-08-13 Thread Amith George
Maybe you meant to use `vector` instead of `vec`? `vec` doesn't accept 
variable args. Hence my original question. 

On Thursday, 13 August 2015 16:24:43 UTC+5:30, Herwig Hochleitner wrote:
>
> 2015-08-13 11:13 GMT+02:00 Amith George >
> :
>
>>
>> Could you please explain why is the `vec` needed? From what I understand, 
>> we are expected to treat the variadic args argument as a seq, nothing more. 
>>
>>
> What Tassilo said.
> Also, it's not nessecary to use `vec`, but you need a function that 
> creates a seqable from varargs, like vec, list, ... .
> That's what the & rest argument syntax does for you: create a collection 
> object from a variable number of arguments.
> ​
>

-- 
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: Function syntax

2015-08-13 Thread Amith George
Hi,

I originally interpreted Erik's reply to mean -> Instead of `#(last (sort 
%&))` do `#((comp last sort) %&)`. This works without any issue. 

Herwig's suggestion was about replacing the entire anonymous function with 
`(comp last sort vec)`. The example you gave `((comp last sort) 3 2 1)`, 
even if we make it `((comp last sort vec) 3 2 1)`, it will throw an error 
about `vec` being called with too many parameters. 

For it to work with variable args, as Herwig said in his reply to me, we 
need a function that can return a sequence from a varargs. `vector` or 
`list would work, not `vec`. It should be `((comp last sort list) 3 2 1)`. 
Please correct me if I am understanding this wrong.



On Thursday, 13 August 2015 16:13:24 UTC+5:30, Tassilo Horn wrote:
>
> Amith George > writes: 
>
> >> That's not the same function as #(last (sort %&)) 
> >> The equivalent would be (comp last sort vec) 
> > 
> > Could you please explain why is the `vec` needed?  From what I 
> > understand, we are expected to treat the variadic args argument as a 
> > seq, nothing more. 
>
> With ((comp last sort) 3 2 1), sort will be called as 
>
>   (apply sort (list 3 2 1)) 
>
> which essentially is 
>
>   (sort 3 2 1). 
>
> Hovever, sort is no varargs function but wants a collection. 
>
> Bye, 
> Tassilo 
>

-- 
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: Function syntax

2015-08-13 Thread Amith George

Hi,

That's not the same function as #(last (sort %&))
> The equivalent would be (comp last sort vec)


Could you please explain why is the `vec` needed? From what I understand, 
we are expected to treat the variadic args argument as a seq, nothing more. 



On Thursday, 13 August 2015 14:02:38 UTC+5:30, Herwig Hochleitner wrote:
>
> 2015-08-13 10:08 GMT+02:00 Eric Le Goff >:
>
>> I would be curious to know if there are difference (in terms of 
>> performance / elegance ) between those 2 ways of expressing functions
>>
>> E.g
>>
>> *(fn [& x] (-> x sort last))*
>>
>> versus 
>>
>> *#(last (sort %&))*
>>
>> Both are supposedly equivalent, but would you recommend one preferred 
>> syntax , or this just a matter of personal style ?
>>
>
> #() is for very short functions, mostly just one-liners, where the (fn []) 
> would add significant noise.
> The line is blurry and a matter of taste; upper limit is when you need a 
> nested fn, since #(#()) is not possible.
> Performance is equivalent, since #() desugars into (fn [..]). 
>
> 2015-08-13 10:14 GMT+02:00 Erik Assum >:
>
>> (comp last sort)
>>
>
> That's not the same function as #(last (sort %&))
> The equivalent would be (comp last sort vec)
>
> cheers
>

-- 
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 first Clojure program (and blog post about it)

2015-07-30 Thread Amith George

Hi,

>From a cursory glance, I didn't really understand the domain, so the 
function names I used in my rewrite might seem silly. But I wanted to 
illustrate that there is a lot of repetition in your code. Also discrete 
functions (with proper names) can make the code easier to grok. 

https://gist.github.com/amithgeorge/15b1cb607c32d39b70c7

;; instead of relying on the caller to pass the edges in the right order,
;; we accept a map and process the keys in the correct order

(defn- squared-edge-values
  [edges]
  (->> [:oc :oa :ob :ca :ab :bc]
   (map #(edges %1))
   (map #(* %1 %1

;; all operations on the edges are performed on the squared values.
;; the squared values are guaranteed to be in the correct order.

;; this separates out the logic specific to opposite edges and can be tested 
separately
(defn- opposite-edge-values
  [edges]
  (let [[a2 b2 c2 d2 e2 f2] (squared-edge-values edges)]
[[a2 e2 (+ a2 e2)]
 [b2 f2 (+ b2 f2)]
 [c2 d2 (+ c2 d2)]]))

(defn- closed-edge-values
  [edges]
  (let [[a2 b2 c2 d2 e2 f2] (squared-edge-values edges)]
[[a2 b2 d2]
 [d2 e2 f2]
 [b2 c2 e2]
 [a2 c2 f2]]))

(defn- open-edge-values
  [edges]
  ;; implement later
  [[0 0 0]])

(defn- compute-edge-values
  [edge-fn edges]
  (->> edges
   (edge-fn)
   (map (fn [[x y z]] (* x y z)))
   (reduce +)))

(def ^:private add-opposite (partial compute-edge-values opposite-edge-values))
(def ^:private add-closed (partial compute-edge-values closed-edge-values))
(def ^:private add-open (partial compute-edge-values open-edge-values))

;; this is the public entry point.
;; the precondition ensures all the edges are present in the input

(defn volume 
  [{:keys [oa ob oc ab bc ca] :as edges}]
  {:pre [(every? #(number? %1) [oa ob oc ab bc ca])]}
  (let [opposite (add-opposite edges)
closed (add-closed edges)
open (add-open edges)]
(Math/sqrt (* (- (- open closed) opposite) 0.5


;; sample input
(defn a-mod-input
  []
  (let [a 1.0]
{:oc (* a (/ (Math/sqrt 6.0) 12.0))
 :oa (* a (/ (Math/sqrt 6.0) 4.0))
 :ob (* a (/ (Math/sqrt 2.0) 4.0))
 :ca (* a (/ (Math/sqrt 3.0) 3.0))
 :ab (/ a 2.0)
 :bc (* a (/ (Math/sqrt 3.0) 6.0))}))

(defn e-mod-input
  []
  (let [d 1.0
r (/ d 2.0)
h r]
{:oc h
 :oa 1
 :ob 1
 :ca 1
 :ab 1
 :bc 1}))

(def a-mod-volume (volume (a-mod-input)))
(def e-mod-volume (volume (e-mod-input)))


Again, the idea is to have small functions that reflect the steps you would 
normally do, as required by the domain or algo you are implementing. 

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-20 Thread Amith George
Oh, a few more things I observed;

   - I figured out how to use *unchecked-math* and *warn-on-reflection* :)

Earlier, I was setting them within a binding, but that didn't seem to do 
anything. Seems the correct way is to set them at the very top of the file, 
the first 2 lines after the namespace declaration. 

https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/0f49b7979f9c2e0e7a522f5ad875de0807d4e2da/src/rdp/214_intermediate_arr.clj#L4-L5

   - With the warnings now being generated properly, I was able to figure 
out where the type hints needed to be added. For example, 

(defn- covered?
  [^long canvas-x ^long canvas-y ^Paper paper]
  (and (<= ^long (.x1 paper) canvas-x ) (<= canvas-x ^long (.x2 paper)) 
   (<= ^long (.y1 paper) canvas-y ) (<= canvas-y ^long (.y2 paper


 The `^long` type hint is not needed within the `<=` forms. As paper is 
typed to `Paper` and the various `x1, x2 etc` fields are of type long in 
the Paper definition. 

   - Also, 

(recur (unchecked-inc i))


can be 

(recur (inc i))


because `*unchecked-math*` is set to a truthy value. 

Please correct me if I misunderstood anything :)


On Tuesday, 19 May 2015 23:02:11 UTC+5:30, Steven Yi wrote:
>
> Hi Amith, 
>
> One last optimization yields a 4x increase over the last version, and 
> now 12x over the original: 
>
> "Elapsed time: 22848.384642 msecs" 
>
> Code here: 
>
> https://gist.github.com/kunstmusik/db6e14118e818abf3bb8 
>
> Changes from last version: 
>
> - parse-inputs - Put parsed Paper objects into an array instead of a 
> vector. 
> - visible-color iterates through the array of Paper objects using a 
> loop-recur 
>
> I spent a moment looking at this using JVisualVM and saw from the 
> previous version that there was a lot of time spent in sequence 
> related stuff and in the some function.  I realized from using some it 
> was going through the vector items pretty often, and since that list 
> of items is static, are read-only within the context of the code, and 
> the values aren't shared around a codebase, I went ahead and optimized 
> it to use a fixed array. 
>
> Hope this runs well on your side too! 
> steven 
>
>
> On Tue, May 19, 2015 at 12:49 PM, Steven Yi  > wrote: 
> > Hi Amith, 
> > 
> > Just got back from a trip and had a chance to look at this again.  I'm 
> > not sure why you didn't see a change there; I'm running the same 
> > version of Clojure and Java here. 
> > 
> > I did another change to move from using a reduce to nested 
> > loop-recurs.  That with a some additional type hints for ^Paper, and 
> > moving the retrieval of :height and :width outside of the loops got a 
> > performance increase of almost 3x from the original: 
> > 
> > "Elapsed time: 109335.307414 msecs" 
> > 
> > The modified code is here: 
> > 
> > https://gist.github.com/kunstmusik/e1081d417142a90d5cfa 
> > 
> > Some general notes: 
> > 
> > - covered? - type-hinted ^Paper 
> > - visible-color - switched to pass in ^long x and y, used fn form for 
> > passed-in function and type-hinted ^Paper argument 
> > - visible-color-frequencies - switched to nested loop-recur, moved out 
> > height and width to single call outside critical loop 
> > 
> > Could you try the version from the gist there to see if you get a 
> > similar speedup? 
> > 
> > Cheers! 
> > steven 
> > 
> > On Tue, May 19, 2015 at 4:38 AM, Amith George  > wrote: 
> >> Hi, 
> >> 
> >> Thanks for taking the time to profile the code. I implemented the two 
> >> suggestions (using the two argument arity of lte and using aset instead 
> of 
> >> aset-long). 
> >> 
> >> 
> https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/2655a83f7fcf51e4fedae164d7d17386a0c8854f/src/rdp/214_intermediate_arr.clj
>  
> >> 
> >> lein run -m rdp.214-intermediate-arr 1 true 
> >> ;; took around 250s. 
> >> 
> >> The changes didn't seem to make a difference. The before and after runs 
> all 
> >> take between 250 - 260s. I kept the reduce as-is. From your reply, it 
> looks 
> >> like these two changes reduced the execution time by almost 30s. Any 
> >> thoughts of why there isn't much of a difference for me? - I am using 
> >> Clojure 1.7.3-beta3 and Oracle Java 1.8.0_45 on OSX Mavericks. 
> >> 
> >> On Saturday, 16 May 2015 08:32:12 UTC+5:30, Steven Yi wrote: 
> >>> 
> >>> Ah, I see.  Well, I think then you can ignore the stuff about warming 
> >>> up, as this certainly takes a while

Re: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-20 Thread Amith George
Wow. This is rather hard to believe. But the execution time is now 10s. :D

All of your suggestions were on the mark. I implemented them in 
stages/commits. The command to execute the file remains the same - `lein 
run -m rdp.214-intermediate-arr 1 true`

1. Replaced the coordinates vector with separate x and y. Added relevant 
type hints.

https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/0ba1992ff892928beb71400fb44cce471318d187/src/rdp/214_intermediate_arr.clj#L60

Best time - 110s. Can't believe that simply changing from `[[^long x ^long 
y]]` to `[^long x ^long y]` can reduce the execution time by half!! 

2. Replaced the reduce in visible-color-frequencies-arr to nested 
loop-recurs. 

https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/75db0f839b748a4ca313bc319c4970a9a0329fb6/src/rdp/214_intermediate_arr.clj#L86

Best time - 90s. I thought reduce was equivalent to a loop recur. Might 
have to create a separate bare-minimum code sample to investigate why 
reduce was slower.

3. Stored papers in a native array. The parsed input still contains the 
papers in a vector. Its only when the main function is called with array 
true, that we convert to an array and store as a local value.

https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/0f49b7979f9c2e0e7a522f5ad875de0807d4e2da/src/rdp/214_intermediate_arr.clj#L115

Best time - 10s. I really don't get why the `some` over a vector was so 
slow. I tried replacing the `some` with a loop-recur (one style using an 
incrementing index and `get papers index` and the other style using `rest 
papers`.) Surprisingly both styles were slower than using `some`.

Thanks a lot for figuring out the slow areas. You made me aware of two 
tools I could use to find bottlenecks. At the very least, I now know 
Clojure doesn't necessarily mean 10x slower. 

That said, I really wanna know why storing papers in a native array made 
such a difference. Ideally I shouldn't have to expose a mutable array to 
other functions. In this case, the functions that accept/use the mutable 
array are meant to be private and under my control, so I could have some 
measure of confidence that mutation wouldn't occur. 


On Tuesday, 19 May 2015 23:02:11 UTC+5:30, Steven Yi wrote:
>
> Hi Amith, 
>
> One last optimization yields a 4x increase over the last version, and 
> now 12x over the original: 
>
> "Elapsed time: 22848.384642 msecs" 
>
> Code here: 
>
> https://gist.github.com/kunstmusik/db6e14118e818abf3bb8 
>
> Changes from last version: 
>
> - parse-inputs - Put parsed Paper objects into an array instead of a 
> vector. 
> - visible-color iterates through the array of Paper objects using a 
> loop-recur 
>
> I spent a moment looking at this using JVisualVM and saw from the 
> previous version that there was a lot of time spent in sequence 
> related stuff and in the some function.  I realized from using some it 
> was going through the vector items pretty often, and since that list 
> of items is static, are read-only within the context of the code, and 
> the values aren't shared around a codebase, I went ahead and optimized 
> it to use a fixed array. 
>
> Hope this runs well on your side too! 
> steven 
>
>
> On Tue, May 19, 2015 at 12:49 PM, Steven Yi  > wrote: 
> > Hi Amith, 
> > 
> > Just got back from a trip and had a chance to look at this again.  I'm 
> > not sure why you didn't see a change there; I'm running the same 
> > version of Clojure and Java here. 
> > 
> > I did another change to move from using a reduce to nested 
> > loop-recurs.  That with a some additional type hints for ^Paper, and 
> > moving the retrieval of :height and :width outside of the loops got a 
> > performance increase of almost 3x from the original: 
> > 
> > "Elapsed time: 109335.307414 msecs" 
> > 
> > The modified code is here: 
> > 
> > https://gist.github.com/kunstmusik/e1081d417142a90d5cfa 
> > 
> > Some general notes: 
> > 
> > - covered? - type-hinted ^Paper 
> > - visible-color - switched to pass in ^long x and y, used fn form for 
> > passed-in function and type-hinted ^Paper argument 
> > - visible-color-frequencies - switched to nested loop-recur, moved out 
> > height and width to single call outside critical loop 
> > 
> > Could you try the version from the gist there to see if you get a 
> > similar speedup? 
> > 
> > Cheers! 
> > steven 
> > 
>

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

Re: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-19 Thread Amith George
Hi,

Thank you for taking the time. That is a rather smart algo. The code and 
the changes were easy to understand. 

I didn't implement the parallelized version as my aim was to understand why 
the clojure version was so slow compared to the equivalent C# version. 
(Btw, you have access to a 12 core machine! :O)

Ok. Two versions of the code - 

https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/2655a83f7fcf51e4fedae164d7d17386a0c8854f/src/rdp/214_intermediate_leifp.clj

lein run -m rdp.214-intermediate-leifp 1
;; took around 100s

https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/2655a83f7fcf51e4fedae164d7d17386a0c8854f/src/rdp/214_intermediate_arr_leifp.clj

lein run -m rdp.214-intermediate-arr-leifp 1 true
;; took around 70s

The first file (214_intermediate_leifp.clj) is similar to what you had 
after point 1. 

The second file (214_intermediate_arr_leifp.clj) is your algo combined with 
the tips provided in the posts above - mainly - using type hints; native 
arrays, two argument arity of `<=` etc. It also uses a record `Paper` 
instead of a map. However the record values are accessed by the keyword 
instead of direct field access. 

Applying those tips to my algo, reduced the time taken from 500s to 250s. 
For your algo, those tips only reduced the time taken by 1/4th. Which makes 
sense as your algo performs far less operations, so there are lesser number 
of operations that can get a speed bump... 

That said, I am none the wiser on how to write to fast single threaded 
clojure :( 

On Tuesday, 19 May 2015 05:34:21 UTC+5:30, Leif wrote:
>
> Summary:  With a new algorithm + parallelism, I reduced it from 528s to 
> 11s.
>
> This sounded fun, so I took a crack at it, starting with your solution.  
> Description and patch files here: 
> https://gist.github.com/leifp/a864bca941ecdacb5840
>
> Starting with your solution, I:
>
>1. Divided the canvas into 100 blocks, created an index of {blockindex 
>-> papers that intersect that block}. The reasoning is that if we 
> calculate 
>which block a pixel is in, we only need to check the papers that intersect 
>that block.  In the extreme case, certain blocks only intersected one 
> paper 
>(the background).  In the original code we would have had to check all 100 
>papers for each pixel in that block; now we just check one. (5x average 
>speedup)
>2. Changed the code to calculate color areas for a block at a time; 
>after that, it was a simple 2-line change to parallelize the work using 
> pmap. 
>(8x speedup on 12-core machine) 
>3. Make paper a record; use direct field access (this resulted in a 
>modest ~10% improvement, but maybe not worth it).
>
> So clojure was helpful in trying out algorithm ideas and parallelizing the 
> code.  The final program would no doubt also be faster in C#, but my goal 
> is "fast enough."
>
> Further idea (which I don't think I'll implement):  Index the papers using 
> an data structure built for geometrical indexing, like an R-tree or 
> variation, to get a near-optimal index without tuning.
>
> I hope my solution is interesting to you.  Questions / comments welcome.
> Leif
>
> P.S.  I apologize for the messy, repetitive, stream-of-consciousness code.
>
>
>

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-19 Thread Amith George
Hi,

Thanks for taking the time to profile the code. I implemented the two 
suggestions (using the two argument arity of lte 

 
and using aset instead of aset-long 
).
 


https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/2655a83f7fcf51e4fedae164d7d17386a0c8854f/src/rdp/214_intermediate_arr.clj

lein run -m rdp.214-intermediate-arr 1 true
;; took around 250s.

The changes didn't seem to make a difference. The before and after runs all 
take between 250 - 260s. I kept the reduce as-is. From your reply, it looks 
like these two changes reduced the execution time by almost 30s. Any 
thoughts of why there isn't much of a difference for me? - I am using 
Clojure 1.7.3-beta3 and Oracle Java 1.8.0_45 on OSX Mavericks. 

On Saturday, 16 May 2015 08:32:12 UTC+5:30, Steven Yi wrote:
>
> Ah, I see.  Well, I think then you can ignore the stuff about warming 
> up, as this certainly takes a while to run here: 
>
> "Elapsed time: 314763.93 msecs" 
>
> I tried profiling with Yourkit and saw a couple of things to change: 
>
> ;; I think lte with more than two args ends up being slower than 
> unrolling out here 
> ;; I also tried type-hinting values from paper to ^long to avoid lte 
> calls with Number 
> (defn- covered? 
>   [[^long canvas-x ^long canvas-y] paper] 
>   (and (<= ^long (:x1 paper) canvas-x ) (<= canvas-x ^long (:x2 paper)) 
>(<= ^long (:y1 paper) canvas-y ) (<= canvas-y ^long (:y2 paper 
>
> ;; for the reduce function in visible-color-frequencies-arr 
> ;; using aset instead of aset-long, as it looked like aset-long was 
> using reflection 
>  (aset colorCounts color (+ 1 (aget colorCounts color))) 
>
> That got it down to: 
>
> "Elapsed time: 279864.041477 msecs" 
>
> I suspect you might get improvement too if you change 
> visible-color-frequencies-arr to use loop-recur instead of reduce 
> since you're doing a bit of magic there. 
>
> Unfortunately I have to stop at the moment as I have to leave on a 
> trip early in the morning, but hopefully that's useful. 
>
> steven 
>
>

-- 
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: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-15 Thread Amith George
Hi Steven,

My bad. You need to invoke the code using the command 

lein run -m rdp.214-intermediate-arr 1 true

The `1` tells it to select a certain input file, (in this case the biggest) 
and the `true` tells it to use the function that internally uses a java 
array (as opposed to the function that internally uses a transient map.) 

The above mentioned command takes around 250secs on my laptop. My apologies 
again, I should have made it clear how to execute the project. 

On Saturday, 16 May 2015 05:48:43 UTC+5:30, Steven Yi wrote:
>
> Hi Amith,
>
> I checked out your project from git and just doing 'lein run' I got a 
> reported:
>
> "Elapsed time: 185.651689 msecs"
>
> However, if I modify the -main function in 214_intermediate.clj to wrap 
> the time testing with (doseq [_ (range 20)]), to run the test multiple 
> times, the behavior is much better after the first 9 or so runs, and by the 
> end it is down to:
>
> "Elapsed time: 35.574945 msecs"
>
> I think you might be running into a situation where the VM hasn't run the 
> functions enough times to optimize.  
>
> Rather than use the time function, you might want to try using 
> criterium[1] to benchmark the code. The site explains all the wonderful 
> things it does to get a good benchmark. 
>
> Unfortunately, if your data set is small, and you're running a one off 
> calculation like this, I don't know if there's much to improve due to the 
> warmup cost. You could fiddle a bit with VM flags to try to optimize with 
> less calls (I can't recall the flag, but I think the JVM defaults to 
> optimizing after a functions been called 10,000 times).  On the other hand, 
> if you're processing larger datasets, I think it's reassuring that once 
> warmed up, the Clojure code performs pretty well.  
>
> For reference, this was run on an Macbook Pro 13" early 2011, Core i7 
> 2.7ghz. 
>
> steven
>
> [1] - https://github.com/hugoduncan/criterium/
>
> On Friday, May 15, 2015 at 3:59:22 AM UTC-4, Amith George wrote:
>>
>> Thanks for the detailed suggestions. Implementing them did bring the 
>> execution time down to around 250secs. Though that value is still much 
>> longer than 45secs. Could you please verify if I have implemented them 
>> correctly?
>>
>> Code - 
>> https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/4ec02600e025d257a59d76fee0ad0eb01f4785ff/src/rdp/214_intermediate_arr.clj
>>
>> project.clj contains the line 
>>
>> :jvm-opts ^:replace ["-Xms1024m" "-Xmx1g" "-server"]
>>
>>   > 0) Switch to Clojure 1.7.0-beta3 - it's faster and some things below 
>> are dependent on it for best performance. And use Java 1.8.
>>
>> Done. 
>>
>>   > 1) Parse the lines you're reading directly into longs (Clojure 
>> focuses on 64-bit primitives - longs and doubles)
>>
>> (defn- read-line-nums
>>   ([] (read-line-nums (read-line) #(Long/parseLong %1)))
>>   ([input-line parse-fn]
>>(if-let [line input-line]
>>  (->> line
>>   (#(clojure.string/split %1 #" "))
>>   (map parse-fn)
>>
>>   > 2) Put the longs first into a data structure that preserves the 
>> primitive type. The two best options for that here are records (which can 
>> have primitive fields) and arrays. I would create a Canvas defrecord with 
>> ^long width and height and a Paper defrecord with all ^long fields for 
>> example.
>>
>> (defrecord Paper [^long color 
>>   ^long x1  ^long y1
>>   ^long x2 ^long y2])
>>
>> (defrecord Canvas [^long width ^long height])
>>
>> (defn- make-paper
>>   ([^long w ^long h] (make-paper [0 0 0 w h]))
>>   ([^longs [color x y w h]]
>>(Paper. color x y (+ x w -1) (+ y h -1
>>
>> I had to make the second arity accept a vector, as it seems impossible to 
>> create a function accepting more than 4 primitive arguments. Though I 
>> suppose I could grouped the args into a `record` of its own?
>>
>>   > 3) Store the papers in a vector (using transient to create it)
>>
>> The `read-input-file` function which creates and stores the papers, it 
>> finishes within 20ms. So I didn't bother using a transient. 
>>
>>   > 4) I suspect visible-color and covered? could probably be tightened 
>> up into a reduce over papers or a single loop-recur over papers - can't say 
>> I totally get what's happening there.
>>
>> Th

Re: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-15 Thread Amith George
Thanks for the detailed suggestions. Implementing them did bring the 
execution time down to around 250secs. Though that value is still much 
longer than 45secs. Could you please verify if I have implemented them 
correctly?

Code - 
https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/4ec02600e025d257a59d76fee0ad0eb01f4785ff/src/rdp/214_intermediate_arr.clj

project.clj contains the line 

:jvm-opts ^:replace ["-Xms1024m" "-Xmx1g" "-server"]

  > 0) Switch to Clojure 1.7.0-beta3 - it's faster and some things below 
are dependent on it for best performance. And use Java 1.8.

Done. 

  > 1) Parse the lines you're reading directly into longs (Clojure focuses 
on 64-bit primitives - longs and doubles)

(defn- read-line-nums
  ([] (read-line-nums (read-line) #(Long/parseLong %1)))
  ([input-line parse-fn]
   (if-let [line input-line]
 (->> line
  (#(clojure.string/split %1 #" "))
  (map parse-fn)

  > 2) Put the longs first into a data structure that preserves the 
primitive type. The two best options for that here are records (which can 
have primitive fields) and arrays. I would create a Canvas defrecord with 
^long width and height and a Paper defrecord with all ^long fields for 
example.

(defrecord Paper [^long color 
  ^long x1  ^long y1
  ^long x2 ^long y2])

(defrecord Canvas [^long width ^long height])

(defn- make-paper
  ([^long w ^long h] (make-paper [0 0 0 w h]))
  ([^longs [color x y w h]]
   (Paper. color x y (+ x w -1) (+ y h -1

I had to make the second arity accept a vector, as it seems impossible to 
create a function accepting more than 4 primitive arguments. Though I 
suppose I could grouped the args into a `record` of its own?

  > 3) Store the papers in a vector (using transient to create it)

The `read-input-file` function which creates and stores the papers, it 
finishes within 20ms. So I didn't bother using a transient. 

  > 4) I suspect visible-color and covered? could probably be tightened up 
into a reduce over papers or a single loop-recur over papers - can't say I 
totally get what's happening there.

The papers vector represents a sheets of papers that have been stacked on 
top of each other. ie, the last element in the vector is the canvas, and 
the first element is the topmost sheet. Each sheet is of different 
dimensions. Depending on the coordinates where they are placed, they may 
cover a part of the canvas. Different sheets may overlap in the areas they 
cover and thus we only want to consider the topmost sheet for that area. 

The `visible-color` function accepts a canvas coordinate and the stack 
papers and goes through the stack to find the first sheet that covers said 
coordinate. That papers color will be visible color for that coordinate.

  > 5) In visible-color-frequencies, you could use "update" instead of get 
+ transient assoc! on the acc map, but this is never going to be terribly 
fast. Another option here would be to create an array with the max color 
(you could track that while reading if it's not a well-known answer) and 
bash the array. That can retain int or long counters and will be *way* 
faster.

(defn- visible-color-frequencies-arr
  [{:keys [colors canvas papers]}]
  (let [colorCounts (long-array (count colors))] 
(reduce 
 (fn [_ ^longs coord]
   (if-let [color (visible-color coord papers)]
 (aset-long colorCounts color (+ 1 (aget colorCounts color)))
 _))
 -1
 (for [^long y (range (:height canvas))
   ^long x (range (:width canvas))]
   [x y]))
 (zipmap (range) colorCounts)))

It's a bit messy with me abusing reduce and totally ignoring the 
accumulator, but the version using arrays is atleast 10 seconds faster than 
the one using transient maps. That said, even the hashmap version took 
around 260-270secs. So the bulk of the time savings is caused by some other 
change. 

  > 6) You can use (set! *unchecked-math* :warn-on-boxed) to get faster 
math (no overflow checks) and also issue warnings (added in 1.7) if you 
happened to use boxed math by accident. 

I added these to both the old code (which didn't use type hints) and the 
new one. I ran the `-main` function of both from within the repl and using 
lein run. I didn't see any warnings in any of the executions. How am I 
supposed to use these?

(defn -main 
  ([] (-main "0" "false"))
  ([index use-arrays] 
   (time 
(binding [*unchecked-math* :warn-on-boxed
  *warn-on-reflection* true] 
  (if-not (Boolean/parseBoolean use-arrays) 
(solve (input-files (Integer/parseInt index)))
(solve-arr (input-files (Integer/parseInt index

  > Use: ^:jvm-opts ^:replace ["-server"] 

In my case there isn't any noticable difference between explicitly using 
'-server' and not using it. Which b

Re: Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-14 Thread Amith George
I forgot to link the input files 

https://raw.githubusercontent.com/fsufitch/dailyprogrammer/0e4bb5ba1e3bc6e749b9e9bb49387513d5a623b7/ideas/pile_of_paper/100rects100x100.in
https://raw.githubusercontent.com/fsufitch/dailyprogrammer/0e4bb5ba1e3bc6e749b9e9bb49387513d5a623b7/ideas/pile_of_paper/100rects100Kx100K.in

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


Why does the following Clojure code take 10x the time the C# version does? How to improve the Clojure version?

2015-05-14 Thread Amith George
I wrote the following code to solve this challenge - 
https://www.reddit.com/r/dailyprogrammer/comments/35s2ds/20150513_challenge_214_intermediate_pile_of_paper/.

Code - 
https://github.com/amithgeorge/reddit-dailyprogrammer-clojure/blob/56ce1dbb6a08e96150dc85934caecfeb68108a53/src/rdp/214_intermediate.clj

I executed the -main function using `lein run 1`. 

Output

;; lein run 1

0 12605919
1 3578145
2 15356894
3 19134293
4 2394558
5 15030409
6 6424953
7 14893444
8 1592254
9 1914025
10 7075106
"Elapsed time: 501168.972435 msecs"

The code originally used an immutable hashmap, but I lost patience waiting 
for the computation to end. With mutable hashmap, it still takes around 8 
mins.

I wrote a C# version of the above code - 
https://gist.github.com/amithgeorge/766b8220f39d48221e58. It finishes under 
40secs. The C# exe was built under Release mode and executed directly from 
the commandline. I expected the Clojure version to perform similarly.

Any tips on what I am doing wrong?

-
Explanation of the code - Create a vector of all paper sheets, such that 
the sheet placed last is the first element of the vector and the last 
element is the canvas. To compute the frequency of each visible color - for 
each point in the canvas find the first sheet in the vector that covers the 
point. Store/increment its count in the hashmap. I understand there might 
be better more efficient ways to solve this, but currently I am interested 
in why the Clojure versions is so slow vis-a-vis the C# version.

-- 
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] Cryogen - Static Site Generator

2014-11-14 Thread Tom George
Cool stuff!

Tom

On Thursday, November 13, 2014 4:27:44 PM UTC-5, Carmen La wrote:
>
> Check out my first project! As the title says, it's a static site 
> generator :)
>
> Blog post: http://carmenla.me/blog/posts/12-11-2014-post1.html
> Github repo: https://github.com/lacarmen/cryogen
>
> Any feedback is appreciated :)
>

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


Clojure meetup in Rochester, NY?

2014-11-13 Thread Tom George
Hi everyone,

I wonder if there are any people in the Rochester, NY area that are on this 
mailing list that would like to set up a meetup to talk about cool Clojure 
stuff.  I did some digging and I see that RocLisp was a thing a couple 
years ago.  Their twitter has been dead since 2012 and their website no 
longer exists.

Anyway, if theres any interest in the Greater Rochester area, I'd love to 
get something going.  Drop me an email or reply to this if you are 
interested!


Tom

tg82...@gmail.com
tgeo...@paychex.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.


Re: [ANN] Grimoire: up to date Clojure web docs

2014-07-11 Thread George Oliver

>
>
> I'd also love to see a custom domain for this as well. I'm happy to pay 
> for it if no one else will. How about clj-docs.org or clj-doc.org (which 
> are available)? I do see clojuredoc.org is available but could easily be 
> confused with clojuredocs.org
>

There's also clojure-doc.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
--- 
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] Grimoire 0.2.0

2014-07-11 Thread George Oliver
Great UI improvement, nice work!

-- 
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: Game logic with Clojure

2014-06-23 Thread George Oliver


On Monday, June 23, 2014 12:54:56 PM UTC-7, Majen Ful wrote:
>
>
> Could you give me some tips and lead me to the right things to do.
>
>
There's also this often referenced series of posts that might help, 

http://prog21.dadgum.com/23.html 

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

2014-05-04 Thread George Oliver
Arrow keys (left/right movement and up for history) on my lein repl in 
Windows XP works fine. Sounds like something on your system. 

-- 
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 + BDD + TDD + Pairing...

2014-04-11 Thread Tom George
Marcus,

I think the idea of working on a small project with fellow novices would be 
a great idea.

Tom

On Tuesday, October 29, 2013 11:43:54 PM UTC-4, Marcus Blankenship wrote:
>
> Hi Folks,
>
> I’m a Clojure n00b, but am interested in finding another n00b who aspires 
> to learn Clojure, and do so using BDD / TDD practices through regular 
> pairing sessions.  I’ve found novice <-> novice pairing to be a great way 
> to ramp up on skills, but I don’t live near anyone who I can pair with.  
>
> I’m thinking that doing 3 1-hour sessions a week, for a month, would give 
> us a nice start.  Obviously, this would be remote pairing via ScreenHero 
> (or some other tool).
>
> Anyone interested?
>
> Best,
> Marcus
>
>
> marcus blankenship
> \\\ Partner, Problem Solver, Linear Thinker
> \\\ 541.805.2736 \ @justzeros \ skype:marcuscreo
>  
>

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


[ANN] vim-gains-nrepl

2013-10-18 Thread George Kibardin
Hi!

vim-gains-nrepl is a simple plugin for Vim. No frills, just eval...  not 
actually, it also supports multiple  nREPL servers and sessions so you can 
use it for ClojureScript development. Find it here 
https://github.com/shashurup/vim-gains-nrepl

Enjoy!

Georgy

-- 
-- 
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: cloure-mode indenting (or not)

2013-10-11 Thread George Oliver


On Friday, October 11, 2013 2:33:54 PM UTC-7, naipmoro wrote:

The other strange thing, auto-indent no longer works; I have to hit the TAB 
> key after ENTER to get indentation. I can't believe *that* was 
> intentional (famous last words). So something must've broke. 
>

I think it was intentional. Possibly related to this, 
https://github.com/clojure-emacs/clojure-mode/issues/29

 

-- 
-- 
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 to reload Clojure files while connected to Clojurescript browser repl in Emacs?

2013-10-06 Thread George Oliver


On Sunday, October 6, 2013 11:15:26 PM UTC-7, George Oliver wrote:
>
>
> I could be wrong but my understanding is that the browser is just 
> connecting to your cljs repl which actually is in the 'clojure repl'. 
> Certainly if you refresh the page state built up in the browser is reset, 
> but state in the cljs repl is a different story.  
>

Well, that'll teach me to make a claim without verifying it first -- state 
in the repl -is- refreshed on a page refresh.  

-- 
-- 
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 to reload Clojure files while connected to Clojurescript browser repl in Emacs?

2013-10-06 Thread George Oliver


On Sunday, October 6, 2013 1:26:21 PM UTC-7, Tim Visher wrote:
>
>
> That sounds really cool. I was not aware that Austin could do this. Do 
> you have any pointers to documentation about it? Again, my model of 
> how the system works is that the browser _is_ the repl, so refreshing 
> the browser completely resets you back to the last time the 
> clojurescript was built. 
>
>
The Austin sample project is a good example, 
https://github.com/cemerick/austin/blob/master/browser-connected-repl-sample/README.md
 . 

I could be wrong but my understanding is that the browser is just 
connecting to your cljs repl which actually is in the 'clojure repl'. 
Certainly if you refresh the page state built up in the browser is reset, 
but state in the cljs repl is a different story.  

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

2013-10-02 Thread George Oliver


On Sunday, September 29, 2013 8:12:23 PM UTC-7, Tim Visher wrote:

Now with nrepl's ability to have multiple sessions open at once (an 
> ability I haven't taken any advantage of personally), you should be 
> able to have a JVM nrepl open _and_ a browser repl nrepl session, both 
> of which would be modifying client and server sides of the code 
> respectively. 
>

Tim, yes I think this is possible (I've read that people can do this with 
vim and Eclipse), I just haven't found a good working method yet for Emacs 
and nrepl.el. And it's true I haven't really thought ahead to whether this 
workflow is a good idea or not :), but I would like to give it a try. The 
functionality in Austin enables browser refreshes while maintaining a 
connected browser repl, dealing with state is another issue. 

After reading more on the nrepl.el list I found some relevant posts, [1] 
 [2], and I was able to get things to work using 
nrepl-make-repl-connection-default though it's not that smooth (and all 
manual at the moment).

[1]  https://groups.google.com/forum/#!topic/nrepl-el/tfsHaDTsYxY
[2] https://groups.google.com/forum/#!topic/nrepl-el/9xl6yd51tbQ

-- 
-- 
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: Problems starting with Clojure and Leiningen and Light Table

2013-10-01 Thread George Oliver
To add to Shantanu's directions, if you receive an error when doing mkdir 
in C:\ it's probably because your user account doesn't have permissions to 
create directories there. At that point you have two basic options:

1) use a user account with admin privileges to do all your work (not 
recommended)
2) create your work account in your user directory (e.g. 
C:\Users\Zeynel\work)

To add lein to your PATH, follow these steps:

http://geekswithblogs.net/renso/archive/2009/10/21/how-to-set-the-windows-path-in-windows-7.aspx


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


how to reload Clojure files while connected to Clojurescript browser repl in Emacs?

2013-09-29 Thread George Oliver
I sent this to Clojure-tools before I realized that list is not really for 
support questions, apologies for the crosspost. 

I'm hoping someone can help me fit the missing piece in this workflow:

(this works)

1. nrepl-jack-in in Emacs
2. launch web server from nrepl, modify Clojure files and reload (C-c C-k), 
refresh browser to see changes
3. launch browser repl from Emacs nrepl, connect it to the browser (using 
Austin [0], works great)

(this doesn't work)

4. while connected with browser repl, modify Clojure files and reload, 
refresh browser to see changes

All with the goal of being able to reload server-side code and also have 
the live browser repl to interact with the client-side. 

So far step 4 seems to reload Clojure code into the Clojurescript repl, 
obviously this won't work. 

I tried to connect two nrepl sessions to the same nrepl server following 
this thread [1] as so:

>  1) call nrepl-jack-in to start a server
>  2) get *nrepl* buffer for Clojure session
>  3) connect to the same server once more to get *nrepl*<2>
>  4) rename it to *cljs-repl*
>  5) make nrepl-nrepl-buffer local
>  6) set value of nrepl-nrepl-buffer to *cljs-repl* in cljs buffers

I got everything up to (5), but setting nrepl-repl-buffer (I think that's 
what he meant ??) buffer local to my cljs file then doing step 6 didn't 
have any effect. I don't know much of elisp or Emacs though so I'm not sure 
if I followed those steps correctly. 

There have been some recent threads on this topic [2] but no complete 
solution as far as I can tell. 


thanks for any help, 

George



[0] https://github.com/cemerick/austin
[1] https://groups.google.com/forum/#!topic/clojure-tools/C0jND-uuV28
[2] https://groups.google.com/forum/#!topic/clojure-tools/aCk59YTUV_I


-- 
-- 
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: Design/structure for a game loop in clojure

2013-05-20 Thread George Oliver


On Sunday, May 19, 2013 6:02:23 PM UTC-7, Daniel Wright wrote:
>
> thoughts/guidance appreciated! 
>
>
You might get something out of http://clojurefun.wordpress.com/2013/03/ -- "In 
this (somewhat extended) post I’m going to describe my experiences using 
Clojure for the 7DRL challenge – with discussion how to get the most out of 
Clojure for game development." 

The issue I'm having is that this system results in rather a lot of 
> looping through every entity in the world.


I'm not sure if this works with your code design, but can you reduce that 
by subscribing entities only to specific events? 

-- 
-- 
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: noob question about try/catch

2013-04-26 Thread George Oliver


On Friday, April 26, 2013 8:01:45 AM UTC-7, larry google groups wrote:
>
>
> I thought I had written the try/catch blog so that this exception would be 
> logged, but otherwise ignored. 
>
> Instead, this exception stops my app cold -- the app stops. 
>
>
>
See http://clojure.org/special_forms#try , you're still responsible for the 
logic in the catch to ignore the exception.  

-- 
-- 
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: Advice on state handling for a multiplayer poker app

2013-04-11 Thread George Oliver


On Thursday, April 11, 2013 2:35:03 PM UTC-7, James Adams wrote:
>
>
> How would you do this?  All thoughts welcome and appreciated
>

To simplify matters you could think about decoupling the incoming game 
events from the state changes; for example, have a queue hold game events 
and then serially apply those to the game state (which in that case could 
simply be contained in a map). 

-- 
-- 
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 to create dependncies for mysql in clojure

2013-04-07 Thread George Oliver


On Sunday, April 7, 2013 4:03:46 PM UTC-7, jayvan...@gmail.com wrote:
>
> I want to access  mysql. it is in c:\program files as mysql
> what is the rule   to create a dependicy statement "  
> [mysql/mysql-connector-java "5.1.23"]]".
> I have two books "Practical Clojure"
> "Programming Clojure"
> No answer in the books that I find
>

That looks right, what errors are you getting?

-- 
-- 
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: Invoke a specific multimethod

2013-03-29 Thread George Oliver


On Friday, March 29, 2013 6:19:19 PM UTC-7, JvJ wrote:
>
> Is it possible to invoke a particular multimethod and bypass the dispatch 
> function?
>
> For instance, suppose that I have a multimethod with a dispatch value of 
> ::foo, and it's a really complex method.
>
> Now, I want all cases where the dispatch function returns nil to use the 
> same multimethod.  Is there a way I can intercept the nil and
> pass it directly on to the ::foo multimethod?
>

You could use the default multimethod to catch nil, and then call the multi 
with ::foo. 

-- 
-- 
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: Debug prints don't execute on multimethod dispatch functions

2013-03-24 Thread George Oliver


On Sunday, March 24, 2013 3:01:53 PM UTC-7, George Oliver wrote:
>
>
>
> Not sure, but is it possible you're running afoul of a redefined defmulti 
> not overriding the original defmulti in the REPL? Try clearing the defmulti 
> with a (def dispatch-fn nil) and then reloading the defmulti?
>

Sorry, of course that should be (def testmulti nil) 

-- 
-- 
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: Debug prints don't execute on multimethod dispatch functions

2013-03-24 Thread George Oliver


On Sunday, March 24, 2013 12:49:40 PM UTC-7, JvJ wrote:
>
>
> I started using the meta-type function for dispatch, but then started 
> using debug-switch.  It actually works fine, running the appropriate 
> version of the method, but the println doesn't execute.  Does anyone know 
> why?
>
>
Not sure, but is it possible you're running afoul of a redefined defmulti 
not overriding the original defmulti in the REPL? Try clearing the defmulti 
with a (def dispatch-fn nil) and then reloading the defmulti?

-- 
-- 
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: Coding while running the program

2013-03-23 Thread George Oliver
Also, I forgot to mention this, 

http://www.lighttable.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/groups/opt_out.




Re: Coding while running the program

2013-03-23 Thread George Oliver


On Saturday, March 23, 2013 7:22:14 AM UTC-7, Oskar Kvist wrote:
>
> Hi!
>
> I saw this video http://www.youtube.com/watch?v=BES9EKK4Aw4 of Notch 
> coding on Minecraft while the game was running, and of course seeing the 
> changes in the running program. He used some kind of debug mode in his IDE 
> (I don't really know which IDE). I want to make a game, and I want to to 
> also be able to code while the program is running. 
>

I think Notch uses Eclipse, which allows you to hot load (reload) code on 
the fly (and I believe tweak state in the debugger but I haven't done 
that). Funny you should post this, I just watched a video yesterday that 
you might like to see, 

http://vimeo.com/14709925

He's using Emacs in that video. Eclipse has the Counterclockwise plugin for 
Clojure if you prefer. I definitely would recommend using something like 
those over a plain REPL. See also this SO 
answer, http://stackoverflow.com/a/5119355/216798 . 

You shouldn't have to mess with JVM settings but there are a few things to 
keep in mind doing interactive development. However it's probably best to 
get started with the links above and then come back here with specific 
questions. 



 

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

2013-03-12 Thread George Oliver


On Tuesday, March 12, 2013 1:34:21 PM UTC-7, Reginald Choudari wrote:
>
> Any resources/people dedicated to game development using 
> Clojure/Clojurescript?
> I have made a couple games using HTML5/Javascript with the canvas element, 
> and seeing that Clojurescript can replace Javascript coupled with Clojure 
> hosting an HTTP web server, I was thinking of moving over to the Clojure 
> way of coding things.. Any suggestions?
>

There are some links here, http://lispgames.org/index.php/Clojurescript 

-- 
-- 
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: Windows Installation

2013-03-08 Thread George Oliver


On Friday, March 8, 2013 7:55:59 PM UTC-8, James Ashley wrote:
>
>
> But the bare-bones part of the installation process Just Worked.
>
>
I agree, things are working well on Windows lately! It's pretty great. I've 
never bothered with cygwin. Some lightweight alternatives might be the bash 
shell provided with msys git or Gow. 

-- 
-- 
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: does a future call redirect printlns?

2013-03-06 Thread George Oliver
I found the problem -- I was blocking on a select call made from the while 
loop, so my shutdown function wasn't cleaning up properly (not to mention 
my while test was a little goofy!). Adding a timeout to the select fixes 
it. 

 

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




does a future call redirect printlns?

2013-03-05 Thread George Oliver
hi, 

I could use some help figuring out why this is working the way it is. It 
seems like a future function call is rebinding *out* so I don't see some 
printlns at the repl. 

I have a couple of functions for a server like this, 

(defn run [handler]
  (let
  [server (create-server)
   selector (:selector server)
   start (fn [] (future (handler server)))
   shutdown (fn []
  (println "Shutting down...")
  (doseq [k (.keys selector)]
(.close (.channel k)))
  (.close selector)
  (println "...done.")
  )]
{:server server :start start :shutdown shutdown}))

(defn app [server]
  (let
[acceptor (:acceptor server)
 selector (:selector server)]
(println "Starting Ex v Arcis on" (.getLocalAddress acceptor))
(while (.isOpen selector)   
  (select! selector)
  (echo-all (filter #(and (.isValid %) (.attachment %)) (.keys 
selector)))
  (Thread/sleep 3000))
(println "after")))


And a repl session looks like this, 

exvarcis.core> (def my-server (run #'app))
#'exvarcis.core/my-server

exvarcis.core> ((:start my-server))
#
Starting Ex v Arcis on #

exvarcis.core> ((:shutdown my-server))
Shutting down...
...done.
nil

exvarcis.core> 


So I never see the "after" called after the while loop.

If I comment out the while loop, I do see it. 

Anyone have a clue why this is working like it is?


thanks, George

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




beginner would like help with refactoring some functions in basic echo server

2013-03-03 Thread George Oliver
hi, 

I'm working on a basic single-threaded echo server for fun and learning 
(short-term goal is to have a simple chat server), and I'm at a point where 
I'd appreciate some feedback on refactoring a few functions. I've put them 
in a paste here, https://www.refheap.com/paste/12068 with some comments to 
explain the logic (or lack of it, as the case may be!). 

What I'd really appreciate are comments on:

* better ways to isolate changing state in the clients' ByteBuffers from 
reading these buffers -- since the act of reading a buffer changes its 
state in the first place this gets a little hairy. 

* maybe some better practices in dealing with ByteBuffers in the first 
place, this is the first time I've used them directly. 


thanks for any help, George


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




libs and resources for upcoming 7 day roguelike challenge?

2013-03-03 Thread George Oliver
hi, 

I've made a short list of Clojure resources for the upcoming 7 day 
roguelike challenge [1] [2], but I feel like I'm missing a few libs and 
games I've seen mentioned before. If anyone could jog my memory I'd 
appreciate it. In particular I feel like I saw a cljs roguelike link on 
Twitter last year but I couldn't find it again. 

Here's what I have at the moment:

libs

 (for Clojurescript)

  http://tapiov.net/unicodetiles.js/

  http://ondras.github.com/rot.js/hp/

 (for Clojure)

  https://code.google.com/p/blacken/

  https://github.com/SquidPony/SquidLib

  https://github.com/sjl/clojure-lanterna/

games

 https://github.com/thomcc/dunjeon

 http://stevelosh.com/blog/2012/07/caves-of-clojure-01/


thanks, George

[1] http://7drl.roguetemple.com/

[2] http://roguebasin.roguelikedevelopment.org/index.php?title=7DRL





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




wrapping multimethods?

2013-02-26 Thread George Oliver
hi, 

I'm interested in what techniques are useful for adding functionality to 
multimethods without modifying the defmethod itself. A while back I asked a 
similar question [1] and there are good answers there, but recently I've 
been looking at simple concepts like Ring middleware and wrapping functions 
with functions defining :pre and :post conditions,  and now wonder if there 
isn't a similar idea for multimethods. 

My code is a basic socket server with a defmulti that dispatches based on 
whether the socket is ready to accept, read, etcetera. I would like to add 
behavior to the defmethods in a simple and composable way and keep concerns 
separate (for example separating reading a socket from checking if it's 
actually closed). 

Here's a paste, https://www.refheap.com/paste/11861. 


thanks, George

[1] 
https://groups.google.com/forum/?fromgroups=#!searchin/clojure/george$20before$20after/clojure/beqWiVSn8ws/CihDwDumLDQJ

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




how to understand differences in results for nrepl.el interrupt evaluation (C-c C-b)?

2013-02-15 Thread George Oliver
hi, I am experimenting at the repl with a while form. For now I just write 
it as (while true ...) and interrupt it with C-c C-b. This is for a basic 
socket server. 

Recently I noticed a difference in how C-c C-b behaves that I don't 
understand. Normally when I interrupt, the repl returns immediately to the 
prompt, regardless of the client state. However if I swap one function for 
another, when I interrupt the repl doesn't return to the prompt until I 
initiate some action on the client end -- say, close the connection on the 
client end, or if all connections are closed, try to open a new connection. 

Is there a rule of thumb for under what conditions the repl will return to 
the prompt on an interrupt?

-- 
-- 
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: recommended way to write loop where a binding depends on a previous 'useless binding' operation?

2013-02-12 Thread George Oliver


On Tuesday, February 12, 2013 9:52:35 AM UTC-8, Evan Mezeske wrote:
>
> The big advantage to my reorganization of your loop is that it doesn't 
> have an unused "x" binding. []
>

Good points Evan, thank 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/groups/opt_out.




Re: recommended way to write loop where a binding depends on a previous 'useless binding' operation?

2013-02-12 Thread George Oliver
@Baishampayan, I'm just experimenting at the repl right now so there's no 
stopping condition yet. It's a socket server.


On Monday, February 11, 2013 11:56:22 PM UTC-8, Evan Mezeske wrote:
>
> Generally when you are calling functions that have (and depend on) 
> side-effects, you will end up using "do" a lot.  Also, I noticed that in 
> your example there's really no reason to make the x and y bindings part of 
> the loop.
>

I hadn't thought about using a let in the loop but you're right, I could 
just as easily bind in a let. Is there a benefit to doing it there rather 
than in the loop binding? Maybe it makes it easier to read?

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




recommended way to write loop where a binding depends on a previous 'useless binding' operation?

2013-02-11 Thread George Oliver
hi, 

I have a loop that looks like this, 

(loop
  [x (a-function)
   y (another-function)] ; another-function must be called after a-function
  () ; x is not used in body
  (recur (a-function) (another-function)))

This gets the job done (my a-function is a select() call which I don't use 
the return value of in the body), but it feels a little hacky so I'm 
wondering what's a better way?

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

2013-02-08 Thread George Oliver
There might be some good information here to carry 
over, http://www.gettingclojure.com/start .

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




techniques to work with Java mutable collections?

2013-02-04 Thread George Oliver
Hello, I'm writing a single-threaded TCP server for a bit of fun and 
learning, so I'm dealing with java.nio. I'm wondering how people here like 
to deal with mutable Java collections from Clojure.

For example, I need to use java.nio.Selector and its Set of selected-keys 
(the channel sockets registered with it). I need to add to and remove from 
this Set regularly to process new connections, reads, and writes. Is this 
just a situation of needing to isolate I/O from other parts of my Clojure 
program, or are there additional techniques to keep in mind when working 
with collections like selected-keys? Thanks for any feedback. 

-- 
-- 
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: Installing Clojure on Windows 7

2013-01-29 Thread George Oliver



> On Thursday, January 24, 2013 12:56:59 PM UTC-5, 
> sampso...@googlemail.comwrote:
>>
>> Apparently installing a development environment for Clojure on Windows 7 
>> is very difficult. What is the best way, that has a chance that it might 
>> work?
>>
>

I just wanted to repeat the link that Phil Hagelberg posted earlier, as it 
seems like it got lost a little in the thread:

http://clojure-doc.org/articles/tutorials/emacs.html 

This is an excellent current tutorial. I just installed a complete Windows 
setup and it took 5 minutes to go from zero to nrepl-jack-in. 

I have a related question, do I need a contributor agreement filed to make 
changes to http://dev.clojure.org/display/doc/Getting+Started+with+Emacs ? 
I have an account there but can't find the edit option for that page. 

-- 
-- 
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: Installing Clojure on Windows 7

2013-01-27 Thread George Oliver


On Saturday, January 26, 2013 7:01:34 PM UTC-8, Ravi Sundaar wrote:
>
> I am running into problems getting emacs (24.2) to work with clojure as 
> well on windows 7. I have installed leiningen fine. Clojure (1.4.0) itself 
> seems to be behaving. The packages seem to install fine in emacs - no 
> problems. When I invoke "nrepl-jack-in" from emacs, I get an "Access 
> Denied" error. No idea what that could be. There does not seem to be any 
> discussions on this on the web. 
>
> Any thoughts? Should I abandon the emacs approach on windows and choose a 
> different editor?
>

No, Emacs works perfectly well on Windows. What packages did you install 
and how did you install them? 

-- 
-- 
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: Installing Clojure on Windows 7

2013-01-24 Thread George Oliver


On Thursday, January 24, 2013 10:22:41 AM UTC-8, Sean Corfield wrote:
>
> Having now setup an Emacs-bsaed dev environment on XP and multiple 
> Windows 8 machines, I no longer think it's as difficult as some people 
> make it out to be. 
>


Sean, have you been using lein trampoline successfully on Windows? The last 
time I tried there was a persistent bug that hadn't been tracked down.  

-- 
-- 
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: EOF when executing lein trampoline cljsbuild repl-listen

2012-12-23 Thread George Oliver


On Sunday, December 23, 2012 3:30:53 PM UTC-8, Mark wrote:
>
>
> I figure the reader is trying to load the project.clj but I'm executing 
> from the project's root directory.  I'm using lein 2.0 preview 10 on a 
> Windows 7 machine if that matters.
>


This might be a Windows + trampoline problem. 
See https://groups.google.com/d/msg/clojure/J0imbgVWh5I/lXL8DlvJxAoJ . 

 

-- 
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] new book: "ClojureScript: Up and Running"

2012-11-19 Thread George Oliver


On Monday, November 19, 2012 9:34:29 PM UTC-8, puzzler wrote:
>
> Ugh, I should have guessed.  My attempts to do clojurescript several 
> months back were foiled by trampolining problems, but that was on lein 
> 1.7.  I was under the impression those problems had been fixed in lein 2.0, 
> so I had expected it to work, but it looks like there is still an issue.  
> Any easy workaround?
>


VirtualBox? :) 

-- 
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] new book: "ClojureScript: Up and Running"

2012-11-19 Thread George Oliver


On Monday, November 19, 2012 8:18:16 PM UTC-8, puzzler wrote:
>
>
> Then, at the command prompt I typed:
> lein trampoline cljs-build repl-rhino
> and got the following error message.  I'm running on Windows.  Any idea 
> what's going wrong?
> Thanks.
>
>
>

These kinds of errors usually mean a file path or constructed command line 
is misquoted, double-quoted where it shouldn't be, etcetera. For example 
see issues like this, https://github.com/technomancy/leiningen/issues/674. 
Not sure myself what the problem is here since it seems like most of these 
issues have been closed but maybe there's something still there. 

 

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

architecture for distributed game server?

2012-11-18 Thread George Oliver
hi, apologies if this is slightly off-topic but I'd appreciate advice on 
something I don't have much experience with. 

I'm writing a mud (multiplayer text game) where you can write the game 
logic in different programming languages; for example, the combat system in 
Ruby and the movement system in Clojure. The different systems communicate 
over sockets with a central Clojure server which handles player 
connections. 

Message queues seem like a good solution for the interprocess communication 
so I'm looking at brokers like RabbitMQ. My question is, does a message 
broker like RMQ seem like overkill for what is basically a small-scale 
application (most muds never run more than a couple dozen game systems and 
see more than a couple of hundred player connections), and if so, is there 
is a more lightweight alternative that you would recommend?


thanks, George


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

Re: newbie question regarding maps

2012-09-25 Thread George Oliver


On Monday, September 24, 2012 3:04:42 AM UTC-7, Mond Ray wrote:
>
>
> As you can see the REPL gives me an error stating that the keys must be 
> Integers. Is that right?  Or is my call process faulty?
>
>
I think the problem is that wish-lists is a vector, so you need a key for 
the vector first (e.g. 0, 1. etc.) in assoc-in. That's what the error is 
saying. 

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

2012-09-09 Thread George Oliver


On Sunday, September 9, 2012 5:20:13 PM UTC-7, James Ashley wrote:
>
> I don't want to add noise to this group. Is there somewhere more 
> appropriate to ask? (The wiki on the site doesn't seem to fit). 
>

No apologies necessary, this is the list according to the clojure-clr 
readme.  

-- 
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 ritz 0.4.0 release with nREPL debugger support

2012-09-07 Thread George Jahad
Impressive, (as always,) Hugo.

g


On Wednesday, September 5, 2012 1:45:41 PM UTC-7, Hugo Duncan wrote:
>
>
> ritz started life as a swank server for emacs SLIME. With this release 
> it has evolved into several components: 
>
> * ritz-nrepl provides both nREPL middleware, that can be used in any 
>   nREPL server (and any client), and a debugger for use with nrepl.el, 
>   the emacs client for nREPL. The nrepl middleware provide the complete, 
>   doc, javadoc, apropos and describe-symbol nREPL operations. 
>
> * ritz-swank corresponds to the previous ritz functionality and provides 
>   a swank server with debugger capabilities. 
>
> * ritz-debugger provides a library for using the JVM JPDA debugger 
>   classes from clojure. 
>
> * ritz-repl-utils provides a library of functions, used to provide 
>   common repl behaviour between ritz-nrepl and ritz-swank. This is also 
>   independent of emacs. 
>
> The project can be found at https://github.com/pallet/ritz 
>
> Hugo 
>

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

2012-08-24 Thread George Oliver


On Friday, August 24, 2012 4:03:32 AM UTC-7, David Della Costa wrote:
>
>
> What I ended up feeling like was, these are the options more or less: 
>
>
Thanks David, this plus your github link is a great write-up and exactly 
what I was hoping to find by posting to the list. Regarding #3, if you're 
going to run Jetty standalone then Josh's link to Immutant seems like a 
good choice to consider. 

There's a couple of other interesting links I've found that might shed some 
light on .war's, Jetty, and other means of deployment:

 https://groups.google.com/forum/#!topic/aleph-lib/wyHuMKfle1A

https://groups.google.com/forum/#!topic/clj-noir/C9D1Dc02w4Q 


best, George

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

deployment

2012-08-17 Thread George Oliver
hi, 

I'm a Clojure beginner working on a web project and starting to think about 
deployment. Currently I host my project in a local VM and have a small VPS 
for public testing. Looking down the road I'd like a more flexible hosting 
solution. 

It seems like the hosting landscape is changing fast so I'd like to know -- 
how do you deploy your projects 'now'?

So far I've found stuff like:

* A continuum of Clojure support from cloud providers, with some free tiers 
at AWS, Heroku, Openshift, etc.
* tools like lein-beanstalk for hosting apps on Elastic Beanstalk
* libraries like appengine-magic for hosting on GAE
* libraries like pallet for abstracting deployment to multiple cloud 
providers
* many more tools depending on how much 'more Java' you're willing to 
incorporate into your project, for example deploying a WAR in a Tomcat 
container (not even sure I have the lingo right there! :) )
* combining these tools and libraries with CI tools such as Jenkins for a 
complete automatic develop -> build -> deploy solution. 

>From what I've seen, and given that (a) I have a small project (probably 
not more than 5k users eventually) and (b) I'm not a professional 
programmer, but (c) I'd like to manage this in a professional way, it seems 
like a strategy could be:

1. use a tool like lein-beanstalk for public deployment and use simple 
scripts for building
2. in the meantime get familiar with pallet for more flexibility in the 
future
3. eventually deploy using pallet
4. at this point learn a CI tool to fully automate the process. 

What do you think?


thanks, George

-- 
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: auxiliary methods like :before and :after for multimethods?

2012-07-27 Thread George Oliver


On Friday, July 27, 2012 12:06:33 PM UTC-7, Vinzent wrote:
>
> robert-hooke actualy doesn't work with multimethods afaik. You can try my 
> new library (https://github.com/dnaumov/hooks), but it's alpha (no docs 
> yet, sorry).


Yes, from the robert-hooke readme, "Adding hooks to a defmulti is 
discouraged as it will make it impossible to add further methods. Hooks are 
meant to extend functions you don't control; if you own the target function 
there are obviously better ways to change its behaviour.". 

What got me thinking about :before and :after was the question of how to 
add a lightweight rules system to an application. Do you think hooks are 
appropriate here?

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

auxiliary methods like :before and :after for multimethods?

2012-07-26 Thread George Oliver
hi, I'm wondering if anyone has extended multimethods with auxiliary 
methods like CL-style :before and :after, and if not what a suitable 
substitute might be. 


thanks, George

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

2012-07-19 Thread George McKinney
+1

On Saturday, June 9, 2012 6:03:46 PM UTC-7, aboy021 wrote:
>
> Is there anywhere that I can get a Clojure sticker?

-- 
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: lein-cljsbuild simple example on Windows XP with lein2, "Could not locate example/routes__init.class or example/routes.clj on classpath"

2012-07-15 Thread George Oliver


On Sunday, July 15, 2012 3:15:34 PM UTC-7, Evan Mezeske wrote:
>
> > Thanks; do you know of a project that uses the latest cljsbuild with 
> lein 2 I could try to test?
>
> Not off the top of my head.  Unfortunately, github's search tool is junk, 
> otherwise it might be possible to find something there...



I had a go with the clojurescript branch of hiccup (
https://github.com/r0man/hiccup/tree/clojurescript ). From its project.clj 
it looks like it's using lein2 with cljsbuild 0.2.4. However it seems I'm 
running into the same issue.  I've sent it to the lein mailing list 

-- 
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: lein-cljsbuild simple example on Windows XP with lein2, "Could not locate example/routes__init.class or example/routes.clj on classpath"

2012-07-15 Thread George Oliver


On Sunday, July 15, 2012 1:17:04 PM UTC-7, Evan Mezeske wrote:
>
> Since Leiningen 2.x has not yet been released, lein-cljsbuild uses 
> Leiningen 1.x for both the example projects, and building the plugin 
> itself.  The problem you ran into is a difference between Leiningen 1.x and 
> 2.x.
>
> I created an issue to make sure that this fact is made more clear: 
> https://github.com/emezeske/lein-cljsbuild/issues/107 .
>


Thanks; do you know of a project that uses the latest cljsbuild with lein 2 
I could try to test? I was able to launch the ring server in the advanced 
project, but I'm still failing launching the repl.  

-- 
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: lein-cljsbuild simple example on Windows XP with lein2, "Could not locate example/routes__init.class or example/routes.clj on classpath"

2012-07-15 Thread George Oliver


On Sunday, July 15, 2012 12:00:57 AM UTC-7, George Oliver wrote:
>
> hi, I'm trying to get lein-cljsbuild running on Windows XP. I copied the 
> simple example at  
> https://github.com/emezeske/lein-cljsbuild/tree/master/example-projects/simple
>  



I think I found a fix for this; in the example project.clj there is the 
option 

 :source-path "src-clj"

I changed this to 

   :source-paths ["src-clj"]

(per https://github.com/technomancy/leiningen/blob/master/sample.project.clj
 )

And the example project instructions worked. 

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

lein-cljsbuild simple example on Windows XP with lein2, "Could not locate example/routes__init.class or example/routes.clj on classpath"

2012-07-15 Thread George Oliver
hi, I'm trying to get lein-cljsbuild running on Windows XP. I copied the 
simple example at  
https://github.com/emezeske/lein-cljsbuild/tree/master/example-projects/simple 
and 
then did

$ lein cljsbuild once
$ lein ring server-headless 3000

Which gives the error, 

C:\george\work\simple>lein ring server-headless 3000
Exception in thread "main" java.io.FileNotFoundException: Could not locate 
example/routes__init.class or example/routes.clj on classpath:
at clojure.lang.RT.load(RT.java:432)
at clojure.lang.RT.load(RT.java:400)
at clojure.core$load$fn__4890.invoke(core.clj:5415)
at clojure.core$load.doInvoke(core.clj:5414)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5227)
at clojure.core$load_lib.doInvoke(core.clj:5264)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$require.doInvoke(core.clj:5381)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at user$eval1.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.eval(Compiler.java:6500)
at clojure.lang.Compiler.eval(Compiler.java:6477)
at clojure.core$eval.invoke(core.clj:2797)
at clojure.main$eval_opt.invoke(main.clj:297)
at clojure.main$initialize.invoke(main.clj:316)
at clojure.main$null_opt.invoke(main.clj:349)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)


Does anyone know what the problem might be?

Another weird thing about this is if I try a lein repl from this project, I 
get:

C:\george\work\simple>lein repl
nREPL server started on port 1740
Welcome to REPL-y!
Clojure 1.4.0
Exit: Control+D or (exit) or (quit)
Commands: (user/help)
Docs: (doc function-name-here)
  (find-doc "part-of-name-here")
  Source: (source function-name-here)
nil  (user/sourcery function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org: [clojuredocs or cdoc]
  (user/clojuredocs name-here)
  (user/clojuredocs "ns-here" "name-here")


The cursor then freezes on the last line. 

However doing a lein repl from an empty project made with 'lein new' (and 
making sure Clojure 1.4 is specified in dependencies) works normally. 


thanks for any help, George


-- 
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: Help getting Clojure/Leiningen 2.0 building with LWJGL

2012-07-10 Thread George Oliver


On Sunday, July 8, 2012 7:26:05 PM UTC-7, Karl Smeltzer wrote:
>
>
> 3. Added :native-path "native" to my project.clj, although I'm not sure 
> this is correct or working the way I expect
>
>

Have a look at this, 

http://stackoverflow.com/questions/10558795/using-lwjgl-in-leiningen-clojure
 

-- 
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: any advice for translating the book "The Joy of Clojure"?

2012-04-22 Thread George Oliver


On Apr 22, 10:40 am, Zhitong He  wrote:
> Hi, all. I am new to Clojure and feel exciting playing with it.
>
> Recently, I read the book "The Joy of Clojure", and got a strong
> feeling toward translating the book from English to Chinese, to
> introduce Clojure to more programmers in China.

I think your best bet is to contact the publisher (Manning) to
negotiate the translation rights.

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


Re: Newbie's Guide to Learning Clojure

2012-03-29 Thread George Oliver


On Mar 28, 10:16 am, Elango Cheran  wrote:
> Hi everyone,
> On Gregg's suggestion, I want to share a writeup about how total beginners
> can learn Clojure in a minimally painful way.  I'd welcome any comments,
> suggestions, etc.

You could add a link to this guide,

http://www.unexpected-vortices.com/clojure/brief-beginners-guide/

It covers a lot of the development environment setup a beginner should
know.

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


  1   2   3   >