Re: Possible ClojureScript compiler issue...

2016-10-18 Thread David Nolen
This issue is fixed in master now thanks to Thomas Heller. The performance
hit is negligible.

Thank you for the report.

David

On Tue, Oct 18, 2016 at 3:45 PM, John Szakmeister 
wrote:

> On Tue, Oct 18, 2016 at 5:59 AM, Thomas Heller 
> wrote:
> > Don't think there is a best practice for your case in particular.
>
> Okay.  Earlier in the thread you said "while this issue can be very
> confusing you will hardly ever run into it when following best
> practices."  So it seemed to me that perhaps I missing something
> important, or didn't know about a best practice that would have saved
> me.  I think the issue here is a bit different though.  There's
> nothing that would have saved short of knowing that js->clj has this
> issue lurking in the background. :-)
>
> > The issue is that js->cli is built on top of protocols to allow
> converting
> > custom JS types to CLJS types. Which makes it extensible for the price of
> > checking protocols. In your case you are converting JSON which cannot
> have
> > custom types, so a custom converter only checking for the very few
> possible
> > JSON types would "fix" your problem (and would probably be a lot faster).
>
> Yep.  OTOH, I don't really need the performance and js->clj would have
> been just as nice to use, if it worked correctly. :-)
>
> > The case can be made that cljs-ajax should not be using js->clj when
> > converting JSON, maybe even add a json->clj to cljs.core.
>
> I think having json->clj would be a nice option.  Though for
> cljs-ajax, we probably need to roll our own since the api wouldn't be
> available in older ClojureScript versions.
>
> > The sentinel is the "safest" solution but impacts the performance of
> > everyone, so we should be doing more benchmarks on more platforms before
> > deciding anything. Benchmarks and Votes on the Jira Issue would help to
> push
> > this along.
>
> True, but I think the correctness argument here is pretty valuable.
> Again, much of what I see out there is the js->clj is the way to
> convert data, and having this problem lurking seems like setting folks
> up for failure.  I'm pretty persistent when it comes to
> troubleshooting this stuff, but I could see others being awfully
> frustrated by the result.  So I hope that some version of the sentinel
> patch makes it in. :-)
>
> -John
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you 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 ClojureScript compiler issue...

2016-10-18 Thread John Szakmeister
On Tue, Oct 18, 2016 at 5:59 AM, Thomas Heller  wrote:
> Don't think there is a best practice for your case in particular.

Okay.  Earlier in the thread you said "while this issue can be very
confusing you will hardly ever run into it when following best
practices."  So it seemed to me that perhaps I missing something
important, or didn't know about a best practice that would have saved
me.  I think the issue here is a bit different though.  There's
nothing that would have saved short of knowing that js->clj has this
issue lurking in the background. :-)

> The issue is that js->cli is built on top of protocols to allow converting
> custom JS types to CLJS types. Which makes it extensible for the price of
> checking protocols. In your case you are converting JSON which cannot have
> custom types, so a custom converter only checking for the very few possible
> JSON types would "fix" your problem (and would probably be a lot faster).

Yep.  OTOH, I don't really need the performance and js->clj would have
been just as nice to use, if it worked correctly. :-)

> The case can be made that cljs-ajax should not be using js->clj when
> converting JSON, maybe even add a json->clj to cljs.core.

I think having json->clj would be a nice option.  Though for
cljs-ajax, we probably need to roll our own since the api wouldn't be
available in older ClojureScript versions.

> The sentinel is the "safest" solution but impacts the performance of
> everyone, so we should be doing more benchmarks on more platforms before
> deciding anything. Benchmarks and Votes on the Jira Issue would help to push
> this along.

True, but I think the correctness argument here is pretty valuable.
Again, much of what I see out there is the js->clj is the way to
convert data, and having this problem lurking seems like setting folks
up for failure.  I'm pretty persistent when it comes to
troubleshooting this stuff, but I could see others being awfully
frustrated by the result.  So I hope that some version of the sentinel
patch makes it in. :-)

-John

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

