Re: What is this notation? "-a"

2021-12-26 Thread William la Forge
https://stackoverflow.com/questions/10846423/is-there-a-clojure-convention-for-naming-private-functions/10853372

On Saturday, December 25, 2021 at 6:53:56 PM UTC-5 hank@gmail.com wrote:

> Hello --
>
> Sometimes I see a notation that uses a prefix "-", as in:
>
> user> (def -a (atom []))
> #'user/-a
>
> Is there a special meaning/convention regarding this use of a hyphen 
> prefix?
> TIA
> -- Hank
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/dd81c045-f6a3-4c31-94ea-1f252e0fa86an%40googlegroups.com.


Re: What are resources to learn Clojure for beginners in Programming and get better?

2021-11-03 Thread William la Forge
This may seem silly at times, but I think very highly of it as a starting 
point: https://www.braveclojure.com/

Also, I suggest that you shift approaches from time to time. Clojure is 
unbelievably rich and supports programming methodologies that you've never 
hear of, as well as all the ones you have previously encountered. 

Here's a quick access page that provides an index into a lot of basic 
clojure 
functions: 
https://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html

On Wednesday, November 3, 2021 at 10:07:09 AM UTC-4 shouk...@gmail.com 
wrote:

> As in title,
> I am not too good of programmer, best I can do is like, write simple 
> number guessing game, and I guess that is an elementary thing to even be 
> able to do..
>
> So,
> My question is, what are good resources to get better at clojure, that 
> does not require much prior experience?
>
> And other question while we are at it..
> Would be going through specific tutorials, like for example, how to write 
> simple snake game in clojure, and then playing around with it, changing 
> things, be a decent approach?
>
> In advance, I appreciate all replies, 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/f4d03588-3153-4f27-a9ca-a3d2370495fen%40googlegroups.com.


Re: clojure.edn/read isn't spec compliant

2020-10-17 Thread William la Forge
My understanding is that run-time validation is often left weak in 
preference to speed of execution. In contrast to validation by the 
"compiler". Thus clojure throws many more exceptions than does the edn 
reader. --Bill la Forge

On Friday, October 16, 2020 at 9:07:40 PM UTC-4 EuAndreh wrote:

