Re: How to configure a library from a file in the project that has it as a dependency?

2016-04-20 Thread Facundo Olano
I've tried carica as squeegee suggested and it worked as I expected. I'm 
going with that so I can allow both dynamic binding and static config via 
file.

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 configure a library from a file in the project that has it as a dependency?

2016-04-20 Thread Facundo Olano
I just noticed I replied with a private message earlier
 

> If you end up using a separate config file rather than project.clj, you 
> might find Carica https://github.com/sonian/carica useful. It allows 
> merging config files on the classpath into one effective config hierarchy 
> with predictable overriding behavior.


Thanks, I'll give that one a try.

How about accepting a fn as argument to provide the config required? In 
> that case the user is free to use whichever library/hand-rolled code to 
> read config from a file.
>
 

>  It's very simple: Leave configuration file management and stuff out of 
> the lib. Instead, pass the translations dictionary to your library as an 
> argument.
> On your app level, you could still load the desired dictionary from a 
> config file but the lib should stay independent of this.

 

About passing the config as an argument to my lib, I understand that's the 
purest approach and I would go with that in most cases, but in this case I 
feel it would be inconvenient for the lib's user.

I'm doing calls to the lib everywhere in the code where a translatable 
string appears (and that's in a lot of places in my project, since it has a 
pure text interface). So if I wanted to pass the config in each lib call 
I'd have to add a parameter, make it available everywhere throughout the 
project and force the user to handle the config loading before making any 
function calls.

The other approach would be to pass that configuration to some sort of init 
function of my lib, but it has the same problem: not being able to require 
any namespace that contains translatable strings before handling lib 
initialisation. I've tried something like that and it forced me to break 
apart my ns :requires, do initialisation, do the rest of the requires 
after. A lot of hassle to use a small lib.

For context, this 
 is 
how I expected my lib to work. I've used a similar approach in other 
languages, perhaps I need to rethink my design to better fit clojure.

Thanks, 
Facundo.

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

2016-04-20 Thread JvJ
I don't think I'll go with primitive arrays.  A big part of the reason I'm 
using Clojure is for the immutable persistence.  I just want to use them in 
the most efficient way possible.  I know I'm not going to get hyper-blazing 
C-level performance.

On Wednesday, 20 April 2016 15:38:11 UTC-7, Stuart Sierra wrote:
>
> The first answer: test & measure. Benchmark your code, use a JVM profiler 
> to find hotspots, etc. Test every change you make to see if it has a 
> measurable improvement. Any assumptions about what “should” be 
> faster/slower are likely to be wrong.
>
> The long answer:
>
> The JVM does not give you much control over how objects are arranged in 
> memory. In Java and Clojure, almost everything is a pointer to an object on 
> the heap. Java collection classes and Clojure collections store pointers to 
> objects; they do not store values “in-line” like an array of structs in C. 
> The JVM *may* have optimizations that try to arrange objects “near” other 
> objects, but you have no control over this.
>
> So my (untested) expectation is that all Clojure collection types are 
> more-or-less equal in terms of memory locality.
>
> The only built-in data structure that offers the possibility of contiguous 
> allocation in Java — without dropping down to native code — is an array of 
> primitives, such as integers or doubles. Clojure has built-in functions to 
> create and manipulate Java primitive arrays, if that works for your use 
> case.
>
> –S
>
>
> On Wednesday, April 20, 2016 at 2:03:10 PM UTC-4, JvJ wrote:
>>
>> I'm writing some code that I would like to perform as quickly as 
>> possible.  Currently, I am iterating over large hash maps and performing 
>> assocs and dissocs.
>>
>> I don't know much about performance optimization, but I am told that 
>> memory locality is a big factor.  I would like to know how Persistent Maps, 
>> Persistent Vectors, Transient Maps, and Transient Vectors compare to one 
>> another in this respect.
>>
>> Also, the objects in the collection that I'm iterating over will 
>> themselves be maps.  So, if I had a vector with good memory locality, but 
>> it stored what are effectively pointers to maps allocated elsewhere, will 
>> that nullify the benefits of memory locality?
>>
>> 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: Recur in an overloaded function does not work?

2016-04-20 Thread J.-F. Rompre
Ooops - my apologies (attempted correction below)

Here is a horribly contrived example (sorry, that's all I can come up 
withht now rig) using recur across different arities of the same function, 
together with trampoline.