2016-10-18 Thread Gary Trakhman
Just a quick glance makes it look like handlers can be overridden, but I
haven't tried this and I don't think it's documented anywhere:
https://github.com/cognitect/transit-cljs/blob/master/src/cognitect/transit.cljs#L109

On Tue, Oct 18, 2016 at 11:41 AM John Szakmeister 
wrote:

> Yes, you could do that, but it could also do Bad Things.  Namely if
> you have strings that match some of the format, it could be
> misinterpreted as Transit data rather than JSON, so I don't consider
> it a particularly useful solution either.  It just moves where the
> problem can happen. :-(  If there was a way to so "ignore the transit
> extensions", that would change things though.
>
> -John
>
> On Tue, Oct 18, 2016 at 7:36 AM, Gary Trakhman 
> wrote:
> > If you're parsing raw json streams/strings, I think transit claims to be
> a
> > 30x perf improvement over js/JSON.parse+js->clj:
> > http://swannodette.github.io/2014/07/26/transit-clojurescript
> >
> > On Tue, Oct 18, 2016 at 6:41 AM Matching Socks 
> wrote:
> >>
> >> A reliable "implements?" would be better than a fast-and-sometimes-wrong
> >> "implements?".
> >>
> >> With that in mind, have you tried a distinct sentinel object, as opposed
> >> to true?
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> >> Groups "Clojure" group.
> >> To post to this group, send email to clojure@googlegroups.com
> >> Note that posts from new members are moderated - please be patient with
> >> your first post.
> >> To unsubscribe from this group, send email to
> >> clojure+unsubscr...@googlegroups.com
> >> For more options, visit this group at
> >> http://groups.google.com/group/clojure?hl=en
> >> ---
> >> You received this message because you 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.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you 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 ClojureScript compiler issue...

2016-10-18 Thread John Szakmeister
Yes, you could do that, but it could also do Bad Things.  Namely if
you have strings that match some of the format, it could be
misinterpreted as Transit data rather than JSON, so I don't consider
it a particularly useful solution either.  It just moves where the
problem can happen. :-(  If there was a way to so "ignore the transit
extensions", that would change things though.

-John

On Tue, Oct 18, 2016 at 7:36 AM, Gary Trakhman  wrote:
> If you're parsing raw json streams/strings, I think transit claims to be a
> 30x perf improvement over js/JSON.parse+js->clj:
> http://swannodette.github.io/2014/07/26/transit-clojurescript
>
> On Tue, Oct 18, 2016 at 6:41 AM Matching Socks  wrote:
>>
>> A reliable "implements?" would be better than a fast-and-sometimes-wrong
>> "implements?".
>>
>> With that in mind, have you tried a distinct sentinel object, as opposed
>> to true?
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you 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.

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

2016-10-18 Thread Alex Miller


On Saturday, October 15, 2016 at 10:17:15 PM UTC-5, Josh Tilles wrote:
>
> I’ve got a couple questions for Alex Miller and/or the other Cognitect 
> folks.
>
>1. *Are single-segment namespaces still “bad” when it comes to 
>registering specs under qualified keywords?*
>
> I will give a qualified *sometimes*. :) There are several possible 
contexts and I would not give the same answer for all of them. 

If you are creating a library, particularly a library that will 
interoperate with other libraries, I would strongly recommend using 
namespaced keywords with sufficient namespaces that you will not clash with 
others. In some cases, a library may be well-entrenched or well-known 
enough to make a single namespace sufficient. For example, consider ring 
request/response maps and middleware, which is a prime example for 
interoperable libraries. If you were creating a Ring session middleware, 
you might want to use namespace keys in the request like 
:ring.session/token (or whatever, don't compare this to any actual existing 
lib). Here, "ring" is probably sufficiently established to be unambiguous 
and "ring.session" scopes you to something narrower. I think that's highly 
preferable to just :ring/token. 

If you're creating a brand new library designed for interoperation with 
other libs, I would strongly consider using more than a single segment 
namespace that combines some notion of organization and project. 

If you're creating an internal application, I think you're free to do 
whatever you want. So a single segment path in the context of a single 
application might be totally fine - :domain/email. As long as you're not 
colliding with some library and you coordinate in your private scope, do 
what communicates the best for you. If you have multiple internal projects 
that need to coordinate, you might need more namespace segments to 
disambiguate.

>
>1. In the past, single-segment namespaces have been discouraged in the 
>Clojure community—both because of Java interop concerns and because of the 
>possibility of name-collision when combining projects. However, many of 
> the 
>spec examples I’ve seen have demonstrated registering specs under keywords 
>qualified by a single-segment namespace. For example, the guide’s 
>section on multi-spec  
>defines :search/url and :error/message. Is that because 
>namespace-qualifiers of specs shouldn’t be under the same constraints as 
>namespaces used to organize code? 
>
> These short names are mostly chosen to make the examples brief and 
readable, although they might be sufficient when used in an application as 
mentioned above. However, I think it is important to note that your 
namespace qualifiers do NOT need to correspond to your code. You can use 
create-ns and alias to create shorter names in the context of a particular 
namespace just to save typing, while still using namespaces independent 
from your code. We are considering changing alias to automatically create a 
ns if it does not exist (see http://dev.clojure.org/jira/browse/CLJ-2030).

>
>1. I’m *guessing* not; it seems more likely that the single-segment 
>namespaces have been used only to keep the code snippets straightforward 
>and focused on spec, and that “real” code would alias (e.g.) 
>my-company.my-project.search as search before defining a ::search/url 
>spec.
>
> Yes. 

>
>1. 
>2. *When designing, how do you decide whether to use a simple keyword 
>or a qualified one?*
>There’s an interesting mix of the two in the official docs and in the 
>code for spec itself. For example: the spec rationale 
> and guide 
> both use simple keywords 
>when labeling path components, and spec reports invocation errors for 
>instrumented functions with maps that exclusively use qualified keys at 
> the 
>“root” but simple keywords appear as values 
>
> 
>  
>and as keys in nested maps 
>
> 
>.
>
> Path components are simple as they exist in the context of a particular 
spec which has a fully-qualified name. I suspect in general the other 
choices mostly follow that pattern - fully-qualified when they are used 
without context or when they might be intermingled with other keys and 
unqualified when used as keys in the scope of some other context. That 
said, things may not be 100% consistent in every possible case.

Hope that helps!
Alex

 

> Thank you for your help. I really appreciate it.
>
> Best,
> Josh
>

-- 
You received this message because you are subscribed 

Re: join* tables from csv

2016-10-18 Thread Alan Thompson
You may also like this answer using DataScript to solve a similar problem:


http://stackoverflow.com/questions/39712460/how-to-map-different-values-from-2-sets-in-clojure-based-on-unique-value/39714081#39714081

On Tue, Oct 18, 2016 at 6:09 AM, Moe Aboulkheir  wrote:

> (defn join* [d1 c1 d2 c2]
>   (clojure.set/join (into #{} d1) (into #{} d2) {c1 c2}))
>
> Or else look at the implementation of set/join.
>
> Take care,
> Moe
>
> On Tue, Oct 18, 2016 at 9:41 AM,  wrote:
>
>> Hey guys, i'm beginner and need help.
>>
>> I have a task:
>>
>> ;; (join* (join* student-subject :student_id student :id) :subject_id
>> subject :id)
>> ;; => [{:subject "Math", :subject_id 1, :surname "Ivanov", :year 1998,
>> :student_id 1, :id 1}
>> ;; {:subject "Math", :subject_id 1, :surname "Petrov", :year 1997,
>> :student_id 2, :id 2}
>> ;; {:subject "CS", :subject_id 2, :surname "Petrov", :year 1997,
>> :student_id 2, :id 2}
>> ;; {:subject "CS", :subject_id 2, :surname "Sidorov", :year 1996,
>> :student_id 3, :id 3}]
>> ;;
>> ;; Hint: reduce, conj, merge, first, filter, get
>> ;; Here column1 belongs to data1, column2 belongs to data2.
>> (defn join* [data1 column1 data2 column2]
>>   )
>>
>> so.. i'm trying to write join (defn join* [data1 col1 data2 col2] ... )
>> data1 and data2 like: ({:key1 val1 :key2 val2} {:key1 val3 :key2 val4})
>> after => example result.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you 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.
>

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

2016-10-18 Thread Moe Aboulkheir
(defn join* [d1 c1 d2 c2]
  (clojure.set/join (into #{} d1) (into #{} d2) {c1 c2}))

Or else look at the implementation of set/join.

Take care,
Moe

On Tue, Oct 18, 2016 at 9:41 AM,  wrote:

> Hey guys, i'm beginner and need help.
>
> I have a task:
>
> ;; (join* (join* student-subject :student_id student :id) :subject_id
> subject :id)
> ;; => [{:subject "Math", :subject_id 1, :surname "Ivanov", :year 1998,
> :student_id 1, :id 1}
> ;; {:subject "Math", :subject_id 1, :surname "Petrov", :year 1997,
> :student_id 2, :id 2}
> ;; {:subject "CS", :subject_id 2, :surname "Petrov", :year 1997,
> :student_id 2, :id 2}
> ;; {:subject "CS", :subject_id 2, :surname "Sidorov", :year 1996,
> :student_id 3, :id 3}]
> ;;
> ;; Hint: reduce, conj, merge, first, filter, get
> ;; Here column1 belongs to data1, column2 belongs to data2.
> (defn join* [data1 column1 data2 column2]
>   )
>
> so.. i'm trying to write join (defn join* [data1 col1 data2 col2] ... )
> data1 and data2 like: ({:key1 val1 :key2 val2} {:key1 val3 :key2 val4})
> after => example result.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you 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.


join* tables from csv

2016-10-18 Thread evgeniy . kurpanov
Hey guys, i'm beginner and need help.

I have a task:

;; (join* (join* student-subject :student_id student :id) :subject_id 
subject :id)
;; => [{:subject "Math", :subject_id 1, :surname "Ivanov", :year 1998, 
:student_id 1, :id 1}
;; {:subject "Math", :subject_id 1, :surname "Petrov", :year 1997, 
:student_id 2, :id 2}
;; {:subject "CS", :subject_id 2, :surname "Petrov", :year 1997, 
:student_id 2, :id 2}
;; {:subject "CS", :subject_id 2, :surname "Sidorov", :year 1996, 
:student_id 3, :id 3}]
;;
;; Hint: reduce, conj, merge, first, filter, get
;; Here column1 belongs to data1, column2 belongs to data2.
(defn join* [data1 column1 data2 column2]
  )

so.. i'm trying to write join (defn join* [data1 col1 data2 col2] ... ) 
data1 and data2 like: ({:key1 val1 :key2 val2} {:key1 val3 :key2 val4}) 
after => example result.

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

2016-10-18 Thread Gary Trakhman
If you're parsing raw json streams/strings, I think transit claims to be a
30x perf improvement over js/JSON.parse+js->clj:
http://swannodette.github.io/2014/07/26/transit-clojurescript

On Tue, Oct 18, 2016 at 6:41 AM Matching Socks  wrote:

> A reliable "implements?" would be better than a fast-and-sometimes-wrong
> "implements?".
>
> With that in mind, have you tried a distinct sentinel object, as opposed
> to true?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you 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 ClojureScript compiler issue...

2016-10-18 Thread Matching Socks
A reliable "implements?" would be better than a fast-and-sometimes-wrong 
"implements?". 

With that in mind, have you tried a distinct sentinel object, as opposed to 
true?  

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

2016-10-18 Thread Thomas Heller
Don't think there is a best practice for your case in particular.

The issue is that js->cli is built on top of protocols to allow converting 
custom JS types to CLJS types. Which makes it extensible for the price of 
checking protocols. In your case you are converting JSON which cannot have 
custom types, so a custom converter only checking for the very few possible 
JSON types would "fix" your problem (and would probably be a lot faster).

The case can be made that cljs-ajax should not be using js->clj when 
converting JSON, maybe even add a json->clj to cljs.core.

The sentinel is the "safest" solution but impacts the performance of 
*everyone*, so we should be doing more benchmarks on more platforms before 
deciding anything. Benchmarks and Votes on the Jira Issue would help to 
push this along.

Cheers,
/thomas

On Tuesday, October 18, 2016 at 10:21:21 AM UTC+2, John Szakmeister wrote:
>
> On Tue, Oct 18, 2016 at 2:59 AM, Thomas Heller  > wrote: 
> [snip] 
> > While this issue can be very confusing you will hardly ever run into it 
> when 
> > following best practices. As David suggested using a custom js->clj here 
> > would prevent the issue and is probably the best course of action 
> > regardless. 
>
> Which best practices?  Is there a good place to read about them?  I've 
> not seen anything that would have steered me away from this problem. 
> In fact, I've seen quite the opposite: js->clj appears to be *the* way 
> to convert from JavaScript data structures to ClojureScript ones. :-( 
>
> FWIW, I did end up putting something together that was able to do what 
> I needed, but it could have easily gone a different direction. 
> js->clj was being called in a library that I'm using (cljs-ajax), and 
> it, fortunately, had a knob that I could turn to just get the raw json 
> back out without running anything through js->clj.  Had the knob been 
> missing, I think the solution would have been much more painful as I'd 
> either have to fork and maintain a copy of the library, migrate to a 
> different library, or write my own to replace it with. :-( 
>
> I also like the sentinel idea.  I hope some version of your patch is 
> incorporated. 
>
> -John 
>

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

2016-10-18 Thread Rostislav Svoboda
1. Use Yoneda Lemma. Its intuitive explanation is:
You work at a particle accelerator. You want to understand some particle. All
you can do are throw other particles at it and see what happens. If you
understand how your mystery particle responds to all possible test particles at
all possible test energies, then you know everything there is to know about your
mystery particle.

2. Use Howard Curry isomorphism. It states something like:
A program is a proof that from a given business problem a certain solution
(proposed by a business domain expert) can really be derived. I.e. it's not the
programmer solving problems. All the solutions exist per se already. The
programmer just connects a problem with a particular solution by writing some
code.

So:
- For every method using global variables create its functional version with
  object types, e.g.:
old: int foo(int x) { return x + this.y;}
new: Integer fooFunctional(Integer x, Integer y) { return x + y;}

- For every function create its fully typed version:
old: Integer fooFunctional(Integer x, Integer y) { return x + y;}
new: FooType fooFunctionalTyped(XType x, YType y) { return x + y;}

where XType and YType may be e.g. only odd or even Integers and FooType is
an union of XType and YType.

- simplify your type system

- profit! :)

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

2016-10-18 Thread John Szakmeister
On Tue, Oct 18, 2016 at 2:59 AM, Thomas Heller  wrote:
[snip]
> While this issue can be very confusing you will hardly ever run into it when
> following best practices. As David suggested using a custom js->clj here
> would prevent the issue and is probably the best course of action
> regardless.

Which best practices?  Is there a good place to read about them?  I've
not seen anything that would have steered me away from this problem.
In fact, I've seen quite the opposite: js->clj appears to be *the* way
to convert from JavaScript data structures to ClojureScript ones. :-(

FWIW, I did end up putting something together that was able to do what
I needed, but it could have easily gone a different direction.
js->clj was being called in a library that I'm using (cljs-ajax), and
it, fortunately, had a knob that I could turn to just get the raw json
back out without running anything through js->clj.  Had the knob been
missing, I think the solution would have been much more painful as I'd
either have to fork and maintain a copy of the library, migrate to a
different library, or write my own to replace it with. :-(

I also like the sentinel idea.  I hope some version of your patch is
incorporated.

-John

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

2016-10-18 Thread 'Jason Courcoux' via Clojure
Hi Alex,

Thanks very much for this, makes sense and has solved my issue.

After a trying a few things, it appears that the ArityException was thrown
because I would have needed to wrap my regex with s/spec

i,e,

(s/fdef my-function :args (s/cat :board (s/spec ::board)))

So I think this all makes sense now.

Thanks again.

Jason



On 17 October 2016 at 21:02, Alex Miller  wrote:

> I would back way up to the beginning and reconsider your ::board spec.
> Generally for any data where the structures are homogenous, you're probably
> better off using one of the collection specs like coll-of (or map-of,
> every, every-kv) rather than a regex, which should primarily be used when
> you have a sequential structure with syntactic "parts" to it (such as an
> arg string or other "dsl" type use case).
>
> Because s/and flows conformed values you can get the same effect as you
> did with &:
>
> (s/def ::board (s/and (s/coll-of ::row :min-count 1) #(apply = (map count
> %
>
> Your generator seems like it should work. You might also want to constrain
> more tightly than pos-int? to keep it from getting out of hand. You could
> use something like (s/gen (s/int-in 1 10)) for example.
>
>
>
> On Monday, October 17, 2016 at 2:32:20 PM UTC-5, Jason Courcoux wrote:
>>
>> Hi.
>>
>> I've been experimenting with clojure spec and a game of life problem, and
>> have been trying to spec a rectangular board of unknown size made up of a
>> collection of rows, each of which contain an equal number of cells. My
>> initial attempt was:-
>>
>> (def cell? #{0 1})
>>
>> (s/def ::row (s/coll-of cell? :min-count 1))
>>
>> (s/def ::board (s/& (s/+ ::row)
>> #(apply = (map count %
>>
>>
>> This appears to work, but I'm wondering if there is a better way to
>> specify the constraint that every row should be the same length? What would
>> be the recommended way to achieve this?
>>
>> Following on from this, I then wanted to generate input boards and
>> exercise a function so I tried the following which give me an
>> ArityException:-
>>
>> (s/def ::board (s/with-gen
>>  (s/& (s/+ ::row)
>>   #(apply = (map count %)))
>>  #(gen/bind (s/gen pos-int?)
>> (fn [n]
>>   (s/gen (s/coll-of (s/coll-of cell? :count 
>> n)))
>>
>> (s/fdef my-function :args (s/cat :board ::board))
>>
>> (defn my-function [board])
>>
>> (s/exercise (:args (s/get-spec `my-function)) 1)
>>
>> => ([([1] [0] [0] [1] [0]) {:board [[1] [0] [0] [1] [0]]}])
>>
>> (s/exercise-fn `my-function)
>>
>> => ArityException Wrong number of args (20) passed to: user/my-function
>>
>>
> This is pretty interesting and the number 20 is pretty suspicious as
> that's the max number of args per function - I'm guessing pos-int? is
> causing problems there.
>
>
>>
>>
>> If I try and do something similar without the custom generator such as:
>>
>> (s/def ::coll (s/coll-of (s/coll-of int? :count 2)))
>>
>> (s/fdef my-function2 :args (s/cat :board ::coll))
>>
>> (defn my-function2 [board])
>>
>> (s/exercise (:args (s/get-spec `my-function2)) 1)
>>
>> => ([(*[*[0 -1] [0 -1] [0 -1]*]*) {:board [[0 -1] [0 -1] [0 -1]]}])
>>
>> (s/exercise-fn `my-function2)
>>
>> This all works as expected. I can see that there is an extra level of
>> nesting here though and this must be where the error is coming from, as
>> it's applying my-function to the collection rather than using it as a
>> single argument - but I'm not sure what is causing this difference.
>>
>> These look the same in terms of structure:
>>
>> (gen/sample (s/gen ::coll) 1)
>> => ([[-1 -1] [-1 0] [0 -1] [-1 -1] [-1 0] [-1 0]])
>>
>> (gen/sample (s/gen ::board) 1)
>> => ([[0 1] [1 1] [1 1] [1 1] [1 1] [0 0] [0 1]])
>>
>> (s/fdef my-function :args (s/cat :board ::board))
>>
>> (s/fdef my-function2 :args (s/cat :board ::coll))
>>
>>
>> But these don't:
>>
>> (gen/sample (s/gen (:args (s/get-spec `my-function))) 1)
>> => (([1 0] [0 0] [0 1] [0 1] [1 1]))
>> (gen/sample (s/gen (:args (s/get-spec `my-function2))) 1)
>> => (([[-1 -1] [-1 -1] [0 0] [0 0] [-1 0] [-1 -1] [0 0]]))
>>
>>
>> I'm sure it's something obvious, but I been looking for a couple of hours
>> and can't seem to see it - could someone please help point me in the right
>> direction.
>>
>> Thanks in advance.
>>
>> Jason
>>
>>
>> --
>> Jason Courcoux
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails 

Re: [ANN] clj-xchart – A charting/plotting library for Clojure

2016-10-18 Thread Joachim De Beule
Hi Marshall,

You might want to have a look at https://github.com/aphyr/gnuplot

>From the repo: "Datasets are streamed as sequences directly to gnuplot's 
stdin, so there's no temporary files to worry about. Yep, lazy sequences 
are streamed lazily. My laptop can plot about 10 million points in about a 
minute, and most of the CPU time is spent inside gnuplot in that test, so 
I'm reasonably happy."

Cheers,
Joachim.

Op maandag 17 oktober 2016 07:54:41 UTC+2 schreef Mars0i:
>
> Looks very nice! Thanks Jean Niklas.  I've been using Incanter for charts, 
> which has been fine so far for my needs, but clj-xchart looks like it will 
> make it easier to make nicer charts, and it would avoid loading much of 
> Incanter when you don't need some of the other things Incanter provides.  
> (I also use nvd3 to generate charts in a browser with Clojurescript.)
>
> Since you've developed a charting library, maybe I'll mention a feature 
> that I have wanted (I think!): 
>
> I've been making plots with a large number of points--100K, sometimes even 
> 1M or 2M per data sequence.  Sometimes I will sample a larger sequence 
> every 10 or 100 steps to reduce the burden on the Incanter or nvd3 plotting 
> function, but sometimes I want to see what the data looks like with all of 
> the points.
>
> I generate the data in a lazy sequence, using iterate, where, let's say, 
> each element of the sequence is a map containing several pieces  of y 
> values for the x value corresponding to that element of the sequence, e.g.
>
> data = ({:a y-a-1, :b y-b-1, :c y-c-1}, {:a y-a-2, :b y-b-2, :c y-c-2}, 
> ...)
>
> In order to plot all three sequences of y values in Incanter or nvd3 (and 
> clj-xchart?), I have to extract a new sequence of values for each data 
> series, e.g. like this:
>
> (map :a data)
> (map :b data)
> (map :c data)
>
> and I have to generate several sequences of x values by calling (range) 
> repeatedly.  I pass these six lazy sequences to the chart function, but at 
> least in Incanter and nvd3, I don't believe Incanter does anything until it 
> realizes all of the sequences.  That means that it realizes six distinct 
> sequences, I think, and my initial sequence of maps will have been realized 
> as well.  
>
> But if I'm plotting several sequences of y values that are embedded in a 
> sequence of maps or vectors, each with several y values for the same x, I 
> wonder if it could be more to efficient pass the entire complex sequence to 
> the plotting function at once, and only provide one set of x values if all 
> of the y values will share the same x's.  If the plotting function extracts 
> the y values as it reads through the sequence of maps/vectors, and needs 
> only one sequence of x's, then only two sequences are realized.
>
> Maybe this is an unusual need, at present, but as Clojure is used for more 
> scientific applications, it might become more common.
>
>
>

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

2016-10-18 Thread Thomas Heller
Yeah the issue can be quite confusing since the error produced may complain 
about protocols you are not even calling anywhere. I've run into it several 
times when the code ended up checking protocols on js/window. Since that 
has all the munged global variables closure produces just about anything 
can result in a false positive there.

As for the sentinel, there is no notable difference to which sentinel is 
used. Strings, Numbers, boolean, object ... doesn't really matter. object 
with ===/identical? check seemed the simplest without a chance for a false 
positive (any number, string, boolean can in theory still clash).

4) would not be acceptable to me as there are quite a lot of "$cljs..." 
properties and increasing the code size for such a tiny benefit isn't 
really justified IMHO.

While this issue can be very confusing you will hardly ever run into it 
when following best practices. As David suggested using a custom js->clj 
here would prevent the issue and is probably the best course of action 
regardless.

/thomas

On Tuesday, October 18, 2016 at 3:12:40 AM UTC+2, Antonin Hildebrand wrote:
>
> I think one reason why these issues are reported infrequently is because 
> it is really hard to track them down. I can imagine people disable 
> :advanced optimizations or restructure their code instead of hunting down 
> the real cause. John went really far to isolate/demonstrate the issue.
>
> Thanks for posting that sentinel idea, Thomas. It looks really simple. I 
> think instead of sentinel object we could use some large random integer 
> which could have similar performance profile as checking for boolean.
>
> I would add another possible idea:
>
> 4. we could alter google closure compiler with ClojureScript-aware 
> renaming logic, it would preserve prefix $cljs prefix when renaming 
> properties[1]. Also in ClojureScript compiler we would rename all 
> cljs-related properties to use this convention.
>
> Pros:
> 1. This would decrease a chance of clashes. When someone runs into it - it 
> would be quite self-describing that "$cljs" named property is involved.
>
> Cons:
> 1. This would lead to slightly bigger generated code (all the $cljs 
> prefixes which would previously disappear).
> 2. The bigger downside IMO is that we would have to maintain our own fork 
> of Closure Compiler. Which is not that scary with git. It is pretty easy to 
> automate rebasing of a few patch-commits on top of arbitrary complex 
> foreign repo.
>
> [1] 
> https://github.com/google/closure-compiler/blob/5616a66e40c5dc6ec9be9beacfc0ea20d47bbcfc/src/com/google/javascript/jscomp/RenameProperties.java#L284
>
>
>
> On Sunday, October 16, 2016 at 4:36:38 PM UTC+2, Thomas Heller wrote:
>>
>> FWIW I investigated the check with "true" and a sentinel value and found 
>> them to both have a small performance impact over just checking for a 
>> true-ish property.
>>
>> http://dev.clojure.org/jira/browse/CLJS-1658
>>
>> The impact is really small so it might be worth the trade-off.
>>
>> /thomas
>>
>> On Sunday, October 16, 2016 at 3:59:20 PM UTC+2, David Nolen wrote:
>>>
>>> It's true that there other scenarios where you can encounter this but it 
>>> gets reported infrequently enough that I don't think these kinds of 
>>> property name collisions are common.
>>>
>>> Still it has come up before and I think the simplest solution least 
>>> likely to adversely affect performance is to test for a def'onced unique 
>>> object instead of `true`.
>>>
>>> David
>>>
>>> On Sat, Oct 15, 2016 at 8:46 PM, Antonin Hildebrand <
>>> antonin.h...@gmail.com> wrote:
>>>
 Unfortunately, this problem is not specific to `js->clj` only.

 I believe in general under :advanced optimizations, any object which 
 was created or modified by a code which 
 was not subject of the same closure compiler optimization pass could 
 exhibit similar problems when used with ClojureScript core functions like 
 `satisfies?`.

 That also includes working with external data (your case), and working 
 with objects created/modified by adding properties by string names.

 To illustrate, I created a screenshot of cljs type instance with two 
 protocols, to see the internals in dev mode:

 https://dl.dropboxusercontent.com/u/559047/cljs-protocol-internals-01.png
 In the selected text I highlighted part of generated code for 
 `satisfies?` call.

 ClojureScript adds/checks $cljs prefixed properties to objects. These 
 internal properties get renamed by closure compiler.
 So any object which happens to have one of those renamed names 
 independently added as their property will potentially confuse functions 
 like `satisfies?`.

 Possible solutions I see:

 1. use string names for clojurescript internal properties, and avoid 
 clashes by using "unique-enough" prefix even in advanced mode - still not 
 safe solution, but would minimize clash chances

 or