>
> Hello there.
>
> I was working on implementing a specification compliant edn reader on
> Rust, and I found that clojure.edn/read itself isn't specification
> compliant.
>
> I have three examples below that should all throw exceptions, but
> instead they are valid values according to clojure.edn/read. The quotes
> were taken verbatim from the text of the specification[0].
>
> --8<---cut here---start->8---
> ;; "Per the symbol rules above, :/ and :/anything are not legal keywords."
> [(edn/read-string ":/")
> ;; "It can be used once only in the middle of a symbol to separate
> the _prefix_ (often a namespace) from the _name
> _"
> (name (edn/read-string "a/b/c"))
>
> ;; specification doesn't talk about namespaced maps
> (edn/read-string "#:a{:k 1}")]
>
> [:/ "b/c" #:a{:k 1}]
> --8<---cut here---end--->8---
>
> I couldn't find many references to these issues, other than a Jira
> ticket[1] and a thread on clojure-dev[2]. Both talk about
> clojure.edn/read being consistent with LispReader, though. I have no
> opinions on that.
>
> Since the clojure.edn/read is an edn reader, shouldn't it comply with
> the edn specification? Maybe not the namespaced maps parts, which the
> specification itself could be extended to cover. But the other two cases
> are explicitly forbidden on the specification, and clojure.edn/read
> allows them.
>
> I'm willing to write a patch to fix those, but is it something that
> would be welcome? One could consider it a breaking change since the
> reader will stop accepting data that is now does, but I could also argue
> that this is a bug on the reader that was fixed, and the behaviour was
> changed to match the expected behaviour, which is the specification.
>
> The specification itself could change to match the behaviour of the
> reader, but this is not desirable since it would invalidate the work
> that others have done to implement edn outside of Clojure.
>
> The tension between breaking the reader and matching the specification
> should, IMHO, be favoured towards the matching the specification.
> Otherwise, the actual specification isn't what edn-format.org says, but
> it would instead be "whatever clojure.edn/read does", which is worse.
> The value proposition of having an specification to begin with is lost.
>
> WDYT? Is there any other resource on this that I missed?
>
> [0]: 
> https://raw.githubusercontent.com/edn-format/edn/a51127aecd318096667ae0dafa25353ecb07c9c3/README.md
> [1]: https://clojure.atlassian.net/browse/CLJ-1530
> [2]: https://groups.google.com/g/clojure-dev/c/b09WvRR90Zc/discussion
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/1a9c0924-0b94-4094-8fa0-c8cd8f9bc667n%40googlegroups.com.


Re: Making a Java class implement ILookup

2017-03-03 Thread William la Forge


On Friday, March 3, 2017 at 9:42:30 AM UTC-5, Ernesto Garcia wrote:
>
>
> Can you point out to some implementation of this kind? I don't know what 
> you are referring to here. Would AOT compilation help in my case?
>
>
In the clojure toolbox, the first entry under data structures is 
aatree: https://github.com/laforge49/aatree but beware bit rot as it is now 
a bit dated. :-( 

Because genclass is being used, the code extends things like 
clojure.lang.APersistentMap. 
This might be a good starting point: 
https://github.com/laforge49/aatree/blob/master/src/aatree/AAMap.clj

The extensions to map et al are quite extensive, going so far as to 
implement virtual structures that need not even fit in memory. (check the 
readme.)

So have fun!

Bill

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Making a Java class implement ILookup

2017-03-01 Thread William la Forge
Alternative implementations for clojure maps are hard. You tend to use AOT 
a lot, which is non-idiomatic. But a number of people have done this, 
including myself. In retrospect, it isn't worth it. At least not most of 
the time.

One thing that really bothers me is that Java supports subMap. And even 
clojure vectors have sub-vec. I've got a lot of code that builds on sub 
maps. But without reverting to aot, I need to define my own types which 
implement clojure's interfaces. A bit of a pain, but better than reverting 
to using aot methinks.

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


Re: Is this a bug that is already fixed?

2017-02-19 Thread William la Forge
Upgraded clojure too and now it works. Phew!
 

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


Re: Is this a bug that is already fixed?

2017-02-19 Thread William la Forge
Now it gets complicated.

I upgraded to the latest clojurescript. and switched to reader version 
1.0.0-beta3 which holds the/a fix.

No change. The bug is still present.

Here's my build 
boot: https://github.com/rolonicArk/simpleArk/blob/master/build.boot

:-(

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


Re: Is this a bug that is already fixed?

2017-02-19 Thread William la Forge
Thanks Timothy! I found a similar issue with the same answer 
here: https://github.com/ptaoussanis/sente/issues/241

Closed!

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


Re: Is this a bug that is already fixed?

2017-02-19 Thread William la Forge

>
> I'll note that when I add a second entry to the map, everything is fine:
>
>
 {:fix nil :local/contacts-capability contacts-capability}

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


Is this a bug that is already fixed?

2017-02-19 Thread William la Forge
Here's my clojure data: {:local/contacts-capability contacts-capability}

pr-str gives me this:  #:local{:contacts-capability #uuid 
"--4000-8000-0003"}

I pass this over to clojurescript and when I read it I get...

Uncaught Error: Could not find tag parser for :local in 
("simpleArk.arkRecord.Ark-record" "uuid/Timestamp" "inst" "js" "queue" 
"uuid" "miMap/MI-map" "tailrecursion.priority-map" 
"simpleArk.rolonRecord.Rolon-record")
at 
Function.cljs.reader.reader_error.cljs$core$IFn$_invoke$arity$variadic 
(reader.cljs:71)
at cljs$reader$reader_error (reader.cljs:69)
at cljs$reader$maybe_read_tagged_type (reader.cljs:613)
at cljs$reader$read_dispatch (reader.cljs:260)
at cljs$reader$read_delimited_list (reader.cljs:233)
at cljs$reader$read_vector (reader.cljs:280)
at cljs$reader$read (reader.cljs:464)
at cljs$reader$read_string (reader.cljs:477)
at console$client$display_property (client.cljs:366)
at console$client$explore_BANG_ (client.cljs:404)

Dependencies:

[org.clojure/clojure "1.9.0-alpha10"  :scope "provided"]
[org.clojure/clojurescript "1.9.198"]


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Deploying multiple Clojure apps on one server using Reagent, Nginx, and Supervisor (Solved)

2017-01-02 Thread William la Forge

>
> Seth, something seems amiss. 1,000 GB is 1,000,000 MB. At 84 mb per jar, 
>>> you can spin up 11,904 jar files. Which is worse than only being able to 
>>> run only dozens of PHP apps.
>>>
>>
--b 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Cyclic namespace dependencies!

2016-12-31 Thread William la Forge
I think Timothy Baldridge had a great answer. For example, I often have 
records which use each other's constructors. But you can put your factoy 
methods in a map of dependencies.

I generally have a build function which takes a hash map as an argument, 
associates the various data and functions that other modules depend on, and 
returns the updated hashmap. Each module has such a function and at the top 
level I build the composite map with the modules I'll be using.

Not only does this eliminate those nasty cyclic dependencies, it allows me 
to easily swap different implementations by just changing the choice of 
build functions to call at the top level.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: defrecord in cljc

2016-11-11 Thread William la Forge
To answer my own question, it is because IPrintWithWriter is already 
defined for records. Only define this with deftype.

On Friday, November 11, 2016 at 3:16:46 PM UTC-5, William la Forge wrote:
>
> WARNING: Protocol IPrintWithWriter implemented multiple times at line 9 
> src\simpleArk\rolonRecord.cljc
>
> Any ideas?
>
> (ns simpleArk.rolonRecord)
>
>
> #?(:clj
>(defrecord Rolon-record [rolon-uuid])
>:cljs
>(defrecord Rolon-record [rolon-uuid] ;;this is line 9
>   IPrintWithWriter
>   (-pr-writer [this writer opts]
>   (let [pr-pair (fn [keyval]
> (pr-sequential-writer writer 
> pr-writer "" " " "" opts keyval))]
>(pr-sequential-writer writer pr-pair
>  "#ark/Rolon-record {"
>  ", "
>  "}"
>  opts 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.


defrecord in cljc

2016-11-11 Thread William la Forge
WARNING: Protocol IPrintWithWriter implemented multiple times at line 9 
src\simpleArk\rolonRecord.cljc

Any ideas?

(ns simpleArk.rolonRecord)


#?(:clj
   (defrecord Rolon-record [rolon-uuid])
   :cljs
   (defrecord Rolon-record [rolon-uuid] ;;this is line 9
  IPrintWithWriter
  (-pr-writer [this writer opts]
  (let [pr-pair (fn [keyval]
(pr-sequential-writer writer 
pr-writer "" " " "" opts keyval))]
   (pr-sequential-writer writer pr-pair
 "#ark/Rolon-record {"
 ", "
 "}"
 opts 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: core.async top use cases

2016-10-13 Thread William la Forge
On Thursday, October 13, 2016 at 3:38:16 PM UTC-4, larry google groups 
wrote:
>
> So when to use agents? I've looked through Clojure repos on Github, 
> looking for uses of agents, and I found very few. (I was writing a blog 
> post about concurrency in Clojure, and I found that agents are among the 
> least used tools for concurrency). I found a lot of uses of futures and 
> promises and channels and core.async, and certainly atoms, but I didn't 
> find many uses of agents. When are agents best used? 
>
>>
>>>
When using clojurescript, adding async really increases the load time. 
That's one place where you might want to use agents when you can.
 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: parallel sequence side-effect processor

2016-09-23 Thread William la Forge
I've run into this when I wanted to print each item in a seq. Since println 
returns nil, I just did (first (keep println coll)). --Needed the first 
here because keep returns a lazy seq.

On Friday, September 23, 2016 at 12:02:09 AM UTC-4, Mars0i wrote:
>
> This is almost the same as an issue I raised in this group over a year and 
> a half ago, here 
> .
>   
> I suggested that Clojure should include function with map's syntax but that 
> was executed only for side-effects, without constructing sequences.  No one 
> else was interested--no problem.   It's still bugging me.
>
> It's not map syntax that I care about at this point.  What's bugging me is 
> that there's no standard, built-in way to process multiple sequences for 
> side effects without (a) constructing unnecessary sequences or (b) rolling 
> my own function with loop/recur or something else.
>
> If I want to process multiple sequences for side-effects in the the way 
> that 'for' does, Clojure gives me 'doseq'.  Beautiful.  I can operate on 
> the cross product of the sequences, or filter them in various ways.
>
> If I want to process multiple sequences by applying an n-ary function to 
> the first element of each of n sequences, then to the second element of 
> each sequence, and so on, I can use 'map' or 'mapv', but that means 
> constructing unnecessary collections.
>
> Or I can splice my n sequences together, and make a single sequence of 
> n-tuples, and use doseq to process it.  (There's an example like this on 
> the doseq doc page.)  Or I can process such a sequence with 'reduce'.  More 
> unnecessary collections, though.
>
> Or I can use 'dotimes', and index into each of the collections, which is 
> OK if they're vectors, but ... ugh. why?
>
> Or I can construct my own function using first and rest or first and next 
> on each of my sequences, via loop/recur, for example.   But that seems odd 
> to me.  
>
> Isn't this a common use case?  Is processing multiple sequences for 
> side-effects with corresponding elements in each application so unusual?  
> (Am I the only one?)  Isn't it odd that we have doseq and map but nothing 
> that processes multiple sequences for side-effects, in sequence, rather 
> than as a cross-product?  
>
> (I admit that in my current use case, the sequences are small, so creating 
> a sequence of n-tuples would have only a trivial cost.  It just bugs me, 
> though. :-)
>
> I'd still be OK with something that had a map-like syntax, but my current 
> inclination is that it would be better for such a function to have 
> doseq-style syntax.  The name might be derived from "doseq"--maybe 
> "doseq*". 
>
> (I'd be willing to suggest this in a JIRA ticket, but that doesn't seem 
> reasonable unless there's a call for something like this from more than one 
> person.)
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.async top use cases

2016-09-20 Thread William la Forge
My bad. I was thinking of atomic. Swap! doesn't work with side effects, but 
send does.

On Tuesday, September 20, 2016 at 2:50:53 AM UTC-4, Matan Safriel wrote:
>
> Thanks but I'm not entirely sure about this. I could use agents for side 
> effects too, or at least I thought so. Care to further clarify?
>
>
>  Original Message 
> From:William la Forge 
> Sent:Tue, 20 Sep 2016 02:37:20 +0300
> To:Clojure 
> Subject:Re: core.async top use cases
>
> The really nice thing to me is that async handles side-effects while 
> agents do not.
>
> -- 
> 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 a topic in the 
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/clojure/peJXvE0nBZs/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to 
> clojure+u...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.async top use cases

2016-09-19 Thread William la Forge
The really nice thing to me is that async handles side-effects while agents 
do not.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Hoplon with websockets

2016-08-07 Thread William la Forge
A little documentation never hurt: 
https://github.com/hoplon/hoplon/wiki/Hoplon-with-Sente

On Friday, August 5, 2016 at 4:48:04 PM UTC-4, William la Forge wrote:
>
> I've added a new demo to hoplon which uses sente websockets in place of 
> castra: https://github.com/hoplon/demos/tree/master/ws-simple#readme
>
> The demo is similar to the castra-simple demo, where the client requests 
> and then displays a series of random numbers that are generated by the 
> server. The main difference here is that castra server responses had to be 
> synchronous, while websocket pushes from the server need not be.
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


Hoplon with websockets

2016-08-05 Thread William la Forge
I've added a new demo to hoplon which uses sente websockets in place of 
castra: https://github.com/hoplon/demos/tree/master/ws-simple#readme

The demo is similar to the castra-simple demo, where the client requests 
and then displays a series of random numbers that are generated by the 
server. The main difference here is that castra server responses had to be 
synchronous, while websocket pushes from the server need not be.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: more minimal clojurescript intro/app

2016-04-13 Thread William la Forge
I've never learned javascript and had hoped that clojurescript would make 
it easy. Much to my delight, I found that hoplon let me write everything in 
a single language and not have to worry about how html/js are joined.

Love Hoplon!

https://github.com/hoplon/hoplon

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] components.md

2016-04-07 Thread William la Forge
Ah, discussions which do not define terms are subject to endless round and 
rounds.

I see several characteristics of a component. The first is that there is a 
lifecycle. A component may need to be opened and closed.

The second is that components are not singletons. So you can have multiple 
instances of a component that can be configured differently.

Third, a component implements protocols/interfaces and access other 
components via their protocols/interfaces.

And most important, the other components that a component depends on are 
configurable. In java, it would mean injecting one or more component 
factories into a component.

Given this, any automation of the initialization process will have limited 
use.

This is why I believe in ultra-light components, where the component close 
frees up the links between a component and the component it depends on. Now 
you can have variants where some types of components can only be used/owned 
by one other component and other types of components need to maintain a 
reference count to control when they automatically close. But the second 
case is something I have never needed and is usually handled by separating 
ordinary components from framework components.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 library

2016-04-01 Thread William la Forge
OK, here is an older library project that uses 
lein: https://github.com/laforge49/aatree

So I guess that covers all the bases. Personally I find boot to be amazing. 
And easy to use.

Bill

On Friday, April 1, 2016 at 8:19:46 PM UTC-4, William la Forge wrote:
>
> OOps. Here's the link: https://github.com/aatree/aautil/
>
> On Friday, April 1, 2016 at 8:19:01 PM UTC-4, William la Forge wrote:
>>
>> Here is a sample library which works the way you are asking. It uses 
>> boot, but then you didn't specify what build tool you wanted to use. :-)
>>
>> On Friday, April 1, 2016 at 9:33:45 AM UTC-4, Fernando Abrao wrote:
>>>
>>> Hello all,
>>>
>>> What is the best way to create a lib for internal propose, that generate 
>>> a jar file with .clj sources instead of .class, like it is in the libs from 
>>> clojars? My idea is to create a lib (jar) common for all projects. Another 
>>> idea is welcome.
>>>
>>> Regards,
>>>
>>> Fernando
>>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 library

2016-04-01 Thread William la Forge
Here is a sample library which works the way you are asking. It uses boot, 
but then you didn't specify what build tool you wanted to use. :-)

On Friday, April 1, 2016 at 9:33:45 AM UTC-4, Fernando Abrao wrote:
>
> Hello all,
>
> What is the best way to create a lib for internal propose, that generate a 
> jar file with .clj sources instead of .class, like it is in the libs from 
> clojars? My idea is to create a lib (jar) common for all projects. Another 
> idea is welcome.
>
> Regards,
>
> Fernando
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 library

2016-04-01 Thread William la Forge
OOps. Here's the link: https://github.com/aatree/aautil/

On Friday, April 1, 2016 at 8:19:01 PM UTC-4, William la Forge wrote:
>
> Here is a sample library which works the way you are asking. It uses boot, 
> but then you didn't specify what build tool you wanted to use. :-)
>
> On Friday, April 1, 2016 at 9:33:45 AM UTC-4, Fernando Abrao wrote:
>>
>> Hello all,
>>
>> What is the best way to create a lib for internal propose, that generate 
>> a jar file with .clj sources instead of .class, like it is in the libs from 
>> clojars? My idea is to create a lib (jar) common for all projects. Another 
>> idea is welcome.
>>
>> Regards,
>>
>> Fernando
>>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] aatree/aautil release 0.0.8 (a cljc library containing snippets of useful code): building on octet

2016-03-10 Thread William la Forge
Added buffer. Buffer builds on the funcool/octet project, adding a number 
of capabilities from java.nio.bytebuffer while supporting the extensible 
specs from octet. See https://github.com/aatree/aautil#buffer

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: ClojureScript sequence implementation does not print

2016-03-05 Thread William la Forge
I found what I needed. In cljs.core we have this

(extend-protocol IPrintWithWriter ...)


Which defines how to print various sequences.




On Friday, March 4, 2016 at 8:07:29 PM UTC-5, William la Forge wrote:
>
> I've implemented sequences in Clojure with no problems. But I'm a lot 
> weaker when it comes to clojurescript!
>
> When I create an instance of my own sequence type, CountedSequence, and 
> try to print it, all I get is
>
> #object[durable.CountedSequence.CountedSequence]
>
> Here's the code: 
> https://github.com/aatree/aademos/blob/master/durable/src/cljs/durable/CountedSequence.cljs
>
> I've tried modeling it on cljs.core/IndexedSeq, but to no avail.
>
> Any hints would be appreciated. Thanks!
>

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


ClojureScript sequence implementation does not print

2016-03-04 Thread William la Forge
I've implemented sequences in Clojure with no problems. But I'm a lot 
weaker when it comes to clojurescript!

When I create an instance of my own sequence type, CountedSequence, and try 
to print it, all I get is

#object[durable.CountedSequence.CountedSequence]

Here's the 
code: 
https://github.com/aatree/aademos/blob/master/durable/src/cljs/durable/CountedSequence.cljs

I've tried modeling it on cljs.core/IndexedSeq, but to no avail.

Any hints would be appreciated. Thanks!

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


Re: How to compile with optimizations none when using web workers

2016-02-19 Thread William la Forge
Thomas,

Your worker demo includes the entire cljs runtime as part of the 
project? 
https://github.com/thheller/worker-example/tree/master/demo/js/cljs-runtime

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 compile with optimizations none when using web workers

2016-02-19 Thread William la Forge
Thomas,

Have you seen this? A simple demo using workers in 
clojurescript: https://github.com/MarcoPolo/Servant
I've converted the demo to use 
boot: https://github.com/aatree/aademos/tree/master/servant-demo


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 compile with optimizations none when using web workers

2016-02-19 Thread William la Forge
Thomas,

Modules looks quite exciting. I would be glad to help in developing a boot 
task for same.

Bill 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 compile with optimizations none when using web workers

2016-02-19 Thread William la Forge


Compiling with optimizations none is no doubt quite handy, especially in 
conjunction with source maps, as a traceback will take you to the line of 
code causing the problems, and with the same variable names used in your 
original clojurescript code. But this is not currently possible for .jc 
files used by web workers as the unoptimized .js file contains a reference 
to js/window--and window does not exist in a web worker.


You should still be able to use optimizations none with your main 
javascript code, but you will need to compile your main code and your web 
worker code separately so that you can use different optimizations as 
appropriate. And you can do this so long as your not using shared workers. 
The question then is, how to compile the .js files separately.

The duracell  demo 
uses a web worker AND is itself compiled with optimizations none. There are 
two things done to accomplish this:

   1. Duracell itself has no web worker code. Though it uses a library, 
   durable-cells , which includes 
   a web worker.
   2. In the duracell build.boot 
    file, 
   the dev task uses pandeiro/boot-http 
    rather than the simpler 
   tailrecursion/boot-jetty . 
   The advantage to using boot-http is that it supports the loading of static 
   files from library jar files. In this case, that means the main code in 
   aaworker can create a web worker using durable-cell's dcells.js file.

So how does the durable-cells library create the dcells.js file? Again, 
there are two things done to accomplish this:

   1. In the durable-cells build.boot 
    file, 
   the dev task includes (cljs :optimizations :simple). This invokes the 
   compiler with an appropriate level of optimizations.
   2. But we still need to define the .js file. This is done in the 
   dcells.cljs.edn 
   

 file. 
   See Multiple Builds 
    for 
   more information on cljs.edn files.

>From https://github.com/aatree/aaworker/wiki/Compiling-with-Optimizations-None

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


record implementing interface with boolean signature, how to???

2016-02-03 Thread William la Forge
Having a bit of a problem implementing the IAtom interface in a record. 
Specifically, this is the signature giving me grief:

boolean compareAndSet(Object oldv, Object newv);

This isn't the answer:

(^boolean compareAndSet [oldv newv] ... )


I get "Can't define method not in interfaces: compareAndSet".

Any ideas? Thanks!

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


Re: record implementing interface with boolean signature, how to???

2016-02-03 Thread William la Forge
Forgot the this parameter. Sorry. Please ignore. :-(

On Wednesday, February 3, 2016 at 3:18:34 PM UTC-5, William la Forge wrote:
>
> Having a bit of a problem implementing the IAtom interface in a record. 
> Specifically, this is the signature giving me grief:
>
> boolean compareAndSet(Object oldv, Object newv);
>
> This isn't the answer:
>
> (^boolean compareAndSet [oldv newv] ... )
>
>
> I get "Can't define method not in interfaces: compareAndSet".
>
> Any ideas? Thanks!
>
>

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


Re: record implementing interface with boolean signature, how to???

2016-02-03 Thread William la Forge
Here's the interface I'm 
overriding: 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IAtom.java

And I'm using clojure 1.8.0.

Oh. Interesting. I was using cursive for compiling, but switched to boot. 
Getting some interesting warnings now too:

WARNING: Bad method signature in protocol implementation, IDeref does not 
declare method called deref at line 90 src\cljc\aautil\dewdrop.cljc
WARNING: Bad method signature in protocol implementation, IAtom does not 
declare method called reset at line 90 src\cljc\aautil\dewdrop.cljc
WARNING: Bad method signature in protocol implementation, IAtom does not 
declare method called swap at line 90 src\cljc\aautil\dewdrop.cljc
WARNING: Bad method signature in protocol implementation, IAtom does not 
declare method called compareAndSet at line 90 src\cljc\aautil\dewdrop.cljc
 clojure.lang.ExceptionInfo: 
java.lang.IllegalArgumentException: Can't define method not in interfaces: 
compareAndSet, compiling:(aautil/dewdrop.cljc:90:1)
data: {:file
  
 "C:\\Users\\Bill\\AppData\\Local\\Temp\\boot.user1581043804101612299.clj",
   :line 31}
java.util.concurrent.ExecutionException: 
java.lang.IllegalArgumentException: Can't define method not in interfaces: 
compareAndSet, compiling:(aautil/dewdrop.cljc:90:1)


So here's the whole thing:

(ns aautil.dewdrop
  #?(:clj (:require [clojure.string :as str]
[clojure.edn :refer [read-string]])
 :cljs (:require [clojure.string :as str]
 [cljs.reader :refer [read-string]]))
  #?(:clj (:refer-clojure :exclude [read-string]))
  #?(:clj (:import (clojure.lang IDeref IAtom

(defn new-lens
  "Create a new lens."
  [getter setter]
  {:getter getter :setter setter})

(defn lget
  "Extract an item from some data.
  Returns the extracted item."
  [lens data]
  ((:getter lens) data))

(defn lderef
  "Extract an item from data held by an atom.
  Returns the extracted item."
  [lens data-atom]
  (lget lens @data-atom))

(defn lset!
  "Revise some data with an item.
  Returns the revised data."
  [lens data item]
  ((:setter lens) data item))

(defn lreset!
  "Revise some data held by an atom with an item.
  Returns the revised data."
  [lens data-atom item]
  (reset! data-atom (lset! lens @data-atom item)))

(defn lupd!
  "Update an item in some data.
  Returns the revised data."
  [lens data f]
  (lset! lens data (f (lget lens data

(defn lswap!
  "Update an item in some data held by an atom.
  Returns the revised data."
  [lens data-atom f]
  (swap! data-atom
 (fn [data]
   (lupd! lens data f

(defn lcomp
  "Combine a lens with another."
  [left right]
  {:getter
   (fn [data] (lget left (lget right data)))
   :setter
   (fn [data item]
 (let [right-data (lget right data)
   left-data (lset! left right-data item)]
   (lset! right data left-data)))})

(defn key-lens
  "Builds a lens using get and assoc"
  [key]
  {:getter (fn [data] (get data key))
   :setter (fn [data item] (assoc data key item))})

(defn atom-key-lens
  "Builds a lens using get and assoc"
  [key-atom]
  {:getter (fn [data] (get data @key-atom))
   :setter (fn [data item] (assoc data @key-atom item))})

;A lens built using read-string and pr-str.
(def edn-lens
  {:getter read-string
   :setter (fn [_ item] (pr-str item))})

(defn printing-lens
  "A lens for debugging"
  [id]
  {:getter (fn [item]
 (println id :got item)
 item)
   :setter (fn [data item]
 (println id :set data item)
 item)})

(defrecord lens-view [lens data-atom]
  IDeref
  (deref [this] (lderef lens data-atom))
  IAtom
  (reset [this item] (lreset! lens data-atom item))
  (swap [this f] (lswap! lens data-atom f))
  (swap [this f arg]
(swap! data-atom
   (fn [data]
 (lset! lens data (f (lget lens data) arg)
  (swap [this f arg1 arg2]
(swap! data-atom
   (fn [data]
 (lset! lens data (f (lget lens data) arg1 arg2)
  (swap [this f x y args]
(swap! data-atom
   (fn [data]
 (lset! lens data (apply f (lget lens data) x y args)
  (^Boolean compareAndSet [oldv newv]
(swap! data-atom
   (fn [data]
 (let [v (lget lens data)]
   (if (= oldv v)
 (lset! lens data newv)
 data)
  )

(defn lview [lens data-atom]
  (->lens-view lens data-atom))


On Wednesday, February 3, 2016 at 3:18:34 PM UTC-5, William la Forge wrote:
>
> Having a bit of a problem implementing the IAtom interface in a record. 
> Specifically, this is the signature giving me grief:
>
> boolean compareAndSet(Object oldv, Object newv);
>
> This isn't the answer:
>
> (^boolean compareAndSet [oldv newv] ... )
>
>
> I get "Can't define method not in interfaces: compareA

Re: record implementing interface with boolean signature, how to???

2016-02-03 Thread William la Forge
The hint seems to have no effect.

On Wednesday, February 3, 2016 at 3:28:44 PM UTC-5, Gregg Reynolds wrote:
>
>
> On Feb 3, 2016 2:18 PM, "William la Forge" <lafo...@gmail.com 
> > wrote:
> >
> > Having a bit of a problem implementing the IAtom interface in a record. 
> Specifically, this is the signature giving me grief:
> >
> > boolean compareAndSet(Object oldv, Object newv);
> >
> > This isn't the answer:
> >
> > (^boolean compareAndSet [oldv newv] ... )
> >
>
> ^Boolean?
>
> >
> > I get "Can't define method not in interfaces: compareAndSet".
> >
> > Any ideas? Thanks!
> >
> > -- 
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clo...@googlegroups.com 
> 
> > Note that posts from new members are moderated - please be patient with 
> your first post.
> > To unsubscribe from this group, send email to
> > clojure+u...@googlegroups.com 
> > For more options, visit this group at
> > http://groups.google.com/group/clojure?hl=en
> > --- 
> > You received this message because you are subscribed to the Google 
> Groups "Clojure" group.
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to clojure+u...@googlegroups.com .
> > For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: compare-and-set deep value in hashmap atom

2016-02-01 Thread William la Forge
The easy way is the big atom approach. Put the entire structure in an atom 
and use swap! to make updates.

First, the function passed to swap! should be free of side-effects, as 
swap! may need to call it more than once in the case of a collision.

Second, within the function passed to swap! is where you check to see if 
the resource is available. If it is, you take it. Otherwise not.

Now as for suitability. Note that the function passed to swap! must return 
the replacement value of your immutable structure. So it important
that your structure records who got the resource being requested. And it 
looks like your structure handles that.

No need to use compare and set. The swap! function is good enough. It is 
really a convenience function layered over compare-and-set.
Sometimes swap! is not powerful enough, which is when you use 
compare-and-set.

On Monday, February 1, 2016 at 7:29:39 AM UTC-5, Jeremy Vuillermet wrote:
>
> Hello,
>
> I'm making a game where players can choose a box in a grid to discover 
> what's behind it.
>
> My data structure is an atom with {:grid-size 5, :picks {5 "player1}} 
> where 5 is the box position in the grid.
>
> How can I be sure that two players can't pick the same box. From my 
> understanding, checking the box and then swaping if the box is free is not 
> enough.
> So I guessed I should use compare and set but I only understand how it 
> works with simple atom like (atom 1).
>
> 2 questions then : Is my data structure adapted for that ?
>
> How to compare and set only for a nested path like [:picks 5] ?
>
> Thanks
>

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


Re: compare-and-set deep value in hashmap atom

2016-02-01 Thread William la Forge
True, but very bad practice. Better to check after the swap! completes to
see if it was successful and then send the notifications.

If you do the notifications within the swap! function, you are holding the
atom for longer than need be and increasing the chance of contention.
Contention means that the other contenders keep looping until they are able
to acquire the atom. And that means a potentially significant increase in
overhead. compare-and-set! and swap! only work well when the number of
contenders is small, and a slow swap! function increases the chance of
having other contenders more frequently.

When contention is high, atoms are a poor choice. That's when you switch
over to something like async.core. :-)

On Mon, Feb 1, 2016 at 10:48 AM, Jeremy Vuillermet <
jeremy.vuiller...@gmail.com> wrote:

> That's very clear thank you. Some follow up questions:
>
> In my case, I still need to notify every player that the resource is not
> available anymore and that is a side effect.
> Should I just make it idempotent so it doesn't matter if it's called more
> than once.
>
> If I check for the resource within the function passed to swap! and do my
> side effect only when it's available, It should not happen more than once,
> right ?
>
> On Mon, Feb 1, 2016 at 3:27 PM, William la Forge <laforg...@gmail.com>
> wrote:
>
>> The easy way is the big atom approach. Put the entire structure in an
>> atom and use swap! to make updates.
>>
>> First, the function passed to swap! should be free of side-effects, as
>> swap! may need to call it more than once in the case of a collision.
>>
>> Second, within the function passed to swap! is where you check to see if
>> the resource is available. If it is, you take it. Otherwise not.
>>
>> Now as for suitability. Note that the function passed to swap! must
>> return the replacement value of your immutable structure. So it important
>> that your structure records who got the resource being requested. And it
>> looks like your structure handles that.
>>
>> No need to use compare and set. The swap! function is good enough. It is
>> really a convenience function layered over compare-and-set.
>> Sometimes swap! is not powerful enough, which is when you use
>> compare-and-set.
>>
>>
>> On Monday, February 1, 2016 at 7:29:39 AM UTC-5, Jeremy Vuillermet wrote:
>>>
>>> Hello,
>>>
>>> I'm making a game where players can choose a box in a grid to discover
>>> what's behind it.
>>>
>>> My data structure is an atom with {:grid-size 5, :picks {5 "player1}}
>>> where 5 is the box position in the grid.
>>>
>>> How can I be sure that two players can't pick the same box. From my
>>> understanding, checking the box and then swaping if the box is free is not
>>> enough.
>>> So I guessed I should use compare and set but I only understand how it
>>> works with simple atom like (atom 1).
>>>
>>> 2 questions then : Is my data structure adapted for that ?
>>>
>>> How to compare and set only for a nested path like [:picks 5] ?
>>>
>>> Thanks
>>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to a topic in the
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/clojure/X59ZTmPQhZ0/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.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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 fro

Re: [ANN] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread William la Forge
Ah, but my understanding is that the hoplon template itself does not work. 
Micha made a fix some time back to the handler wrapper order--it was 
backwards in the template, but can not himself release it to clojars.

>From the hoplon channel:
>
>

levitanong  *[*10:56 AM*]* 
 @laforge49 
, @flyboarder 
, I figured out what the 
problem was. It wasn’t with my code! (refresher: My problem is the thing 
with `*session*` not working as expected) Turns out the problematic bit was 
the handler, as generated by `lein new hoplon-castra`.

```(def app
  (-> app-routes
  (d/wrap-defaults d/api-defaults)
  (castra/wrap-castra-session "a 16-byte secret")
  (castra/wrap-castra 'thingy.api)))
```


If I rearrange it by moving the form up to the top like so:

```(def app
  (-> app-routes
  (castra/wrap-castra 'thingy.api)
  (d/wrap-defaults d/api-defaults)
  (castra/wrap-castra-session "a 16-byte secret")))
```


`*session*` suddenly works. Which is great, except I don’t exactly know why 
this is causing the screwup. Do you guys have any idea?(edited)

flyboarder  *[*10:58 AM*]* 
 Could be 
something else interacting with session, in the stack
*[*10:58*]* 
 
I have all my Castra forms up top and wrap defaults last

levitanong  *[*10:58 AM*]* 
 hmm
*[*10:58*]* 
 
thing is, when i apply that to the demos
*[*10:59*]* 
 
sessions stop working
*[*10:59*]* 
 
i mean, when i use the arrangement as in the hoplon castra template, the 
demo breaks
*[*10:59*]* 
 
specifically, castra-chat

flyboarder  *[*11:01 AM*]* 
 That may 
be something we need to fix in the template, I'm not sure who usually works 
on that but I'm sure they are open to a PR

levitanong  *[*11:12 AM*]* 
 @flyboarder 
: Do you think I should file 
an issue somewhere, like the hoplon castra repo? After all, you seem to 
think the order shouldn’t matter much. Or perhaps I should tag micha or 
alan?

micha  *[*11:27 AM*]* 
 hello
*[*11:28*]* 
 
@levitanong : the order in 
which middleware are applied definitely matters

laforge49  *[*11:28 AM*]* 
 On advice 
from micha,, I have this which works:
 (-> app-routes
 (castra/wrap-castra
   'castra-notify-chat.chat-api
   'castra-notify-chat.user-api
   'notify.notification-api)
 (castra/wrap-castra-session "a 16-byte secret")
 (d/wrap-defaults d/api-defaults)))
So like @flyboarder  I have 
defaults on the bottom. And like @levitanong 
 's arrangement that works, I 
have wrap castra thingie on top.
The actual problem is that the template is backwards because -> reverses 
the order.

micha  *[*11:28 AM*]* 
 because 
it's a pipeline, each layer adding information for the subsequent layers to 
use
*[*11:29*]* 
 

```(-> foo bar baz) ; is the same as:
(baz (bar foo))
```

(edited)
*[*11:29*]* 
 
so the order definitely matters

laforge49  *[*11:30 AM*]* 

Re: [ANN] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread William la Forge
 
levitanong  *[*11:30 AM*]* 
 yay I’m 
not crazy!
1 

*[*11:30*]* 
 
thanks, @micha , @laforge49 
  and @flyboarder 


micha  *[*11:30 AM*]* 
 :+1:
*[*11:30*]* 
 
i thought i fixed the lein template, no?

laforge49  *[*11:31 AM*]* 
 doesn't 
look like it.

micha  *[*11:31 AM*]* 
 i think i 
didn't have permission to push it to clojars
*[*11:31*]* 
 
but the git repo should be fixed



-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread William la Forge
Heres the rest...


levitanong  *[*11:12 AM*]* 
 @flyboarder 
: Do you think I should file 
an issue somewhere, like the hoplon castra repo? After all, you seem to 
think the order shouldn’t matter much. Or perhaps I should tag micha or 
alan?

micha  *[*11:27 AM*]* 
 hello
*[*11:28*]* 
 
@levitanong : the order in 
which middleware are applied definitely matters

laforge49  *[*11:28 AM*]* 
 On advice 
from micha,, I have this which works:
 (-> app-routes
 (castra/wrap-castra
   'castra-notify-chat.chat-api
   'castra-notify-chat.user-api
   'notify.notification-api)
 (castra/wrap-castra-session "a 16-byte secret")
 (d/wrap-defaults d/api-defaults)))
So like @flyboarder  I have 
defaults on the bottom. And like @levitanong 
 's arrangement that works, I 
have wrap castra thingie on top.
The actual problem is that the template is backwards because -> reverses 
the order.

micha  *[*11:28 AM*]* 
 because 
it's a pipeline, each layer adding information for the subsequent layers to 
use
*[*11:29*]* 
 

```(-> foo bar baz) ; is the same as:
(baz (bar foo))
```

(edited)
*[*11:29*]* 
 
so the order definitely matters

laforge49  *[*11:30 AM*]* 
 So where 
do I file the issue? :simple_smile:

levitanong  *[*11:30 AM*]* 
 yay I’m 
not crazy!
1 

*[*11:30*]* 
 
thanks, @micha , @laforge49 
  and @flyboarder 
(edited)

micha  *[*11:30 AM*]* 
 :+1:
*[*11:30*]* 
 
i thought i fixed the lein template, no?

laforge49  *[*11:31 AM*]* 
 doesn't 
look like it.

micha  *[*11:31 AM*]* 
 i think i 
didn't have permission to push it to clojars
*[*11:31*]* 
 
but the git repo should be fixed

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] aautil 0.0.3--lightweight cljc lenses

2016-01-26 Thread William la Forge
AAUTIL is a collection of cljc snippets intended to make writing cljc code 
easier. It includes code for logging, ultra-light component lifecycle 
support, and now lenses.
https://github.com/aatree/aautil

For each snippet there is also a demo written using hoplon.
https://github.com/aatree/aademos

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Pattern for service with multiple clients using two-way channels?

2016-01-07 Thread William la Forge
So use a mixed approach.

Queries are likely best handled by including a return channel with the
request.

Updates are likely best handled with a flow approach.

Complex queries may involve passing a return channel deeper into the
process. Especially notification requests.

No one answer is best for all, as usual. But keep simple things simple.

Bill

On Thu, Jan 7, 2016 at 11:16 AM, Vic Putz  wrote:

> Thanks to both of you!
>
> On Wednesday, January 6, 2016 at 10:11:39 PM UTC, tbc++ wrote:
>>
>> Most would perhaps start with the classic approach of having each request
>> contain a :reply-to channel that the responses go into, but I think this is
>> a mistake.
>>
>> IMO, there are two main ways of building systems with core.async 1)
>> request/response. 2) dataflow graphs.
>>
>
> I like the dataflow-graph approach, because I don't like the idea of
> conflating routing with messages that a "sender" or "reply-to" within the
> message requires (though William, I hadn't thought of just putting the
> channel itself as reply-to... great idea if I go that route and much
> simpler than dropping into pub/sub).  So I'd rather the service just
> have "in" and "out" channels and have the wiring be done externally
> (probably through initialization via "component").
>
> And if the components were wired together 1-to-1, that would be dead
> easy.  I'm just not sure how to deal with a component/service which should
> be able to handle multiple in-out connections ... my naïve approach would
> probably just be for services to have a vector of in/out connection pairs
> that got wired up at initialization and maybe go-loops over all of them,
> which would probably work but seems mildly inelegant somehow.
>
> (again, using the toy application of a jukebox service and three
> clients... the clients can't request a song until they know what songs are
> available, so bidirectional communication seems necessary somehow; I can't
> see how to design a wiring diagram without 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/_8fHJ3J-MYg/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.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Pattern for service with multiple clients using two-way channels?

2016-01-06 Thread William la Forge
Let each request carry the callback channel. It is then the requestor's 
option to reuse a channel for multiple requests or to open one for each 
request or some combination.

For example, some requests might get a lot of responses and the requestor 
may need to close the channel before getting them all. Obviously in this 
case you would want the request to have its own dedicated channel.

In general I'd start with one channel per request and then optimize as 
needed. :-)

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


Re: clojars down?

2016-01-02 Thread William la Forge
So nice to see clojars working, at least for the moment.

Retrieving pod-2.5.5.jar from https://clojars.org/repo/
Retrieving core-2.5.5.jar from https://clojars.org/repo/
Retrieving worker-2.5.5.jar from https://clojars.org/repo/
Retrieving aether-2.5.5.jar from https://clojars.org/repo/
Retrieving boot-cljs-1.7.48-3.jar from https://clojars.org/repo/
Retrieving bootlaces-0.1.10.jar from https://clojars.org/repo/

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] dewdrop 0.1.0 -- lenses made simple(r?)

2016-01-02 Thread William la Forge
For me, Dewdrop is an exercise to help me understand lenses. Specter speaks 
my language in terms of speed of implementation without apologies to the 
functionally bent.

Bill

On Saturday, January 2, 2016 at 8:04:30 AM UTC-5, JeremyS wrote:
>
> Hey guys,
>
> I might be besides the point but, have you played with specter 
>  ? It seems to me that it's worth 
> investigating when going the lens route. 
> What's your take on it ?
>
>
> Cheers,
>
> Jeremy.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] dewdrop 0.1.0 -- lenses made simple(r?)

2016-01-01 Thread William la Forge
Hi again Andrey!

Not to drag this out, but you seem to have missed my main point, which also 
means that I failed to make it. :-)

Understanding how comp works and seeing the function, lens, for defining a 
cat's lens, it is not at all obvious how a cat's lens works. On the other 
hand, the dewdrop lens constructor simply creates a record. And a quick 
review of the code for dewdrop's ladd shows clearly how dewdrop lenses are 
composed. Dewdrop then allows a developer to leverage ones own intuition. 
So a developer may quickly pick up on how to use cat, but must trust that 
any bugs lie in that developer's own code. Or perhaps take time to learn 
how a cat lens works at 3 AM when the servers are crashing. Not likely, 
I'll grant you. But I prefer not to have to trust in magic when I have a 
choice. Too often such magic has a domain that is a bit different than what 
I was expecting. Not understanding how something works, I usually lack a 
similar understanding as to when I should or should not use it.

Keep in mind also that clojure has a lot more than just functions, and 
composition applies to a lot more things than just functions as well. 
Indeed, my favorite technique is compositions of bags of properties serving 
in place of objects. So learning how to call a method to compose two 
records is hardly a stretch and well worth the price for being able to 
understand what is going on internally.

On Friday, January 1, 2016 at 3:35:29 PM UTC-5, Andrey Antukh wrote:
>
>
>
> On Fri, Jan 1, 2016 at 9:53 PM, William la Forge <lafo...@gmail.com 
> > wrote:
>
>> Andrey,
>>
>> This is where I have a problem. Ii could have implemented dewdrop lenses 
>> as functions that could be composed. But the code would be harder to 
>> understand and possibly be slower. I just do not see the point.
>>
>
> I agree with your main argument, but I don't know how using records makes 
> thinks more easy understandable in this concrete case and how using 
> functions over records will make code slower. Transducers has a performance 
> improvements over classical transformation compositions, and in this case, 
> the cats lenses leverage the same technique.
>  
>
>>
>> Implementing dewdrop lenses as records makes it dirt simple for anyone to 
>> create more kinds of lenses. And the ladd function to create a new record 
>> with the composed getter and setter functions is pretty clean as well.
>>
>
> Yes but it implies more api to know, that is not bad but if you limit the 
> set of new api that one should learn/use, will contribute to more familiar 
> and easy api. Adding new api also implies more time to understand it and 
> remember when it should be used.
>  
>
>>
>> Isn't it more important to have code you can analyze easily, and which 
>> even a novice clojurist like myself can embrace and enhance a whole lot 
>> more important than being able to say that we can use comp to compose these 
>> lenses???
>>
>
> Yes, I agree with you, the code readability is very very important. But 
> this concrete case I don't found big differences in code readability:
>
> ;; dewdrop
> (defn key-lens [k]
>   (lens.
> (fn [d] (get d k))
> (fn [d v] (assoc d k v
>
> ;; cats
> (defn key
>   [k]
>   (lens 
>(fn [s] (get s k))
>(fn [s f] (update s k f
>
> The code is mostly the same...
>
>
>> I see good engineering as leveraging computer science so the programming 
>> grunts can make effective use of it. Programming is real grunt work, after 
>> all. No matter how much you dress it up, we all needs must get our hands 
>> dirty and put our backs into it.
>>
>
> My two cents.
> Andrey 
>
>>
>> Bill
>>
>> On Friday, January 1, 2016 at 9:09:08 AM UTC-5, Andrey Antukh wrote:
>>>
>>> Hi!
>>>
>>> I have read the readme and I don't found a big evidence of something 
>>> wrong so, nice work! 
>>> Furthermore, do you know about https://github.com/funcool/cats ? It has 
>>> a lens and traversable implementation for clj/cljs. You can read the 
>>> related documentation here: http://funcool.github.io/cats/latest/#lens 
>>> . 
>>>
>>> You can found that lenses, using cats approach, are working just like 
>>> transducers (function composition), you do not need any special function 
>>> for combine lenses, just use comp. One of the readme examples (from 
>>> your repository) that combines two lenses, in cats can be written in this 
>>> way:
>>>
>>> (require '[cats.labs.lens :as l])
>>> (def xy-lens (comp (l/key :x) (l/key :y))
>>> ;; Or just use (l/in [:x :y])
>>&g

Re: [ANN] dewdrop 0.1.0 -- lenses made simple(r?)

2016-01-01 Thread William la Forge
Andrey,

This is where I have a problem. Ii could have implemented dewdrop lenses as 
functions that could be composed. But the code would be harder to 
understand and possibly be slower. I just do not see the point.

Implementing dewdrop lenses as records makes it dirt simple for anyone to 
create more kinds of lenses. And the ladd function to create a new record 
with the composed getter and setter functions is pretty clean as well.

Isn't it more important to have code you can analyze easily, and which even 
a novice clojurist like myself can embrace and enhance a whole lot more 
important than being able to say that we can use comp to compose these 
lenses???

I see good engineering as leveraging computer science so the programming 
grunts can make effective use of it. Programming is real grunt work, after 
all. No matter how much you dress it up, we all needs must get our hands 
dirty and put our backs into it.

Bill

On Friday, January 1, 2016 at 9:09:08 AM UTC-5, Andrey Antukh wrote:
>
> Hi!
>
> I have read the readme and I don't found a big evidence of something wrong 
> so, nice work! 
> Furthermore, do you know about https://github.com/funcool/cats ? It has a 
> lens and traversable implementation for clj/cljs. You can read the related 
> documentation here: http://funcool.github.io/cats/latest/#lens . 
>
> You can found that lenses, using cats approach, are working just like 
> transducers (function composition), you do not need any special function 
> for combine lenses, just use comp. One of the readme examples (from your 
> repository) that combines two lenses, in cats can be written in this way:
>
> (require '[cats.labs.lens :as l])
> (def xy-lens (comp (l/key :x) (l/key :y))
> ;; Or just use (l/in [:x :y])
>
> (l/focus xy-lens {:x {:y 1}})
> ;; => 1
> (l/over xy-lens inc {:x {:y 1}})
> ;; => {:x {:y 2}}
>
> Happy new year!
> Andrey
>
> On Fri, Jan 1, 2016 at 2:54 PM, William la Forge <lafo...@gmail.com 
> > wrote:
>
>> I've been looking at lenses and while it looks pretty simple and very 
>> useful, I had a hard time getting it. So I came up with my own take on 
>> lenses. https://github.com/laforge49/dewdrop#readme
>>
>> So perhaps I still do not understand lenses and what I've done is wrong. 
>> Or perhaps having been through the exercise I'm now getting it and what 
>> I've done is no simpler than what everyone else has done. Or perhaps I've 
>> just described things with fewer technical terms.
>>
>> So I'd appreciate it if you would review this very short document and 
>> tell me what I don't understand. Or that I've actually done something 
>> worthwhile with lenses???
>>
>> Thanks!
>> Bill
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> Andrey Antukh - Андрей Антух - <ni...@niwi.nz >
> http://www.niwi.nz
> https://github.com/niwinz
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] dewdrop 0.1.0 -- lenses made simple(r?)

2016-01-01 Thread William la Forge
I've been looking at lenses and while it looks pretty simple and very 
useful, I had a hard time getting it. So I came up with my own take on 
lenses. https://github.com/laforge49/dewdrop#readme

So perhaps I still do not understand lenses and what I've done is wrong. Or 
perhaps having been through the exercise I'm now getting it and what I've 
done is no simpler than what everyone else has done. Or perhaps I've just 
described things with fewer technical terms.

So I'd appreciate it if you would review this very short document and tell 
me what I don't understand. Or that I've actually done something worthwhile 
with lenses???

Thanks!
Bill

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Can I use Clojure to build a mobile chat application?

2015-12-29 Thread William la Forge
Here's a chat demo written in 
clojure/clojurescript: https://github.com/hoplon/demos/tree/master/castra-chat

It is a pretty basic starting point, but it does show how to do a reactive 
(mobile compatible) web chat. And for a school project it is likely fine.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] hoplon/notify release 0.0.1

2015-12-26 Thread William la Forge
Notify is focused on sending server-side notifications to the client for 
applications building on hoplon and castra. The idea is to have a single 
poll loop (for now) and to send changes (in the form of notifications) 
rather than snapshots of server state. Notifications are sequenced and sent 
in batches; acknowledgements are for a given notification and for all prior 
notifications.


   - https://github.com/hoplon/notify
   - http://clojars.org/hoplon/notify
   - https://github.com/hoplon/demos/tree/master/castra-simple2
   

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] hoplon/notify release 0.0.1

2015-12-26 Thread William la Forge
OOPS! Manifest error.

Released as 0.0.2. Tested the result. Everything runs again.

Also defined a deploy-release task in boot.build to make releasing a bit 
easier. The release is a tad non-standard because of the need to include a 
.hl file.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] aatree release 0.6.1--Db-chan, Null-db-cache and LRU-db-cache

2015-12-11 Thread William la Forge
The aatree project provides fully compatible alternatives to Clojure 
sorted-map, sorted-set and vector, with several extensions:
  - AAVector supports add/drop at any point using addn and dropn.
  - AAMap and AASet implement Reversible, Counted, Indexed and Sorted
  - CountedSequence implements Counted and do not use synchronized.
  - Lazy deserialization/reserialization provides ridiculously fast 
deserialize/update/reserialize processing typical of disk access.
  - Virtual Structures that can be larger than memory.

New in Release 0.6.1:

   - Calf and Yearling now use the db chan trait in place of the db agent 
   trait by default.
   - Yearling now uses the lru db cache trait by default but also works 
   with the null db cache trait.
   
For more information about traits, see the AATree API 
.

https://github.com/laforge49/aatree#readme

On Clojars: https://clojars.org/aatree

Please feel free to comment on this project. Your participation would be 
most welcome.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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] aatree release 0.6.0--building databases from components

2015-12-06 Thread William la Forge
The aatree project provides fully compatible alternatives to Clojure 
sorted-map, sorted-set and vector, with several extensions:
  - AAVector supports add/drop at any point using addn and dropn.
  - AAMap and AASet implement Reversible, Counted, Indexed and Sorted
  - CountedSequence implements Counted and do not use synchronized.
  - Lazy deserialization/reserialization provides ridiculously fast 
deserialize/update/reserialize processing typical of disk access.
  - Virtual Structures that can be larger than memory.

New in Release 0.6.0:

   - The Calf and Yearling databases have been reimplemented as composites 
   of bags of properties, with a minimal close function stack supporting a 
   simple component lifecycle.
   - The database content is now simply the uber map, with everything else 
   moved into atoms and volatiles in the options map, i.e. in the bag of 
   properties.
   - Updates are done via side-effects (update-assoc-in! and 
   update-dissoc-in! methods) within the context of a transaction to 
   facilitate a greater separation of concerns.

For more information on Calf and Yearling, see 
https://github.com/laforge49/aatree/wiki/ 
Calf 
and https://github.com/laforge49/aatree/wiki/Yearling

https://github.com/laforge49/aatree#readme

On Clojars: https://clojars.org/aatree

Please feel free to comment on this project. Your participation would be 
most welcome.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


om next quickstart

2015-11-28 Thread William la Forge
Working my way through the quickstart tutorial for om 
next: https://github.com/omcljs/om/wiki/Quick-Start-%28om.next%29

Got to the point (not very far) where I enter this command: lein run -m 
clojure.main script/figwheel.clj

clojure.lang.Compiler$CompilerException: java.io.FileNotFoundException: 
Could not locate figwheel_sidecar/repl__init.class or 
figwheel_sidecar/repl.clj on classpath. Please check that namespaces with 
dashes use underscores in the Clojure file name., 
compiling:(C:\Users\Bill\Documents\GitHub\om-tutorial\script\figwheel.clj:1:1)

Any ideas? Here's my figwheel.clj file:

(require '[figwheel-sidecar.repl :as r]
 '[figwheel-sidecar.repl-api :as ra])

(ra/start-figwheel!
  {:figwheel-options {}
   :build-ids ["dev"]
   :all-builds
   [{:id "dev"
 :figwheel true
 :source-paths ["src"]
 :compiler {:main 'om-tutorial.core
:asset-path "js"
:output-to "resources/public/js/main.js"
:output-dir "resources/public/js"
:verbose true}}]})

(ra/cljs-repl)

And my project.clj file:

(defproject om-tutorial "0.1.0-SNAPSHOT"
  :description "My first Om program!"
  :dependencies [[org.clojure/clojure "1.7.0"]
 [org.clojure/clojurescript "1.7.170"]
 [org.omcljs/om "1.0.0-alpha22"]
 [figwheel-sidecar "0.5.0-SNAPSHOT" :scope "test"]])

Also tried figwheel-sidecar 0.5.0 and 0.5.0-2. Same results.

Bill

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: om next quickstart

2015-11-28 Thread William la Forge
Perhaps this is the problem? openjdk version "1.8.0_40"

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: om next quickstart

2015-11-28 Thread William la Forge
Switched to java version "1.8.0_31" to no avail.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-25 Thread William la Forge
Atamert,

I didn't get far on yo-yo--stopped reading when it started talking about 
monadic functions. :-)

But there is one main difference. I expect a component to "do its own 
thing", i.e. register its close function on opening. So there is nothing 
like defining a component. Well, except that when registering for a close, 
a component name is now being provided for use in the log. 

--b

On Tuesday, November 24, 2015 at 1:35:06 AM UTC-5, Atamert Ölçgen wrote:
>
> Hi William,
>
> How is this different than Yo-yo? (
> https://groups.google.com/forum/#!topic/clojure/PvCc5sSeSRY)
>
> > Justifying things is generally impossible.
>
> Actually, no. It is possible, at least when you are dealing with 
> reasonable people. And when you make claims like "lightweight" or 
> "ultralight", people will naturally ask "oh, interesting, how so?"
>
> -
>
> Some functional programming folks are allergic to exceptions. They go out 
> of their ways to prevent any and all exceptions and they end up 
> unnecessarily complicating their types for little or no gain.
>
> It seems to me, you are trying to avoid using protocols like it's a plague.
>
> > I am tired of doing ongoing refactorings interrupted periodically by 
> complete rewrites. Class hierarchies are the worst...
>
> When your ultralight function based components get out of hand, you will 
> have a worse time refactoring. With component you only have two functions, 
> your lightweight design will end up having (* n 2) functions.
>
> Also, looking at a component's code (it's defrecord form I mean) I can see 
> what other components it depends on. Your design would bury them inside 
> functions making it harder to read.
>
>
> On Tue, Nov 24, 2015 at 6:57 AM, James Reeves <ja...@booleanknot.com 
> > wrote:
>
>> Have you watched Simple Made Easy 
>> <http://www.infoq.com/presentations/Simple-Made-Easy>?
>>
>> I mention it because you remark about being tired of refactoring. It's my 
>> opinion that's a symptom of complexity, in the Hickey definition of the 
>> term.
>>
>> - James
>>
>> On 24 November 2015 at 03:31, William la Forge <lafo...@gmail.com 
>> > wrote:
>>
>>> James,
>>>
>>> Being fun is important but not a justification. We should strive to keep 
>>> things fun, but there are plenty of thing worth doing and our resources are 
>>> always limited. And if it is not fun, you are not going to do your best 
>>> work.
>>>
>>> Justifying things is generally impossible. If vanilla clojure meets your 
>>> needs, then vanilla clojure it is. If macros solve the problems you have 
>>> been dealt in the past, then three cheers for macros. If unifying client 
>>> and server addresses your needs, then Om Next may well be a major blessing 
>>> for you.
>>>
>>> For me, the winner is avoiding static structures. I am tired of doing 
>>> ongoing refactorings interrupted periodically by complete rewrites. Class 
>>> hierarchies are the worst--being the largest, they are the least stable. I 
>>> like small files that I can put to bed as finished. And self-defining 
>>> aggregation. Because these meet my very real needs. I constantly 
>>> reconceptualize what I am working on while bringing projects to completion. 
>>> So having a programming style which keeps code relevant in the face of such 
>>> an onslaught is very helpful and also a genuine delight.
>>>
>>> --b
>>>
>>> On Mon, Nov 23, 2015 at 10:08 PM, James Reeves <ja...@booleanknot.com 
>>> > wrote:
>>>
>>>> I feel you might be barking up the wrong tree with this approach, as it 
>>>> seems to complicate things without providing any compelling advantages.
>>>>
>>>> That said, if it's fun then by all means continue to experiment. Maybe 
>>>> I'm wrong :)
>>>>
>>>> - James
>>>>
>>>> On 24 November 2015 at 02:45, William la Forge <lafo...@gmail.com 
>>>> > wrote:
>>>>
>>>>> I think you have read too deeply into my thoughts on reserving the 
>>>>> first argument of a function. I haven't actually written any polymorphic 
>>>>> functions relating to this.
>>>>>
>>>>> Really, the take off point for me is being able to operate on an 
>>>>> object by implementing it as a map of functions and data. That is to say, 
>>>>> making objects data. Implementing multiple inheritance becomes trivial 
>>>>&g

Re: Ultralight Components

2015-11-25 Thread William la Forge
+1

On Wednesday, November 25, 2015 at 8:14:32 AM UTC-5, Colin Yates wrote:
>
> (let [x …] (if x true false)) is exactly what (if-let [x …] 
> true false) is for (
> http://stackoverflow.com/questions/2010287/when-to-use-let-vs-if-let-in-clojure
> )
>
> :-)
>
> On 25 Nov 2015, at 13:10, William la Forge <lafo...@gmail.com 
> > wrote:
>
> James,
>
> I've been thinking about protocols. Yes, I can now put them on an 
> aggregate, but there may be a lot of places where it is better not to use a 
> protocol and just use functions instead.
>
> The code below does not use a protocol and I rather like it. In other 
> cases we can use functions to achieve indirection by calling functions in 
> an aggregate. So it remains to be seen if there is a good case for using a 
> protocol with an aggregate. But at least I know how now--create an 
> aggregate in a record.
>
> Bill
>
> (ns aatree.closer-trait
>   (:require [clojure.tools.logging :as log]))
>
> (set! *warn-on-reflection* true)
>
> (defn on-close [this f]
>   (let [fsa (:closer-fsa this)]
> (if fsa
>   (do
> (swap! fsa
>(fn [fs]
>  (if fs
>(conj fs f)
>(atom (list f)
> this)
>   (assoc this :closer-fsa (atom (list f))
>
> (defn- do-closer [this fs]
>   (when fs
> (try
>   ((first fs) this)
>   (catch Exception e
> (log/warn e "exception on close")))
> (recur this (next fs
>
> (defn do-close [this]
>   (let [fsa (:closer-fsa this)]
> (if fsa
>   (let [fs @fsa]
> (if fs
>   (if (compare-and-set! fsa fs nil)
> (do-closer this fs)
> (recur this)))
>
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com 
> Note that posts from new members are moderated - please be patient with 
> your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com 
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> --- 
> You received this message because you are subscribed to the Google Groups 
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+u...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-25 Thread William la Forge
James,

I've been thinking about protocols. Yes, I can now put them on an 
aggregate, but there may be a lot of places where it is better not to use a 
protocol and just use functions instead.

The code below does not use a protocol and I rather like it. In other cases 
we can use functions to achieve indirection by calling functions in an 
aggregate. So it remains to be seen if there is a good case for using a 
protocol with an aggregate. But at least I know how now--create an 
aggregate in a record.

Bill

(ns aatree.closer-trait
  (:require [clojure.tools.logging :as log]))

(set! *warn-on-reflection* true)

(defn on-close [this f]
  (let [fsa (:closer-fsa this)]
(if fsa
  (do
(swap! fsa
   (fn [fs]
 (if fs
   (conj fs f)
   (atom (list f)
this)
  (assoc this :closer-fsa (atom (list f))

(defn- do-closer [this fs]
  (when fs
(try
  ((first fs) this)
  (catch Exception e
(log/warn e "exception on close")))
(recur this (next fs

(defn do-close [this]
  (let [fsa (:closer-fsa this)]
(if fsa
  (let [fs @fsa]
(if fs
  (if (compare-and-set! fsa fs nil)
(do-closer this fs)
(recur 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: Reducing Reuse Coupling

2015-11-24 Thread William la Forge
For greater clarity, I've cleaned up the code and broken it into 2 files, 
record-play0 and record-play:

(ns aatree.record-play0)

(set! *warn-on-reflection* true)

(defrecord base [])

(defn new-base [opts]
  (-> (->base)
  (into opts)
  (assoc :blap (fn [this] 42

(defrecord wackel [])

(defn new-wackel [opts]
  (-> (->wackel)
  (into opts)
  (assoc :blip (fn [this x y z] (+ x y z)


---


(ns aatree.record-play
  (:require [aatree.record-play0 :refer :all]))

(set! *warn-on-reflection* true)

(defprotocol gran
  (blip [this x y z])
  (blap [this]))

(def w (-> {} new-base new-wackel))

(extend-type aatree.record_play0.wackel
  gran
  (blip [this x y z]
((:blip this) this x y z))
  (blap [this]
((:blap this) this)))

(def w (-> {} new-base new-wackel))

(println (blip w 1 2 3)); -> 6

(println (blap w))  ; -> 42


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

2015-11-24 Thread William la Forge
Code can be found 
here: 
https://github.com/laforge49/aatree/blob/master/test/aatree/record_play.clj

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


Reducing Reuse Coupling

2015-11-24 Thread William la Forge
I love composition of traits and abstractions like protocols. But I 
especially love clojure's extend, which allows me to refactor interfaces 
without having to change the code for the traits.

That's pretty abstract. We obviously need to look at some code. Lets start 
by looking at two traits. But where before I was defining traits as maps, 
now I am using records:

(defrecord base [])

(defn new-base [opts]
  (let [b (->base)
  b (into b opts)
  b (assoc b :blap (fn [this] 42))]
b))

(defrecord wackel [])

(defn new-wackel [opts]
  (let [w (->wackel)
  w (into w opts)
  w (assoc w :blip (fn [this x y z] (+ x y z)))]
w))

Now here is our story. We have this protocol, gran. It has two methods, 
where each method is implemented by a different trait:

(defprotocol gran
  (blip [this x y z])
  (blap [this]))

To service this protocol, we create an aggregate, w:

(def w (-> {} new-base new-wackel))

We also extend wackel with the gran protocol:

(extend wackel
  gran
  {:blip (fn [this x y z]
   ((:blip this) this x y z))
   :blap (fn [this]
   ((:blap this) this))})

Testing this is pretty easy:

(println (blip w 1 2 3)); -> 6
(println (blap w)); -> 42

But lets look at what we have achieved. 
1. We can add functions to the protocol without changing the traits. We 
just need to change the aggregate, w.
2. We can move functions from one trait to another, so long as the 
functions are still defined in the aggregate.

So we have largely decoupled the interface from its implementation. I 
suspect the ultimate benefit here is a reduction of reuse coupling.
http://programmer.97things.oreilly.com/wiki/index.php/Reuse_Implies_Coupling


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: difficulties using extend--'elp!

2015-11-24 Thread William la Forge
Hi Steve!

I deleted this post, but still it gets mailed out.

Fixes are in and have been posted already.

See "Reduces Reuse Coupling".

But in any case, thanks. And thanks for the pointer to extend-type. :-)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


difficulties using extend--'elp!

2015-11-24 Thread William la Forge
This is not working for me:

(ns aatree.record-play)

(defprotocol gran
  (blip [x y z]))

(defrecord wackel [])

(defn new-wackel [opts]
  (let [w (->wackel)]
(into w opts)
(assoc w :blip (fn [this x y z] (+ x y z)

(extend wackel
  gran
  {:blap (fn [this x y z]
   ((:blip this) x y z))})

(println (.blap (new-wackel {}) 1 2 3))


I get this: No matching method found: blap for class aatree.record_play.wackel


I changed the println to this:


(let [^gran w (new-wackel {})]
  (println (.blap w 1 2 3)))


And now I get this: Unable to resolve classname: gran


Clearly there is something about protocols and/or extend that I do not 
understand.

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

2015-11-24 Thread William la Forge
It occurs to me that this can be simplified by using defrecord in place of
deftype. We can eliminate the Composite interface, because compositeMap
becomes the identity function. The code now becomes:

(def blip [this x y z] ((:blip this) this x y z))
(defprotocol gran
  (blip this x y z))
(defrecord wackel)
(defn new-wackel [opts] (assoc opts :blip (fn [this x y z] (+ x y z)))
(extend wackel
  gran
  {:blip blip})

This is better, but still a bit to swallow. Also, note I fixed a bug in
new-wackel.


On Tue, Nov 24, 2015 at 9:37 AM, William la Forge <laforg...@gmail.com>
wrote:

> So lets look at some artifacts then. I think we need an interface that all
> composites implement:
>
> (definterface Composite
>   (compositeMap []))
>
> The function composite-map returns the map which holds the aggregated
> functions and data.
>
> Now lets look at a sample function, blip:
>
> (def blip [^Composite this x y z] ((:blip (.compositeMap this)) this x y
> z))
>
> and a protocol that includes blip:
>
> (defprotocol gran
>   (blip ^Composite this x y z))
>
> Next we define a type which will hold an aggregate that includes an
> implementation of blip:
>
> (deftype wackel [my-map]
>   Composite
>   (defn compositeMap [_] my-map))
>
> and a function to create an instance of that type:
>
> (defn new-wackel [this opts] (assoc opts :blip (fn [this x y z] (+ x y z)))
>
> Finally, we can extend our type with the protocol:
>
> (extend wackel
>   gran
>   {:blip blip})
>
> I find this uncomfortable. In Rich's terms this is simple but hard. To be
> expected, as it is a major decomplection. But it will take me a while to
> get comfortable with this. :-(
>
> --b
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-24 Thread William la Forge
So lets look at some artifacts then. I think we need an interface that all
composites implement:

(definterface Composite
  (compositeMap []))

The function composite-map returns the map which holds the aggregated
functions and data.

Now lets look at a sample function, blip:

(def blip [^Composite this x y z] ((:blip (.compositeMap this)) this x y z))

and a protocol that includes blip:

(defprotocol gran
  (blip ^Composite this x y z))

Next we define a type which will hold an aggregate that includes an
implementation of blip:

(deftype wackel [my-map]
  Composite
  (defn compositeMap [_] my-map))

and a function to create an instance of that type:

(defn new-wackel [this opts] (assoc opts :blip (fn [this x y z] (+ x y z)))

Finally, we can extend our type with the protocol:

(extend wackel
  gran
  {:blip blip})

I find this uncomfortable. In Rich's terms this is simple but hard. To be
expected, as it is a major decomplection. But it will take me a while to
get comfortable with this. :-(

--b

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-24 Thread William la Forge
I better take this off line. I'm getting sloppy. Back to it later.

On Tue, Nov 24, 2015 at 9:50 AM, William la Forge <laforg...@gmail.com>
wrote:

> It occurs to me that this can be simplified by using defrecord in place of
> deftype. We can eliminate the Composite interface, because compositeMap
> becomes the identity function. The code now becomes:
>
> (def blip [this x y z] ((:blip this) this x y z))
> (defprotocol gran
>   (blip this x y z))
> (defrecord wackel)
> (defn new-wackel [opts] (assoc opts :blip (fn [this x y z] (+ x y z)))
> (extend wackel
>   gran
>   {:blip blip})
>
> This is better, but still a bit to swallow. Also, note I fixed a bug in
> new-wackel.
>
>
> On Tue, Nov 24, 2015 at 9:37 AM, William la Forge <laforg...@gmail.com>
> wrote:
>
>> So lets look at some artifacts then. I think we need an interface that
>> all composites implement:
>>
>> (definterface Composite
>>   (compositeMap []))
>>
>> The function composite-map returns the map which holds the aggregated
>> functions and data.
>>
>> Now lets look at a sample function, blip:
>>
>> (def blip [^Composite this x y z] ((:blip (.compositeMap this)) this x y
>> z))
>>
>> and a protocol that includes blip:
>>
>> (defprotocol gran
>>   (blip ^Composite this x y z))
>>
>> Next we define a type which will hold an aggregate that includes an
>> implementation of blip:
>>
>> (deftype wackel [my-map]
>>   Composite
>>   (defn compositeMap [_] my-map))
>>
>> and a function to create an instance of that type:
>>
>> (defn new-wackel [this opts] (assoc opts :blip (fn [this x y z] (+ x y
>> z)))
>>
>> Finally, we can extend our type with the protocol:
>>
>> (extend wackel
>>   gran
>>   {:blip blip})
>>
>> I find this uncomfortable. In Rich's terms this is simple but hard. To be
>> expected, as it is a major decomplection. But it will take me a while to
>> get comfortable with this. :-(
>>
>> --b
>>
>>
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-24 Thread William la Forge
Timothy, I'm definitely dancing on the leaves instead of the twigs. Or as
you said, I'm far out in the weeds. As for the problems I've had, it is
because I often change abstractions which have only minor impact on the
code. Classically, I'll redefine the meaning of a value and need to make
only one or two changes and get a major change in how a program works.
Which is why I hate mixing comments in the code--the comments change a lot
faster than the code for me.

The source of my divergence is my own mental processes. I do not visualize.
Mostly I do not think using words. And I am a rabid first-principals
thinker. So I am constantly re-conceptualizing.

I've gotten a lot of feedback. Very helpful. I really need to go quiet for
a bit and digest all this.

Thanks!

On Tue, Nov 24, 2015 at 9:46 AM, Timothy Baldridge <tbaldri...@gmail.com>
wrote:

> So let's back up a bit and take a look at your assumptions. In your
> previous post you stated ", I kept thinking about why I am avoiding
> protocols. In general, I very much like having abstractions. But I find
> that even small abstractions tend to complect what with how."
>
> I would love to see an example of this in code.
>
> I tend to agree with some other people here, I think you're so far out in
> the weeds with this approach that you haven't realized that one of your
> starting assumptions could be incorrect. You state that protocols and
> multimethods complicate refactoring, can you show us an example?
>
> Timothy
>
>
>
> On Tue, Nov 24, 2015 at 7:37 AM, William la Forge <laforg...@gmail.com>
> wrote:
>
>> So lets look at some artifacts then. I think we need an interface that
>> all composites implement:
>>
>> (definterface Composite
>>   (compositeMap []))
>>
>> The function composite-map returns the map which holds the aggregated
>> functions and data.
>>
>> Now lets look at a sample function, blip:
>>
>> (def blip [^Composite this x y z] ((:blip (.compositeMap this)) this x y
>> z))
>>
>> and a protocol that includes blip:
>>
>> (defprotocol gran
>>   (blip ^Composite this x y z))
>>
>> Next we define a type which will hold an aggregate that includes an
>> implementation of blip:
>>
>> (deftype wackel [my-map]
>>   Composite
>>   (defn compositeMap [_] my-map))
>>
>> and a function to create an instance of that type:
>>
>> (defn new-wackel [this opts] (assoc opts :blip (fn [this x y z] (+ x y
>> z)))
>>
>> Finally, we can extend our type with the protocol:
>>
>> (extend wackel
>>   gran
>>   {:blip blip})
>>
>> I find this uncomfortable. In Rich's terms this is simple but hard. To be
>> expected, as it is a major decomplection. But it will take me a while to
>> get comfortable with this. :-(
>>
>> --b
>>
>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from 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.
>>
>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/7Q7QvlSUGL4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, vi

Re: Clojure Objects

2015-11-24 Thread William la Forge
As in quantum entanglement? :-)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-24 Thread William la Forge
James, thanks for recommending Simple Made Easy
. As usual, I strongly
agree with 95% or more of everything Rich says.

While listening to this talk, I kept thinking about why I am avoiding
protocols. In general, I very much like having abstractions. But I find
that even small abstractions tend to complect what with how.

Protocols are the perspective of the client code. It defines what is there
to be used. But they should not be part of the code that provides a
service. Rather, they should belong to the aggregate of service providers.
Lets look at an example.

Suppose we have get and set! functions which an aggregate supports.
Normally you would think of get and set! as being implemented by code that
implements both. So you define a protocol that has both. It is a small
protocol that has nothing else. But it is possible that these are
implemented by very different pieces of code within an aggregate.

So it dawns on me. I need more code, not less! I should (a) define
functions with the aggregate map as the first argument rather than the last
and (b) use extend to add these functions to the Map interface. Now I have
protocols. Only, there is no type name since all aggregates are maps. So I
have not gained anything.

OK, so lets use deftype to define a type. It has a single field, which is
the aggregate map. And we construct the type by creating that aggregate.
AND THEN we extend that type with various protocols as convenient for how
we use it. We need code to create specific aggregations anyway, so the only
additional code here are the protocols and the extend. These provide the
abstractions convenient to the code that wants to use the aggregate.

So wow, even more code. Have we accomplished anything??? YES! We have
decoupled the abstractions from the implementations. Indeed, we can
completely rework our abstractions (which I do a lot) without touching the
code that implements them. For me, this is a major win. A substantial
decomplection!

One question remains then. Is it worth the added code? This is
simplification at the cost of easy. Loved that talk, 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.


Ultralight Components

2015-11-23 Thread William la Forge


When an object is built from a map, aggregating mixins is a trivial 
operation. But when a mixin needs to be closed, it is better to have a 
common mechanism to manage a stack of the close functions of all the 
aggregated mixins than to depend on application logic to do so. Case in 
point, I'd like to use an actor mixin or an alternative async channel mixin 
when composing a database. The async channel mixin will require a close but 
the actor mixin will not. So I developed the closer mixin to handle the 
calls to both the async channel and db file close functions. The database 
will only know the closer's do-close method. And it is the responsibility 
of the async channel and the db file mixins to register their close 
functions with the closer mixin.


My inspiration is Stuart Sierra's component library 
. But I am not handling 
dependencies per say, only managing a stack of close functions. And the 
"components" are only functions and atoms added to a common map structure, 
not records or deftypes. The result is a very lightweight pattern for 
components. The closer code itself is a lock-free mixin that gets added to 
the common map as needed when the on-close method is called.

For more information, see Closer 
.

(ns aatree.closer
  (:require [clojure.tools.logging :as log]))

(set! *warn-on-reflection* true)

(defn on-close [f opts]
  (let [fsa (:closer-fsa opts)]
(if fsa
  (do
(swap! fsa
   (fn [fs]
 (if fs
   (conj fs f)
   (atom (list f)
opts)
  (assoc opts :closer-fsa (atom (list f))

(defn- do-closer [fs opts]
  (when fs
(try
  ((first fs) opts)
  (catch Exception e
(log/warn e "exception on close")))
(recur (next fs) opts)))

(defn do-close [opts]
  (let [fsa (:closer-fsa opts)]
(if fsa
  (let [fs @fsa]
(if fs
  (if (compare-and-set! fsa fs nil)
(do-closer fs opts)
(recur opts)))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-23 Thread William la Forge
Sounds like you looked at wikipedia, which is the only place where I've 
seen mixin refer to the aggregate class. I've always seen mixin, or at 
least my understanding was that a mixin was the class that got added to the 
mixture. Could be just bad editing at the start of the wikipedia page, as 
they seem to reverse the sense of the term as you read further down the 
page. But as I look at other references to mixin, things become less and 
less clear.

Yeah, I am talking about creating compositions by aggregating the contents 
of other maps. It looks like a clearer term for the map being mixed into an 
aggregate would be trait. So I would have a db-file trait, the closer 
trait, the actor trait and the async-channel trait, all of which can be 
used in the composition of a database. Trait is clearer and nicely puts the 
emphasis on the functionality/capability being added.

It is hard coming up with good terms. I very much appreciate your help here 
James.

--b

On Monday, November 23, 2015 at 6:50:21 PM UTC-5, James Reeves wrote:
>
> Just to be clear, by "mixin" you're referring to merging two maps of 
> functions?
>
> Have you considered using composition instead of mixins? 
>
> - James
>
> On 23 November 2015 at 20:01, William la Forge <lafo...@gmail.com 
> > wrote:
>
>> When an object is built from a map, aggregating mixins is a trivial 
>> operation. But when a mixin needs to be closed, it is better to have a 
>> common mechanism to manage a stack of the close functions of all the 
>> aggregated mixins than to depend on application logic to do so. Case in 
>> point, I'd like to use an actor mixin or an alternative async channel mixin 
>> when composing a database. The async channel mixin will require a close but 
>> the actor mixin will not. So I developed the closer mixin to handle the 
>> calls to both the async channel and db file close functions. The database 
>> will only know the closer's do-close method. And it is the responsibility 
>> of the async channel and the db file mixins to register their close 
>> functions with the closer mixin.
>>
>>
>> My inspiration is Stuart Sierra's component library 
>> <https://github.com/stuartsierra/component>. But I am not handling 
>> dependencies per say, only managing a stack of close functions. And the 
>> "components" are only functions and atoms added to a common map structure, 
>> not records or deftypes. The result is a very lightweight pattern for 
>> components. The closer code itself is a lock-free mixin that gets added to 
>> the common map as needed when the on-close method is called.
>>
>> For more information, see Closer 
>> <https://github.com/laforge49/aatree/wiki/Closer>.
>>
>> (ns aatree.closer
>>   (:require [clojure.tools.logging :as log]))
>>
>> (set! *warn-on-reflection* true)
>>
>> (defn on-close [f opts]
>>   (let [fsa (:closer-fsa opts)]
>> (if fsa
>>   (do
>> (swap! fsa
>>(fn [fs]
>>  (if fs
>>(conj fs f)
>>(atom (list f)
>> opts)
>>   (assoc opts :closer-fsa (atom (list f))
>>
>> (defn- do-closer [fs opts]
>>   (when fs
>> (try
>>   ((first fs) opts)
>>   (catch Exception e
>> (log/warn e "exception on close")))
>> (recur (next fs) opts)))
>>
>> (defn do-close [opts]
>>   (let [fsa (:closer-fsa opts)]
>> (if fsa
>>   (let [fs @fsa]
>> (if fs
>>   (if (compare-and-set! fsa fs nil)
>> (do-closer fs opts)
>> (recur opts)))
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-23 Thread William la Forge
I think you have read too deeply into my thoughts on reserving the first
argument of a function. I haven't actually written any polymorphic
functions relating to this.

Really, the take off point for me is being able to operate on an object by
implementing it as a map of functions and data. That is to say, making
objects data. Implementing multiple inheritance becomes trivial and without
having to define any classes or any interfaces. And with full support for
circular references without needing to do declares.

What I like about it is that I get separation of concerns and maximal reuse
without, I suspect, the usual usage coupling. The small maps which define
traits can even participate in the lifecycle of the aggregate, so they
start taking on the characteristics of components.

My biggest problem with writing code over the decades has been the constant
desire to do rewrites--which are costly and devastating in their impact.
That is *why *I am fascinated with this approach.

A second *why *is that when I have clear separation of concerns and the
pieces of code can be easily tested independently, documentation becomes
clearer and more fun to write. And keeping code fun is a critical driver
for open source.

On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge <tbaldri...@gmail.com>
wrote:

> So I feel compelled at this point to ask..."why?". The whole point of
> functional programming in Clojure is to de-couple state from data. When you
> need polymorphic dispatch on the contents of a map, you have access to
> multi methods. Sure this is a fun thought experiment, but I don't
> understand the design goals. It's a fairly verbose way to write more
> complex code to accomplish what we already have good tools for
> (protocols/multimethods, etc).  Maybe I'm missing something.
>
> Timothy
>
> On Mon, Nov 23, 2015 at 7:15 PM, William la Forge <laforg...@gmail.com>
> wrote:
>
>> James, when I used the term mixin I was referring to a map that acts like
>> a trait that gets merged into a larger map. You would define several such
>> smaller maps that can then be used in various combinations to compose
>> "objects". The identity of the composite object (this) is the map which
>> holds the merged contents of the smaller maps. I.E. The entries in the
>> smaller maps get copied into the larger map.
>>
>> When executing functions held by a map, the last parameter is always the
>> map itself, i.e. the "this". On the other hand, when placing closures into
>> the map, the self reference is no longer needed as it is implicit in the
>> closure. But this means that a closure can only reference the contents of
>> the map when the closure was created, while a function can reference any of
>> the contents of the map passed as its last argument.
>>
>> Why did I make the map reference the last argument for functions held by
>> the map? So that we can do type polymorphism on the first argument passed
>> to the function. But we should make an exception to this. To facilitate
>> threading, functions which return an updated map should take that map as
>> the first argument. But that is an API change and needs to wait for release
>> 0.6.0.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from 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.
>>
>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic

Re: Ultralight Components

2015-11-23 Thread William la Forge
Raoul,

The problem for me here is that all that terminology refers to classes.
What I am dealing with here are objects implemented as persistent maps and
operations on those maps. Which is why I'm grasping for terminology.

Perhaps I should just define a new term like UltraLight Component (ULC).

--b

On Mon, Nov 23, 2015 at 7:48 PM, Raoul Duke  wrote:

> re: mixins, traits, etc. those terms have all been used in both
> research & shipped languages. Please see e.g. how Scala evolved with
> those terms. :)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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/7Q7QvlSUGL4/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.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Ultralight Components

2015-11-23 Thread William la Forge
James,

Being fun is important but not a justification. We should strive to keep
things fun, but there are plenty of thing worth doing and our resources are
always limited. And if it is not fun, you are not going to do your best
work.

Justifying things is generally impossible. If vanilla clojure meets your
needs, then vanilla clojure it is. If macros solve the problems you have
been dealt in the past, then three cheers for macros. If unifying client
and server addresses your needs, then Om Next may well be a major blessing
for you.

For me, the winner is avoiding static structures. I am tired of doing
ongoing refactorings interrupted periodically by complete rewrites. Class
hierarchies are the worst--being the largest, they are the least stable. I
like small files that I can put to bed as finished. And self-defining
aggregation. Because these meet my very real needs. I constantly
reconceptualize what I am working on while bringing projects to completion.
So having a programming style which keeps code relevant in the face of such
an onslaught is very helpful and also a genuine delight.

--b

On Mon, Nov 23, 2015 at 10:08 PM, James Reeves <ja...@booleanknot.com>
wrote:

> I feel you might be barking up the wrong tree with this approach, as it
> seems to complicate things without providing any compelling advantages.
>
> That said, if it's fun then by all means continue to experiment. Maybe I'm
> wrong :)
>
> - James
>
> On 24 November 2015 at 02:45, William la Forge <laforg...@gmail.com>
> wrote:
>
>> I think you have read too deeply into my thoughts on reserving the first
>> argument of a function. I haven't actually written any polymorphic
>> functions relating to this.
>>
>> Really, the take off point for me is being able to operate on an object
>> by implementing it as a map of functions and data. That is to say, making
>> objects data. Implementing multiple inheritance becomes trivial and without
>> having to define any classes or any interfaces. And with full support for
>> circular references without needing to do declares.
>>
>> What I like about it is that I get separation of concerns and maximal
>> reuse without, I suspect, the usual usage coupling. The small maps which
>> define traits can even participate in the lifecycle of the aggregate, so
>> they start taking on the characteristics of components.
>>
>> My biggest problem with writing code over the decades has been the
>> constant desire to do rewrites--which are costly and devastating in their
>> impact. That is *why *I am fascinated with this approach.
>>
>> A second *why *is that when I have clear separation of concerns and the
>> pieces of code can be easily tested independently, documentation becomes
>> clearer and more fun to write. And keeping code fun is a critical driver
>> for open source.
>>
>> On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge <tbaldri...@gmail.com>
>> wrote:
>>
>>> So I feel compelled at this point to ask..."why?". The whole point of
>>> functional programming in Clojure is to de-couple state from data. When you
>>> need polymorphic dispatch on the contents of a map, you have access to
>>> multi methods. Sure this is a fun thought experiment, but I don't
>>> understand the design goals. It's a fairly verbose way to write more
>>> complex code to accomplish what we already have good tools for
>>> (protocols/multimethods, etc).  Maybe I'm missing something.
>>>
>>> Timothy
>>>
>>> On Mon, Nov 23, 2015 at 7:15 PM, William la Forge <laforg...@gmail.com>
>>> wrote:
>>>
>>>> James, when I used the term mixin I was referring to a map that acts
>>>> like a trait that gets merged into a larger map. You would define several
>>>> such smaller maps that can then be used in various combinations to compose
>>>> "objects". The identity of the composite object (this) is the map which
>>>> holds the merged contents of the smaller maps. I.E. The entries in the
>>>> smaller maps get copied into the larger map.
>>>>
>>>> When executing functions held by a map, the last parameter is always
>>>> the map itself, i.e. the "this". On the other hand, when placing closures
>>>> into the map, the self reference is no longer needed as it is implicit in
>>>> the closure. But this means that a closure can only reference the contents
>>>> of the map when the closure was created, while a function can reference any
>>>> of the contents of the map passed as its last argument.
>>>>
>>>> Why did I make th

Re: Ultralight Components

2015-11-23 Thread William la Forge
James, when I used the term mixin I was referring to a map that acts like a 
trait that gets merged into a larger map. You would define several such 
smaller maps that can then be used in various combinations to compose 
"objects". The identity of the composite object (this) is the map which 
holds the merged contents of the smaller maps. I.E. The entries in the 
smaller maps get copied into the larger map. 

When executing functions held by a map, the last parameter is always the 
map itself, i.e. the "this". On the other hand, when placing closures into 
the map, the self reference is no longer needed as it is implicit in the 
closure. But this means that a closure can only reference the contents of 
the map when the closure was created, while a function can reference any of 
the contents of the map passed as its last argument.

Why did I make the map reference the last argument for functions held by 
the map? So that we can do type polymorphism on the first argument passed 
to the function. But we should make an exception to this. To facilitate 
threading, functions which return an updated map should take that map as 
the first argument. But that is an API change and needs to wait for release 
0.6.0.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Objects

2015-11-21 Thread William la Forge
Hi James!

I'll be the first to admit that I do not yet have a strong case here. And 
yeah, it looks like I'm introducing some boilerplate myself to do things 
this way. Which probably just means that I need to learn how to write 
macros or some such. :-)

I was just saying that the calf and yearling databases both do file io and 
I was going to have more of the same in the heifer database. So my 
duplicate code argument was a bit bogus, as in-line code is always cleaner 
and faster.

I am looking now at instance mixins for atoms and channels. Should be an 
interesting experiment. Calf and yearling both are based on an atom and I 
need to switch to channels in heifer as I want to pipeline the transaction 
log. So I am thinking of first writing an atom mixin, then reworking calf 
and yearling to use it, and then replacing the atom mixin with a channel 
mixin. Instance composition gone crazy. :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.


Clojure Objects

2015-11-20 Thread William la Forge


Code as data is the mantra. Functions and closures as data. So why not 
objects as data? What I propose is nothing new, but perhaps a new style.

Making objects from map structures is simple enough in Clojure. And easy 
enough to put functions in a map. So why not closures? A closure in a map 
is a lot like an object method, hmm?

I found clojure components to be inspirational. But as light-weight as they 
are, components are still too heavy-weight to be objects. But a simple map 
seems ideal. And with only a map instead of a record or deftype, 
composition is simplicity itself. But the key idea here comes from clojure 
components: contents of the map should be configuration parameters or 
architecture, but not state. Put state in an atom and then (optionally) put 
the atom in the map. But once an object is formed, the contents of the map 
should not change. There should be no need to update a reference to this 
map.

Below is what I am calling a Clojure Object. Like a Java object, the method 
holds both data and methods (closures). Note that, because we are using 
closures, local data can be accessed without having to be put in the map. 
For example, the file-channel variable is not accessed via the map and need 
not have been added to the map.

Bill

(ns aatree.db-file
  (:require [clojure.tools.logging :as log])
  (:import (java.nio.channels FileChannel)
   (java.nio.file OpenOption StandardOpenOption)))

(defn db-file-open
  ([file opts]
(db-file-open (assoc opts :db-file file)))
  ([opts]
(if (not (:db-file opts))
  (throw (Exception. "missing :db-file option")))
   (let [file (:db-file opts)
 ^FileChannel file-channel
 (FileChannel/open (.toPath file)
   (into-array OpenOption
   [StandardOpenOption/CREATE
StandardOpenOption/READ
StandardOpenOption/WRITE]))
 opts (assoc opts :db-file-channel file-channel)
 opts (assoc opts
:db-close
(fn []
  (try
(.close file-channel)
(catch Exception e
  (log/warn e "exception on close of db-file")))
  (dissoc opts :db-file-channel)))
 opts (assoc opts
:db-file-empty?
(fn []
  (= 0 (.size file-channel
 opts (assoc opts
:db-file-read
(fn [byte-buffer position]
  (.read file-channel byte-buffer position)))
 opts (assoc opts
:db-file-write
(fn [byte-buffer position]
  (.write file-channel byte-buffer position)))
 opts (assoc opts
:db-file-write-root
(fn [byte-buffer position]
  (.force file-channel true)
  (.write file-channel byte-buffer position)
  (.force file-channel true)))
 opts (assoc opts
:db-file-force
(fn []
  (.force file-channel true)))]
 opts)))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Objects

2015-11-20 Thread William la Forge
The advantage of maps over records is if I have 3 objects as maps I can
easily munge them into a single map. But if I have 3 objects as records, I
loose that option. OK, I can nest records inside each other but it is not
the same. With objects as maps I've got something closer to mixins. But not
type based.

Hmm. Guess the mixins thing is the real advantage. But mixins into objects
rather than extending a type with functions.

Now I did find this:

Function maps are maps of the keywordized method names to ordinary fns

   - this facilitates easy reuse of existing fns and maps, for code
   reuse/mixins without derivation or composition


The above was taken from http://clojure.org/protocols
where it was talking about extend.

It is very similar. But it is more about extending the polymorphic methods.
While I'm talking about extending an object. And aggregating in additional
data as well as methods.


On Sat, Nov 21, 2015 at 12:29 AM, Timothy Baldridge <tbaldri...@gmail.com>
wrote:

> You might want to read up on records and protocols in clojure. This is
> pretty much the use case for which they were designed.
>
> Timothy
>
> On Friday, November 20, 2015, William la Forge <laforg...@gmail.com>
> wrote:
>
>> You can tell I'm still new to clojure. The composition should have been
>> written like this:
>>
>> (-> opts (db-file-open) (db-cache-start) etc)
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from 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.
>>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/N-UG4jh8FDY/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.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Objects

2015-11-20 Thread William la Forge
James,

The advantages of one style over another are often subtle. And indeed, a 
single object written this way has no real advantage. Poor choice, but it 
was the only code I have written in this way so far. The addition of 
closures only occurred to me while writing this piece of code.

I included the file-channel in the map more on principle than anything 
else. Opinionated Clojure does not try to encapsulate the way Java does, or 
such has been my impression anyway. I do sometimes encapsulate when I want 
the API to be clearer, but otherwise not.

The reason for having this "type of object" at all is that I was going to 
have 3 copies of the same code. Which I find to be a bad thing.

One thing I left out was that in aatree.core I have functions which call 
the "object methods". These functions are implemented like this: 

(defn do-something [arg1 arg2 opts] ((:do-something opts) arg1 arg2))

This gives me a lot of decoupling. opts then is the "object" map. But it 
can be a munged together map of lots of key/value pairs from a lot of 
different "types of objects". Composition goes something like this in its 
simplest form:

(opts -> (db-file-open) (db-cache-open) etc)

I end up composing a lot of things richly but with simplicity. Being new to 
Clojure, I am fascinated by all this. And as I add more and more 
capabilities, it looks like everything stays quite stable--which is exactly 
the opposite of my experience in working with Java objects.

Bill

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Objects

2015-11-20 Thread William la Forge
Timothy,

I've been thinking about this a bit more and I see that you can supply data 
via a function in a function map that is part of extend. And while self 
reference between the various parts of a composite can get awkward, you can 
always revert to a function to complete that self-reference the same way I 
do with my core functions which have no knowledge of the implementations 
involved, except that you may be forced to do reflection.

I think the approach I am proposing is simpler both in that it avoids some 
of the boiler plate (thought I'd never say that about Clojure!) and 
completely bypasses the need for reflection. Within a composite (where opts 
is the name of the composed map) you can easily call any "method" like 
this: ((:some-method opts) arg1 arg2) without worrying about the order in 
which things are defined--one of the big weaknesses of Clojure compared to 
Java. Of course, now there is even less type checking that even the little 
that Clojure normally provides. But again, you can always define simple 
functions so that you don't end up invoking closures all over the place via 
(:method-key opts).

In any case, I'm having fun. And while the approach is not the fastest, I 
seem to be producing rock-solid stable code. Which for me is a great big 
plus!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Objects

2015-11-20 Thread William la Forge
You can tell I'm still new to clojure. The composition should have been 
written like this:

(-> opts (db-file-open) (db-cache-start) etc)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Objects

2015-11-20 Thread William la Forge
Oh! Some minor edits. Which can be found 
here: https://github.com/laforge49/aatree/wiki/Clojure-Objects

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Any plan to add log4j 2 support to tools.logging?

2015-11-19 Thread William la Forge
See https://logging.apache.org/log4j/2.x/maven-artifacts.html#SLF4J_Bridge

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Any plan to add log4j 2 support to tools.logging?

2015-11-19 Thread William la Forge
log4j2: While the Log4j 2 API will provide the best performance, Log4j 2 
provides support for the SLF4J and Commons Logging APIs.

Doesn't this mean that log4j 2 now works directly with tools.logging 
without having to go via slf4j-log4j12?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Any plan to add log4j 2 support to tools.logging?

2015-11-19 Thread William la Forge


You mean something besides this?


[org.clojure/tools.logging "0.3.1"]
[org.slf4j/slf4j-log4j12 "1.7.1"]
[log4j/log4j "1.2.17" :exclusions [javax.mail/mail
   javax.jms/jms
   com.sun.jmdk/jmxtools
   com.sun.jmx/jmxri]]

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Any plan to add log4j 2 support to tools.logging?

2015-11-19 Thread William la Forge
Got it working with aatree. Here's my dependencies:

[org.clojure/tools.logging "0.3.1"]
[org.apache.logging.log4j/log4j-core "2.4.1"]
[org.apache.logging.log4j/log4j-api "2.4.1"]
[org.apache.logging.log4j/log4j-slf4j-impl "2.4.1"]


Bill

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Any plan to add log4j 2 support to tools.logging?

2015-11-19 Thread William la Forge
Interesting. The log4j-api is not needed. log4j-slf4j-impl directly 
interfaces with log4j-core.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


aatree release 0.5.3--Transcription makes using aatree easy

2015-11-14 Thread William la Forge
The aatree project provides fully compatible alternatives to Clojure 
sorted-map, sorted-set and vector, with several extensions:
  - AAVector supports add/drop at any point using addn and dropn.
  - AAMap and AASet implement Reversible, Counted, Indexed and Sorted
  - CountedSequence implements Counted and do not use synchronized.
  - Lazy deserialization/reserialization provides ridiculously fast 
deserialize/update/reserialize processing typical of disk access.
  - Virtual Structures that can be larger than memory.

New in Release 0.5.2:

   - With so many different implementations of sorted-map, sorted-set and 
   vector, things could get messy. But the function (aatree.core.transcribe 
   val opts) can be used to convert trees using one implementation to trees 
   that use a different implementation. Even nicer, transcription is invoked 
   transparently when adding structures to an aa structure with a different 
   implementation.
   - Another potential complication occurs when moving data between aatree 
   databases, as virtual aa structures are tied to the database that contains 
   them. But this is handled transparently through transcription when an aa 
   database is updated with data from a different database.
   
For more information on transcription, 
see https://github.com/laforge49/aatree/wiki/Transcription

https://github.com/laforge49/aatree#readme

On Clojars: https://clojars.org/aatree

Please feel free to comment on this project. Your participation would be 
most welcome.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: A call for an idiomatic rendering of Clojure EDN in info/error messages

2015-11-13 Thread William la Forge
As a newbie, a red warning flag pops up when I see a back tick. :-)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


aatree release 0.5.1--Bugs fixed!

2015-11-12 Thread William la Forge
The aatree project provides fully compatible alternatives to Clojure 
sorted-map, sorted-set and vector, with several extensions:
  - AAVector supports add/drop at any point using addn and dropn.
  - AAMap and AASet implement Reversible, Counted, Indexed and Sorted
  - CountedSequence implements Counted and do not use synchronized.
  - Lazy deserialization/reserialization provides ridiculously fast 
deserialize/update/reserialize processing typical of disk access.
  - Virtual Structures that can be larger than memory.

New in Release 0.5.2:

   - Bugs introduced in release 0.5.1 have been fixed.

https://github.com/laforge49/aatree#readme

On Clojars: https://clojars.org/aatree

Please feel free to comment on this project. Your participation would be 
most welcome.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


aatree release 0.5.1--Memory Constrained for Queries

2015-11-08 Thread William la Forge
The aatree project provides fully compatible alternatives to Clojure 
sorted-map, sorted-set and vector, with several extensions:
  - AAVector supports add/drop at any point using addn and dropn.
  - AAMap and AASet implement Reversible, Counted, Indexed and Sorted
  - CountedSequence implements Counted and do not use synchronized.
  - Lazy deserialization/reserialization provides ridiculously fast 
deserialize/update/reserialize processing typical of disk access.
  - Virtual Structures that can be larger than memory.

New in Release 0.5.1:

   - Queries can endlessly deserialize a large database, potentially 
   causing an out-of-memory exception. To prevent this and maintain a minimal 
   memory footprint, weak references are used except during an update.

https://github.com/laforge49/aatree#readme

On Clojars: https://clojars.org/aatree

Please feel free to comment on this project. Your participation would be 
most welcome.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.cache limits?

2015-11-03 Thread William la Forge
That is a great post. Unfortunately I had gotten quite flustered by the 
time I found it and it made little sense to me. But looking at it now it is 
very well done and quite clear. Sigh.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.cache limits?

2015-11-03 Thread William la Forge
Sorry to report that after all that, I will need to pull the dependency on 
core.cache. Dealing with many small items, it is just too slow. 
Unfortunately I do need a thread-safe cache but really want to avoid sync 
locks, so I'd rather not roll my own. Guess I can look at the google caches.

For now I can leave it in. Speed is not the issue at this stage of 
development for virtual structures, so long as I understand what is causing 
the slowdown. Of course, testing for potential out-of-memory cases when 
things are running slow will be painful. So I don't think I will leave it 
in very long!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.cache limits?

2015-11-02 Thread William la Forge
I am also wondering if lirs is still a good choice when the cache is large 
and the items are small. Perhaps lru would be better?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


core.cache limits?

2015-11-02 Thread William la Forge
The lirs cache in core.cache looks good, but I don't follow the code for 
setting the limits. I'd like to use this as a node cache for virtual data 
structures. So I need a large, but configurable, limit.

Did a web search, can't find any examples for setting the limits. Most of 
what I found was discussing the implications of using an immutable 
structure.

Thanks in advance. Bill

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.cache limits?

2015-11-02 Thread William la Forge
It is the parameter list that threw me off: [base & {:keys [s-history-limit 
q-history-limit] :or {s-history-limit 32 q-history-limit 32}}] That's more 
destructuring than I've ever seen.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.cache limits?

2015-11-02 Thread William la Forge
OK, after a bit of digging into destructuring, I THINK I just pass the 
argument {s-history-limit 1000 q-history-limit 1000} or perhaps 
{:s-history-limit 1000 :q-history-limit 1000}.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: core.cache limits?

2015-11-02 Thread William la Forge
Solved by repl.

(f :s-history-limit 1000 q-history-limit 1000) is what I want.

(I'm finding clojure to be a rich language.)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


  1   2   >