(defn is-odd?
  ([n]
   (cond (< n 0) true
 (even? n) #(is-odd? (dec n) true)
 :else (recur (- n 2
  ([n even?]
   (cond 
 even? #(not (is-odd? (dec n)))
(< n 0) true   
(zero? n) false
:else (recur (- n 2) false

=>(trampoline is-odd? 3)
=> true
=>(trampoline is-odd? 40)
=> false
=>(trampoline is-odd? 41 false)
=> true

So I don't see why you can't avoid stack consumption using recur anywhere, 
including across multiple arities with trampoline - just wrap the whole 
thing in a trampoline call  e.g. in andmed's example:
(although I don't understand the logic well)
...
(defn find-comment-in-line
([s] (when (pos? (count s))
  (if-let [cs (seq (comment-s? s))]
  (subs s (count (first cs)))
  (if-let [qs (seq (quote-s? s))]
  #(find-comment-in-line (subs s 1) qs)
  (recur (subs s 1))

 ([s q] (when (pos? (count s))
 (if-let [qs (seq (quote-s? s))]
 (if (= qs q)
   #(find-comment-in-line (subs s 1))
   (recur (subs s 1) q))

=> (trampoline find-comment-in-line ...)



On Wednesday, April 20, 2016 at 4:26:21 PM UTC-4, adrian...@mail.yu.edu 
wrote:
>
> I don't think you're missing anything James. It does not look like this 
> example uses trampoline with the intended effect. 
>
> On Wednesday, April 20, 2016 at 2:45:05 PM UTC-4, James Elliott wrote:
>>
>> Does trampoline really help in this case? I don’t see where we are ever 
>> returning a new function for trampoline to call, avoiding a new stack 
>> frame. It seems to me no different than simply calling the other arities 
>> directly in this example. What am I missing?
>>
>> On Wednesday, April 20, 2016 at 12:00:35 PM UTC-5, J.-F. Rompre wrote:
>>>
>>> You can prevent stack consumption by using trampoline for tail-recursive 
>>> calls to a different arity, and recur for same arity, something like:
>>>
>>> (defn find-comment-in-line
>>>
>>> ([s] (when (pos? (count s))
>>>   (if-let [cs (seq (comment-s? s))]
>>>  ;; yes, a comment symbol found,
>>>  ;; just return the remainder of a string
>>>   (subs s (count (first cs)))
>>>
>>>  ;; no, lets check for an opening quote
>>>
>>>   (if-let [qs (seq (quote-s? s))]
>>>
>>>   ;; yes, an opening quote found,
>>>   ;; now go look for an end quote
>>>   (trampoline find-comment-in-line (subs s 1) qs)
>>>
>>>   ;; no, just some other symbol found,
>>>   ;; check for the rest
>>>   (recur (subs s 1))
>>>
>>>  ([s q] (when (pos? (count s))
>>>  ;; lets check if it is a quote
>>>  (if-let [qs (seq (quote-s? s))]
>>>
>>>  ;; is it a closing quote?
>>>  (if (= qs q)
>>>;; yes, lets check for the rest
>>>(trampoline find-comment-in-line (subs s 1))
>>>
>>>;; no, just ignore the symbol,
>>>;;continue looking for a closing quote
>>>(recur (subs s 1) q))
>>>
>>>
>>>
>>> On Tuesday, April 19, 2016 at 11:18:40 AM UTC-4, andmed wrote:

 Thank you. That the point. If "recur" binds to fn, why it can not know 
 the binding point as the function method based on the number of arguments 
 passed to it? I mean it is clear that Clojure can't do that, but I can see 
 no reason why it could or should not if we choose to implement such 
 syntactic nicety as recur in a function

>>>

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


Re: Memory Locality - Maps vs. Vectors vs. Transient Maps & Vectors

2016-04-20 Thread Stuart Sierra
The first answer: test & measure. Benchmark your code, use a JVM profiler 
to find hotspots, etc. Test every change you make to see if it has a 
measurable improvement. Any assumptions about what “should” be 
faster/slower are likely to be wrong.

The long answer:

The JVM does not give you much control over how objects are arranged in 
memory. In Java and Clojure, almost everything is a pointer to an object on 
the heap. Java collection classes and Clojure collections store pointers to 
objects; they do not store values “in-line” like an array of structs in C. 
The JVM *may* have optimizations that try to arrange objects “near” other 
objects, but you have no control over this.

So my (untested) expectation is that all Clojure collection types are 
more-or-less equal in terms of memory locality.

The only built-in data structure that offers the possibility of contiguous 
allocation in Java — without dropping down to native code — is an array of 
primitives, such as integers or doubles. Clojure has built-in functions to 
create and manipulate Java primitive arrays, if that works for your use 
case.

–S


On Wednesday, April 20, 2016 at 2:03:10 PM UTC-4, JvJ wrote:
>
> I'm writing some code that I would like to perform as quickly as possible. 
>  Currently, I am iterating over large hash maps and performing assocs and 
> dissocs.
>
> I don't know much about performance optimization, but I am told that 
> memory locality is a big factor.  I would like to know how Persistent Maps, 
> Persistent Vectors, Transient Maps, and Transient Vectors compare to one 
> another in this respect.
>
> Also, the objects in the collection that I'm iterating over will 
> themselves be maps.  So, if I had a vector with good memory locality, but 
> it stored what are effectively pointers to maps allocated elsewhere, will 
> that nullify the benefits of memory locality?
>
> 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: Memory Locality - Maps vs. Vectors vs. Transient Maps & Vectors

2016-04-20 Thread Raoul Duke
You can only tell by benchmarking. And even then it can change when
you move to different hardware. You can debate about big O and
constant factors and numa and all that jazz till you are blue in the
face.

There are 3 kinds of people in the world:
1) those who think we should stick with arrays because, after all,
they *are* contiguous, and even if we have ssd's we still have cpu
cache limits.
3) those who think programmer productivity is most important and just
want to get it done and ship it and not have to bend over backwards to
use some api that is not really as easy to use for their use case as,
say, just using a blankeyblank hashmap.
2) everybody else.

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

2016-04-20 Thread JvJ
That was actually the example I used to implement this.  As it turns out, 
assoc-in, update-in, etc. work on anything that supports assoc.

On Wednesday, 20 April 2016 13:39:40 UTC-7, Andy Fingerhut wrote:
>
> I don't know if assoc-in etc. work on the clojure.data.priority-map data 
> structures, but your questions at least reminded me of the implementation 
> of that data structure, which uses two maps internally to maintain the 
> priority map, and keeps their contents consistent with each other [1].  It 
> also implements all of the methods that regular Clojure maps do, so all 
> normal map operations work on priority-maps, too.  Its implementation may 
> give you some ideas for one way to do what you are hoping for.
>
> Andy
>
> [1] https://github.com/clojure/data.priority-map
>
>
> On Wed, Apr 20, 2016 at 10:18 AM, JvJ > 
> wrote:
>
>> I had a bit of trouble fully understanding the EAV concept or the pldb 
>> code.  There's not a good overview of EAV architecture that doesn't focus 
>> on databases.  I'm not much of a DB guy.  So, I'm not sure if I got the 
>> essence of the EAV pattern with my new implementation, but here it is 
>> anyway:
>>
>> I think the legacy of object-orientation was so embedded in my brain that 
>> I failed to see the simple solution: rows and columns.  I was thinking of 
>> items in the map as "containers" of items, when I could have been thinking 
>> of them as rows in a table.  The table is effectively a sparse matrix.
>>
>> The implementation's main map is of type { [row col]->Item }.  It also 
>> uses two other maps: row-idx:{row->{col item}} and 
>> col-idx:{col->{row->item}}.
>>
>> Whenever an assoc occurs on key [r c] and item i, here is how the values 
>> are updated:
>> main-map<-(assoc main-map [r c] i)
>> row-idx<-(assoc-in row-idx [r c] i)
>> col-idx<-(assoc-in col-idx [c r] i)
>>
>> This way, we efficiently maintain row-idx and col-idx, two complementary 
>> nested maps that mirror each others' structure.
>>
>> Did I get close to the EAV pattern here?  Also, I wonder if this approach 
>> is scalable to higher-dimensional tables, for instance where each item is 
>> associated with a 3-tuple.
>>
>> On Monday, 18 April 2016 17:18:45 UTC-7, tbc++ wrote:
>>>
>>> Core.logic has one such implementation: 
>>> https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/pldb.clj
>>>  
>>> 
>>>  
>>> might be a place to start. 
>>>
>>> On Mon, Apr 18, 2016 at 5:35 PM, JvJ  wrote:
>>>
 Can you point me to a working example of one of these structures?

 On Monday, 18 April 2016 16:30:17 UTC-7, tbc++ wrote:
>
> And by "fairly common these days", I mean that I run into this sort of 
> structure a lot in clojure with anything that is trying to logic or query 
> operations. Probably isn't that common outside of projects in that 
> domain. 
>
> On Mon, Apr 18, 2016 at 5:28 PM, Timothy Baldridge  > wrote:
>
>> assoc-in is defined in terms of assoc: 
>> https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L5901
>>
>> And this structure is fairly common these days, it's basically a 
>> index of tuples [e a v], and you're creating a eav index and then an av 
>> index. Datomic does this same sort of thing, for the datom [e a v t] it 
>> creates indices for :eavt :avet and a few others that escape my memory 
>> at 
>> the moment.  
>>
>> On Mon, Apr 18, 2016 at 5:08 PM, JvJ  wrote:
>>
>>> I'm implementing a map data structure where most of the values are 
>>> maps or sets, and these values can be cross-indexed by the keys they 
>>> contain.  I don't know if it already has a name, but I'm calling it a 
>>> cross-map.  It's similar to a two-way map, but they're not the same 
>>> thing.
>>>
>>> For instance, a common operation would be something like "give me 
>>> all values of this map that contain the key :a."
>>>
>>> In order to do this efficiently, I'm maintaining a second map that 
>>> maps keys in the values of the main map to keys of the main map whose 
>>> values contain that key.
>>>
>>> If that sounds confusing, consider this:
>>> main-map:
>>> {:foo {:a 1 :b 2} :bar {:a 2 :c 4} :baz {:b 3 :c 5}}
>>>
>>> Corresponding cross-indices:
>>> {:a #{:foo :bar} :b #{:foo :baz} :c #{:bar :baz}}
>>>
>>> As you can see, each key maintains references to those entries where 
>>> it is found.
>>>
>>> When a nested update occurs that adds an entry to one of the main 
>>> map's values, the efficient thing to do would be to simply conj that 
>>> new 
>>> key onto its corresponding cross-index set.
>>>
>>> However, I am trying to implemen

Re: Memory Locality - Maps vs. Vectors vs. Transient Maps & Vectors

2016-04-20 Thread JvJ
Do you think that maps vs vectors would make a difference in the transient 
case?

On Wednesday, 20 April 2016 13:42:12 UTC-7, Andy Fingerhut wrote:
>
> Transients are a performance optimization that can give quite significant 
> performance increases when you know you will be doing many updates to a 
> Clojure vector or map.  A long sequence of updates on a transient tends to 
> allocate much less memory than the corresponding sequence of updates on a 
> non-transient data structure.
>
> Andy
>
> On Wed, Apr 20, 2016 at 11:03 AM, JvJ > 
> wrote:
>
>> I'm writing some code that I would like to perform as quickly as 
>> possible.  Currently, I am iterating over large hash maps and performing 
>> assocs and dissocs.
>>
>> I don't know much about performance optimization, but I am told that 
>> memory locality is a big factor.  I would like to know how Persistent Maps, 
>> Persistent Vectors, Transient Maps, and Transient Vectors compare to one 
>> another in this respect.
>>
>> Also, the objects in the collection that I'm iterating over will 
>> themselves be maps.  So, if I had a vector with good memory locality, but 
>> it stored what are effectively pointers to maps allocated elsewhere, will 
>> that nullify the benefits of memory locality?
>>
>> 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: Memory Locality - Maps vs. Vectors vs. Transient Maps & Vectors

2016-04-20 Thread Andy Fingerhut
Transients are a performance optimization that can give quite significant
performance increases when you know you will be doing many updates to a
Clojure vector or map.  A long sequence of updates on a transient tends to
allocate much less memory than the corresponding sequence of updates on a
non-transient data structure.

Andy

On Wed, Apr 20, 2016 at 11:03 AM, JvJ  wrote:

> I'm writing some code that I would like to perform as quickly as
> possible.  Currently, I am iterating over large hash maps and performing
> assocs and dissocs.
>
> I don't know much about performance optimization, but I am told that
> memory locality is a big factor.  I would like to know how Persistent Maps,
> Persistent Vectors, Transient Maps, and Transient Vectors compare to one
> another in this respect.
>
> Also, the objects in the collection that I'm iterating over will
> themselves be maps.  So, if I had a vector with good memory locality, but
> it stored what are effectively pointers to maps allocated elsewhere, will
> that nullify the benefits of memory locality?
>
> 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.
>

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

2016-04-20 Thread Andy Fingerhut
I don't know if assoc-in etc. work on the clojure.data.priority-map data
structures, but your questions at least reminded me of the implementation
of that data structure, which uses two maps internally to maintain the
priority map, and keeps their contents consistent with each other [1].  It
also implements all of the methods that regular Clojure maps do, so all
normal map operations work on priority-maps, too.  Its implementation may
give you some ideas for one way to do what you are hoping for.

Andy

[1] https://github.com/clojure/data.priority-map


On Wed, Apr 20, 2016 at 10:18 AM, JvJ  wrote:

> I had a bit of trouble fully understanding the EAV concept or the pldb
> code.  There's not a good overview of EAV architecture that doesn't focus
> on databases.  I'm not much of a DB guy.  So, I'm not sure if I got the
> essence of the EAV pattern with my new implementation, but here it is
> anyway:
>
> I think the legacy of object-orientation was so embedded in my brain that
> I failed to see the simple solution: rows and columns.  I was thinking of
> items in the map as "containers" of items, when I could have been thinking
> of them as rows in a table.  The table is effectively a sparse matrix.
>
> The implementation's main map is of type { [row col]->Item }.  It also
> uses two other maps: row-idx:{row->{col item}} and
> col-idx:{col->{row->item}}.
>
> Whenever an assoc occurs on key [r c] and item i, here is how the values
> are updated:
> main-map<-(assoc main-map [r c] i)
> row-idx<-(assoc-in row-idx [r c] i)
> col-idx<-(assoc-in col-idx [c r] i)
>
> This way, we efficiently maintain row-idx and col-idx, two complementary
> nested maps that mirror each others' structure.
>
> Did I get close to the EAV pattern here?  Also, I wonder if this approach
> is scalable to higher-dimensional tables, for instance where each item is
> associated with a 3-tuple.
>
> On Monday, 18 April 2016 17:18:45 UTC-7, tbc++ wrote:
>>
>> Core.logic has one such implementation:
>> https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/pldb.clj
>> 
>> might be a place to start.
>>
>> On Mon, Apr 18, 2016 at 5:35 PM, JvJ  wrote:
>>
>>> Can you point me to a working example of one of these structures?
>>>
>>> On Monday, 18 April 2016 16:30:17 UTC-7, tbc++ wrote:

 And by "fairly common these days", I mean that I run into this sort of
 structure a lot in clojure with anything that is trying to logic or query
 operations. Probably isn't that common outside of projects in that domain.

 On Mon, Apr 18, 2016 at 5:28 PM, Timothy Baldridge 
 wrote:

> assoc-in is defined in terms of assoc:
> https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L5901
>
> And this structure is fairly common these days, it's basically a index
> of tuples [e a v], and you're creating a eav index and then an av index.
> Datomic does this same sort of thing, for the datom [e a v t] it creates
> indices for :eavt :avet and a few others that escape my memory at the
> moment.
>
> On Mon, Apr 18, 2016 at 5:08 PM, JvJ  wrote:
>
>> I'm implementing a map data structure where most of the values are
>> maps or sets, and these values can be cross-indexed by the keys they
>> contain.  I don't know if it already has a name, but I'm calling it a
>> cross-map.  It's similar to a two-way map, but they're not the same 
>> thing.
>>
>> For instance, a common operation would be something like "give me all
>> values of this map that contain the key :a."
>>
>> In order to do this efficiently, I'm maintaining a second map that
>> maps keys in the values of the main map to keys of the main map whose
>> values contain that key.
>>
>> If that sounds confusing, consider this:
>> main-map:
>> {:foo {:a 1 :b 2} :bar {:a 2 :c 4} :baz {:b 3 :c 5}}
>>
>> Corresponding cross-indices:
>> {:a #{:foo :bar} :b #{:foo :baz} :c #{:bar :baz}}
>>
>> As you can see, each key maintains references to those entries where
>> it is found.
>>
>> When a nested update occurs that adds an entry to one of the main
>> map's values, the efficient thing to do would be to simply conj that new
>> key onto its corresponding cross-index set.
>>
>> However, I am trying to implement this as a clojure IPersistentMap,
>> and the only method I can override is assoc, not assoc-in.
>>
>> Using regular assoc, I would have to compare the old value's keys to
>> the new value's keys and find the set difference of the two, which is not
>> an O(1) operation.
>>
>> Is there any way to override the behaviour of nested associations or
>> updates?
>>
>>

Re: Recur in an overloaded function does not work?

2016-04-20 Thread adrian . medina
I don't think you're missing anything James. It does not look like this 
example uses trampoline with the intended effect. 

On Wednesday, April 20, 2016 at 2:45:05 PM UTC-4, James Elliott wrote:
>
> Does trampoline really help in this case? I don’t see where we are ever 
> returning a new function for trampoline to call, avoiding a new stack 
> frame. It seems to me no different than simply calling the other arities 
> directly in this example. What am I missing?
>
> On Wednesday, April 20, 2016 at 12:00:35 PM UTC-5, J.-F. Rompre wrote:
>>
>> You can prevent stack consumption by using trampoline for tail-recursive 
>> calls to a different arity, and recur for same arity, something like:
>>
>> (defn find-comment-in-line
>>
>> ([s] (when (pos? (count s))
>>   (if-let [cs (seq (comment-s? s))]
>>  ;; yes, a comment symbol found,
>>  ;; just return the remainder of a string
>>   (subs s (count (first cs)))
>>
>>  ;; no, lets check for an opening quote
>>
>>   (if-let [qs (seq (quote-s? s))]
>>
>>   ;; yes, an opening quote found,
>>   ;; now go look for an end quote
>>   (trampoline find-comment-in-line (subs s 1) qs)
>>
>>   ;; no, just some other symbol found,
>>   ;; check for the rest
>>   (recur (subs s 1))
>>
>>  ([s q] (when (pos? (count s))
>>  ;; lets check if it is a quote
>>  (if-let [qs (seq (quote-s? s))]
>>
>>  ;; is it a closing quote?
>>  (if (= qs q)
>>;; yes, lets check for the rest
>>(trampoline find-comment-in-line (subs s 1))
>>
>>;; no, just ignore the symbol,
>>;;continue looking for a closing quote
>>(recur (subs s 1) q))
>>
>>
>>
>> On Tuesday, April 19, 2016 at 11:18:40 AM UTC-4, andmed wrote:
>>>
>>> Thank you. That the point. If "recur" binds to fn, why it can not know 
>>> the binding point as the function method based on the number of arguments 
>>> passed to it? I mean it is clear that Clojure can't do that, but I can see 
>>> no reason why it could or should not if we choose to implement such 
>>> syntactic nicety as recur in a function
>>>
>>

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


Re: Recur in an overloaded function does not work?

2016-04-20 Thread James Elliott
Does trampoline really help in this case? I don’t see where we are ever 
returning a new function for trampoline to call, avoiding a new stack 
frame. It seems to me no different than simply calling the other arities 
directly in this example. What am I missing?

On Wednesday, April 20, 2016 at 12:00:35 PM UTC-5, J.-F. Rompre wrote:
>
> You can prevent stack consumption by using trampoline for tail-recursive 
> calls to a different arity, and recur for same arity, something like:
>
> (defn find-comment-in-line
>
> ([s] (when (pos? (count s))
>   (if-let [cs (seq (comment-s? s))]
>  ;; yes, a comment symbol found,
>  ;; just return the remainder of a string
>   (subs s (count (first cs)))
>
>  ;; no, lets check for an opening quote
>
>   (if-let [qs (seq (quote-s? s))]
>
>   ;; yes, an opening quote found,
>   ;; now go look for an end quote
>   (trampoline find-comment-in-line (subs s 1) qs)
>
>   ;; no, just some other symbol found,
>   ;; check for the rest
>   (recur (subs s 1))
>
>  ([s q] (when (pos? (count s))
>  ;; lets check if it is a quote
>  (if-let [qs (seq (quote-s? s))]
>
>  ;; is it a closing quote?
>  (if (= qs q)
>;; yes, lets check for the rest
>(trampoline find-comment-in-line (subs s 1))
>
>;; no, just ignore the symbol,
>;;continue looking for a closing quote
>(recur (subs s 1) q))
>
>
>
> On Tuesday, April 19, 2016 at 11:18:40 AM UTC-4, andmed wrote:
>>
>> Thank you. That the point. If "recur" binds to fn, why it can not know 
>> the binding point as the function method based on the number of arguments 
>> passed to it? I mean it is clear that Clojure can't do that, but I can see 
>> no reason why it could or should not if we choose to implement such 
>> syntactic nicety as recur in a function
>>
>

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


Memory Locality - Maps vs. Vectors vs. Transient Maps & Vectors

2016-04-20 Thread JvJ
I'm writing some code that I would like to perform as quickly as possible. 
 Currently, I am iterating over large hash maps and performing assocs and 
dissocs.

I don't know much about performance optimization, but I am told that memory 
locality is a big factor.  I would like to know how Persistent Maps, 
Persistent Vectors, Transient Maps, and Transient Vectors compare to one 
another in this respect.

Also, the objects in the collection that I'm iterating over will themselves 
be maps.  So, if I had a vector with good memory locality, but it stored 
what are effectively pointers to maps allocated elsewhere, will that 
nullify the benefits of memory locality?

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: Possible to override assoc-in or update-in?

2016-04-20 Thread JvJ
I had a bit of trouble fully understanding the EAV concept or the pldb 
code.  There's not a good overview of EAV architecture that doesn't focus 
on databases.  I'm not much of a DB guy.  So, I'm not sure if I got the 
essence of the EAV pattern with my new implementation, but here it is 
anyway:

I think the legacy of object-orientation was so embedded in my brain that I 
failed to see the simple solution: rows and columns.  I was thinking of 
items in the map as "containers" of items, when I could have been thinking 
of them as rows in a table.  The table is effectively a sparse matrix.

The implementation's main map is of type { [row col]->Item }.  It also uses 
two other maps: row-idx:{row->{col item}} and col-idx:{col->{row->item}}.

Whenever an assoc occurs on key [r c] and item i, here is how the values 
are updated:
main-map<-(assoc main-map [r c] i)
row-idx<-(assoc-in row-idx [r c] i)
col-idx<-(assoc-in col-idx [c r] i)

This way, we efficiently maintain row-idx and col-idx, two complementary 
nested maps that mirror each others' structure.

Did I get close to the EAV pattern here?  Also, I wonder if this approach 
is scalable to higher-dimensional tables, for instance where each item is 
associated with a 3-tuple.

On Monday, 18 April 2016 17:18:45 UTC-7, tbc++ wrote:
>
> Core.logic has one such implementation: 
> https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/pldb.clj
>  
> 
>  
> might be a place to start. 
>
> On Mon, Apr 18, 2016 at 5:35 PM, JvJ > 
> wrote:
>
>> Can you point me to a working example of one of these structures?
>>
>> On Monday, 18 April 2016 16:30:17 UTC-7, tbc++ wrote:
>>>
>>> And by "fairly common these days", I mean that I run into this sort of 
>>> structure a lot in clojure with anything that is trying to logic or query 
>>> operations. Probably isn't that common outside of projects in that domain. 
>>>
>>> On Mon, Apr 18, 2016 at 5:28 PM, Timothy Baldridge  
>>> wrote:
>>>
 assoc-in is defined in terms of assoc: 
 https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L5901

 And this structure is fairly common these days, it's basically a index 
 of tuples [e a v], and you're creating a eav index and then an av index. 
 Datomic does this same sort of thing, for the datom [e a v t] it creates 
 indices for :eavt :avet and a few others that escape my memory at the 
 moment.  

 On Mon, Apr 18, 2016 at 5:08 PM, JvJ  wrote:

> I'm implementing a map data structure where most of the values are 
> maps or sets, and these values can be cross-indexed by the keys they 
> contain.  I don't know if it already has a name, but I'm calling it a 
> cross-map.  It's similar to a two-way map, but they're not the same thing.
>
> For instance, a common operation would be something like "give me all 
> values of this map that contain the key :a."
>
> In order to do this efficiently, I'm maintaining a second map that 
> maps keys in the values of the main map to keys of the main map whose 
> values contain that key.
>
> If that sounds confusing, consider this:
> main-map:
> {:foo {:a 1 :b 2} :bar {:a 2 :c 4} :baz {:b 3 :c 5}}
>
> Corresponding cross-indices:
> {:a #{:foo :bar} :b #{:foo :baz} :c #{:bar :baz}}
>
> As you can see, each key maintains references to those entries where 
> it is found.
>
> When a nested update occurs that adds an entry to one of the main 
> map's values, the efficient thing to do would be to simply conj that new 
> key onto its corresponding cross-index set.
>
> However, I am trying to implement this as a clojure IPersistentMap, 
> and the only method I can override is assoc, not assoc-in.
>
> Using regular assoc, I would have to compare the old value's keys to 
> the new value's keys and find the set difference of the two, which is not 
> an O(1) operation.
>
> Is there any way to override the behaviour of nested associations or 
> updates?
>
> 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 e

Re: Recur in an overloaded function does not work?

2016-04-20 Thread J.-F. Rompre
You can prevent stack consumption by using trampoline for tail-recursive 
calls to a different arity, and recur for same arity, something like:

(defn find-comment-in-line

([s] (when (pos? (count s))
  (if-let [cs (seq (comment-s? s))]
 ;; yes, a comment symbol found,
 ;; just return the remainder of a string
  (subs s (count (first cs)))

 ;; no, lets check for an opening quote

  (if-let [qs (seq (quote-s? s))]

  ;; yes, an opening quote found,
  ;; now go look for an end quote
  (trampoline find-comment-in-line (subs s 1) qs)

  ;; no, just some other symbol found,
  ;; check for the rest
  (recur (subs s 1))

 ([s q] (when (pos? (count s))
 ;; lets check if it is a quote
 (if-let [qs (seq (quote-s? s))]

 ;; is it a closing quote?
 (if (= qs q)
   ;; yes, lets check for the rest
   (trampoline find-comment-in-line (subs s 1))

   ;; no, just ignore the symbol,
   ;;continue looking for a closing quote
   (recur (subs s 1) q))



On Tuesday, April 19, 2016 at 11:18:40 AM UTC-4, andmed wrote:
>
> Thank you. That the point. If "recur" binds to fn, why it can not know the 
> binding point as the function method based on the number of arguments 
> passed to it? I mean it is clear that Clojure can't do that, but I can see 
> no reason why it could or should not if we choose to implement such 
> syntactic nicety as recur in a function
>

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


Re: Recur in an overloaded function does not work?

2016-04-20 Thread J.-F. Rompre
You can prevent stack consumption by using trampoline for tail-recursive 
calls to a different arity, and recur for same arity, something like:

(defn find-comment-in-line
([s] (when (pos? (count s))
  (if-let [cs (seq (comment-s? s))]
 ;; yes, a comment symbol found, 
 ;; just return the remainder of a string
  (subs s (count (first cs))) 

 ;; no, lets check for an opening quote
  (if-let [qs (seq (quote-s? s))] 

  ;; yes, an opening quote found, 
  ;; now go look for an end quote
  (trampoline find-comment-in-line (subs s 1) qs) 

  ;; no, just some other symbol found, 
  ;; check for the rest
  (recur (subs s 1)) 

 ([s q] (when (pos? (count s))
 ;; lets check if it is a quote 
 (if-let [qs (seq (quote-s? s))] 

 ;; is it a closing quote?
 (if (= qs q) 
   ;; yes, lets check for the rest
   (trampoline find-comment-in-line (subs s 1)) 

   ;; no, just ignore the symbol, 
   ;;continue looking for a closing quote
   (recur (subs s 1) q)) 


On Tuesday, April 19, 2016 at 11:18:40 AM UTC-4, andmed wrote:
>
> Thank you. That the point. If "recur" binds to fn, why it can not know the 
> binding point as the function method based on the number of arguments 
> passed to it? I mean it is clear that Clojure can't do that, but I can see 
> no reason why it could or should not if we choose to implement such 
> syntactic nicety as recur in a function
>

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


Re: Incanter 1.9 and Clojure 1.7

2016-04-20 Thread Bruce Durling
Myriam,

Would you check with the latest commit on the develop branch please?
We're trying to get a new SNAPSHOT release out that might sort a
number of issues.

If yours isn't sorted then I might look at it as we use PCA a fair bit too.

Do you have a small example of some code that is failing?

cheers,
Bruce

On Wed, Apr 20, 2016 at 3:19 PM, myriam abramson  wrote:
> I am getting the following error with Incanter 1.9 running the PCA example
> from the documentation:
>
> CompilerException java.lang.ClassCastException: java.lang.Boolean cannot be
> cast to java.lang.Number, compiling:(pca.clj:17:10)
>
> That works fine with Clojure 1.6. (and yes, I know that the latest is 1.8).
>
> What to do?
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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


cljs-ajax question

2016-04-20 Thread ru
Hi,

cljs-ajax transforms vector parameter into map during transfer like this: 
[40.328 -68.348] -> { 0 40.328, 1 -68.348}.
What does it mean and how avoid this? Thanks.

Sincerely,
  Ru

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


Incanter 1.9 and Clojure 1.7

2016-04-20 Thread myriam abramson
I am getting the following error with Incanter 1.9 running the PCA example
from the documentation:

CompilerException java.lang.ClassCastException: java.lang.Boolean cannot be
cast to java.lang.Number, compiling:(pca.clj:17:10)

That works fine with Clojure 1.6. (and yes, I know that the latest is 1.8).

What to do?

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

2016-04-20 Thread Leon Grapenthin
It's very simple: Leave configuration file management and stuff out of the 
lib. Instead, pass the translations dictionary to your library as an 
argument.

On your app level, you could still load the desired dictionary from a 
config file but the lib should stay independent of this.


On Wednesday, April 20, 2016 at 6:09:12 AM UTC+2, Shantanu Kumar wrote:
>
> How about accepting a fn as argument to provide the config required? In 
> that case the user is free to use whichever library/hand-rolled code to 
> read config from a file.
>
> Shantanu
>
> On Tuesday, 19 April 2016 22:15:22 UTC+5:30, Facundo Olano wrote:
>>
>> Hi! I started to use clojure a couple of months ago and now I'm 
>> struggling to extract a little library from a larger project I'm working on.
>>
>> The lib is a gettext-like tool that allows translating strings based on a 
>> translations dictionary. I'd like to be able to include the lib as a 
>> dependency of the larger project and point to my translations dictionary 
>> from a setting in a configuration file (Ideally I would use project.clj to 
>> avoid having a lib specific file just for one setting).
>>
>> My problem is I'm not sure how to read a configuration file in my project 
>> from the generated JAR of the lib (if that's even possible and not a bad 
>> idea for some reason). I tried using configleaf 
>>  and it worked while I 
>> included the lib as a checkout project but it seems the config file gets 
>> freezed to whatever it is when the lib's JAR is packed.
>>
>> I wonder if there's a straightforward and idiomatic way to achieve this. 
>> "That's a terrible idea" type of answers are also welcome :P
>>
>> Thanks, 
>> Facundo.
>>
>

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