Re: UTF16 Surrogate Pairs in Fressian not encoded to utf8 correctly

2019-11-07 Thread Francis Avila
Perhaps this is so invalid character streams (e.g. mismatched or orphaned 
surrogate pairs) can survive encoding and decoding (I haven't tested)? 
Strictly speaking not every CharacterSequence is validly encode-able to 
utf-8. Java just kind of hides this. For example, this is a reversed 
surrogate pair (or two orphaned surrogates, take your pick):

(mapv #(Integer/toHexString (int %)) (String. (.getBytes "\uDC00\uD800" 
"UTF-8") "UTF-8"))
=> ["3f" "3f"]

Note that Java's utf-8 encoder will translate these to "?", losing 
information about the original char value.

That said, if this is the case, it makes more sense for fressian to say "we 
have a custom encoding that is mostly utf-8 except it preserves invalid 
utf-16" than "this is utf-8". I wonder if other fressian implementations 
handle this the same way? Javascript also shares java's utf-16 string type 
but not every platform does.


On Thursday, November 7, 2019 at 6:51:40 AM UTC-6, Kyle Wilt wrote:
>
> I posted an issue about this to the datomic/fressian github page but I 
> don't know if anyone is monitoring it anymore.
>
> https://github.com/Datomic/fressian/issues/7
>
> I'm trying to find out if this is intentional for some reason or a bug. 
> Right now it encodes UTF16 surrogate pairs as two 3 byte values for 10 
> rather 
> than one 4 byte value as expected.
>

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


Re: [Q] Deploying two artefacts/jars with same group/artefactid via Leiningen

2019-03-28 Thread Francis Avila






I haven't used lein-package but I am surprised it doesn't handle this case. 
This issue I think describes a similar use case, perhaps it helps you? 
https://github.com/pliant/lein-package/issues/9

`lein deploy` has a long form which accepts arbitrary filenames:

$ lein help deploy
Deploy jar and pom to remote repository.

The target repository will be looked up in :repositories in project.clj:

  :repositories [["snapshots" "https://internal.repo/snapshots;]
 ["releases" "https://internal.repo/releases;]
 ["alternate" "https://other.server/repo;]]

If you don't provide a repository name to deploy to, either "snapshots" or
"releases" will be used depending on your project's current version. You may
provide a repository URL instead of a name.

See `lein help deploying` under "Authentication" for instructions on
how to configure your credentials so you are not prompted on each
deploy.

You can also deploy arbitrary artifacts from disk:

$ lein deploy myrepo com.blueant/fancypants 1.0.1 fancypants.jar pom.xml

While this works with any arbitrary files on disk, downstream projects will 
not
be able to depend on jars that are deployed without a pom.

Arguments: ([] [repository] [repository identifier version & files])

So as an extra step after a normal deploy you can do:

lein deploy myrepo com.blueant/fancypants 1.0.1 fancypants-1.0.1-app.jar

This would add this jar as-is to the correct directory in myrepo.


On Thursday, March 28, 2019 at 1:05:39 PM UTC-5, henrik42 wrote:
>
> Hi,
>
> I have an uberjar that I want to deploy to clojars. Part of
> building the uberjar is building the "standard" lib-jar of the
> same project.
>
> Now I'd like to release/deploy both with the same group/artefactid to
> clojars. The uberjar should get the :classifier "app".
>
> So after that people could lein depend on the lib-jar and can download
> the "app" via browser/wget/etc.
>
> I've tried different things (e.g. lein-package) with no luck.
>
> The problem is that deploying them "one at a time" re-deploys pom.xml and 
> that fails. 
> So deployen two jars must be aware of this and deploy pom.xml only once.
>
> Any idea?
>
> -- Henrik
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: global-hierarchy.. private?

2018-04-11 Thread Francis Avila
I'm not certain I know what use case you're getting at. It sounds like you 
want to take the current state of the global hierarchy and "fork" it into a 
private hierarchy? Even though the var is private you can still access its 
value:

@#'clojure.core/global-hierarchy (same as (deref (var 
clojure.core/global-hierarchy)))

I think you are already aware you can make and use your own hierarchies: 
all multimethod-related functions have an optional argument to accept a 
hierarchy directly as a value (or in a mutable ref container such as a var 
or atom in defmulti's case).

So to "fork" your own hierarchy, grab a snapshot the global-hierarchy var's 
value and use the derive and underive on that value to make your own 
hierarchy. Note that the heirarchy-explicit arities of derive and underive 
are pure: they return the new hierarchy map and do not mutate anything. 
(You also don't have to use namespace keywords for the type names.)

I hope you are not talking about something like a "live fork", where you 
want your own hierarchy expressed as a diff against the global-hierarchy 
and updated when the global hierarchy's value changes? You can probably do 
that with enough ILookup magic or a var watcher to recompute the derived 
hierarchy, but that sounds like a bad idea in general. Hierarchies are only 
useful with the named multimethods that explicitly use them, so it's hard 
to imagine a case where you want a multimethod to be "global hierarchy plus 
changes" and not just an entirely separate hierarchy.

On Sunday, April 8, 2018 at 1:57:41 PM UTC-5, Pedro Iago Carvalho Martins 
wrote:

> Ok, this is part of a theme that haunts me and I would like to know if 
> anyone shares my view or has a insteresting point.
>
> The #'global-hierarchy in clojure.core is used to enable things such as 
> multi-methods, and the isa? function.
> Now, we can change a var with alter-var-root, and I see it mostly being 
> used for configuration, as with *unchecked-math* or *warn-on-reflection*.
> But for some reason the global-hierachy is private, and in a weird way 
> where you can change it, as long you play the game.
>
> Example:
> (def a {:type ::a :val 1})
>
> (defn cons-a-foo [bar in]
>   (if (isa? (:type in) ::foo)
> (cons (:val in) bar)
> bar))
>
> (cons-a-foo [] a); => []
> (derive ::a ::foo)   ; we change the global-hierarchy
> (cons-a-foo [] a); => [1]
> (underive ::a ::foo) ; yet again
> (cons-a-foo [] a); => []
>
> ;And then isa? also supports a 3-ary version, which takes a hierarchy as:
>
> (make-hierarchy) ; => {:parents {} :descendants {} :ancestors {}} ;omg it 
> is just a map! glad I know those
>
> This is all good, except for one reason: global-hierarchy is private.
> We can't for instance try a "alternate-hierarchy" that is mostly the 
> global one with some expeculations.
> We lose all the other map functions in dealing with, especifically, the 
> global-hierarchy.
> And then we're back to oop.
>
> If the global-hierarchy was not made private (or any function for that 
> matter), then we could choose if we want to deal it with, or not.
> In my experience, making something private is only worth the trouble if we 
> give a complete substitute, that does everything and better.
> Let's say a rocket would explode if we set it to nil.. Then, just don't.
>
> With all that say, can we please remove the ^{:private true} from the 
> global-hierarchy definition?
> Sorry if I rant.
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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 Programmatically Create Unqualified Keywords?

2018-03-22 Thread Francis Avila
keyword has two arities:

(keyword x) will attempt to parse "x" into a keyword with name and 
namespace parts.

(keyword namespace-part name-part) will make a keyword with name and 
namespace set explicitly.

So to create a keyword dynamically (i.e. not using literal syntax) and be 
*absolutely 
sure* namespace is nil, use (keyword nil "something-empty") in your example.

Note that the keyword function will happily create keywords whose printed 
form is either not readable (e.g. include a space, a digit in the wrong 
place, a bad character, etc) or would be read a different way (include a 
slash in the name part for e.g.). 

On Wednesday, March 21, 2018 at 8:15:43 AM UTC-5, Nick Mudge wrote:
>
> I want to programmatically create some keywords without namespaces?  Or 
> are we not supposed to do that?
>
> I can't use the "keyword" function because that only creates keywords with 
> a namespace.  
>
> For example doing this: 
> (keyword (str "something" "-empty"))
> Creates this: 
> ::something-empty
> But I want this:
> :something-empty
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Transducers eduction vs sequence

2017-12-22 Thread Francis Avila
Even though evaluation and realization of sequences is lazy, they cache 
their result after evaluation. If you consume an object from the `sequence` 
function more than once, the work is only done once. Sequences are iterable 
and reducible, but not as efficiently because of the caching and because 
internally they have a linked-list structure (pointers rather than arrays).

`sequence` produces pretty much the same thing as "normal" lazy-sequence 
clojure. `(sequence (map f) xs)` and `(map f x)` are equivalent.

`eduction` produces an object that does not cache the result of transducer 
transformations. It's iteration and reduction implementations are faster, 
but the result is not cached.

Your error is because cheshire does not know how to serialize an Eduction 
object to Json.

On Friday, December 22, 2017 at 8:32:54 AM UTC-6, Jonathon McKitrick wrote:
>
> I have a `get-summary` function that builds stats and returns them as a 
> web service. Under the hood, it calls quite a few map, group-by, filter, 
> etc. functions.
>
> I’m experimenting with transducers, and `sequence xform` does the trick 
> most of the time. But I want to understand `eduction` use cases. In most 
> cases, `eduction` seems to be a drop-in replacement. But in a few cases, 
> I’m seeing this error:
>
> JsonGenerationException Cannot JSON encode object of class: class 
> clojure.core.Eduction: clojure.core.Eduction@31accd87 
>  cheshire.generate/generate (generate.clj:152)
>
> So there’s something I’m missing about my understanding of `sequence` 
> versus `eduction`. Can someone shine some light on it?
>
> 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: Defrecord Conflict

2017-03-17 Thread Francis Avila
Import does not demand name mapping. You can import a full path without 
aliasing.  This will work fine:

(ns multi.core
  (:require [multi.ns1]
[multi.ns2])
  (:import [multi.ns1.Animal]
   [multi.ns2.Animal]))

(multi.ns1.Animal. "hi")

(But remember to use the keyword :import, not the symbol. This will be 
tightened up in the future.)


On Friday, March 17, 2017 at 4:28:09 PM UTC-5, tmountain wrote:
>
> Say that I have the following:
>
> -- ns1.clj --
> (ns multi.ns1)
> (defrecord Animal [name])
>
>
> -- ns2.clj --
> (ns multi.ns2)
> (defrecord Animal [name])
>
> -- core.clj --
> (ns multi.core
>   (:require [multi.ns1]
> [multi.ns2])
>   (import [multi.ns1 Animal]
>   [multi.ns2 Animal]))
>
>
> My intent is to have a multimethod with target such as:
>
> (defmethod stringify multi.ns1.Animal ...)
> (defmethod stringify multi.ns2.Animal ...)
>
> My problem is that I'm forced to use import to bring in the records 
> defined in ns1 and ns2, but once I do this, I lose the ability to refer to 
> these classes by their fully-qualified names and the following conflict 
> occurs.
>
> java.lang.IllegalStateException: Animal already refers to: class 
> multi.ns1.Animal
>
> This actually works from the repl, which tells me it's getting the records 
> onto the classpath ahead of time.
>
>
>
> multi.core=> (require 'multi.ns1)
> nil
> multi.core=> (require 'multi.ns2)
> nil
> multi.core=> multi.ns1.Animal
> multi.ns1.Animal
>
> I bumped into this in the process of exploring the expression problem. Is 
> there a way around it?
>
>

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


What is the correct way to increment a value in an atom from multiple workers?

2017-02-10 Thread Francis Avila
Not all intermediates appear because in between your completed swap! and your 
log (really the deref of the atom) the value in the atom changed.

You are using atoms correctly. Your swap! function would me more idiomatic if 
it used the threading macro (->) but otherwise is fine.

If you really need to log each and every change of value, consider using 
dosync, one or more refs, and an agent to log. Dosync will not run agent 
send-off!s until the transaction commits successfully, and it will run exactly 
once per commit. 

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


Re: Pattern matching Vs destructuring?

2017-01-27 Thread Francis Avila
There are two different concerns in what people refer to as "pattern 
matching": binding and flow-control. Destructuring only addresses binding. 
Pattern matching emphasizes flow control, and some binding features 
typically come along for free with whatever syntax it uses. (But you could 
in principle have flow control without binding.)

On Friday, January 27, 2017 at 1:04:04 AM UTC-6, Didier wrote:
>
> Some languages have pattern matching, and Clojure is said to not have it 
> (without a library), but it does have destructuring.
>
> It seems to me that destructuring is the same as pattern matching, except 
> that it can only be used inside function arguments, where as pattern 
> matching can also be used when assigning a value or inside case switch 
> statements.
>
> Is that truly the only difference? And if so, why the different 
> terminology?
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Simple clojure example improvements sought

2017-01-10 Thread Francis Avila


On Tuesday, January 10, 2017 at 9:27:24 AM UTC-6, hiskennyness wrote:
>
> Whenever I code something like this I get the feeling a clojure guru could 
> do it more simply, and I love learning new tricks.
>
> Here is my simple (real-world, btw) problem and solution. Is there a 
> better way?
>
> ;; Problem: given optimized* json maps (* to avoid duplicating keys):
> (def optij {:name [:tom :dick :harry]
>:age [1 2 3]
>:tone [:do :re :mi]})
>
> ;; ... produce normal repetitious maps
> (comment
>   [{:name :tom, :age 1, :tone :do}
>{:name :dick, :age 2, :tone :re}
>{:name :harry, :age 3, :tone :mi}])
>
> ;; goal #1: pivot so I can use zipmap
> (comment
>   ((:tom 1 :do) (:dick 2 :re) (:harry 3 :mi)))
>
> ;; my goal #1 approach (improvements welcome):
> (apply (partial map (fn [& vs] vs))
>(vals optij))
>
> (apply (partial map vector)
>(vals optij))
>
>

Your partials are not strictly necessary, apply "auto-partials" all but the 
last argument:

(apply map vector (vals optij))

 
 

> ;; my overall approach (improvements welcome):
> (let [ks (keys optij)
>   vs-pivoted (apply (partial map vector)
> (vals optij))]
>   (vec (for [attributes vs-pivoted]
>  (zipmap ks attributes
>
>

This is a minor variation that uses transducers:
(let [ks (keys optij)
  vs-pivoted (apply map vector (vals optij))]
  (into [] (map #(zipmap ks %)) vs-pivoted)) 

This is a slightly different approach that combines keys and values first, 
then pivots:

(->> optij
 (map (fn [[attr vs]] (mapv #(do [attr %]) vs)))
 ;; [[[:name :tom][:name :dick]...], [[:age 1]...]]
 (apply mapv (fn [& cols]
   ;; cols ([:name :tom] [:age 1] [:tone :do])
   (into {} cols

This is a non-lazy approach that builds up the rows in multiple passes 
without intermediate pivots or seqs:

(reduce-kv (fn [rows k cols]
 (reduce-kv
   (fn [rows i col]
 (assoc-in rows [i k] col))
   rows cols)) 
  []
  optij)


Final fun question: is the original idea of compressing JSON this way 
> commonplace? I thought everyone was just saying to hell with the 
> duplication and taking the convenience of self-defining objects, but 
> apparently one source is not.
>

I don't know.

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

2017-01-06 Thread Francis Avila
A list/seq (not a vector) which is destructured as a map will be first read 
into a map as by (apply hash-map the-seq)

This curiosity exists so the "keyword argument" idiom works:

(defn my-options [_ & {:keys [a b] :as options}]
  options)
=> #'user/my-options
(my-options nil :a 1 :b 2 :c 3)
=> {:c 3, :b 2, :a 1}

(my-options nil :a 1 :b 2 :c)
IllegalArgumentException No value supplied for key: :c

Keyword arguments have in general fallen out of favor (they were more 
idiomatic in Clojure's early days), so you may not see this as often. 
Generally people just pass an option map unless the function is meant 
purely for "easy" interactive use (vs "simple" programmatic use). This is 
because it's more difficult to call a keyword-argumented function correctly 
when the keyword arguments are not literals.

On Friday, January 6, 2017 at 4:54:52 PM UTC-6, John Gabriele wrote:
>
> I've used associative destructing in the usual fashion:
>
> some-app.core=> (def m {:a 1 :b 2})
> #'some-app.core/m
>
> some-app.core=> (let [{:keys [a b]} m] (str a "-" b))
> "1-2"
>
> but what is going on here:
>
> some-app.core=> (def li '(:a 1 :b 2))
> #'some-app.core/li
>
> ;; Wat?
> some-app.core=> (let [{:keys [a b]} li] (str a "-" b))
> "1-2"
>
> I didn't think lists were associative... As in:
>
> some-app.core=> li
> (:a 1 :b 2)
>
> some-app.core=> (associative? li)
> false
>
> ;; So this is expected:
> some-app.core=> (let [{a 1 b 3} li] (str a "-" b))
> "-"
>
> some-app.core=> (def v [:a 1 :b 2])
> #'some-app.core/v
>
> ;; ...as is this (since vectors *are* associative):
> some-app.core=> (let [{a 1 b 3} v] (str a "-" b))
> "1-2"
>
>

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


Re: Why does "clojure.core/run!" end in an exclamation mark?

2017-01-06 Thread Francis Avila
doseq is a macro that accepts comprehension clauses like "for", so doseq is 
a straight translation of for that is eager (but still uses seqs 
internally) and swallows its body's results.

run! is like more like (doall (map f xs)), except it swallows results and 
uses "reduce" for speed and efficiency (no seq allocations).

In general, if I am side-effecting at the end of a ->> threading macro 
pipeline, I use run!. If I care about speed I use run! Otherwise I use 
doseq because it looks and feels more "statement-y" to me.


On Saturday, December 24, 2016 at 12:16:50 PM UTC-6, Shantanu Kumar wrote:
>
> I'm curious about `clojure.core/run!` too, but my question is whether it 
> is meant to be a `reduce` variant of `clojure.core/doseq` or it has some 
> other purpose.
>
> Shantanu
>
> On Saturday, 24 December 2016 21:37:11 UTC+5:30, James Reeves wrote:
>>
>> My understanding is that the convention used in clojure.core is to put an 
>> exclamation mark onto the end of any function unsafe to run in a 
>> transaction.
>>
>> Does the reasoning differ for "run!" or is it assumed that the function 
>> passed to "run!" will not usually be idempotent?
>>
>> - James
>>
>

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


recursive bindings not available in let form?

2016-12-02 Thread Francis Avila
Let bindings are immutable bindings, not refs. They must act as if their value 
could be substituted at the moment they are referenced. Def (i.e. a ref) is a 
mutable container whose contents is examined when it is used (not when 
referenced), which is why your second example works.


Why doesn't let work how you expect? Well, how would the following code work if 
let worked as you intend?

(let [a 1
  a (+ a 2)]
  (= a 3))

However, fn  accepts an optional name binding, so you can do this:

(let [fib (fn fib [...] (fib ...))] fib)

The inner fib reference is bound by the fn form, but the outer fib reference is 
still bound by let.

Or you can use letfn instead of let, which is the same as above with less 
typing AND the bindings can all see one another simultaneously. It's best for 
groups of closed-over  but mutually recursive functions.

(letfn [(fib [...] (fib ...))] (fib ...))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Validate different maps that have the same keys in the same namespace

2016-11-17 Thread Francis Avila
Your spec names need different namespaces, but your functions do not:


(s/def :catalog-a/type #{"a" "b" "c"})
(s/def :catalog-a/ref string?)

(s/def :catalog-b/type #{:x :y :z})
(s/def :catalog-b/ref number?)


Then you need to say that the keys are unqualified when they appear in the 
map for this function:


(s/fdef get-product-from-catalog-a
 :args (s/keys :req-un [:catalog-a/type :catalog-a/ref]
 :retany?)

(s/fdef get-product-from-catalog-b
 :args (s/keys :req-un [:catalog-b/type :catalog-b/ref]
 :retany?)

In general clojure spec tighly binds key names in maps to spec names and it 
is very hard to separate them. This is a formal part of its rationale, 
expressed as "Map specs should be of keysets only" 
.

There is a case I do not understand how to do well, where I want a specific 
function to accept a map with a specific specced key, but I want that key's 
value to conform to some strict subset of possible values as well. In 
essence, I want to "subclass" the key.

The options I see are:

   1.  Make a different spec based on the parent spec but adding 
   refinements, then make and spec adaptor functions which do nothing but 
   change the key (and validate). I.e., do the respec dance before the code.
   2. In the body of the function, call another function that accepts the 
   spec as a value (rather than in a map), and refine the value there. Your 
   outer function will still have to accept other values and handle them 
   somehow (signal error, throw, whatever).

Both of these are awkward when dealing with existing systems which to not 
consider specs to be of keysets only. In particular, we deal with a 
specification called FHIR  whose type model 
allows "profiles", which are declared on an instance (e.g. a map would have 
a type key for the base type and optionally a "profiles" key which is any 
additional specs to which the map must conform). A profile is essentially a 
restriction of the instance's basic types (they can never extend) such that 
any profiled instance must always conform to the base type's spec. E.g. if 
a field is allowed to have values "a" and "b", the profile may say that 
field may only have "a". So in essence we want maps to potentially conform 
to multiple specs at once: the base spec which is the keys in the map, and 
a profile spec which uses the same keys but may add additional 
restrictions. I have not thought of a good way to express this in 
clojure.spec.

On Thursday, November 17, 2016 at 10:54:18 AM UTC-6, damien@gmail.com 
wrote:
>
> I forgot the :req-un.
>
> (s/fdef get-product-from-catalog-[a|b]
>   :args (s/keys :req-un [::type ::ref])
>   :ret any?)
>
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Liberator with ring-cors

2016-10-14 Thread Francis Avila
You could try https://github.com/jumblerg/ring.middleware.cors as your cors 
lib instead. This would at least help you isolate if it is a liberator 
issue or not.

On Friday, October 14, 2016 at 7:22:29 AM UTC-5, Kenny Liu wrote:
>
> Anyone know if this all works out of the box? Preflight OPTIONS is 200 but 
> the GET/POST fails. My attempt to get it working:
>
> (def app
>   "Order must be reversed. See: http://stackoverflow.com/q/19455801/894091
> "
>   (-> (bidi/make-handler v1-routes)
>   (wrap-defaults api-defaults)
>   (wrap-cors :access-control-allow-origin [#".*"]
>  :access-control-allow-headers ["Host"
> "User-Agent"
> "Accept"
> "Accept-Language"
> "Accept-Encoding"
> "Content-Type"
> "Referer"
> "Content-Length"
> "Origin"
> "Connection"
> "Pragma"
> "Cache-Control"]
>  :access-control-allow-methods [:get :put :post :delete
> ])))
>
> http://stackoverflow.com/q/39789487/894091
>
> Based on https://github.com/clojure-liberator/liberator/issues/76, I 
> suspect it might be liberator messing with something. I'm pretty stumped.
>

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


Re: parallel sequence side-effect processor

2016-09-24 Thread Francis Avila
BTW I noticed that sequence got hotter and eventually became the fastest, 
but it took many more runs:

(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 31.321698 msecs"
=> nil
(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 15.492247 msecs"
=> nil
(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 10.9549 msecs"
=> nil
(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 9.122967 msecs"
=> nil
(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 18.056823 msecs"
=> nil
(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 9.381068 msecs"
=> nil


This is likely close to the theoretical maximum (using loop+recur plus a 
mutable iterator over multiple colls). The only thing faster would get rid 
of the iterator, which would require using a memory-indexable data 
structure like an array, and now you are in core.matrix and neanderthal 
territory.


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

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


Re: parallel sequence side-effect processor

2016-09-24 Thread Francis Avila
Well, you pay a cost whenever you use seqs instead of reduce, so it/s 
strange to think of doseq as "as fast as possible". If it/s argument is a 
true collection, its IReduce is usually faster than its seq. If it is a 
sequence already, its IReduce is usually just using seqs anyway.

Let's get some rough numbers here (which is what you should do on a 
case-by-case basis):

(require  '[uncomplicate.fluokitten.core :as f])
=> nil
(def side-effect (constantly nil))
=> #'user/side-effect
(def col1 (range 1))
=> #'user/col1
(def col2 (range 1))
=> #'user/col2
(def col2 (vec (range 1)))
=> #'user/col2
(def col1 (vec (range 1)))
=> #'user/col1

Single-coll:

(time (dotimes [_ 10] (doseq [x col1] (side-effect x
"Elapsed time: 13.916077 msecs"
=> nil
(time (dotimes [_ 10] (dorun (map side-effect col1
"Elapsed time: 5.707441 msecs"
=> nil
(time (dotimes [_ 10] (run! side-effect col1)))
"Elapsed time: 1.190621 msecs"
=> nil


Notice there seems to be some overhead to doseq that dorun doesn't have, so 
actually map+dorun is faster (for this particular coll). And run! is the 
fastest because a vector's IReduce is significantly faster than its seq.

Multi-coll:

(time (dorun (map side-effect col1 col2)))
"Elapsed time: 13.194375 msecs"
=> nil
(time (run! side-effect (map vector col1 col2)))
"Elapsed time: 17.54224 msecs"
=> nil
(time (run! side-effect (mapv vector col1 col2)))
"Elapsed time: 3.892984 msecs"
=> nil
(time (f/foldmap f/op nil side-effect col1 col2))
"Elapsed time: 12.454673 msecs"
=> nil
(time (dorun (sequence (map side-effect) col1 col2)))
"Elapsed time: 31.321698 msecs"
=> nil

Interesting results.

So dorun+map is still pretty good. foldmap wins out a little bit, but is 
still clearly using seqs underneath.

run! over a seq is not better than just consuming the seq. This is because 
the IReduce of a seq uses first/next internally, so there is no IReduce win.

However, run! over a vector is faster (for this collection, at this size) *even 
though we are creating a bunch more intermediate collections!*. The IReduce 
of a vector is really *that much faster* than its seq! So if you really 
need speed and don't care about laziness or memory, it may be faster just 
to make the intermediate collections-of-collections and reduce over it. 
Benchmark your particular hotspot!

And even though sequence uses iterators internally, there is clearly still 
some extra overhead involved.


On Friday, September 23, 2016 at 10:58:42 PM UTC-5, Mars0i wrote:
>
> Thanks very much Francis.  
>
> So it sounds as if, if my data would already be in a vector, list or 
> sequence (maybe a lazy sequence), doseq will process that structure as fast 
> as possible, but there are other structures that might have faster internal 
> reduce operations.
>

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


Re: parallel sequence side-effect processor

2016-09-23 Thread Francis Avila

> Francis, thanks for separating out the different types of intermediate 
> collections.  I'm not entirely clear on type 1.  It sounds like those are 
> just collections that are already there before processing them.  Or are you 
> saying that Clojure has to convert them to a seq as such?  Why would doseq 
> have to do that, for example?

There are two abstractions for working over a collection in clojure: sequences 
(i.e. Something that implements first and rest) and reducibles (something that 
implements IReduce or CollReduce).

Some functions use sequences as their basic interface to a collection: this 
includes map, doseq, etc (all the "traditional" clojure functions). Anything 
that calls first, rest, next, or seq during its operation (including most 
hand-rolled loop-recurs!) is using sequences. If the type is not already a 
sequence, then a sequence object needs to be created over it which knows how to 
walk it. This is an extra intermediate collection. What precisely happens 
depends on the input type, but it almost always involves additional object 
allocations. For efficiency

Other functions use reduction as their abstraction via IReduce, which allows a 
collection to reduce over itself. This is generally much more efficient because 
the type can walk over its own internal structures efficiently and does not 
need to provide the laziness or immutability guarantees of sequences: it can 
use (invisible) mutation internally. But you lose control over the "pace" of 
the reduction: you can't pause it in the middle or access any specific item.

Finally, Java has an Iterator interface, which is not used much in clojure 
because it is mutable.

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


Re: parallel sequence side-effect processor

2016-09-23 Thread Francis Avila
Well, hold on, it is creating seqs for its input collection (allocation 
item 1 in my list), but it is still better than map because it is not 
making an intermediate lazy-seqs of output (item 4).

(I must amend my earlier message,  (map f coll1 col2) only pays 1 and 4)

On Friday, September 23, 2016 at 6:25:14 PM UTC-5, tbc++ wrote:
>
> Yeah, I have to call you out on this one Dragan. I ran the following code: 
>
> (ns fold-test
> (:require [uncomplicate.fluokitten.core :refer [foldmap]]))
>
> (defn fa [& args]
> (println "fa " args)
> 1)
>
> (defn fb [& args]
> (println "fb " args)
> 1)
>
> (defn test-fold []
> (foldmap fa nil fb [1 2 3] [4 5 6]))
>
> (test-fold)
>
>
> This code produced: 
>
> fb  (1 4)
> fa  (nil 1)
> fb  (2 5)
> fa  (1 1)
> fb  (3 6)
> fa  (1 1)
>
> So I put a breakpoint in `fb` and ran it again. The stacktrace says it 
> ends up in algo/collection-foldmap which we can see here: 
> https://github.com/uncomplicate/fluokitten/blob/master/src/uncomplicate/fluokitten/algo.clj#L415-L443
>
> That function is creating seqs out of all its arguments! So it really is 
> not better than clojure.core/map as far as allocation is concerned. 
>
> Timothy
>
> On Fri, Sep 23, 2016 at 5:15 PM, Francis Avila <fav...@breezeehr.com 
> > wrote:
>
>> There are a few intermediate collections here:
>>
>>
>>1. The source coll may produce a seq object. How costly this is 
>>depends on the type of coll and the quality of its iterator/ireduce/seq 
>>implementations.
>>2. You may need to collect multiple source colls into a tuple-like 
>>thing to produce a single object for the side-effecting function
>>3. You may have an intermediate seq/coll of these tuple-like things.
>>4. You may have a useless seq/coll of "output" from the 
>>side-effecting function
>>
>> In the single-coll case:
>>
>> (map f col1) pays 1,4.
>> (doseq [x col1] (f x)) pays 1.
>> (run! f col1) pays 1 if coll has an inefficient IReduce, otherwise it 
>> pays nothing.
>> (fold f col1) is the same (using reducers r/fold protocol for vectors, 
>> which ultimately uses IReduce)
>>
>> In the multi-coll case:
>>
>> (map f coll1 col2) pays all four. 
>> (run! (fn [[a b]] (f a b)) (map vector col1 col2)) pays 1, 2, and 3.
>> (doseq [[a b] (map vector col1 col2)] (f a b)) pays 1, 2, 3.
>> (fold f col1 col2) pays 1 from what I can see? (It uses first+next to 
>> walk over the items stepwise? There's a lot of indirection so I'm not 100% 
>> sure what the impl is for vectors that actually gets used.)
>>
>> There is no way to avoid 1 in the multi-step case (or 2 if you are fully 
>> variadic), all you can do is use the most efficient-possible intermediate 
>> object to track the traversal. Iterators are typically cheaper than seqs, 
>> so the ideal case would be a loop-recur over multiple iterators.
>>
>> In the multi-coll case there is also no way IReduce can help. IReduce is 
>> a trade: you give up the power to see each step of iteration in order to 
>> allow the collection to perform the overall reduction operation more 
>> efficiently. However with multi-coll you really do need to control the 
>> iteration so you can get all the items at an index together.
>>
>> The ideal for multi-collection would probably be something that 
>> internally looks like clojure.core/sequence but doesn't accumulate the 
>> results. (Unfortunately some of the classes necessary to do this 
>> (MultiIterator) are private.)
>>
>> Fluokitten could probably do it with some tweaking to its 
>> algo/collection-foldmap to use iterators where possible instead of 
>> first/next.
>>
>>
>> On Friday, September 23, 2016 at 5:23:51 PM UTC-5, Dragan Djuric wrote:
>>>
>>> fluokitten's fold is MUCH better than (map f a b) because it does NOT 
>>> create intermediate collections. just use (fold f a b) and it would fold 
>>> everything into one thing (in this case nil). If f is a function with side 
>>> effects, it will invoke them. No intermediate collection is created AND the 
>>> folding would be optimized per the type of a.
>>>
>>> On Friday, September 23, 2016 at 10:56:00 PM UTC+2, tbc++ wrote:
>>>>
>>>> How is fluokitten's fold any better than using seqs like (map f a b) 
>>>> would? Both create intermediate collections.
>>>>
>>>> On Fri, Sep 23, 2016 at 11:40 AM, Dragan Djuric <drag...@gmail.com> 
>>>> wrote:
>>>&g

Re: parallel sequence side-effect processor

2016-09-23 Thread Francis Avila
There are a few intermediate collections here:


   1. The source coll may produce a seq object. How costly this is depends 
   on the type of coll and the quality of its iterator/ireduce/seq 
   implementations.
   2. You may need to collect multiple source colls into a tuple-like thing 
   to produce a single object for the side-effecting function
   3. You may have an intermediate seq/coll of these tuple-like things.
   4. You may have a useless seq/coll of "output" from the side-effecting 
   function

In the single-coll case:

(map f col1) pays 1,4.
(doseq [x col1] (f x)) pays 1.
(run! f col1) pays 1 if coll has an inefficient IReduce, otherwise it pays 
nothing.
(fold f col1) is the same (using reducers r/fold protocol for vectors, 
which ultimately uses IReduce)

In the multi-coll case:

(map f coll1 col2) pays all four. 
(run! (fn [[a b]] (f a b)) (map vector col1 col2)) pays 1, 2, and 3.
(doseq [[a b] (map vector col1 col2)] (f a b)) pays 1, 2, 3.
(fold f col1 col2) pays 1 from what I can see? (It uses first+next to walk 
over the items stepwise? There's a lot of indirection so I'm not 100% sure 
what the impl is for vectors that actually gets used.)

There is no way to avoid 1 in the multi-step case (or 2 if you are fully 
variadic), all you can do is use the most efficient-possible intermediate 
object to track the traversal. Iterators are typically cheaper than seqs, 
so the ideal case would be a loop-recur over multiple iterators.

In the multi-coll case there is also no way IReduce can help. IReduce is a 
trade: you give up the power to see each step of iteration in order to 
allow the collection to perform the overall reduction operation more 
efficiently. However with multi-coll you really do need to control the 
iteration so you can get all the items at an index together.

The ideal for multi-collection would probably be something that internally 
looks like clojure.core/sequence but doesn't accumulate the results. 
(Unfortunately some of the classes necessary to do this (MultiIterator) are 
private.)

Fluokitten could probably do it with some tweaking to its 
algo/collection-foldmap to use iterators where possible instead of 
first/next.


On Friday, September 23, 2016 at 5:23:51 PM UTC-5, Dragan Djuric wrote:
>
> fluokitten's fold is MUCH better than (map f a b) because it does NOT 
> create intermediate collections. just use (fold f a b) and it would fold 
> everything into one thing (in this case nil). If f is a function with side 
> effects, it will invoke them. No intermediate collection is created AND the 
> folding would be optimized per the type of a.
>
> On Friday, September 23, 2016 at 10:56:00 PM UTC+2, tbc++ wrote:
>>
>> How is fluokitten's fold any better than using seqs like (map f a b) 
>> would? Both create intermediate collections.
>>
>> On Fri, Sep 23, 2016 at 11:40 AM, Dragan Djuric  
>> wrote:
>>
>>> If you do not insist on vanilla clojure, but can use a library, fold 
>>> from fluokitten might enable you to do this. It is similar to reduce, but 
>>> accepts multiple arguments. Give it a vararg folding function that prints 
>>> what you need and ignores the first parameter, and you'd get what you asked 
>>> for.
>>>
>>>
>>> On Friday, September 23, 2016 at 7:15:42 PM UTC+2, Mars0i wrote:

 On Friday, September 23, 2016 at 11:11:07 AM UTC-5, Alan Thompson wrote:
>
> ​Huh.  I was also unaware of the run! function.​
>
> I suppose you could always write it like this:
>
> (def x (vec (range 3)))
> (def y (vec (reverse x)))
>
> (run!
>   (fn [[x y]] (println x y))
>
>   (map vector x y))
>
>
>  > lein run
> 0 2
> 1 1
> 2 0
>
>
 Yes.  But that's got the same problem.  Doesn't matter with a toy 
 example, but the (map vector ...) could be undesirable with large 
 collections in performance-critical code.

 although the plain old for loop with dotimes looks simpler:
>
> (dotimes [i (count x) ]
>   (println (x i) (y i)))
>
>
> maybe that is the best answer? It is hard to beat the flexibility of a 
> a loop and an explicit index.
>

 I agree that this is clearer, but it kind of bothers me to index 
 through a vector sequentially in Clojure.  We need indexing In Clojure 
 because sometimes you need to access a vector more arbitrarily.  If you're 
 just walking the vector in order, we have better methods--as long as we 
 don't want to walk multiple vectors in the same order for side effects.

 However, the real drawback of the dotimes method is that it's not 
 efficient for the general case; it could be slow on lists, lazy sequences, 
 etc. (again, on non-toy examples).  Many of the most convenient Clojure 
 functions return lazy sequences.  Even the non-lazy sequences returned by 
 transducers aren't efficiently indexable, afaik.  Of course you can always 
 throw any 

Re: Adding JDBC drivers to Clojars

2016-09-23 Thread Francis Avila
Leinigen uses maven repos to satisfy project clj dependencies, but there is 
nothing stopping you from putting your jar directly on the classpath. The 
idiom for local jars is to put them in "libs/". In this case you do *not* 
mention 
this dependency in your project.clj, but the jar will be on the classpath 
at runtime

If you still want project.clj to mention the dep but do not want to host 
the jar somewhere, you can make a local maven repository in your project 
itself (checked-in), and tell leinigen to use it. This stackoverflow answer 
describes that process: http://stackoverflow.com/a/9917149/1002469

If you really want to host the jar on a remote, non-private repo, use the 
full 4-arg form of the lein deploy command. See "lein help deploy" However, 
make sure this HP even lets you redistribute its jar in this way!

On Friday, September 23, 2016 at 10:19:10 AM UTC-5, Eddie wrote:
>
> Thanks for the reply. 
>
> I was under the impression that the jdbc driver (or any jar you want to 
> use as a dependency) needs to be hosted on some kind of maven repository. 
> Am I wrong about that?
>
> Here is the official download link for the Vertica jdbc driver: 
> https://my.vertica.com/client_drivers/7.2.x/7.2.3-0/vertica-jdbc-7.2.3-0.jar
> As far as I can tell, it isn't in a maven repository. Is there still a way 
> to tell lein to look at this address to pull the jar?
>
> Thanks! 
>
>  
>
>
> On Friday, September 23, 2016 at 11:02:07 AM UTC-4, Walter van der Laan 
> wrote:
>>
>> There is no need to push jdbc drivers to clojars.
>>
>> I have never used Vertica but perhaps it helps if I show you how to add 
>> the two jdbc-drivers that I do use.
>>
>>
>> Example 1; postgres
>>
>> The details for the postgres-driver can be found here: 
>> http://mvnrepository.com/artifact/org.postgresql/postgresql
>>
>> The download-link for the jar is; 
>> http://mvnrepository.com/artifact/org.postgresql/postgresql/9.4.1211.jre7
>>
>> This translates to this dependency in my project.clj: 
>> [org.postgresql/postgresql "9.4.1211"]
>>
>>
>> Example 2; h2
>>
>> The details for the h2-driver can be found here: 
>> http://h2database.com/html/download.html
>>
>> The download-link for the jar is; 
>> http://repo2.maven.org/maven2/com/h2database/h2/1.4.192/h2-1.4.192.jar
>>
>> This translates to this dependency in my project.clj: [com.h2database/h2 
>> "1.3.176"]
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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.


parallel sequence side-effect processor

2016-09-23 Thread Francis Avila
It's not crystal clear to me what you are after, either from this post or the 
one you link to. I think you want a map that does not produce intermediate 
collections and accepts multiple colls as input at a time? Do you have some 
pseudocode example so we can be precise?

What about (run! my-side-effect-fn coll)

This doesn't handle multiple coll at a time like the sequence function, but you 
can tupleize coll with (map vector coll1 coll2) at some loss of efficiency. Or 
you can roll your own.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Efficient comparison of persistent structures

2016-09-09 Thread Francis Avila
The only way to have diff consider internal structures is to have a diff 
protocol (with access to internals) to speed up comparison between items of 
the exact same Java class.

However, much of the slowdown you see is from intermediate vectors created 
during the reductions in diff-associative and diff-associative-key (two 
private functions in clojure.data)

This is what Clojure 1.8 has now:

(defn- diff-associative
  "Diff associative things a and b, comparing only keys in ks."
  [a b ks]
  (reduce
   (fn [diff1 diff2]
 (doall (map merge diff1 diff2)))
   [nil nil nil]
   (map
(partial diff-associative-key a b)
ks)))

(defn- diff-associative-key
  "Diff associative things a and b, comparing only the key k."
  [a b k]
  (let [va (get a k)
vb (get b k)
[a* b* ab] (diff va vb)
in-a (contains? a k)
in-b (contains? b k)
same (and in-a in-b
  (or (not (nil? ab))
  (and (nil? va) (nil? vb]
[(when (and in-a (or (not (nil? a*)) (not same))) {k a*})
 (when (and in-b (or (not (nil? b*)) (not same))) {k b*})
 (when same {k ab})
 ]))



This is my baseline:

(defn speedtest []
  (let [doDiff (fn [a b] (time
   (let [delta (clojure.data/diff a b)]
 [(first delta) (second delta)])))
x  (into {} (map vec (partition 2 (range 10
x1 (into {} (map vec (partition 2 (range 10
y  (assoc x -1 -1)]
[(doDiff x x)
 (doDiff x x1)
 (doDiff x y)]))
=> #'clojure.data/speedtest
(speedtest)
"Elapsed time: 0.131537 msecs"
"Elapsed time: 31.887744 msecs"
"Elapsed time: 247.431151 msecs"
=> [[nil nil] [nil nil] [nil {-1 -1}]]
(speedtest)
"Elapsed time: 0.006951 msecs"
"Elapsed time: 26.47309 msecs"
"Elapsed time: 181.248303 msecs"
=> [[nil nil] [nil nil] [nil {-1 -1}]]
(speedtest)
"Elapsed time: 0.007175 msecs"
"Elapsed time: 23.102316 msecs"
"Elapsed time: 174.300056 msecs"
=> [[nil nil] [nil nil] [nil {-1 -1}]]


Now lets replace diff-associative and diff-associative-key with mutable 
objects and transients to contain the reduction:

(let [NF (Object.)] ;; not-found sentinel to avoid a contains? lookup per 
key
  (defn- diff-associative-key
"Diff associative things a and b, comparing only the key k."
[a b k]
(let [va   (get a k NF)
  vb   (get b k NF)
  in-a (not (identical? va NF))
  in-b (not (identical? vb NF))
  [a* b* ab] (diff (when in-a va) (when in-b vb))
  same (and in-a in-b
 (or (not (nil? ab))
   (and (nil? va) (nil? vb]
  (doto (object-array 3)
(aset 0 (when (and in-a (or (not (nil? a*)) (not same))) {k a*}))
(aset 1 (when (and in-b (or (not (nil? b*)) (not same))) {k b*}))
(aset 2 (when same {k ab}))


(defn- diff-associative
  "Diff associative things a and b, comparing only keys in ks."
  [a b ks]
  (transduce
(map (partial diff-associative-key a b))
(fn
  ([] (doto (object-array 3)
(aset 0 (transient {}))
(aset 1 (transient {}))
(aset 2 (transient {}
  ([^objects diff]
   [(not-empty (persistent! (aget diff 0)))
(not-empty (persistent! (aget diff 1)))
(not-empty (persistent! (aget diff 2)))])
  ([^objects diff1 ^objects diff2] ;; These type hints are important!
   (doto diff1
 (aset 0 (conj! (aget diff1 0) (aget diff2 0)))
 (aset 1 (conj! (aget diff1 1) (aget diff2 1)))
 (aset 2 (conj! (aget diff1 2) (aget diff2 2))
ks))

Such mutation, ugh. But, new results (after re-evaling the extend-type):

 
(speedtest)
"Elapsed time: 0.006056 msecs"
"Elapsed time: 32.802827 msecs"
"Elapsed time: 62.53305 msecs"
=> [[nil nil] [nil nil] [nil {-1 -1}]]
(speedtest)
"Elapsed time: 0.006661 msecs"
"Elapsed time: 26.700653 msecs"
"Elapsed time: 70.025767 msecs"
=> [[nil nil] [nil nil] [nil {-1 -1}]]
(speedtest)
"Elapsed time: 0.006686 msecs"
"Elapsed time: 26.426425 msecs"
"Elapsed time: 70.042115 msecs"
=> [[nil nil] [nil nil] [nil {-1 -1}]]


Not bad.

On Wednesday, September 7, 2016 at 9:16:31 PM UTC-5, Marshall handheld Flax 
wrote:
>
> Suppose I create a decently-sized persistent map, and then make a small 
> change.  Clojure is extremely efficient at creating a second persistent map 
> that shares most of its internal data with the first map, but 
> clojure.data/diff appears to be unable to take advantage of that shared 
> internal data -- instead it seems to just exhaustively compare the two 
> trees.  
>
> Comparing a map with itself: "Elapsed time: 0.155404 msecs"
> Comparing two identical -- but separately-created maps -- "Elapsed time: 
> 43.687906 msecs"
> Comparing a map and one with a small change thereof: "Elapsed time: 
> 378.754266 msecs"
>
> Is there a way of comparing two maps that takes advantage of the internals 
> of the commonality between maps "x" and 

Re: [ANN] data.avl 0.0.14 – BUGFIX to splits, faster map/set reductions

2016-08-23 Thread Francis Avila
I wasn't aware Clojure had an IReduce protocol! I thought CollReduce was just 
what IReduce is called in Clojure.

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


Re: Having trouble doing what I want using macros, is there a better way?

2016-06-11 Thread Francis Avila
These functions (as-transducer, transducing) are still completely agnostic 
about the type of the accumulator and result as long as the function you give 
them only touches result in the following ways:

1. Return result unchanged

2. Return (xf (xf result X) Y), I.e. Whatever you get from applying xf to 
result with a value to add, one or many times. (In case result is mutable, eg a 
channel, or the transformation is stateful, never call xf unless you plan to 
use the return value.)

3. (reduced result)

4. Both 3 and 4

The advantage of writing a full transducer (or as-transducer/transducing) is 
that the step arity is truly a reduction-step function and so can efficiently 
not change the result, add multiple items, or short-circuit reduction (or even 
a different thing each time).

Normally data transformations don't do more than one of these at a time, so map 
or mapcat or filter is fine.
But when the transduction is modeling a process (I.e read input, possibly 
keeping old state, and unpredictably emit 0, 1, many results based on the 
input) it is handy to be able to do exactly what you mean instead of using 
mapcat/map/filter/keep etc with intermediate collection or sentinel value 
contortions. It's also nice not to have an intermediate collection (mapcat) if 
you need to reduce object allocations.

Sent from my iPhone

> On Jun 11, 2016, at 1:20 AM, Timothy Baldridge <tbaldri...@gmail.com> wrote:
> 
> Touching the accumulator (the result in your case) from within a transducing 
> function is a bit of an anti-pattern. The whole point of transducers is that 
> you can swap out the accumulator:
> 
> (transduce (map inc) conj [] (range 10))
> (transduce (map inc) async/>! some-channel (range 10))
> (transduce (map inc) + 0 (range 10))
> 
> In this example, we loose that ability to swap out the result type if `(map 
> inc)` assumes that the accumulator will always be a vector, or a integer. 
> This is why I said map/filter/keep should handle most of your cases. 
> 
> If the function you are writing doesn't require the accumulator to function 
> properly, then there is no reason why `(map my-fn)` won't work. 
> 
>> On Sat, Jun 11, 2016 at 12:13 AM, Travis Daudelin 
>> <travis.daude...@gmail.com> wrote:
>>> On Friday, June 10, 2016 at 3:03:38 PM UTC-7, Francis Avila wrote:
>>> A higher-order function can do what this macro does: 
>>> https://gist.github.com/favila/ecdd031e22426b93a78f
>> 
>> Oh nice! It looks like I came up with an almost identical solution:
>> (defn transducing
>>   [f]
>>   (fn [reducing-fn]
>> (fn
>>   ([] (reducing-fn))
>>   ([result] (reducing-fn result))
>>   ([result input] (f result input reducing-fn)
>> 
>> It feels like "writing a custom transducer" should be a common use case, is 
>> there anything like these functions we've written that exists in the core 
>> library? I didn't see anything like them there or in the reducers library 
>> when I first started on my project.
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with your 
>> first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
> 
> 
> 
> -- 
> “One of the main causes of the fall of the Roman Empire was that–lacking 
> zero–they had no way to indicate successful termination of their C programs.”
> (Robert Firth)
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> --- 
> You received this message because you are subscribed to a topic in the Google 
> Groups "Clojure" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/clojure/-XIekEB6zu0/unsubscribe.
> To unsubscribe from this group and

Re: Having trouble doing what I want using macros, is there a better way?

2016-06-10 Thread Francis Avila
A higher-order function can do what this macro 
does: https://gist.github.com/favila/ecdd031e22426b93a78f


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

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


Re: sorted-map vs hash-map issue

2016-04-28 Thread Francis Avila
Sorted maps sort their keys, but keywords and strings are not comparable:


(sorted-map "a" 1 :b 2)
ClassCastException java.lang.String cannot be cast to clojure.lang.Keyword 
 clojure.lang.Keyword.compareTo (Keyword.java:114)




On Thursday, April 28, 2016 at 3:54:33 PM UTC-5, JPatrick Davenport wrote:
>
> Hello,
> Please explain to me what's going on here. The first code snippet causes 
> the following error: "ClassCastException clojure.lang.Keyword cannot be 
> cast to java.lang.String  java.lang.String.compareTo (String.java:111)" The 
> second code snippet doesn't. My understanding is that a *map* is a *map*. 
>
>
> First:
>
>
> (let [s (apply sorted-map '(:a :b, :c {:d :e}))
>   c (assoc {} :payload s)]
>   (clojure.set/rename-keys (:payload c) {:a "a"}))
>
>
> Second:
> (let [s (apply hash-map '(:a :b, :c {:d :e}))
>   c (assoc {} :payload s)]
>  (clojure.set/rename-keys (:payload c) {:a "a"}))
>
>
> Thanks,
>
> JPD
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Compile ClojureScript in Java application

2016-04-26 Thread Francis Avila
On Tuesday, April 26, 2016 at 4:38:02 PM UTC-5, Martin Grześlowski wrote:
>
> I'm trying to compile String that contains Clojure Script code in 
> Java/Groovy. 
>
> I'm not really happy with using *"java -jar ...".execute()*.
>
>
> Is there any way to invoke clojurescript library (version 1.8.51) to 
> compile code?
>

The clojurescript compiler is a clojure library, so you can invoke it from 
Java the same way you can invoke any Clojure code from java.

Basics of invoking Clojure from Java: http://stackoverflow.com/a/23555959

It will probably look something like:

IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("cljs.build.api"));
IFn build = Clojure.var("cljs.build.api","build");
build.invoke("src", Clojure.read("{:output-to ...}"));



The second argument to build can be a HashMap you construct in your Java 
code. (Make sure the keys are Keyword type.)

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


Re: Benchmarking in Clojurescript -- Necessary or not?

2016-04-25 Thread Francis Avila


On Monday, April 25, 2016 at 6:45:13 PM UTC-5, JvJ wrote:
>
> What I want to know is this:  Will the JVM benchmarking numbers reflect 
> how the JS implementation performs?
>

No 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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.


Unexpected nullpointer while processing a transient vector

2016-04-24 Thread Francis Avila
Your reduction function uses when, which returns nil for the false case. You 
need to use if instead and return %1 unchanged in the else case so the 
reduction can continue.

There may still be other problems, but that is the cause of your NPE

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


Re: [ANN] components.md

2016-04-19 Thread Francis Avila
I believe by "several different mem-dbs" he means different instances, not 
implementations, i.e. they differ by name and (maybe) config, but share an 
implementation.

There are two ways this can happen: two system graphs in the same clojure 
runtime, or one system graph that uses the same service-type twice.

In Component, the first case is handled by making a separate Component map; 
the second by adding a new key to the map.

In mount, the first case is AFAIKT not possible (maybe some 
swap-with-states trickery?), and the second by adding a new defstate var 
somewhere.

In general, what Component does with system maps, map keys and records 
mount does with namespaces. The upside is you don't have to be as manual 
and explicit about instances, names, dependencies, instantiation, etc (just 
use normal namespace machinery and accept initialization as a side-effect 
of require). The downside is that namespaces are singletons, so your system 
must be a singleton too.

On Tuesday, April 19, 2016 at 7:46:44 AM UTC-5, Brian Platz wrote:
>
>
> Jeroen,
>
> Happy to talk more about it on Slack.
>
> No matter what you are `def`-ing something somewhere. For Component I’d 
> `def` a big config map, and I do the same with Mount. My advantage with 
> Mount in the REPL is that I can have local vars for ‘components’ that are 
> easy to reference (but still driven from the main config map). In Component 
> I’d accomplish this by outputting what I need to a var, usually in the 
> ‘user’ namespace that I could get a handle to.
>
> As for several different `mem-db`s, if you mean swapping them out for 
> dev/testing, that is explained here: 
> https://github.com/tolitius/mount#swapping-alternate-implementations
>
> -Brian
>
>
>
> On Apr 19, 2016, at 6:03 AM, Jeroen van Dijk  > wrote:
>
> Hi Brian,
>
> When looking at the Readme of Mount (I think) I already see global state 
> backed in. 
>
> (defstate ^{:on-reload :noop} 
>   mem-db :start (connect config) 
>  :stop (disconnect mem-db))
>
>
> Do I misunderstand this or do we just disagree on what global state is? 
> What if I want to have several (different) `mem-db` instances, how would 
> that work? 
>
>
>
> On Fri, Apr 8, 2016 at 4:25 PM, Brian Platz  > wrote:
>
>>
>> >> This is also something that wouldn't be possible with Mount as this 
>> library seems to promote global state.
>>
>> As a recent switcher from Component to Mount, and without trying to 
>> change the thread's topic into a this vs. that -- I'll simply say that I 
>> don't believe any of these tools promote global state, it is people who 
>> code global state, and that can be with any of these tools... or likewise 
>> avoided with any of these tools.
>>
>> Some tools (i.e. Component) probably make it more difficult to have 
>> global state, but I think it is heavy handed. For projects with a lot of 
>> components, I would spend a lot of time backtracking components all feeding 
>> into each other to figure out where some var was when working in REPL. I'd 
>> also repeatedly deal with errors when adding new components as I didn't set 
>> up the dependencies correctly at first... just several interlocking pieces 
>> that all need to be coordinated, and I sometimes forget one (or two).
>>
>> Mount probably makes it a little easier to have global state, but that is 
>> up to the developer - I have no more global state than I had before the 
>> switch. I find it easier to work in REPL and get access to a var, or conn, 
>> etc. when I need to eval something, and I think all these components are 
>> primarily there to make the REPL workflow better. Also, I'm out of the 
>> business of managing my dependencies, which my challenges might just root 
>> from an absent-mindedness that I possess. Once it is in production, the 
>> component stuff matters very little anyhow.
>>
>> All to say that these tools, assuming they provide the feature needs that 
>> have been outlined well in this thread, should not make anything 'not 
>> possible' and can have as much or as little global state as the developer 
>> chooses to code in. I cringe a bit when I repeatedly see that Mount 
>> promotes global state, I think that is a falsehood.
>>
>> -Brian
>>
>>
>> -- 
>> 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 

Re: Encapsulating Local Mutable State

2016-04-15 Thread Francis Avila
If you can model the authentication process as a state machine, have a pure 
function which accepts auth-state and data and returns either a new state 
or an operation to get new data to determine the next state.

E.g. (next-auth-state {:stage :not-authed :login "login" :password "pass"} 
nil) => {:state {:stage :not-authed ...} :operations [{:kind 
:get-auth-token :args {:login "login" ...}]}}.  Then (next-auth-state 
{:stage :not-authed} {:auth-token ""}) => {state {:stage :has-token :token 
"..." :expires "..."} :operations [{:kind :get-session-token :args 
{:session-token "token"}{:kind :invalidate-token :args {:session-token 
"token"}}] etc.

In state machine graph terms, the :stage is the node you are on, the 
:operations are actions which you can take to return data which represent 
the edges the state machine can follow.

Then you have a higher-level reduction function which accepts any auth 
state map and keeps running the state machine until it can return a map 
that is suitable for authentication. This function is responsible (possibly 
indirectly) for turning operation requests into http calls and collecting 
the responses, i.e. is impure, but not necessarily stateful or mutable.

E.g. auth-state map could start in {:stage :not-authed :login "login" 
:password "pass"}. (authorize auth-state) is a reduction function that runs 
(get-auth-token auth-state), returns {:stage :token :expires #inst"..."}, 
then authorize inspects return value and runs (open-session {:stage :token 
:expires "..."}) etc, until either a failure or success.

Lower-level client api calls receive only auth-maps with a non-expired 
stage=:session. They must return, in addition to success or failure of the 
call itself, any auth-related state info from the server which should alter 
the auth-map somehow. Another function (maybe authorize, maybe something 
else) integrates this state with the passed-in auth map and returns a new 
(possibly unchanged) auth-map, which can be used for future calls.


Higher-level client api functions should combine api calls with auth-state 
updating. If you keep your fn argument and return structure regular enough, 
you might even be able to do this with a single higher-order function: 
(call-with-auth low-level-client-api-fn auth-map args) -> {:result x 
:auth-map new-auth-map-state}

Only at this point might it be convenient to have a higher-level, stateful 
construct which completely hides the auth-state map from you. e.g. 
(make-session login pass) => {:auth-state (atom {:state :not-authed :login 
login :pass pass})},
then (call-with-session session client-fn args) => result-only, and mutates 
the auth state in the atom for you. But the emphasis here is on programmer 
convenience (not having to collect the new-auth-state return value and 
propagate it around), not any necessity of modeling the auth flow.

You still need to think about concurrency at the communication level. If 
two client api calls run at the same time, both with expired tokens, what 
can happen? Can both independently run the update with separate http calls 
and get different tokens (or will the server issue the same token to both)? 
Should only one http communication happen on the client side and the client 
is responsible for blocking callers that want a new token until a single 
token is reissued?
Your decision affects the implementation of the state-machine driving 
function (the one that executes operations and calls next-state 
repeatedly): you might put a token and session cache in there, or put 
operations related to the same login on their own queue so there is only a 
single writer per login, or whatever. But the hard auth flow logic in your 
next-state function remains the same.


On, Friday, April 15, 2016 at 7:40:48 AM UTC-5, Stefan Kamphausen wrote:
>
> Hi,
>
>
> Currently, I am in the process of writing a client to server API which is 
> not trivial to consume.  In particular it needs a 3-step authentication 
> process: login with user name and password, get an authentication token, 
> open a session with the token and finally consume the API with the 
> session.  Sessions and tokens can expire and the client should handle that 
> transparently: if it has a token, create a new session, if the token 
> expired and it has username and password, create a new token...  So, 
> sessions and tokens would have to be local, mutable, encapsulated state, as 
> far as I can see.
>
> Now; I wonder how to best model this in Clojure.
>
> My favorite right now is, creating a closure over a local atom and return 
> it to the user.  The downside to this is that it feels unnatural to consume 
> different parts of the API, e.g. (client :do-something ) vs (client 
> :do-something-else & other-args).  It would be nice to defined a protocol 
> with function do-something and do-something-else but then I would have to 
> pass the atom as an argument to the record which feels even worse.
>
> Am I missing an obvious other solution? 

Re: Core.async performance with many channels

2016-04-06 Thread Francis Avila
On Monday, April 4, 2016 at 6:30:07 PM UTC-5, Howard M. Lewis Ship wrote:
>
> David Nolen had an early ClojureScript core.async demo with thousands of 
> channels, controlling individual pixels.
>

This is the demo you are referring to: 
http://swannodette.github.io/2013/08/02/10-processes/
 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Macro for quickly switching libraries

2016-04-06 Thread Francis Avila
The backtick namespace-qualifies symbols automatically:

(macroexpand-1 '(switch-foo-library! x))
;=>
(clojure.core/defn
 user/foo
 [y__3652__auto__]
 ((clojure.core/resolve (clojure.core/symbol (clojure.core/str x "/foo")))
  y__3652__auto__))

The error is about the "user/foo" name of the defn.

You can fix this by quoting the symbol then immediately unquoting it:


(defmacro switch-foo-library! [x]
  `(defn ~'foo [y#] ((resolve (symbol (str ~x "/foo"))) y#)))
;=> #'user/switch-foo-library!
(macroexpand-1 '(switch-foo-library! x))

;=>
(clojure.core/defn
 foo
 [y__3946__auto__]
 ((clojure.core/resolve (clojure.core/symbol (clojure.core/str x "/foo")))
  y__3946__auto__))


However what you really want probably something with with-redefs 

:

(defmacro with-ns [ns vars & body]
  {:pre [(symbol? ns) (nil? (namespace ns))
 (every? #(and (symbol? %) (nil? (namespace %))) vars)]}
  (let [bindings (vec (mapcat #(do [% (symbol (str ns) (str %))]) vars))]
`(with-redefs ~bindings ~@body)))
;=> #'user/with-ns
(ns alt)
;=> nil
(def juxt (constantly (constantly "NEW JUXT")))
;WARNING: juxt already refers to: #'clojure.core/juxt in namespace: alt, 
being replaced by: #'alt/juxt
;=> #'alt/juxt
(in-ns 'user)
;=> #object[clojure.lang.Namespace 0x77b2abef "user"]
(with-ns alt [juxt] (map (juxt :a :b) (repeat 4 {:a 1 :b 2})))
;=> ("NEW JUXT" "NEW JUXT" "NEW JUXT" "NEW JUXT")
((juxt :a) {:a 1})
;=> [1]



If you want to make the var change permanent (i.e. not requiring your body 
be inside with-redefs), you can use alter-var-root 
, but you have to take 
care to allow the vars to be restored somehow, e.g. by storing the old 
mappings somewhere and providing a macro to save and restore them.

It's possible someone has scratched this itch before, too: there might be a 
utility library out there somewhere that does something like this.

On Tuesday, April 5, 2016 at 9:10:15 PM UTC-5, Will Bridewell wrote:
>
> I'm working on some code where I want to evaluate different 
> implementations of the same functionality. Each implementation of a 
> function lives in its own namespace. For example, suppose that I have the 
> following simplified code.
>
> (ns tst1)
> (defn foo [x] (+ x 1))
>
> (ns tst2)
> (defn foo [x] (+ x 2))
>
> (ns tst3)
> (defn foo [x] (+ x 3))
>
> (in-ns 'user)
>
> What I'd like to do is call a macro that binds the function name in user 
> to the function in one of the libraries. The call would look like one of 
> these. 
>
> (switch-library! 'tst1 'foo)
>
> (switch-foo-library! 'tst1)
>
> The closest that I got was to do 
>
> (defmacro switch-foo-library! [x]
>   `(defn foo [y#] ((resolve (symbol (str ~x "/foo"))) y#)))
>
> That's kind of embarrassing, but I think it does what I want. However, 
> suppose I do
>
> (ns-unmap 'user 'juxt)
> (defmacro switch-juxt-library! [x]
>   `(defn juxt [y#] ((resolve (symbol (str ~x "/juxt"))) y#)))
>
> Now I get 
>
> CompilerException java.lang.RuntimeException: Can't create defs outside 
> of current ns, compiling:
>
> Well, gosh. I can't play around with symbols in clojure.core? What's 
> happening here?
>
>
>

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

2016-04-03 Thread Francis Avila
I had some fun with playing around with faster 
solutions. https://gist.github.com/favila/0573e3f644dea252bdaaed5be9d1519f

The biggest speedup comes from avoiding set creation in expanded-range 
(i.e., the function that produces the collection of affected coordinates) 
and ensuring that the ops run on the accumulating set of on-lights using 
transients.  clojure.set/* functions require both items be sets and does 
not use transients internally, so it was much slower.

Another big speedup comes from encoding the light coordinates more 
efficiently. You can encode a light as a number (in my case, a long, with 
high bits the x coordinate and low bits the y coordinate) instead of a 
vector. This creates fewer objects which are easier to hash.

Finally, I tried an approach which doesn't use sets, but instead naively 
creates a 1000x1000 array of booleans and mutates it in place with every 
op. This is the fastest approach: 4 seconds on a 2010-era i3! I'm sure a 
proper matrix library (e.g. core.matrix) could do even better.

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


Re: Trouble using r/fold to optimise a reduce

2016-04-02 Thread Francis Avila


Even stranger - the parallel version seems to at least produce an output 
> (not sure how correct) if run for the first 50 commands instead of 300.
>

I forgot to mention: the reason why r/fold sometimes seems to still work is 
because there is only one chunk (i.e., no parallelism), so the combine 
function is never called.

This is also why r/fold worked when you used a lazy-sequence of commands 
instead of a vector--combine was never called because there was no 
parallelism.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Trouble using r/fold to optimise a reduce

2016-04-02 Thread Francis Avila
You misunderstand how r/fold works.

My understanding is that reducers preserve the order of operation, so it 
> should give the correct answer.


This is not quite true. There are two fundamental principles behind 
reducers. The first is that the process of reduction, stripped of all 
non-essentials, is "apply this function individually to every item in a 
collection, accumulating the result". Notice that there is no mention of 
order.

The second principle is, when reduction has been thus "reduced" to its 
essentials, it is possible for a *collection* to control how reductions are 
done over itself. Whether a reduction process has a particular order is a 
non-essential property that is provided or not-provided by the collection 
itself. The IReduceInit protocol is purposefully agnostic to order. Vectors 
implement it in an ordered way, but hash maps have no meaningful order.

So that's IReduceInit. The coll-fold protocol takes advantage of delegating 
the reduction implementation to the collection by allowing collections to 
provide a potentially-parallel reduction strategy. How this works is that 
the collection divides itself up into chunks, runs a normal reduction over 
each chunk using the same init value, then applies a "combine" function to 
combine the chunks. In the case of vectors, the chunks are combined in 
order, so the operation you are performing does not need to be commutative. 
However, the combine function still needs to be *associative*, because each 
individual sub-reduction is not initialized with the result of the previous 
reduction.


Even stranger - the parallel version seems to at least produce an output 
> (not sure how correct) if run for the first 50 commands instead of 300.
>

The problem here is misunderstanding the "combine" step of fold. You supply 
the same function apply-cmd for both reducing and combining. However, the 
reducing function is called with a set of "on" lights and a command, but 
the combine function is called with two sets of on lights (i.e., it is 
called with the result of two reductions). So in the combine phase, r/fold 
is calling apply-cmd something like this: (apply-cmd #{[1 1]} #{[2 2]}), 
which is not what it expects, hence your strange exception about Longs.

Anyway, the combine function must be associative, but this advent problem 
is *not* associative, because you cannot rearrange the order in which the 
toggle functions are run. Each toggle function must always have the final 
state of every previous line done. You could compute the commands *in 
between* the toggle commands in parallel (essentially coalescing them into 
a single "turn on" command), but you still need to run the whole sequence 
of toggle commands, from start to finish, in order.

Here is a simple example to illustrate:

; Our commands. :toggle simplified to illustrate the point.
(def cmds [[:on #{1 2}] [:toggle 2] [:on #{3}]])
;=> #'advent.a6/cmds
; Our reduction function, with initializing arity
(defn apply-cmd
  ([] #{})
  ([on [cmd arg]]
   (case cmd
 :on (into on arg)
 :toggle (if (contains? on arg)
   (disj on arg)
   (conj on arg)
;=> #'advent.a6/apply-cmd
;; The correct answer, for reference
(r/reduce apply-cmd cmds)
;=> #{1 3}




Now let's perform the steps an r/fold would perform. We have three commands 
and will do two chunks, but we will divide the chunks differently. Here is 
what happens when we split between the second and third command:


; Chunk one
(r/reduce apply-cmd (subvec cmds 0 2))
;=> #{1}
; Chunk two
(r/reduce apply-cmd (subvec cmds 2))
;=> #{3}
; Combine
(into *1 *2)
;=> #{1 3}
; Looks ok...


Now lets try splitting between the first and second command:

; Chunk one
(r/reduce apply-cmd (subvec cmds 0 1))
;=> #{1 2}
; Chunk two
(r/reduce apply-cmd (subvec cmds 1))
;=> #{3 2}
;; Combine
(into *1 *2)
;=> #{1 3 2}
; WRONG ANSWER!!


Notice *how you split the commands up* affects the final answer, which 
means this algorithm can't be safely implemented with r/fold!

On Saturday, April 2, 2016 at 6:45:16 PM UTC-5, Divyansh Prakash wrote:
>
> Just verified - it works and gives the correct answer for shorter 
> collections. 
> No performance boost though. And fails (?) on larger collections.
> Not sure what's happening. The foldvec implementation is also pretty hard 
> to understand.
>
> On Sunday, April 3, 2016 at 2:38:26 AM UTC+5:30, Francis Avila wrote:
>>
>> Your input collection to r/fold is provided by cmds-from-input which 
>> returns a lazy-seq (from map) which is not a parallel-foldable type. You 
>> can try mapv instead: vectors are parallel-foldable. (Note only 
>> PersistentVector and PersistentHashMap have useful coll-fold 
>> implementations: all other objects (including sets) fall back on normal 
>> reduction: 
>> https://github.com/

Re: Trouble using r/fold to optimise a reduce

2016-04-02 Thread Francis Avila
Your input collection to r/fold is provided by cmds-from-input which 
returns a lazy-seq (from map) which is not a parallel-foldable type. You 
can try mapv instead: vectors are parallel-foldable. (Note only 
PersistentVector and PersistentHashMap have useful coll-fold 
implementations: all other objects (including sets) fall back on normal 
reduction: 
https://github.com/clojure/clojure/blob/d5708425995e8c83157ad49007ec2f8f43d8eac8/src/clj/clojure/core/reducers.clj#L347-L367)

Additionally, I'm not sure how this algorithm could be parallelized because 
the order in which you apply the toggle operation matters! I suspect if you 
make the mapv change I suggest you will get different final answers.






On Saturday, April 2, 2016 at 3:24:47 PM UTC-5, Divyansh Prakash wrote:
>
> Hi! 
> I'm solving the problem described here . 
> I've got the solution 
> , 
> but it takes ~50 s to compute.
> I tried optimising it by replacing the main reduce operation with r/fold, 
> but it doesn't seem to have any effect on the performance for whatever n 
> (batch size) I use.
> Any suggestions?
>
> Note: I'm using a MacBook Pro with 8 cores. JDK 7. Clojure 1.8.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Stable clojure.xml/parse

2016-04-01 Thread Francis Avila
Are you sure that it changes the child element order? It hasn't in my 
experience. Example:

(clojure.xml/parse (io/input-stream (.getBytes 
"" "UTF-8")))
=>
{:tag :a,
 :attrs nil,
 :content [{:tag :b1, :attrs nil, :content nil}
   {:tag :a1, :attrs nil, :content nil}
   {:tag :a2, :attrs nil, :content nil}
   {:tag :a3, :attrs nil, :content nil}
   {:tag :a4, :attrs nil, :content nil}]}


Do you have a counter-example? Or are you talking about attribute nodes 
maybe?

Also the only parser included with clojure.xml already uses SAX: it just 
supplies a content handler that builds the clojure structures 
clojure.xml/parse returns. 



On Friday, April 1, 2016 at 10:39:10 AM UTC-5, Olek wrote:
>
> Hi!
>
> I need a stable clojure.xml/parse.
> Unfortunately current implementation changes the order of child elements 
> in a node.
> I use xml as a form of language for DSL. Please don't suggest switching to 
> clojure structures because non-clojure programmers (actually analysts) are 
> editing it and also there are such business requirements.
> Do you know how to achieve that (do I have write SAX parser?! ;-( )? It 
> would be good if the outputting data structure was the same as for 
> clojure.xml/parse (or I will just transform it to desired form).
>
> Thanks in advance!
> Olek
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Reworking :pre condition to add an error message

2016-03-29 Thread Francis Avila
A wonderful hack I read about somewhere is to just use the clojure.test/is 
macro, which I now do all the time:

(require '[clojure.test :refer [is]])
=> nil
(defn get-key [m k]
  {:pre [(is (map? m) "m is not a map!")]}
  (m k))
=> #'user/get-key
(get-key [] 0)

FAIL in clojure.lang.PersistentList$EmptyList@1 
(form-init8401797809408331100.clj:2)
m is not a map!
expected: (map? m)
  actual: (not (map? []))
AssertionError Assert failed: (is (map? m) "m is not a map!")  user/get-key 
(form-init8401797809408331100.clj:1)


This is great for repl use, but it does side-effect (the printed error) and 
doesn't return anything structured. It's suited to development-time human 
use rather than runtime or machine-use.

I see the potential for a macro which rethrows the assertion errors as 
something like ex-info exceptions (i.e. something with structured data.) 
That would fill runtime or machine-uses better (or structured logging?), 
but I'm not sure that fits with the spirit of pre/post conditions in the 
first place. After all, these do raise Java AssertionErrors, which are not 
meant to be recoverable.

On Tuesday, March 29, 2016 at 4:19:12 PM UTC-5, Alex Miller wrote:
>
> (zombie thread back from the dead... :)
>
> I think enhancements on :pre/:post are interesting.
>
> http://dev.clojure.org/jira/browse/CLJ-1817 seems like a good place to 
> work on this.
>
>
> On Tuesday, March 29, 2016 at 4:02:25 PM UTC-5, Colin Taylor wrote:
>>
>> Would there be interest in a ticket in this? Seems simple enough if (as 
>> above) putting the message under the :pre key is acceptable?
>>
>>
>> On Thursday, July 14, 2011 at 3:25:16 AM UTC+12, frye wrote:
>>>
>>> I do think a simple String error message is all that the user of the 
>>> function should provide. From there, An AssertionError can throw up 
>>> something along the lines of what you said - Expected… , Found… , Message. 
>>> That would give enough information for reporting at least in a test 
>>> framework. To get more precise information, like you said, that 
>>> AssertionError could also throw up class/file information, etc. that a 
>>> debugger could use. I would guard against designing these things to 
>>> accomodate a context outside of it's execution scope. In the ideal 
>>> functional world, the input and output are wholly localized. Any 
>>> Error/Exception thrown can be consumed or chained to give very precise 
>>> failure reasoning.  
>>>
>>>
>>> As for how that would fit into the entire exception chain, that's still 
>>> being thought (see here 
>>> ). There are 
>>> already a few approaches, and I think this (see here 
>>> ) is 
>>> the context of how the core team is approaching this problem. 
>>>
>>>
>>> Cheers 
>>> Tim 
>>>
>>>
>>> On Tue, Jul 12, 2011 at 6:01 AM, Shantanu Kumar  
>>> wrote:
>>>
 As I am the culprit of having introduced it with a naive example, I'd
 better admit it may not be very useful in practical scenarios across a
 wide variety of use cases. For example, when there is an assertion
 error with message "`m` should be a map" 14 levels down the stack, I'd
 really wish it said "`m` -- Expected: map, Found: vector [:foo :bar]"
 so that I can debug it quickly.

 Pre-conditions and Post-conditions are a valuable debugging aid, and
 to enable that we need very precise information. Unfortunately passing
 a string error message cannot encapsulate enough error context. A more
 complex example can be where the correctness of input must be
 determined collectively (in association with other args) -- in those
 cases one can only fall back on comparing input values and raise
 IllegalArgumentException accordingly.

 Regards,
 Shantanu

 On Jul 11, 10:40 pm, Timothy Washington  wrote:
 > 

>>>
>>>

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


Re: Trouble replacing deprecated map< function

2016-02-15 Thread Francis Avila
I think the difficulty here is that Chord has a bidirectional channel, 
where putting and taking operate on different "streams" inside the channel. 
(Internally, Chord is actually using a different channel for reads and 
writes. It constructs the "joined" channel using chord.channels/bidi-ch)

I don't think this was envisioned as a proper way to use channels. I think 
they were envisioned as a queue, and queues hold values, not communication 
streams. When you put onto a channel, it contains what you put until you 
take it off. (Note that channels with attached transducers must be buffered 
because it needs a place to hold the result of the reduction step.) A Chord 
channel isn't like this: when you put on it, the value is gone, and 
different values from some other place appear when you take from it.  The 
more usual solution is to use a pair of channels.

map<, map>, etc happened to work because they always put/take a value 
unchanged in the opposite direction onto the transformed channel.

I suspect the core developers were only using map>, map< et al in pipelines 
(where transducers are fine) and not realizing people were using them in a 
way that relied on the other direction being pass-through.

You will always need either a pair of channels to undo the unification done 
by Chord, or you will need to implement a channel (using reify and the 
WritePort and ReadPort protocols) where take and put mean different things 
and you can attach a transducer independently to each. Something like that 
would probably not make it in to core because it encourages the use of 
Chord-style "multistream" channels.

You could try something like this:

(defn eduction> [xform ch]
  (let [in-stream (chan 1 xform)
out-stream (chan)]
(pipe in-stream ch)
(pipe ch out-stream)
(chord.channels/bidi-ch in-stream out-stream)))

Of course it would be more efficient to use reify and implement the channel 
interfaces directly, like map> does, but with transducer semantics for f 
(including the finalize arity and when the f is called).


On Friday, February 12, 2016 at 1:41:20 PM UTC-6, James Reeves wrote:
>
> I currently have some core.async code that looks like:
>
> (map< :foo ch)
>
> However, map< and map> are now deprecated, with the suggestion to use 
> transducers instead. Unfortunately it's not obvious how to go about that.
>
> At first I thought that I could use a pipe and a new channel:
>
> (pipe ch (chan 1 (map :foo)))
>
> But there's no distinction between channel input and output here. This 
> matters because I'm using a bidirectional channel from Chord 
> .
>
> I'm thinking that it would be nice to have some functions like:
>
> (eduction< ch xform)
> (eduction> ch xform)
> (eduction ch xform)
>
> So I could write something like:
>
> (eduction< ch (map :foo))
>
> Have I missed anything? Is there some equivalent to this functionality 
> already in core.async that I haven't noticed?
>
> - James
>

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


[Clojurescript] .getElementById returns NULL

2016-01-03 Thread Francis Avila
Your problem is unrelated to clojurescript.

Your script runs before the body is loaded, so the test-content element doesn't 
exist yet.

Either load your script at the end of the body, or wrap your code in a 
document.onload event handler.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Would a custom constructor for records be a silly idea?

2015-12-27 Thread Francis Avila
In clojurescript you can just "override" the necessary protocols inline in the 
defrecord. You will get a warning, but everything will work. You can silence 
the warning by using extend-type instead of an inline implementation.

In clojure, doing this will give you a compile-time error, meaning you have to 
reimplement all the functionality of a defrecord using deftype, even for 
protocols you do not actually want to override.

The Potemkin library has some macros to make this kind of thing less tedious, I 
recommend taking a look: https://github.com/ztellman/potemkin

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


Re: ANN: ClojureScript 1.7.170, Enhanced Build Pipeline

2015-11-07 Thread Francis Avila
For future travelers.

If you use figwheel 0.5.0-SNAPSHOT you will get this exception:


clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: No such 
var: ana/forms-seq*, compiling:(figwheel_sidecar/utils.clj:49:21)

figwheel 0.5.0-SNAPSHOT has a dependency on cljs 1.7.145 even though it needs 
1.7.170.

To resolve this error you must explicitly depend on clojurescript in your 
plugins. Example:

:plugins [[lein-figwheel "0.5.0-SNAPSHOT"]
  [org.clojure/clojurescript "1.7.170"]] ;; Overrides broken 
lein-figwheel dependency.

lein deps :tree shows cljs 1.7.170 is used.

So, 



On Saturday, November 7, 2015 at 3:30:05 AM UTC-6, Maria Geller wrote:
> Try using 0.5.0-SNAPSHOT for figwheel ;)
> 
> On Saturday, November 7, 2015 at 9:59:24 PM UTC+13, Francis Avila wrote:I'm 
> getting the following exception with figwheel builds (using 0.4.1):
> 
> 
> 
> java.lang.AbstractMethodError: Method 
> clojurescript_build/core/CompilableSourcePaths._find_sources(Ljava/lang/Object;)Ljava/lang/Object;
>  is abstract
> 
>  at clojurescript_build.core.CompilableSourcePaths._find_sources (core.clj:-1)
> 
> 
> 
> 
> 
> (cljsbuild works fine with version 1.1.1)
> 
> 
> 
> Nolan said "All the mentioned tools [inc. figwheel] have already accounted 
> for this change." I don't see any mention in the figwheel docs about cljs 
> 1.7.170 compatibility or any commit message that mentions it. Can anyone 
> confirm this is actually true for figwheel?
> 
> 
> 
> On Friday, November 6, 2015 at 6:05:19 AM UTC-6, David Nolen wrote:
> 
> > ClojureScript, the Clojure compiler that emits JavaScript source code.
> 
> > 
> 
> > 
> 
> > README and source code: https://github.com/clojure/clojurescript
> 
> > 
> 
> > 
> 
> > Leiningen dependency information:
> 
> > 
> 
> > 
> 
> >     [org.clojure/clojurescript "1.7.170"]
> 
> > 
> 
> > 
> 
> > This release includes a major refactor of the build pipeline thanks to
> 
> > Juho Teperi. This change along with some greatly simplified
> 
> > recompilation logic will mean much faster cold build times for larger
> 
> > projects (some users have already reported >10X).
> 
> > 
> 
> > 
> 
> > This is a breaking change for existing tooling. You will need to
> 
> > upgrade lein-cljsbuild, lein-figwheel, and boot-cljs if you intend to
> 
> > adopt this version of ClojureScript. All the mentioned tools have
> 
> > already accounted for this change. Refer to the appropriate
> 
> > documentation for your tooling to determine which version number you
> 
> > should adopt.
> 
> > 
> 
> > 
> 
> > Other interesting changes and fixes include newer Google Closure
> 
> > Compiler and Library dependencies, self hosting tweaks, a Google
> 
> > Closure modules (:modules compiler option) regression,
> 
> > improved warnings, and minor REPL enhancements.
> 
> > 
> 
> > 
> 
> > As always feedback welcome!
> 
> > 
> 
> > 
> 
> > ### Enhancements
> 
> > * Refactor build pipeline
> 
> > * CLJS-1478: Self-host: Allow static-fns opt
> 
> > 
> 
> > 
> 
> > ### Changes
> 
> > * Generate larger range of random UUIDs
> 
> > * make browser REPL file reloads less chatty
> 
> > * CLJS-1475: indicate that cljs.reader/read is safe
> 
> > * CLJS-1470: Bump GCL Dependency
> 
> > * bump Google Closure dep
> 
> > 
> 
> > 
> 
> > ### Fixes
> 
> > * in system-time check that js/process.hrtime is actually a thing
> 
> > * CLJS-1228: cljs.util/topo-sort is polynomial on larger dependency graphs
> 
> > * check that performance.now method actually exists
> 
> > * CLJS-1476: Self-host: Protocol prefixing broken for three- (or more) 
> > segment namespaces
> 
> > * CLJS-1472 Patch for CLJS-1467 causes regression for nodejscli
> 
> > * CLJS-1469 :modules regression
> 
> > * CLJS-1445: Syntax error for var args in protocol methods
> 
> > * Warn if protocol impl methods do not match its protocol
> 
> > * CLJS-1451 Protocol impl do not support qualified method names
> 
> > * CLJS-1422: cljs.js/eval-str fails for ns form on node.js with simple 
> > optimizations
> 
> > * CLJS-1423: self-host: Requiring analyzer/compiler breaks unchecked Boolean
> 
> > * CLJS-1466: Improperly munged output path for GClosure JavaScript
> 
> > * CLJS-1467: Foreign Libraries not included when using :main with :simple 
> > or :advanced

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


Re: ANN: ClojureScript 1.7.170, Enhanced Build Pipeline

2015-11-07 Thread Francis Avila
I'm getting the following exception with figwheel builds (using 0.4.1):

java.lang.AbstractMethodError: Method 
clojurescript_build/core/CompilableSourcePaths._find_sources(Ljava/lang/Object;)Ljava/lang/Object;
 is abstract
 at clojurescript_build.core.CompilableSourcePaths._find_sources (core.clj:-1)


(cljsbuild works fine with version 1.1.1)

Nolan said "All the mentioned tools [inc. figwheel] have already accounted for 
this change." I don't see any mention in the figwheel docs about cljs 1.7.170 
compatibility or any commit message that mentions it. Can anyone confirm this 
is actually true for figwheel?

On Friday, November 6, 2015 at 6:05:19 AM UTC-6, David Nolen wrote:
> ClojureScript, the Clojure compiler that emits JavaScript source code.
> 
> 
> README and source code: https://github.com/clojure/clojurescript
> 
> 
> Leiningen dependency information:
> 
> 
>     [org.clojure/clojurescript "1.7.170"]
> 
> 
> This release includes a major refactor of the build pipeline thanks to
> Juho Teperi. This change along with some greatly simplified
> recompilation logic will mean much faster cold build times for larger
> projects (some users have already reported >10X).
> 
> 
> This is a breaking change for existing tooling. You will need to
> upgrade lein-cljsbuild, lein-figwheel, and boot-cljs if you intend to
> adopt this version of ClojureScript. All the mentioned tools have
> already accounted for this change. Refer to the appropriate
> documentation for your tooling to determine which version number you
> should adopt.
> 
> 
> Other interesting changes and fixes include newer Google Closure
> Compiler and Library dependencies, self hosting tweaks, a Google
> Closure modules (:modules compiler option) regression,
> improved warnings, and minor REPL enhancements.
> 
> 
> As always feedback welcome!
> 
> 
> ### Enhancements
> * Refactor build pipeline
> * CLJS-1478: Self-host: Allow static-fns opt
> 
> 
> ### Changes
> * Generate larger range of random UUIDs
> * make browser REPL file reloads less chatty
> * CLJS-1475: indicate that cljs.reader/read is safe
> * CLJS-1470: Bump GCL Dependency
> * bump Google Closure dep
> 
> 
> ### Fixes
> * in system-time check that js/process.hrtime is actually a thing
> * CLJS-1228: cljs.util/topo-sort is polynomial on larger dependency graphs
> * check that performance.now method actually exists
> * CLJS-1476: Self-host: Protocol prefixing broken for three- (or more) 
> segment namespaces
> * CLJS-1472 Patch for CLJS-1467 causes regression for nodejscli
> * CLJS-1469 :modules regression
> * CLJS-1445: Syntax error for var args in protocol methods
> * Warn if protocol impl methods do not match its protocol
> * CLJS-1451 Protocol impl do not support qualified method names
> * CLJS-1422: cljs.js/eval-str fails for ns form on node.js with simple 
> optimizations
> * CLJS-1423: self-host: Requiring analyzer/compiler breaks unchecked Boolean
> * CLJS-1466: Improperly munged output path for GClosure JavaScript
> * CLJS-1467: Foreign Libraries not included when using :main with :simple or 
> :advanced

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: "get" returns nil even when "not-found" is supplied?

2015-10-16 Thread Francis Avila
Not-found is not the same is not-nil. Is it possible that 
this-users-converstation *does* have an :incoming-message key with a nil 
value?

See the difference between these two cases:

(get {} :a :not-found)
=> :not-found
(get {:a nil} :a :not-found)
=> nil



Notice also that records always "have" keys that are defined on them even 
if they are not set:

(defrecord Rec [a])=> user.Rec
(get (map->Rec {}) :a :not-found)
=> nil



Perhaps you want to use or instead?

(or (get this-users-conversation :incoming-message) "")


Or figure out why nil is written and prevent it?

On Friday, October 16, 2015 at 1:33:29 PM UTC-5, Lawrence Krubner wrote:
>
> What am I doing wrong here? I want to call clojure.string/lower-case  on 
> the :incoming-message of this-users-conversation. If there is no message, I 
> return an empty string. 
>
>
> (defn discern-current-state [this-users-conversation]
>   (cond
> (= (clojure.string/lower-case (get this-users-conversation 
> :incoming-message "")) "yes") (assoc this-users-conversation :current-state 
> :salesforce-write)
>
>
> and yet the error points to the above line: 
>
> java.lang.NullPointerException {:class java.lang.NullPointerException, 
> :message nil, :trace-elems ({:anon-fn false, :fn "lower-case", :ns 
> "clojure.string", :clojure true, :file "string.clj", :line 215} {:anon-fn 
> false, :fn "discern-current-state", :ns "nlph.event-bus", :clojure true, 
> :file "event_bus.clj", :line 92} 
>
>
> but of course, at the REPL, everything works as I would expect: 
>
> (def users {:message "hello"})
> #'nlph.core/users
>
> nlph.core=> (clojure.string/lower-case (get users :message))
> "hello"
>
> nlph.core=> (clojure.string/lower-case (get users :message ""))
> "hello"
>
> nlph.core=> (clojure.string/lower-case (get users :lisa))
>
> NullPointerException   clojure.string/lower-case (string.clj:215)
>
> nlph.core=> (clojure.string/lower-case (get users :lisa ""))
> ""
>
> nlph.core=> (clojure.string/lower-case (get users :lisa))
>
> NullPointerException   clojure.string/lower-case (string.clj:215)
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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 do you process this over multiple values?

2015-10-16 Thread Francis Avila

There are only two steps: filter to select maps to use (e.g. :name = 
"abc"), map to transform them (e.g. extract :value). Here are some examples:

(def xs [{:src "a.png", :name "abc", :value "a"} {:name "def", :src 
"b.gif", :value "b"}])
=> #'user/xs
(->> xs
 (filter (comp #{"abc" "def"} :name))
 (map :value))
=> ("a" "b")
(->> xs
 (filter (comp #{"abc"} :name))
 (map :value))
=> ("a")
(->> xs
 (filter #(= (:name %) "abc"))
 (map #(select-keys % [:name :value])))
=> ({:value "a", :name "abc"})
(->> xs
 (filter #(= (:name %) "abc"))
 (map #(do {:name (:name %) :value (:value %)})))
=> ({:name "abc", :value "a"})
(as-> xs <>
 (filter #(= (:name %) "abc") <>)
 (clojure.set/project <> [:name :value]))
=> #{{:value "a", :name "abc"}}



On Friday, October 16, 2015 at 11:20:30 PM UTC-5, Mike wrote:
>
> I'm still new at this, thanks for any help.
>
> The following line extracts a value from a data structure:
>
> (:value (first (filter #(= (:name %) "abc") input-attrs)))
>
> *input-attrs* is a seq of hashes that for example looks like:
>
> ({:src "a.png", :name "abc", :value "a"} {:name "def", :src "b.gif", :value 
> "b"})
>
> This is test data; the real data will have this structure but have more 
> hashes.  My goal is to return the :value value when a specific :name value 
> is specified.  The first line above is how to extract the :value value when 
> :name = "abc".  The problem is that I need to extract 2 :value values for 2 
> distinct :name values from this one structure.  The structure is moderately 
> expensive to construct, so while I have it built I'd like to pull 
> everything out of it that I need at once.
>
> It struck me that I should pass a vector of :name values to this function 
> and have some sort of *for *or *map *process the vector over this 
> extraction.  But I cannot seem to write that correctly.  It also struck me 
> that once I can do the extractions correctly that I should probably pass a 
> list of hashes back that has the result, such as:
>
> ({name "abc", :value "a"} {:name "def" :value "b"})
>
> But then that looks curiously very similar to the original structure 
> (minus unmatched hashes and some unneeded other values).  Am I just 
> thinking about this "wrongly"?  Thanks for any help.
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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.


what is the shortest series of casts needed to get

2015-10-04 Thread Francis Avila
Does he actually need a real arraylist, or will something fulfilling a 
collection interface (Collection, Iterable, or List for example) be ok? Many 
clojure types do not require any casting at all as long as the java code writes 
to a collection interface and doesn't expect to be able to mutate the object. 
(Both of these are good Java idioms: write to interfaces not classes, and copy 
defensively.)

So if your coworkers code just needs something iterable (for example), you may 
not need to do any casting at all: just give him the vector.

If your coworker's code needs a real ArrayList and can accept no substitutes, 
(java.util.ArrayList. your-vector) will make an ArrayList copy of a vector's 
contents.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: Type hint using protocol

2015-09-08 Thread Francis Avila
I don't quite understand why you are not calling the Protocol method as a 
function, i.e.

(new-node this t-2 lev l r c)

(no leading dot on new-node).

I also don't see anything which actually *implements* INode.

Note that the meaning of "method" in "Protocol method" is not the same as 
in "Java method": i.e. these are not Java methods called via Java interop, 
although protocol implementations may create java methods on the class that 
implements them in some cases (i.e. inline implementations using deftype or 
defrecord) or a Java class may implement the protocol via the 
auto-generated interface of the same name. You are trying to call the 
"new_node" Java method directly on whatever "this" is in that context, 
which requires reflection on "this" to find the implementation.


On Tuesday, September 8, 2015 at 1:31:10 PM UTC-5, William la Forge wrote:
>
> I'm finally looking at warn on reflection. Everything is going fine except 
> in the nodes.clj file where I define a protocol, INode, with a method, 
> new-node and then try to call that method from a function, revise.
>
> I'm using Clojure 1.7.0 and the file is 
> https://github.com/laforge49/aatree/blob/master/src/aatree/nodes.clj
> The reflection warning occurs on line 51.
>
> Depending on what I try, either I get a class not found compiler error for 
> file nodes.cli or a runtime error that new-node is NOT a member of the 
> record that implements INode. I've spent hours on this and have tried many 
> different things to no avail.
>
> My reason for using a method in a protocol is that I have several records 
> that implement it and I'm trying to not duplicate functions which take the 
> protocol as an argument.
>
> Oh yes, because I'm also using genclass, I have no option but to use AOT. 
>
> On Sunday, January 12, 2014 at 8:52:14 AM UTC-5, Jim foo.bar wrote:
>>
>> there you go:
>>
>> (defprotocol IBark
>>  (bark [this]))
>>
>> (in-ns 'other)
>> (set! user/*warn-on-reflection* true)
>>
>> (clojure.core/defrecord Dog []
>> user/IBark
>> (bark [_] (clojure.core/println "WOOF!")))
>>
>> (def d (Dog.))
>>
>> (user/bark d) ;;NO reflection
>>
>> (.bark d) ;;reflection
>>
>> it should be obvious now :)
>>
>> Jim
>>
>>
>> On 12/01/14 13:38, Jim - FooBar(); wrote:
>>
>> It is not compiling because it cannot find the function...either fully 
>> qualify it like in my previous email or change your ns declaration to 
>> something like: 
>>
>> [cqrs.storage :as stora] 
>>
>> and then simply use stora/ret-value, stora/write, stora/write-batch
>>
>> Jim
>>
>>
>>
>> On 12/01/14 13:26, bob wrote:
>>
>> If I remove the dot, it cannot be compiled. can you give an example?
>>
>> On Sunday, January 12, 2014 9:22:00 PM UTC+8, Jim foo.bar wrote: 
>>>
>>> I am suspecting you are calling the protocol implementations via the `.` 
>>> form, whereas you should be going via the protocol itself (whatever 
>>> namespace that may be in). 
>>>
>>> Jim 
>>>
>>> -- 
>> -- 
>> 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/groups/opt_out.
>>
>>
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email 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: (fail promise exception)

2015-08-07 Thread Francis Avila
Futures automatically capture exceptions raised in their bodies and reraise 
them when the future is derefed. Promises also throw exceptions when 
derefed.

Unlike promises, futures are created with the code that delivers their 
value, so calling fail and deliver explicitly on a future makes no sense.

Think of futures as a thin wrapper around a promise which spawns a thread, 
runs the code, and to the wrapped promise either delivers the result of the 
code or calls (fail private-promise raised-exception) for you.

On Friday, August 7, 2015 at 2:14:30 PM UTC-5, William la Forge wrote:

 A future fails when it throws an exception. How to do that with a future?

 It looks like (fail future exception) does not do the trick: 
 http://dev.clojure.org/display/design/Promises



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: (fail promise exception)

2015-08-07 Thread Francis Avila
Huh, I was sure I had done this before, but I misremembered, I was using my 
own promise that rethrew Throwable instances on deref (and it was in 
clojurescript!)

Clojure promises have no notion of failure, only realized/not-realized. You 
need to deliver a sentinel type or value and check for it on deref, or 
implement your own promise type which does it for you. (It's not that 
hard: 
https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L6803
 
)

On Friday, August 7, 2015 at 4:09:39 PM UTC-5, William la Forge wrote:

 Sorry, I meant to ask how to fail with a promise? It seems that there is 
 no fail method.

 On Friday, August 7, 2015 at 4:52:47 PM UTC-4, Francis Avila wrote:

 Futures automatically capture exceptions raised in their bodies and 
 reraise them when the future is derefed. Promises also throw exceptions 
 when derefed.

 Unlike promises, futures are created with the code that delivers their 
 value, so calling fail and deliver explicitly on a future makes no sense.

 Think of futures as a thin wrapper around a promise which spawns a 
 thread, runs the code, and to the wrapped promise either delivers the 
 result of the code or calls (fail private-promise raised-exception) for you.

 On Friday, August 7, 2015 at 2:14:30 PM UTC-5, William la Forge wrote:

 A future fails when it throws an exception. How to do that with a future?

 It looks like (fail future exception) does not do the trick: 
 http://dev.clojure.org/display/design/Promises



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: no set-car! in clojure

2015-08-06 Thread Francis Avila
There is no equivalent to set-car!, because conses are not mutable. Only 
vars, refs, atoms, and agents are mutable, and they are simply containers 
for immutable values.  You could put a cons inside an atom and put a new 
transformed list into the atom. (Note even among schemes set-car! is highly 
discouraged, and I don't think Racket even has it in core 
anymore: 
http://blog.racket-lang.org/2007/11/getting-rid-of-set-car-and-set-cdr.html)

The idiomatic Clojure way of handling this is to always have an immutable 
environment and contain it in a single environment atom.  When you change 
the environment, you return a new copy of it with your change and put it in 
to the global env atom. The SICP mutates the environment instead. There's 
probably a reason for this (late/dynamic binding?) which would have a 
completely different approach in Clojure.

Some more notes:

(empty? nil) ;= true

def and defn create namespace-global vars as a side effect--the vars are 
not lexically scoped! This is NOT like scheme's define. I suspect all of 
your inner uses of def and defn should be let and letfn instead. def and 
defn are used at the top level or (rarely) are used a level or two down to 
close over some private data (e.g. a def inside a let). However, defs are 
practically never inside other defs.

On Thursday, August 6, 2015 at 12:36:20 PM UTC-5, 杨旸 wrote:

 Hi everyone,
 I am current trying to implement a scheme interpreter in clojure following 
 the instruction on SICP chap4.

 Where I encounter a problem with adding/modifying a def var/fn in 
 enviroment.

 according to chap4  4.1.3 the set-variable-value! function looks like the 
 following in scheme:
 (define (set-variable-value! var val env)
   (define (env-loop env)
 (define (scan vars vals)
   (cond ((null? vars)
  (env-loop (enclosing-environment env)))
 ((eq? var (car vars))
  (set-car! vals val))
 (else (scan (cdr vars) (cdr vals)
 (if (eq? env the-empty-environment)
 (error Unbound variable -- SET! var)
 (let ((frame (first-frame env)))
   (scan (frame-variables frame)
 (frame-values frame)
   (env-loop env))




 But I found there's no set-car! in clojure, which make me have to 
 re-create the env while loop though the defied variables like:
 *https://github.com/zacyang/sicp-in-clj/blob/master/src/sicp/ch4/core.clj 
 https://github.com/zacyang/sicp-in-clj/blob/master/src/sicp/ch4/core.clj 
 line #348*


 (defn set-variable-value!
   [var-looking-for val-to-be-set env]


   (defn find-and-change [vars vals]
 (cond
  (empty? vars)   '()
  (= (first vars) var-looking-for)  (conj (find-and-change (rest vars) 
 (rest vals))  val-to-be-set) 
  :else (conj (find-and-change (rest vars) (rest vals)) (first vals


   (defn env-loop
 [e]
 
 (if (= @env @the-empty-environment) 
   :ERROR-TRY-SET-UNBOUND-VARIABLE
   (let  [frame (first-frame e)
  frame-vars (frame-variables frame)
  frame-vals (frame-values frame)]
 
 (if (not= @(enclosing-enviroment e) @the-empty-environment)
   (extend-enviroment frame-vars frame-vals (env-loop 
 (enclosing-enviroment e)))
   (extend-enviroment 
frame-vars
(find-and-change frame-vars frame-vals)
the-empty-environment)


   (env-loop env)
 )

 My question is, is there any good substitution for set-car! in scenarios 
 where I need just *change* the car and cdr of something created by cons??

 PS: tried swap! atom , but it will also need to change the whole 
 environment structure. 



   


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: Should the Cheat Sheet mention assoc-in for vectors?

2015-08-06 Thread Francis Avila
assoc-in works for vectors in the sense that both vectors and maps 
implement ILookup (get) and IAssoc (assoc). assoc-in can navigate any 
collection that understands get (including sets!), and add to any 
collection that understands assoc.

However, assoc-in will *always* create *maps* when it encounters missing 
keys. This is unlikely to be what you want most of the time when working 
with a vector structure. Examples:

(assoc-in [:a [:b [:c :d] :e]] [1 1 1] :f)
;= [:a [:b [:c :f] :e]]
(assoc-in [] [0] :a)
;= [:a]
(assoc-in [] [1] :a)
;IndexOutOfBoundsException   clojure.lang.PersistentVector.assocN 
(PersistentVector.java:183)
(assoc-in [] [0 0] :a)
;= [{0 :a}]
(assoc-in [] [0 0 0] :a)
;= [{0 {0 :a}}]
(assoc-in [] [0 0 1] :a)
;= [{0 {1 :a}}]



On Thursday, August 6, 2015 at 7:29:04 AM UTC-5, Carl Smotricz wrote:

 Dunno if this is the correct place and way to suggest a correction: 

 Someone just mentioned to me that (assoc-in) seems to only work for maps, 
 as the Cheat Sheet section on vectors doesn't mention it. I was able to 
 show him otherwise, but maybe this is something the CS should pick up?


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


Re: Beginner question

2015-07-29 Thread Francis Avila
Note: my knowledge of soap is not very deep, but I have done the following 
in a production system.

If you have a WSDL available, a good approach is to generate the (Java) 
client code and then use it via Java interop.  You can smooth out the rough 
edges and shed the extra java types by using the clojure.java.data library 
to define to-java and from-java 
methods. https://github.com/clojure/java.data


The state-of-the-art in java code generation from a WSDL seems to be Apache 
cxf http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html 
 Below is a mini-tutorial of its use.

In the project.clj, add the configuration and dependencies that cxf needs. 
We'll be using cxf through a maven plugin that wraps it 
(cxf-codegen-plugin).  The maven plugin
is configured via a pom, so we'll use leinigen's :pom-additions and 
:pom-plugins keys to inject stuff into the pom it generates.


(defproject my-soap-client 0.0.1-SNAPSHOT
  :description Example of using leinigen to generate a pom to generate Java 
from WSDLs using maven and cxf-codegen-plugin

  :source-paths [] ;; NOTE: No Clojure code!
  :java-source-paths [src] ;; NOTE: Where the *generated* java will go!
  ;; NOTE: Adding source path to clean targets because it is generated code!
  :clean-targets ^{:protect false} [:target-path :compile-path 
:java-source-paths]

  :pom-addition [:properties [:project.build.sourceEncoding UTF-8]]

;; This is all Maven stuff, documented here: 
https://maven.apache.org/guides/mini/guide-configuring-plugins.html#Configuring_Build_Plugins
;; What you see below is serialized as XML in the generated pom.xml
  :pom-plugins
  [[org.apache.maven.plugins/maven-source-plugin 2.4
{:executions
 [:execution
  [:id bundle-sources]
  [:goals
   [:goal jar-no-fork]]]}]
   [org.apache.cxf/cxf-codegen-plugin 3.1.1
{:executions
 [:execution
  [:id my-execution-id]
  [:phase generate-sources]
  [:configuration
   [:sourceRoot ${project.basedir}/src]
;; NOTE: Options documented here: http://cxf.apache.org/docs/wsdl-to-java.html
;; Some WSDLs may need more or fewer options than shown here.
   [:wsdlOptions
[:wsdlOption
;; NOTE: Consider downloading the wsdl to a file.
 [:wsdl https://example.org/mywsdl;]
 [:extraargs
  [:extraarg -verbose]
  [:extraarg -mark-generated]
  [:extraarg -exsh] [:extraarg true]
  [:extraarg -autoNameResolution]
  [:goals [:goal wsdl2java]]]}]])



Then with this project.clj in place, you build your java code like so:

#!/bin/sh

lein do clean, pom  mvn package

# This will define variables used below.
source target/maven-archiver/pom.properties

BUILT_JAR=target/${artifactId}-${version}.jar
SRC_JAR=target/${artifactId}-${version}-sources.jar

# You can then use the full form of lein deploy to create a maven-compatible 
release artifact
# Include this in your *real* clojure project as a dependency!
# TODO: I don't know how (or if it is possible) to get leinigen to deploy 
separate
# java/maven source or javadoc jars too.

lein deploy releases ${groupId}/${artifactId} ${version} ${BUILT_JAR} 
pom.xml



Up until now we have done nothing that really involves Clojure. This could 
have been a plain Java maven project with a handcrafted pom.xml. The jar 
itself is just compiled java class files. I just used leinigen because it 
was more familiar.


In your actual Clojure project, require this java-soap-client project you 
deployed:

[my-soap-client 0.0.1-SNAPSHOT]

Then use it via Java interop. Details may vary (see your WSDL or the SOAP 
service documentation), but usually there's a Service object you need to 
instantiate somehow, and then call getSoapXX on it to get a Port object 
which has methods on it corresponding to the SOAP methods the service 
provides.  I think both of these are stateless and long-lived and can be 
shared by threads.

(import '(my.soap.service ServiceClass))

(let [service (ServiceClass.)
  port(.getSoap12 service)]

;; Sometimes the WSDL does not include the url of the soap service and you 
have to set it manually
(import '(javax.xml.ws BindingProvider))

  (.. ^BindingProvider port (getRequestContext) (put 
BindingProvider/ENDPOINT_ADDRESS_PROPERTY endpoint))


  ;; Now call your SOAP methods!
  (.mySoapMethod port)

)


Depending on the SOAP service and its WSDL, probably have a huge jumble of 
Java types to deal with in requests and responses, and you may even have 
raw XML to contend with, too. Your life will be much easier if you 
immediately convert instances from the Java client into plain Clojure data 
structures, and convert those data structures into the proper types right 
before you call the SOAP methods. clojure.data.java makes doing this much 
easier: you define a to-java and a from-java multimethod for the SOAP types 
you care about. It is also generic enough to handle many Java-bean like 
objects automatically. Example:

(require 

Re: ring.middleware.reload and figwheel

2015-07-28 Thread Francis Avila
I've never used ring.middleware.reload, but I do run client figwheel and 
server in the same jvm.

In your project.clj, make figwheel listen on an nrepl port:

:figwheel
{:nrepl-port   7888
 :server-port  3000 ; http
 :repl false ; Optional: keep this off and bootstrap to cljs 
repl: see below. 
 :ring-handler your-ring-handler}


Connect to that port with an nrepl client: this will be a clj repl for the 
server.

To get the cljs repl, you can either leave :repl true and use it from 
stdin/stdout, or you can piggieback to a cljs repl like so:

(do (use 'figwheel-sidecar.repl-api) (cljs-repl))

Since you can connect multiple nrepl clients to the same nrepl server, you 
can easily have one client for the server clj and another for the client 
cljs/figwheel.

On Thursday, April 30, 2015 at 5:06:13 AM UTC-5, Dan Kersten wrote:

 Hi,

 I've got a clojure(script) project where I use figwheel to live-reload 
 cljs and this works great, but I'm now trying to set up live reloading of 
 the server-side clojure too.
 Since I don't want to run multiple jvm/lein instances, I'm using figwheels 
 :ring-handler feature to add my server ring handler into figwheels embedded 
 webserver.
 In the past, I've live-reloaded my server code using the reloaded 
 workflow, but since figwheel gives me a cljs repl and not a clj repl, I 
 don't know how to do that without running the server independently.

 So, instead I'm just trying to get ring.middleware.reload working, but its 
 not picking up file changes. 

 Has anyone got this working? Alternatively, does anyone have any tips on 
 getting a nice workflow without running multiple jvm/lein instances?

 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 can I write a string into Redis such that a Java app might see its contents as a primitive string?

2015-07-15 Thread Francis Avila
As I said before, you need another layer of encoding/decoding, e.g. JSON. 
(Unless you plan on using Redis hash maps directly? They only support byte 
keys and values.)
Your example looks like Javascript or Python, but I don't know where you 
got it. Neither Clojure nor Java will print a map-like native structure in 
that format! I'll assume you are dealing with JSON.

To write: native data structure - JSON string - UTF-8 bytes - Redis SET
To read: Redis GET - UTF-8 bytes - JSON string - native data structure.

Example with carmine in Clojure:

user= (require '[taoensso.carmine :as car] '[cheshire.core :refer [generate
-string parse-string]])
nil
user= (defn json-set [k v] (car/set k (car/raw (.getBytes (generate-string 
v) UTF-8
#'user/json-set
user= (defn json-get [k] (car/parse #(parse-string %) (car/get k)))
#'user/json-get
user= (def conn {:pool {} :spec {}})
#'user/conn
user= (def test-data { money 10, contact_name Martha Vena})
#'user/test-data
user= (car/wcar conn (json-set test test-data))
OK
user= (car/wcar conn (json-get test))
{contact_name Martha Vena, money 10}

redis-clj:

127.0.0.1:6379 get test
{\contact_name\:\Martha Vena\,\money\:\10\}

Here's an example with a smiley face to test the UTF-8 encoding:

user= (car/wcar conn (json-set test2 [☺]))
OK
user= (car/wcar conn (json-get test2))
[☺]
user= (count (first *1))
1

In redis-cli:

127.0.0.1:6379 get test2
[\\xe2\x98\xba\]




On Wednesday, July 15, 2015 at 11:43:08 AM UTC-5, gingers...@gmail.com 
wrote:

 Sorry, I am stupid. I misunderstood the problem entirely. Escaped quote 
 marks are never really the problem. The real issue is that this works for 
 us: 

 { money : 10, contact_name : Martha Vena }

 and this doesn't work for us: 

 { \money\ : \10\, \contact_name\ : \Martha Vena\ }

 but in the second case the whole thing is a string. In the first case I 
 suppose the structure is a hashmap. I'll look at Carmine to see if it can 
 help me get the hashmap structure consistently. 

  


 On Friday, July 10, 2015 at 6:04:01 PM UTC-4, gingers...@gmail.com wrote:


 Hmm, well, I am grateful to you for running such a detailed test, and I 
 should have tested this myself: 

 The actual bytes stored at the test key are 0x61 0x22 0x62

 However, something in our code fails when the quote marks are escaped, 
 but everything works the way we expect when the quote marks do not appear 
 to be escaped. I amazed by this:

 user= (count *1)
 3

 Perhaps the error is something entirely different from what I was 
 assuming. 





 On Thursday, July 9, 2015 at 7:52:54 PM UTC-4, Francis Avila wrote:

 This is what I am doing with Carmine and it seems to work properly.

 First some setup in the repl:

 user=(require '[taoensso.carmine :as car])
 nil
 user= (def conn {:pool {} :spec {}})
 #'user/conn
 user= (defn raw-str-set [k ^String v] (car/set k (car/raw (.getBytes v 
 UTF-8
 #'user/raw-str-set
 user= (defn raw-str-get [k] (car/parse (car/get k) #(String. ^bytes % 
 UTF-8)))
 #'user/raw-str-get


 Now I save a test string:

 user= (car/wcar conn (raw-str-set test a\b))
 OK

 In a redis-cli terminal:

 $ redis-cli
 127.0.0.1:6379 get test
 a\b
 127.0.0.1:6379 

 The escaped \ you see in redis-cli is just for printing. The actual 
 bytes stored at the test key are 0x61 0x22 0x62

 Now lets pull this out of redis with Carmine:


 user= (car/wcar conn (raw-str-get test))
 a\b
 user= (count *1)
 3

 As you can see, we round-tripped without any strange extra escaping.

 Probably your java app can just use Jedis client.get(test) and 
 client.set(test,a-string), since I think it does UTF-8 encode and 
 decode of strings and no other serialization.


 You still need to use JSON on top of this so you can get richer data 
 structures instead of just strings.

 On Thursday, July 9, 2015 at 4:18:51 PM UTC-5, gingers...@gmail.com 
 wrote:

 I am sorry, I should have explained this sooner. When I do this: 

 (.getBytes document-as-string UTF-8)

 The quote marks are always escaped. When I do this: 

 document-as-byte-array (bytes (byte-array (map (comp byte int) 
 document-as-string)))

 The quote marks are sometimes escaped, but most of the time they are 
 not. 

 I need to avoid having those quote marks escaped. I am not clear what 
 is causing the escaping. 




 On Thursday, July 9, 2015 at 12:01:51 PM UTC-4, Francis Avila wrote:

 your document-as-byte-array is wrong--it only handles ascii, and very 
 inefficiently too.

 Just say (.getBytes document-as-string UTF-8) to get a utf-8 
 encoding of the string as a byte array.

 On Thu, Jul 9, 2015 at 10:41 AM, gingers...@gmail.com wrote:


  As for the escaped quotes, you may be using pr or prn to print, or 
 maybe you are 
  using pr-str to produce the string representation. I can't be sure. 

 At the moment I create the string like this: 

 document-as-string (str {\transaction-id\ : \ 
 transaction-id \, \message\ : \ message \})
 document-as-byte-array

Re: How can I write a string into Redis such that a Java app might see its contents as a primitive string?

2015-07-15 Thread Francis Avila
You are either encoding something incorrectly at some layer of your code 
(or the Java app's code), or you are misinterpreting what is printed as 
actual escaping when it actually is not escaped. Having to escape or 
unescape strings *is not normal* and is a symptom of a bigger problem.

As I demonstrated in my earlier post, redis-cli will PRINT \, but that is 
only for PRINTING.  The stored byte is actually just the quote. If you had 
an escaped string, redis would print \\\. Example:

127.0.0.1:6379 set test \
OK
127.0.0.1:6379 strlen test
(integer) 1
127.0.0.1:6379 get test
\
127.0.0.1:6379 set test \\\
OK
127.0.0.1:6379 strlen test
(integer) 2
127.0.0.1:6379 get test
\\\


You do need to take special care to bypass carmine's nippy encoding. That 
is what my raw-str-get and raw-str-set functions are doing. In fact, that 
code is a complete solution to round-tripping strings through redis! Are 
you saying you are getting different results?

And I don't know for sure what Jedis is doing because I've only read its 
code, not actually tried it. Perhaps it is to blame.


This is how you troubleshoot using the test string  (One-character string 
containing a double-quote). Repeat these steps on the Clojure app and the 
Java app.

   1. In app, verify the INPUT string is   (length 1)
   2. In app, verify the UTF-8 bytes is length 1
   3. In app, SET (bytes or string, depending on interface) into redis at 
   known key.
   4. In redis-cli, GET the key. You should see \
   5. In redis-cli STRLEN the key. It should return (integer) 1.
   6. In app, GET the key.
  1. If you get bytes, it should be length 1 and (= (String. byte-val 
  UTF-8) \)
  2. If you get a string, it should be (= (.length str-val) 1) and (= 
  str-val \))
   
If any of these steps is broken, you know that you did something wrong in 
the previous step.

On Wednesday, July 15, 2015 at 9:16:57 AM UTC-5, gingers...@gmail.com wrote:


 I have not yet found a solution for this problem. If I do this:

 (.getBytes v UTF-8)

 Then in Redis the quotes are escaped 100% of the time. What is the 
 standard way to handle this? I do see this on StackOverflow:


 http://stackoverflow.com/questions/12423071/how-to-remove-escape-characters-from-a-string-in-java

 which suggests: 

 String noSlashes = input.replace(\\, );

  
 Would this be considered a hack, or would this be the normal way to do 
 this? 







 On Friday, July 10, 2015 at 6:04:01 PM UTC-4, gingers...@gmail.com wrote:


 Hmm, well, I am grateful to you for running such a detailed test, and I 
 should have tested this myself: 

 The actual bytes stored at the test key are 0x61 0x22 0x62

 However, something in our code fails when the quote marks are escaped, 
 but everything works the way we expect when the quote marks do not appear 
 to be escaped. I amazed by this:

 user= (count *1)
 3

 Perhaps the error is something entirely different from what I was 
 assuming. 





 On Thursday, July 9, 2015 at 7:52:54 PM UTC-4, Francis Avila wrote:

 This is what I am doing with Carmine and it seems to work properly.

 First some setup in the repl:

 user=(require '[taoensso.carmine :as car])
 nil
 user= (def conn {:pool {} :spec {}})
 #'user/conn
 user= (defn raw-str-set [k ^String v] (car/set k (car/raw (.getBytes v 
 UTF-8
 #'user/raw-str-set
 user= (defn raw-str-get [k] (car/parse (car/get k) #(String. ^bytes % 
 UTF-8)))
 #'user/raw-str-get


 Now I save a test string:

 user= (car/wcar conn (raw-str-set test a\b))
 OK

 In a redis-cli terminal:

 $ redis-cli
 127.0.0.1:6379 get test
 a\b
 127.0.0.1:6379 

 The escaped \ you see in redis-cli is just for printing. The actual 
 bytes stored at the test key are 0x61 0x22 0x62

 Now lets pull this out of redis with Carmine:


 user= (car/wcar conn (raw-str-get test))
 a\b
 user= (count *1)
 3

 As you can see, we round-tripped without any strange extra escaping.

 Probably your java app can just use Jedis client.get(test) and 
 client.set(test,a-string), since I think it does UTF-8 encode and 
 decode of strings and no other serialization.


 You still need to use JSON on top of this so you can get richer data 
 structures instead of just strings.

 On Thursday, July 9, 2015 at 4:18:51 PM UTC-5, gingers...@gmail.com 
 wrote:

 I am sorry, I should have explained this sooner. When I do this: 

 (.getBytes document-as-string UTF-8)

 The quote marks are always escaped. When I do this: 

 document-as-byte-array (bytes (byte-array (map (comp byte int) 
 document-as-string)))

 The quote marks are sometimes escaped, but most of the time they are 
 not. 

 I need to avoid having those quote marks escaped. I am not clear what 
 is causing the escaping. 




 On Thursday, July 9, 2015 at 12:01:51 PM UTC-4, Francis Avila wrote:

 your document-as-byte-array is wrong--it only handles ascii, and very 
 inefficiently too.

 Just say (.getBytes document-as-string UTF-8) to get a utf-8 
 encoding of the string as a byte array.

 On Thu

reducers question

2015-07-14 Thread Francis Avila
Reducers can perform fewer allocations than lazy seqs, but that does not 
automatically translate into a big speed difference, especially with your 
trivial example.

Try comparing chained lazy seq ops (map, mapcat, filter, take, drop, etc) to an 
equivalent chain of reducer calls: you may see a more pronounced speed 
difference.

Reducers can also be foldable (thus parallel) if the source data structure 
supports it but are not so automatically. Try r/foldcat or r/fold to possibly 
see pmap speeds.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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 can I write a string into Redis such that a Java app might see its contents as a primitive string?

2015-07-09 Thread Francis Avila
your document-as-byte-array is wrong--it only handles ascii, and very
inefficiently too.

Just say (.getBytes document-as-string UTF-8) to get a utf-8 encoding of
the string as a byte array.

On Thu, Jul 9, 2015 at 10:41 AM, gingersafflo...@gmail.com wrote:


  As for the escaped quotes, you may be using pr or prn to print, or maybe
 you are
  using pr-str to produce the string representation. I can't be sure.

 At the moment I create the string like this:

 document-as-string (str {\transaction-id\ : \ transaction-id
 \, \message\ : \ message \})
 document-as-byte-array (bytes (byte-array (map (comp byte int)
 document-as-string)))

 The crazy thing is that this sometimes works, but other times the quote
 marks appear in Redis as escaped quote marks. As near as I can tell, the
 important factor is the length of the string. A short string is likely to
 have its quote marks escaped. A long string does not have its quote marks
 escaped.

 My co-worker is working on the Java app. I am working on the Clojure app.
 We can both adjust out apps freely, just so long as we can get data to and
 from each other, in a manner that allows us to eventually cast the data to
 and from JSON.

 Any suggestions are welcome.






 On Wednesday, July 8, 2015 at 8:58:53 PM UTC-4, Francis Avila wrote:

 Who is saving these strings, and who is reading them? Do you have
 complete control over both apps, or does one of them need to be aligned
 with the other?

 If the Java app is the baseline, you need to know the exact details of
 the format of the data it saves. Just knowing it's JSON is not enough,
 because there may be other data types (e.g. dates) that don't have native
 JSON representations. (The go-to JSON de/encoder for clojure is cheshire:
 https://github.com/dakrone/cheshire )

 I took a quick look at Jedis and the easy, default way of using it is
 with strings. It will encode strings to UTF-8 before sending to Redis and
 decode from UTF-8 on read. You can set raw byte arrays too (which will not
 be altered in any way before sending), but it's not clear to me how it can
 read out raw byte arrays. (I'm sure there's a way, but it's not immediately
 obvious.)

 As for the escaped quotes, you may be using pr or prn to print, or maybe
 you are using pr-str to produce the string representation. I can't be sure.

 On Wednesday, July 8, 2015 at 5:31:27 PM UTC-5, gingers...@gmail.com
 wrote:

 And I have another stupid question. Using the above code, I am sometimes
 getting strings in Redis that have escaped quotation marks, like this:

  \transaction-id\ : \ 1ec47c2e-21ee-427c-841c-80a0f89f55d7 \
 \debrief\ :  \ Susan Hilly at Citi called to get a quotation for
 discounted weekly car rental for approximately 3 cars per week, or 150
 rentals annually. \  

 Why is that happening?



 On Wednesday, July 8, 2015 at 5:38:20 PM UTC-4, gingers...@gmail.com
 wrote:

 Francis Avila,

 Thank you for your response. The Java app is using Jedis and the
 Clojure app is using Carmine. I'm wondering if you can suggest what you
 think would be the easiest way to allow these 2 apps to understand each
 other's strings?

 You were correct about how unsafe the above code was. I tested it for
 less than 15 minutes and ran into the fact that a \n newline made a mess of
 everything.



 On Wednesday, July 8, 2015 at 5:15:35 PM UTC-4, Francis Avila wrote:

 You are running into Carmine's automatic nippy serialization.
 https://github.com/ptaoussanis/carmine#serialization

 Redis only stores byte arrays (what it calls strings). Carmine uses
 the nippy library (the meaning of NPY in your byte stream) to represent
 rich types compactly as bytes. https://github.com/ptaoussanis/nippy

 If you give Carmine a byte array to store, it will store it directly
 without nippy-encoding it. E.g. (.getBytes {} UTF-8)

 BTW your document-as-string example is extremely unsafe: how will you
 reliably read this message out again? e.g. what if the 'debrief' string
 contains a single quote? Use a proper serialization format.

 So the key is to have both your Clojure and Java app store *bytes* in
 Redis using the same serialization. You can store anything you want 
 (nippy,
 utf-8-encoded json, fressian, bson, utf-8 xml, utf-16 java strings,
 whatever) as long as it's bytes and it's read and written the same way in
 all your apps.

 The Redis library your Java app is using may have its own automatic
 de/serialization, too. You need to find out what it's doing and either 
 work
 with this or turn it off, just like with Carmine.

 Nippy unfortunately does not have a Java API out of the box:
 https://github.com/ptaoussanis/nippy/issues/66


 On Wednesday, July 8, 2015 at 3:35:49 PM UTC-5, gingers...@gmail.com
 wrote:


 I am not sure if this is a Clojure question or a Java question. I
 don't know Java, so I could use whatever help folks can offer.

 primitive string here means what I can write when I am at the
 terminal.

 We have 2 apps, one in Clojure, one

Re: How can I write a string into Redis such that a Java app might see its contents as a primitive string?

2015-07-09 Thread Francis Avila
This is what I am doing with Carmine and it seems to work properly.

First some setup in the repl:

user=(require '[taoensso.carmine :as car])
nil
user= (def conn {:pool {} :spec {}})
#'user/conn
user= (defn raw-str-set [k ^String v] (car/set k (car/raw (.getBytes v 
UTF-8
#'user/raw-str-set
user= (defn raw-str-get [k] (car/parse (car/get k) #(String. ^bytes % 
UTF-8)))
#'user/raw-str-get


Now I save a test string:

user= (car/wcar conn (raw-str-set test a\b))
OK

In a redis-cli terminal:

$ redis-cli
127.0.0.1:6379 get test
a\b
127.0.0.1:6379 

The escaped \ you see in redis-cli is just for printing. The actual bytes 
stored at the test key are 0x61 0x22 0x62

Now lets pull this out of redis with Carmine:


user= (car/wcar conn (raw-str-get test))
a\b
user= (count *1)
3

As you can see, we round-tripped without any strange extra escaping.

Probably your java app can just use Jedis client.get(test) and 
client.set(test,a-string), since I think it does UTF-8 encode and 
decode of strings and no other serialization.


You still need to use JSON on top of this so you can get richer data 
structures instead of just strings.

On Thursday, July 9, 2015 at 4:18:51 PM UTC-5, gingers...@gmail.com wrote:

 I am sorry, I should have explained this sooner. When I do this: 

 (.getBytes document-as-string UTF-8)

 The quote marks are always escaped. When I do this: 

 document-as-byte-array (bytes (byte-array (map (comp byte int) 
 document-as-string)))

 The quote marks are sometimes escaped, but most of the time they are not. 

 I need to avoid having those quote marks escaped. I am not clear what is 
 causing the escaping. 




 On Thursday, July 9, 2015 at 12:01:51 PM UTC-4, Francis Avila wrote:

 your document-as-byte-array is wrong--it only handles ascii, and very 
 inefficiently too.

 Just say (.getBytes document-as-string UTF-8) to get a utf-8 encoding 
 of the string as a byte array.

 On Thu, Jul 9, 2015 at 10:41 AM, gingers...@gmail.com wrote:


  As for the escaped quotes, you may be using pr or prn to print, or 
 maybe you are 
  using pr-str to produce the string representation. I can't be sure. 

 At the moment I create the string like this: 

 document-as-string (str {\transaction-id\ : \ 
 transaction-id \, \message\ : \ message \})
 document-as-byte-array (bytes (byte-array (map (comp byte int) 
 document-as-string)))

 The crazy thing is that this sometimes works, but other times the quote 
 marks appear in Redis as escaped quote marks. As near as I can tell, the 
 important factor is the length of the string. A short string is likely to 
 have its quote marks escaped. A long string does not have its quote marks 
 escaped. 

 My co-worker is working on the Java app. I am working on the Clojure 
 app. We can both adjust out apps freely, just so long as we can get data to 
 and from each other, in a manner that allows us to eventually cast the data 
 to and from JSON. 

 Any suggestions are welcome. 






 On Wednesday, July 8, 2015 at 8:58:53 PM UTC-4, Francis Avila wrote:

 Who is saving these strings, and who is reading them? Do you have 
 complete control over both apps, or does one of them need to be aligned 
 with the other?

 If the Java app is the baseline, you need to know the exact details of 
 the format of the data it saves. Just knowing it's JSON is not enough, 
 because there may be other data types (e.g. dates) that don't have native 
 JSON representations. (The go-to JSON de/encoder for clojure is cheshire: 
 https://github.com/dakrone/cheshire )

 I took a quick look at Jedis and the easy, default way of using it is 
 with strings. It will encode strings to UTF-8 before sending to Redis and 
 decode from UTF-8 on read. You can set raw byte arrays too (which will not 
 be altered in any way before sending), but it's not clear to me how it can 
 read out raw byte arrays. (I'm sure there's a way, but it's not 
 immediately 
 obvious.)

 As for the escaped quotes, you may be using pr or prn to print, or 
 maybe you are using pr-str to produce the string representation. I can't 
 be 
 sure. 

 On Wednesday, July 8, 2015 at 5:31:27 PM UTC-5, gingers...@gmail.com 
 wrote:

 And I have another stupid question. Using the above code, I am 
 sometimes getting strings in Redis that have escaped quotation marks, 
 like 
 this:

  \transaction-id\ : \ 1ec47c2e-21ee-427c-841c-80a0f89f55d7 \  
 \debrief\ :  \ Susan Hilly at Citi called to get a quotation for 
 discounted weekly car rental for approximately 3 cars per week, or 150 
 rentals annually. \  

 Why is that happening? 



 On Wednesday, July 8, 2015 at 5:38:20 PM UTC-4, gingers...@gmail.com 
 wrote:

 Francis Avila, 

 Thank you for your response. The Java app is using Jedis and the 
 Clojure app is using Carmine. I'm wondering if you can suggest what you 
 think would be the easiest way to allow these 2 apps to understand each 
 other's strings?

 You were correct about how unsafe the above code was. I tested

Re: How can I write a string into Redis such that a Java app might see its contents as a primitive string?

2015-07-08 Thread Francis Avila
You are running into Carmine's automatic nippy 
serialization. https://github.com/ptaoussanis/carmine#serialization

Redis only stores byte arrays (what it calls strings). Carmine uses the 
nippy library (the meaning of NPY in your byte stream) to represent rich 
types compactly as bytes. https://github.com/ptaoussanis/nippy

If you give Carmine a byte array to store, it will store it directly 
without nippy-encoding it. E.g. (.getBytes {} UTF-8)

BTW your document-as-string example is extremely unsafe: how will you 
reliably read this message out again? e.g. what if the 'debrief' string 
contains a single quote? Use a proper serialization format.

So the key is to have both your Clojure and Java app store *bytes* in Redis 
using the same serialization. You can store anything you want (nippy, 
utf-8-encoded json, fressian, bson, utf-8 xml, utf-16 java strings, 
whatever) as long as it's bytes and it's read and written the same way in 
all your apps.

The Redis library your Java app is using may have its own automatic 
de/serialization, too. You need to find out what it's doing and either work 
with this or turn it off, just like with Carmine.

Nippy unfortunately does not have a Java API out of the box: 
 https://github.com/ptaoussanis/nippy/issues/66


On Wednesday, July 8, 2015 at 3:35:49 PM UTC-5, gingers...@gmail.com wrote:


 I am not sure if this is a Clojure question or a Java question. I don't 
 know Java, so I could use whatever help folks can offer. 

 primitive string here means what I can write when I am at the terminal.

 We have 2 apps, one in Clojure, one in Java. They talk to each other via 
 Redis. I know the Java app can read stuff out of Redis, using our 
 transaction-id, if I use the terminal and open up redis-clj and write a 
 string directly from the terminal. But I have this Clojure code, which 
 depends on Peter Taoussanis's Carmine library:
 (defn worker [document]
   {:pre [(string? (:transaction-id document))]}
   (let [transaction-id  (:transaction-id document)
 document-as-string (str {'transaction-id' : ' transaction-id ', 
 'debrief' : ' (:debrief document) '} )
 redis-connection {:pool {} :spec {:host 127.0.0.1 :port 6379 }}]
 (timbre/log :trace  message we will send to NLP   document-as-string)
 (carmine/wcar redis-connection (carmine/set transaction-id document))
 (loop [document-in-redis (carmine/wcar redis-connection (carmine/get 
 transaction-id))]

   (if-not (.contains (first document-in-redis) processed)
 (recur (carmine/wcar redis-connection (carmine/get 
 transaction-id)))
 (do
   (carmine/wcar redis-connection (carmine/del transaction-id))
   document-in-redis)
  
 This line in particular, I have tried doing this several ways: 

 document-as-string (str {'transaction-id' : ' transaction-id ', 
 'debrief' : ' (:debrief document) '} )

 In Redis, I expect to see: 

 {'transaction-id' : '42e574e7-3b80-424a-b9ff-01072f1e0358', 'debrief' : 
 'Smeek Hallie of Withers, Smeg, Harrington and Norvig responded to our 
 proposal and said his company is read to move forward. The rate of $400 per 
 ton of shredded paper was acceptable to them, and they shred about 2 tons 
 of documents every month. $96,000 in potential revenue annually. I will 
 meet with him tomorrow and we will sign the contract.'}

 But if I then launch redis-cli, I see: 


 127.0.0.1:6379 keys *
 1) 42e574e7-3b80-424a-b9ff-01072f1e0358

 127.0.0.1:6379 get 42e574e7-3b80-424a-b9ff-01072f1e0358
 \x00NPY\b\x00\x00\x01\xfc\xf1\xfe\x1b\x00\x00\x00\nj\nip-addressi\x0e165.254.84.238j\x05tokeni$46b87d64-cff3-4b8b-895c-e089ac59544dj\x0bapi-versioni\x02v1j\x0etransaction-idi$42e574e7-3b80-424a-b9ff-01072f1e0358j\adebrief\r\x00\x00\x01YSmeek
  
 Hallie of Withers, Smeg, Harrington and Norvig responded to our proposal 
 and said his company is rea-\x00\xf1\x06move forward. The 
 raty\x00\xf0\x0c$400 per ton of shredded pa\x16\x00\xf1\bwas acceptable to 
 them,q\x00Bthey0\x00\x80 about 2E\x00\x10sF\x00\xf1Ldocuments every month. 
 $96,000 in potential revenue annually. I will meet with him 
 tomorrow{\x00\we#\x00@sign\x92\x00\xa0 contract.


 I don't know what all of those extra characters are. The Java app is not 
 picking this item up, so I assume the Java app is not seeing this as a 
 string. I expected this to look the same as if I had written this at the 
 terminal: 

 {'transaction-id' : '42e574e7-3b80-424a-b9ff-01072f1e0358', 'debrief' : 
 'Smeek Hallie of Withers, Smeg, Harrington and Norvig responded to our 
 proposal and said his company is read to move forward. The rate of $400 per 
 ton of shredded paper was acceptable to them, and they shred about 2 tons 
 of documents every month. $96,000 in potential revenue annually. I will 
 meet with him tomorrow and we will sign the contract.'}

 I assume it is easy to get a string into a format that can be understood 
 by both a Clojure app and a Java app. I don't care what format that is, 

Re: How can I write a string into Redis such that a Java app might see its contents as a primitive string?

2015-07-08 Thread Francis Avila
Who is saving these strings, and who is reading them? Do you have complete 
control over both apps, or does one of them need to be aligned with the 
other?

If the Java app is the baseline, you need to know the exact details of the 
format of the data it saves. Just knowing it's JSON is not enough, 
because there may be other data types (e.g. dates) that don't have native 
JSON representations. (The go-to JSON de/encoder for clojure is 
cheshire: https://github.com/dakrone/cheshire )

I took a quick look at Jedis and the easy, default way of using it is with 
strings. It will encode strings to UTF-8 before sending to Redis and decode 
from UTF-8 on read. You can set raw byte arrays too (which will not be 
altered in any way before sending), but it's not clear to me how it can 
read out raw byte arrays. (I'm sure there's a way, but it's not immediately 
obvious.)

As for the escaped quotes, you may be using pr or prn to print, or maybe 
you are using pr-str to produce the string representation. I can't be sure. 

On Wednesday, July 8, 2015 at 5:31:27 PM UTC-5, gingers...@gmail.com wrote:

 And I have another stupid question. Using the above code, I am sometimes 
 getting strings in Redis that have escaped quotation marks, like this:

  \transaction-id\ : \ 1ec47c2e-21ee-427c-841c-80a0f89f55d7 \  
 \debrief\ :  \ Susan Hilly at Citi called to get a quotation for 
 discounted weekly car rental for approximately 3 cars per week, or 150 
 rentals annually. \  

 Why is that happening? 



 On Wednesday, July 8, 2015 at 5:38:20 PM UTC-4, gingers...@gmail.com 
 wrote:

 Francis Avila, 

 Thank you for your response. The Java app is using Jedis and the Clojure 
 app is using Carmine. I'm wondering if you can suggest what you think would 
 be the easiest way to allow these 2 apps to understand each other's strings?

 You were correct about how unsafe the above code was. I tested it for 
 less than 15 minutes and ran into the fact that a \n newline made a mess of 
 everything. 



 On Wednesday, July 8, 2015 at 5:15:35 PM UTC-4, Francis Avila wrote:

 You are running into Carmine's automatic nippy serialization. 
 https://github.com/ptaoussanis/carmine#serialization

 Redis only stores byte arrays (what it calls strings). Carmine uses 
 the nippy library (the meaning of NPY in your byte stream) to represent 
 rich types compactly as bytes. https://github.com/ptaoussanis/nippy

 If you give Carmine a byte array to store, it will store it directly 
 without nippy-encoding it. E.g. (.getBytes {} UTF-8)

 BTW your document-as-string example is extremely unsafe: how will you 
 reliably read this message out again? e.g. what if the 'debrief' string 
 contains a single quote? Use a proper serialization format.

 So the key is to have both your Clojure and Java app store *bytes* in 
 Redis using the same serialization. You can store anything you want (nippy, 
 utf-8-encoded json, fressian, bson, utf-8 xml, utf-16 java strings, 
 whatever) as long as it's bytes and it's read and written the same way in 
 all your apps.

 The Redis library your Java app is using may have its own automatic 
 de/serialization, too. You need to find out what it's doing and either work 
 with this or turn it off, just like with Carmine.

 Nippy unfortunately does not have a Java API out of the box:  
 https://github.com/ptaoussanis/nippy/issues/66


 On Wednesday, July 8, 2015 at 3:35:49 PM UTC-5, gingers...@gmail.com 
 wrote:


 I am not sure if this is a Clojure question or a Java question. I don't 
 know Java, so I could use whatever help folks can offer. 

 primitive string here means what I can write when I am at the 
 terminal.

 We have 2 apps, one in Clojure, one in Java. They talk to each other 
 via Redis. I know the Java app can read stuff out of Redis, using our 
 transaction-id, if I use the terminal and open up redis-clj and write 
 a 
 string directly from the terminal. But I have this Clojure code, which 
 depends on Peter Taoussanis's Carmine library:
 (defn worker [document]
   {:pre [(string? (:transaction-id document))]}
   (let [transaction-id  (:transaction-id document)
 document-as-string (str {'transaction-id' : ' transaction-id 
 ', 'debrief' : ' (:debrief document) '} )
 redis-connection {:pool {} :spec {:host 127.0.0.1 :port 6379 
 }}]
 (timbre/log :trace  message we will send to NLP   
 document-as-string)
 (carmine/wcar redis-connection (carmine/set transaction-id 
 document))
 (loop [document-in-redis (carmine/wcar redis-connection 
 (carmine/get transaction-id))]

   (if-not (.contains (first document-in-redis) processed)
 (recur (carmine/wcar redis-connection (carmine/get 
 transaction-id)))
 (do
   (carmine/wcar redis-connection (carmine/del transaction-id))
   document-in-redis)
  
 This line in particular, I have tried doing this several ways: 

 document-as-string (str {'transaction-id' : ' transaction-id 
 ', 'debrief' : ' (:debrief

Re: Datomic query question

2015-06-04 Thread Francis Avila
(This question is more appropriate to the datomic 
group: https://groups.google.com/forum/#!forum/datomic)

Datomic/datalog queries always perform aggregation as a last step so the 
results of aggregation are unavailable to the :where clause. In other 
words, what you want is impossible with a single datalog query.

However, this isn't SQL: the datalog query is run in the peer and all the 
data used for aggregation is transmitted to the peer anyway. Just filter 
over the results yourself with normal Clojure code. There's no advantage to 
expressing everything in a single query like there is in SQL.

(let [db [[:t1 :track/name foo]
  [:l1 :lesson/track :t1]
  [:t2 :track/name bar]
  [:l2 :lesson/track :t2]
  [:t3 :track/name baz]
  [:l3 :lesson/track :t3]
  [:l4 :lesson/track :t3]]]
  (- (d/q '[:find ?track (count ?lessons)
  :where
  [?t :track/name ?track]
  [?lessons :lesson/track ?t]]
 db)
(filter (fn [[_ cnt]] ( cnt 1)
;= ([baz 2])


You can also use two queries: one to get the count per track, another to 
get the track names (but a simple filter is less verbose):

(let [db [[:t1 :track/name foo]
  [:l1 :lesson/track :t1]
  [:t2 :track/name bar]
  [:l2 :lesson/track :t2]
  [:t3 :track/name baz]
  [:l3 :lesson/track :t3]
  [:l4 :lesson/track :t3]]]
  (-
(d/q '[:find ?t (count ?lessons)
   :where [?lessons :lesson/track ?t]]
  db)
(d/q '[:find ?track ?num-lessons
   :in $ [[?t ?num-lessons]]
   :where
   [( ?num-lessons 1)]
   [?t :track/name ?track]]
 db)))
;= #{[baz 2]}



As a side note, be aware that if your track names are not unique you may 
get unexpected results from your current query:

(let [db [[:t1 :track/name foo]
  [:l1 :lesson/track :t1]
  [:t2 :track/name bar]
  [:l2 :lesson/track :t2]
  [:t3 :track/name foo]
  [:l3 :lesson/track :t3]
  [:l4 :lesson/track :t3]]]
  (d/q '[:find ?track (count ?lessons)
 :where
 [?t :track/name ?track]
 [?lessons :lesson/track ?t]]
db))
;= [[bar 1] [foo 3]]


This is because the aggregation is done over an unaggregated result *set*  
(i.e. all unique values) and  ?track is the same for multiple ?t. The 
solution is to either include ?t in the :find, or use :with. See the 
Datomic docs more more details: http://docs.datomic.com/query.html#sec-5-17


On Thursday, June 4, 2015 at 6:35:08 AM UTC-5, Wilker wrote:

 Hi, good morning.

 I have this query here:

 [:find ?track (count ?lessons)
  :where
  [?t :track/name ?track]
  [?lessons :lesson/track ?t]
 ]

 A lesson has a track (so a track can be on multiple lessons), and with 
 this query I can return the track names and the number of lessons where 
 this track is being used, all good here.

 But I would like to use this count information to filter, and return only 
 tracks that are present in more than one lesson, I tried:

 [:find ?track (count ?lessons)
  :where
  [?t :track/name ?track]
  [?lessons :lesson/track ?t]
  [( (count ?lessons) 1)]
 ]

 Also tried:

 [:find ?track ?lc
  :where
  [?t :track/name ?track]
  [?lessons :lesson/track ?t]
  [(count ?lessons) ?lc]
  [( ?lc 1)]
 ]

 But I feel like I'm going on the wrong direction... How can I make this 
 query works?

 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: multi-arity functions with macros

2015-06-04 Thread Francis Avila
This is exactly the approach to take: a macro which expands to a defn with 
all your arities filled out.

Here's a simple approach which might be enough for your problem: it will 
splice in argument names whenever some marker symbol is encountered, and 
repeat for the range of arities you want.


(defn splice [marker replacement form]
  (cond
(seq? form) (reduce #(if (= marker %2)
  (into %1 (reverse replacement))
  (conj %1 (splice marker replacement %2)))
  () (reverse form))

(or (vector? form) (set? form))
(reduce #(if (= marker %2)
  (into %1 replacement)
  (conj %1 (splice marker replacement %2)))
  (empty form) form)

(map? form)
(reduce-kv #(assoc %1 (splice marker replacement %2)
  (splice marker replacement %3)) {} form)

(= marker form)
(throw (ex-info Cannot splice into a top-level form! {}))

:else form))

(defmacro defvariadic
;; Full support for defn options (attr-map, docstring, pre/post conditions)
;; an exercise for the reader.
  [name marker max-arity params  body]
  (assert (and (symbol? name) (nil? (namespace name
  (assert (and (symbol? marker)))
  (assert (and (integer? max-arity) (= 0 max-arity 24)))
  (assert (vector? params))
  (let [arg-syms (mapv gensym (subs abcdefghijklmnopqrstuvwxyz 0 
max-arity))
params+bodies
 (map (fn [arity]
(let [var-params (subvec arg-syms 0 arity)]
  (list* (splice marker var-params params)
(splice marker var-params body
   (range max-arity))]
`(defn ~name ~@params+bodies)))


This produces output like the following:

(clojure.pprint/pprint (macroexpand-1
  '(defvariadic default-ontology-dispatch  5
[f ]
(dispatch f 


(clojure.core/defn
 default-ontology-dispatch
 ([f] (dispatch f))
 ([f a23733] (dispatch f a23733))
 ([f a23733 b23734] (dispatch f a23733 b23734))
 ([f a23733 b23734 c23735] (dispatch f a23733 b23734 c23735))
 ([f a23733 b23734 c23735 d23736]
  (dispatch f a23733 b23734 c23735 d23736)))






On Thursday, June 4, 2015 at 11:55:23 AM UTC-5, Phillip Lord wrote:


 I have a number of fairly nasty functions with a form that looks like 
 this: 

 (defn default-ontology 
   ([f] 
  (dispatch f)) 
   ([f a] 
  (dispatch f a)) 
   ([f a b] 
  (dispatch f a b)) 
   ([f a b c] 
  (dispatch f a b c)) 
   ([f a b c d] 
  (dispatch f a b c d)) 
   ([f a b c d e] 
  (dispatch f a b c d e)) 
   ([f a b c d e fa] 
  (dispatch f a b c d e fa)) 
   ([f a b c d e fa g] 
  (dispatch f a b c d e fa g)) 
   ([f a b c d e fa g h] 
  (dispatch f a b c d e fa g h)) 
   ([f a b c d e fa g h i] 
  (dispatch f a b c d e fa g h i)) 
   ([f a b c d e fa g h i j] 
  (dispatch f a b c d e fa g h i j))) 

 The reason for all of this is that I need to avoid the use of variadic 
 function calls for performance reasons -- this function gets called a 
 lot in my code base, and without this unwinding, I box and unbox 
 consistantly. 

 Now, I dislike the code repetition here, and indeed have found already 
 found one bug in my code where I missed a variable out, something like 

 ([f a b c d] 
  (dispatch f a b d)) 

 which is hard to pick up on. 

 I can't make the whole thing a macro because I need to pass this as a 
 first class function. And I can't macro each of the variadic elements 
 since the I'd need to return two elements at once. 

 The best I have done up with so far is: 

 (defn ^:private form-with-arity[n] 
   ;; left as an exercise for the reader 
 ) 

 (defmacro ^:private m-default-ontology 
   `(defn default-ontology 
   ~@(map form-with-arity (range 1 10 

 (m-default-ontology) 

 Or am I missing something more obvious? 

 Phil 



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: Lein :provided profile and uberjar not working

2015-06-03 Thread Francis Avila
Possibly you are also including the dependencies in the non-profile part of 
the project.clj? You shouldn't: the :provided profile is normally included, 
but excluded when running the uberjar task.

More concrete example:

(defproject myproj 0.1.0
  :dependencies [[org.clojure/clojure 1.6.0]] ;; notice standford-corenlp 
is *not* mentioned!!
  :uberjar {:aot :all}  
  :profiles {:provided {:dependencies
[[edu.stanford.nlp/stanford-corenlp 3.4.1]
 [edu.stanford.nlp/stanford-corenlp 3.4.1
  :classifier models]]}})



On Wednesday, June 3, 2015 at 2:35:30 PM UTC-5, Scott Klarenbach wrote:

 I'm unable to post a new topic to the leinigen group so I thought I'd try 
 my luck here.

 I'd like to exclude certain dependencies from my uberjar, by using the 
 :provided profile, but the jars are always included.

 I've added the following to my project.clj, but the edu.stanford.nlp jars 
 end up in the uberjar no matter what.  I've also tried with a simple 
 project just to exclude a few jars and that doesn't seem to work either. 
  Am I missing something simple?  Or is there a better way to exclude large 
 dependencies from uberjar if the deployment environment will already have 
 them on the classpath?  Thanks.

 :profiles {:uberjar {:aot :all}
  :provided {:dependencies
 [[edu.stanford.nlp/stanford-corenlp 3.4.1]
  [edu.stanford.nlp/stanford-corenlp 3.4.1
   :classifier models]]}
  :dev {:resource-paths [test-data]}}



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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 can I remove this nil? check from my code?

2015-05-26 Thread Francis Avila
Your two functions can be written more succinctly (and with fewer explicit 
conditionals) like these, but they will be harder for a beginner to 
understand. (The nested update-in with fnil in particular may cause 
confusion.)


(defn add-placeholder-to-history [users]
  (reduce-kv (fn [users uk {:keys [history]}]
   (assoc-in users [uk :history]
 (into [{}] (take 2 history
users users))


(defn update-history [users {:keys [category prize-money winner]}]
  (update-in users [winner]
(fnil update-in {:history [{}]}) [:history 0 category]
(fnil + 0) prize-money))


You may have a good pedagogical reason for your current implementation, but 
I would take a different approach: build the new history entries first, 
then add them to the users.


(defn winnings-by-user [contests]
  (reduce
(fn [user+winning {:keys [category winner prize-money]}]
  (update-in user+winning [winner category] (fnil + 0) prize-money))
{} contests))

(defn update-histories [users new-winnings]
  (let [all-user-keys (set (concat (keys users) (keys new-winnings)))]
(reduce (fn [users ukey]
  (update-in users [ukey :history]
#(into [(get new-winnings ukey {})] (take 2 %
  users all-user-keys)))


(update-histories users (winnings-by-user contests))







On Tuesday, May 26, 2015 at 12:37:34 AM UTC-5, Chris Freeman wrote:

 It seems like, if you don't mind doing the assoc all the time, you could 
 replace the whole if with something like:

 (assoc nu (:winner c) (or ((:winner c) nu) {:history [{}]}))

 You might want to wrap that in a let so you don't repeat (:winner c). 

 Also, it looks like add-placeholder-to-history could be a map over an 
 update-in instead of a loop, like:

 (defn prepend-hash [x]
   (into [{}] x))

 (defn add-placeholder-to-history [us]
   (into {} (map #(update-in % [1 :history] prepend-hash) us)))

 Chris



 On Mon, May 25, 2015 at 5:07 PM, lawr...@waleup.com javascript: wrote:


 I started to write an essay, aimed at those programmers who are 
 experienced with highly mutable languages such as Javascript, Ruby, PHP, 
 etc, to demonstrate how one's code style changes when one switches to a 
 mostly immutable language such as Clojure. However, my Clojure code is not 
 nearly as terse as I wanted. In particular, I have this nil check: 

   (if (nil? ((:winner c) nu))
   (assoc nu (:winner c) {:history [{}]})
 nu) 

 which I assume I am writing because I am ignorant. I'm guessing there 
 might be something clever I can do to avoid this? 

 For my code examples, I'm working with these 2 data structures: 

 (def users  {
  :henry {
:history 
[
  {:housing  25, :restaurants 40, :theater 930},
  {:restaurants  30, :crisis  220}
]
   },
   :lisa  {
:history 
[
  {:theater  80},
  {:housing  445, :restaurants  15, :theater  35}
]
   },
   :pasha  {
:history 
[
  {:restaurants  5},
  {:restaurants  40, :theater  60}
]
   },
   :eli  {
:history 
[
  {:crisis  135, :restaurants  440, :theater  65},
  {:theater  95}
]
   }
 })

 (def contests [{:category :housing, :prize-money 100, :winner :eli},
{:category :housing, :prize-money 30, :winner :henry},
{:category :housing, :prize-money 340, :winner :henry},
{:category :housing, :prize-money 45, :winner :susan},
{:category :housing, :prize-money 15, :winner :henry},
{:category :housing, :prize-money 10, :winner :pasha},
{:category :housing, :prize-money 25, :winner :pasha},
{:category :crisis, :prize-money 100, :winner :eli},
{:category :crisis, :prize-money 2330, :winner :henry},
{:category :crisis, :prize-money 90, :winner :henry},
{:category :restaurants, :prize-money 1130, :winner :eli},
{:category :restaurants, :prize-money 130, :winner :pasha},
{:category :theater, :prize-money 60, :winner :eli},
{:category :theater, :prize-money 90, :winner :pasha},
{:category :theater, :prize-money 130, :winner :pasha},
{:category :theater, :prize-money 830, :winner :susan},
{:category :theater, :prize-money 90, :winner :susan},
{:category :theater, :prize-money 270, :winner :eli}])

 Presumably users shows past winnings from 2 rounds of some contest, 
 whereas contests shows the winnings from the 3rd round, which need to be 
 added to users. So I wrote: 


 (defn 

Re: Core async pipeline should return to channel.

2015-04-17 Thread Francis Avila
Core.async issues are reported on Clojure's 
JIRA: http://dev.clojure.org/jira/browse/ASYNC

pipeline does not have an incidental return value: it returns a channel 
which closes when there are no more transformation results, i.e. when the 
pipelining process is finished. There is no other way to get this 
information, especially when close? is false.

You're right this hurts threading, but sometimes you do need to monitor 
when pipelining is done. In fact, the pipe function does return the to 
channel like you suggest, and I had to write my own version that returned 
its inner go-loop because I needed to monitor the piping 
process. 
https://gist.github.com/favila/8e7ad6ea5b01bd7466ff#file-async-util-clj-L27


On Friday, April 17, 2015 at 2:33:58 PM UTC-5, Claudius Nicolae wrote:

 Since issue tracker for core.async is disabled on github, I'll spill this 
 here.
 I think pipeline should return the to channel, to make it 
 threading-friendly:

 (- (range 100)
(a/to-chan)
(a/pipeline 10 (a/chan) (map inc))
(a/pipeline 2 (a/chan) (filter odd?)))

 Currently return value is incidental.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: Use reduce or something appropriate instead of loop / recur

2015-03-24 Thread Francis Avila
Separate out traversal from selection to make this clearer.

We make a generic traversal function get-in-via. It accepts a via function 
which takes the current result and some value which determines the next 
result, and returns the next result.

(defn get-in-via [m via ks]
  (reduce (fn [m' k] (via m' k)) m ks))


Here is a via function that follows folder paths. This is a single step 
of the reduction.

(defn via-folderpath [items foldername]

  (- items
   (filter #(and (= (:type %) :folder)
 (= (:name %) foldername)))
   (first)
   :children))



Example of use:

(get-in-via ffs via-folderpath [sub2 sub21])

;= [{:name lein-env, :type :file}]




On Tuesday, March 24, 2015 at 4:22:21 PM UTC-5, Sven Richter wrote:

 Hi,

 I wrote a function to trackdown a path in a vector containing nested maps:

 (defn get-files-from-folder-path [ffs folder-path]
   (filter #(= :file (:type %))
   (loop [tree-path-position 0 acc [] fof ffs]
 (let [folder (first (filter #(and
   (= :folder (:type %))
   (= (nth folder-path 
 tree-path-position nil) (:name %))) fof))]
   (if (not (:children folder))
 acc
 (recur (inc tree-path-position)
(if (= (+ tree-path-position 1) (count folder-path)) 
 (concat acc (:children folder)) acc)
(:children folder)))

 And these are the inputs:
 (def ffs [{:type :folder, :name sub1, :children [{:type :file, :name 
 datomic-data.edn}]} 
   {:type :folder, :name sub2, :children [{:type :file, :name foo 
 (1).csv} 
{:type :folder, :name 
 sub21, :children [{:type :file, :name lein-env}]}]}])

 (def tree-path [sub2 sub21])

 And I call it like this:

 (get-files-from-folder-path ffs tree-path)

 Is there a way to use reduce for that? I was stuck because I think I have to 
 reduce on two lists here, 
 but reduce only takes one to start with, thats why I chose the loop / recur 
 route. Which works
 but it looks ugly to me and I am afraid in one week I want understand it 
 anymore.

 Thanks Regards,
 Sven





-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: Use reduce or something appropriate instead of loop / recur

2015-03-24 Thread Francis Avila
Notice that get-in-via is simply reduce:

(defn get-in-via [m via ks]
  (reduce (fn [m' k] (via m' k)) m ks))


Same as:

(defn get-in-via [m via ks]
  (reduce via m ks))



Same as:

(reduce via m ks)



So once you write your step function, traversal is taken care of by the 
reduction.

On Tuesday, March 24, 2015 at 4:55:23 PM UTC-5, Francis Avila wrote:

 Separate out traversal from selection to make this clearer.

 We make a generic traversal function get-in-via. It accepts a via function 
 which takes the current result and some value which determines the next 
 result, and returns the next result.

 (defn get-in-via [m via ks]
   (reduce (fn [m' k] (via m' k)) m ks))


 Here is a via function that follows folder paths. This is a single step 
 of the reduction.

 (defn via-folderpath [items foldername]

   (- items
(filter #(and (= (:type %) :folder)
  (= (:name %) foldername)))
(first)
:children))



 Example of use:

 (get-in-via ffs via-folderpath [sub2 sub21])

 ;= [{:name lein-env, :type :file}]




 On Tuesday, March 24, 2015 at 4:22:21 PM UTC-5, Sven Richter wrote:

 Hi,

 I wrote a function to trackdown a path in a vector containing nested maps:

 (defn get-files-from-folder-path [ffs folder-path]
   (filter #(= :file (:type %))
   (loop [tree-path-position 0 acc [] fof ffs]
 (let [folder (first (filter #(and
   (= :folder (:type %))
   (= (nth folder-path 
 tree-path-position nil) (:name %))) fof))]
   (if (not (:children folder))
 acc
 (recur (inc tree-path-position)
(if (= (+ tree-path-position 1) (count folder-path)) 
 (concat acc (:children folder)) acc)
(:children folder)))

 And these are the inputs:
 (def ffs [{:type :folder, :name sub1, :children [{:type :file, :name 
 datomic-data.edn}]} 
   {:type :folder, :name sub2, :children [{:type :file, :name foo 
 (1).csv} 
{:type :folder, :name 
 sub21, :children [{:type :file, :name lein-env}]}]}])

 (def tree-path [sub2 sub21])

 And I call it like this:

 (get-files-from-folder-path ffs tree-path)

 Is there a way to use reduce for that? I was stuck because I think I have to 
 reduce on two lists here, 
 but reduce only takes one to start with, thats why I chose the loop / recur 
 route. Which works
 but it looks ugly to me and I am afraid in one week I want understand it 
 anymore.

 Thanks Regards,
 Sven





-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: map-in

2015-03-24 Thread Francis Avila
The reduce in your mapped function is already implemented by get-in. Other 
possible implementations using get-in:

(defn map-in [coll ks f  args]
  (- coll
   (map #(get-in % ks))
   (map #(apply f % args

Or:

(defn map-in [coll ks f  args]
  (map #(apply f (get-in % ks) args) coll))


On Tuesday, March 24, 2015 at 9:16:58 PM UTC-5, Steve Ashton wrote:

 Is there anything for map which operates like update-in and assoc-in, 
 where we can call a function with the value looked up in a nested structure?

 What I've come up with:
 (defn map-in
   Returns a lazy sequence consisting of the results of
   calling map on coll, for each value in the coll,
   extracting the value using keys ks, finally applying f the
   that value and args: (apply f item args)
   [coll [ ks] f  args]
   (map (fn [item]
  (let [value (reduce #(%2 %1) item ks)]
(apply f value args)))
coll))

 Which could then be used like:
 (def customers [{:name Alice :address {:city Raleigh :state NC}}
 {:name Bob :address   {:city Seattle :state WA}}])

 (map-in customers [:address :state] #(- % clojure.string/lower-case 
 keyword))
 = (:nc :wa)

 Just wondering if I am re-inventing something here.

 Thanks,
 Steve


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


Re: Sum up second elemsts of pairs in a sequence by grouping by the first item in pair

2015-03-20 Thread Francis Avila
Yet another way:

(vec (reduce
   (fn [m [k v]]
 (assoc m k (+ (m k 0) v)))
   {}
   [[1 0.5] [1 0.7] [2 1.0] [3 0.1] [3 0.1]]))
= [[3 0.2] [2 1.0] [1 1.2]]


On Friday, March 20, 2015 at 8:45:10 AM UTC-5, Emrehan Tüzün wrote:

 Yet another way to solve it:











 *user= x[[1 0.5] [1 0.7] [2 1.0] [3 0.1] [3 0.1]]user= (group-by first 
 x){1 [[1 0.5] [1 0.7]], 2 [[2 1.0]], 3 [[3 0.1] [3 0.1]]}user= (map 
 #(vector (first %) (second %)) (group-by first x))([1 [[1 0.5] [1 0.7]]] [2 
 [[2 1.0]]] [3 [[3 0.1] [3 0.1]]])user= (map #(vector (first %) (reduce + 
 (map second (second % (group-by first x))([1 1.2] [2 1.0] [3 0.2])*

 All the best,
 Emrehan

 On Thursday, 19 March 2015 23:57:18 UTC+2, Alex wrote:

 Hello everybody,

 How to transform sequence 

 *[[1 0.5] [1 0.7] [2 1.0] [3 0.1] [3 0.1]]*

 to

 *[[1 1.2] [2 1.0] [3 0.2]]*

 ?

 Best regards,
 Alex
  



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: [GSoC] Source meta information model proposal

2015-03-16 Thread Francis Avila
Wishlist: for macros, metadata about the vars a macro will define. (E.g., 
(defmacro defrecord [...]) will define (-NAME arg...), (map-NAME m) when 
executed.)

This would allow a lot more source analysis for the common case of def* 
macros which are just fancy ways of def-ing vars, but without having to 
eval the macro. Maybe even without having to eval anything, if the 
mechanism is entirely declarative!

This is an issue Colin Fleming (creator of Cursive) has talked about 
before, and I remember him saying something about creating such a mechanism 
for library authors to use for better Cursive integration. It'd be nice if 
such a mechanism could be standardized so the entire ecosystem could 
benefit. You should talk to him about this because he's given a fair amount 
of thought to this problem.

On Monday, March 16, 2015 at 1:53:53 PM UTC-5, Christopher Medrela wrote:

 Hello! My name is Christopher Medrela and I'd like to work at source 
 metadata
 information model project mentored by Alex Miller at Google Summer of 
 Code. I
 hope that this mailing list is the right place to discuss such projects 
 (if I'm
 wrong, correct me).

 I'd like to introduce some standard of source meta information model to
 represent the code from the API perspective. There exist a lot of tools 
 like
 codox, autodoc, Grimoire, ClojureDocs, crosscls.info and so on. Each of 
 these
 tools has some repetitive code responsible for extracting this kind of
 information.

 I'd like to discuss what the model should be and from which tasks you will
 benefit most? You can find the model and tasks proposal in model schema 
 and
 tasks (deliverables) sections in my [proposal] draft. I'd like to 
 emphasis
 that the tasks list is very highly inspired by Alex Miller.

 [proposal] 
 https://gist.github.com/chrismedrela/6c9517c14ce1ca00062b#model-schema


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: defmulti: dispatch function is not called

2015-02-23 Thread Francis Avila
You can work around this by using a symbol for the dispatch function 
instead of inlining the function:

(defn create-fact-dispatch [item-vector]
  (do
(print item-vector)
(first item-vector)))


(defmulti create-fact create-fact-dispatch)



When you reload in the REPL the defmulti will not be redefed, but the 
dispatch function will. This is usually all you need when you are messing 
around in the REPL.

There may be some performance cost, but I don't know if it is significant. 
There is at least the var lookup cost. Maybe defmulti dispatch result can't 
be cached? (not sure)

On Sunday, February 22, 2015 at 12:19:24 PM UTC-6, Timur wrote:

 Thank you all for your answers. The problem was caused by not starting the 
 REPL. I did not know that defmulti had defonce semantics. 

 On Sunday, February 22, 2015 at 7:04:58 PM UTC+1, Jeremy Heiler wrote:

 On 2/22/15 12:52 PM, Timur wrote: 
  Hi everyone, 
  
  I have the following question regarding the defmultis of clojure: 
  
  (defmulti create-fact 
 (fn [item-vector] (do 
 (print item-vector) 
 (first item-vector 
  
  (defmethod create-fact [:a] [item-vector] 
 (str a)) 
  
  (defmethod create-fact [[:a safs]] [item-vector] 
 (str safs)) 
  
  
  (mapv create-fact {:a safs}) 
  
  
  Dispatch function is not called in this case and return is safs so 
 the 
  matching key is [[:a safs]]. I except it to be :a, why is that [[:a 
  safs]]? 

 First, observe: 

   (seq {:a 1 :b 2}) 
 ([:a 1] [:b 2]) 

 A map is converted into a sequence with each element being a key/value 
 pair. The mapv function does this under the hood so that it can operate 
 on the map as a sequence. 

 Now, when I run your code, I get an IllegalArgumentException stating 
 that :a is not a dispatch value. This is correct, because the two 
 dispatch values defined are [:a] and [[:a safs]]. If you change the 
 [:a] method to be :a, then the return value will be a. The dispatch 
 values in each defmethod must be literal, and not wrapped in a vector 
 like when defining the arguments to a fn. 

 Does that clear things up? 



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: Performant flattening of nested data structures

2015-02-17 Thread Francis Avila
This is probably easier if you do it in two passes: one to assemble the 
get-in path down to a value, and another to stringify that path. 

(def input {:name {:first Rich :last Hickey} :number [1 415 123 4567]})
;= #'user/input
(def expected {$.number[0] 1, $.number[1] 415, $.number[2] 123, 
$.number[3] 4567, $.name.first Rich, $.name.last Hickey})
;= #'user/expected
(defn keypaths
  ([xs] (keypaths [] xs))
  ([path-prefix xs]
(reduce-kv
  (fn [kp+v k v]
(let [path (conj path-prefix k)]
  (if (associative? v) ;; You may need to change this.
(into kp+v (keypaths path v))
(conj kp+v [path v]
  []
  xs)))
;= #'user/keypaths
(defn keypath-str [path]
  (let [str-part
(fn [x] (cond
  (or (string? x) (char? x)) (str \. x)
  (instance? clojure.lang.Named x) (str \. (name x))
  :else (str \[ x \])))
str-path ^String (apply str (map str-part path))]
(if (.startsWith str-path .)
  (subs str-path 1)
  str-path)))
;= #'user/keypath-str
(keypaths input)
;= [[[:number 0] 1] [[:number 1] 415] [[:number 2] 123] [[:number 3] 4567] 
[[:name :first] Rich] [[:name :last] Hickey]]
(keypaths [$] input)
;= [[[$ :number 0] 1] [[$ :number 1] 415] [[$ :number 2] 123] [[$ :
number 3] 4567] [[$ :name :first] Rich] [[$ :name :last] Hickey]]
(- (keypaths [$] input)
 (map (fn [[path v]] [(keypath-str path) v]))
 (into {}))
;= {$.number[0] 1, $.number[1] 415, $.number[2] 123, $.number[3] 
4567, $.name.first Rich, $.name.last Hickey}
(= *1 expected)
;= true

So that increases readability. What about performance?

I'm not entirely sure what you are trying to optimize. You mention a 
whitelist of keys. Is there something related to that you want to optimize? 
Maybe you don't need to stringify keys at all? Perhaps you need to 
represent your whitelist as a set of vectors (each of which is a keypath), 
then filter the un-stringified keypaths from maps by that whitelist:

(def whitelist #{[:number 0] [:number 1] [:number 2] [:name :first] [:name 
:last]})
;= #'user/whitelist
(- (keypaths input)
 (filter (comp whitelist first)))
;= ([[:number 0] 1] [[:number 1] 415] [[:number 2] 123] [[:name :first] 
Rich] [[:name :last] Hickey])


If the problem is that you have extremely large maps to flatten, you can 
try folding reducers. There are two opportunities for parallelism: 
constructing the paths, and stringifying the paths. Stringifying the paths 
is more obvious:

(require '[clojure.core.reducers :as r])
;= nil
(defn r-flatten-assoc [m]
  (- (keypaths [\$] m)
   (r/map (fn [[path v]] [(keypath-str path) v]
;= #'breeze.mast.repl/r-flatten-assoc
(- (r-flatten-assoc input) (r/foldcat) (into {}) (= expected)
;= true


But paralleling construction of paths is a bit harder. The following 
example only folds over maps; to fold over the vectors with index without 
lazy seqs or realizing maps requires a custom reducer. (I also use 
transients for good measure.)

(defn r-keypaths
  ([xs] (r-keypaths [] xs))
  ([path-prefix xs]
(if (map? xs)
  (- xs
   (r/mapcat (fn [k v]
   (let [path (conj path-prefix k)]
 (if (associative? v)
   (r-keypaths path v)
   [[path v]]
   (r/foldcat))
  (- (reduce-kv
 (fn [kp+v k v]
   (let [path (conj path-prefix k)]
 (if (associative? v)
   (reduce conj! kp+v (r-keypaths path v))
   (conj! kp+v [path v]
 (transient [])
 xs)
   (persistent!)







On Tuesday, February 17, 2015 at 10:18:58 AM UTC-6, Mark Watson wrote:

 A slightly cleaner version:

 (defn- flatten-keys* [a ks m]

   (cond

;; Is a map?

(map? m) (reduce into

 (map (fn [[k v]]

(flatten-keys* a (str ks . (name k)) v))

  (seq m)))

;; Is an arr/vec/seq?

(and (sequential? m)

 (not (instance? clojure.lang.MapEntry m))) (reduce into

(map-indexed (fn 
 [idx itm]

   
 (flatten-keys* a

   
(str ks [ idx ])

   
itm))

 (seq 
 m)))

;; Is not a collection

:else (assoc a ks m)))

 (defn flatten-keys [m] (flatten-keys* {} $ m))



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

Re: [ANN] clj-uuid: thread-safe, performant unique identifiers

2015-02-16 Thread Francis Avila
This is nice to have, thank you! uuid v5 generation seems to be something I 
reimplement over and over, but which is never big enough for a library. I 
would like to stop doing that and just include your library in the future.

However, I think your v3/v5 implementations need much more control over 
canonicalization to guarantee consistent uuid generation on different 
machines. Right now you just turn a string into bytes with 
String.getBytes() and feed that to a hash algorithm. The bytes generated 
are going to depend on the platform charset, and there's no way to just 
feed plain bytes in to get around this issue because these functions demand 
a string.

I think you should add a UuidNameBytes protocol and implement a sensible 
default encoding for strings (say UTF-8), and some implementations for at 
least byte arrays and uuids. Then your v3/v5 functions can accept anything 
byte-able as a name argument. I've done something like this before and 
would be happy to submit a pull request if you are interested.

Finally, this is just a style point, but you use :use a fair amount in your 
namespaces. :use is an anti-pattern in Clojure and avoided because it 
obscures where the functions come from. (I had a lot of trouble reading 
your digest namespace because of it!)

On Monday, February 16, 2015 at 7:25:17 PM UTC-6, danl...@gmail.com wrote:

 Hello Clojurians,

 I've just been polishing my modest library, clj-uuid 
 http://danlentz.github.io/clj-uuid/ and would like to invite everyone to 
 have a look if such a thing might be of interest. 

 What is it?

 clj-uuid is a Clojure library for generation and utilization of UUIDs 
 (Universally Unique Identifiers) as described by RFC-4122. This library 
 extends the standard Java UUID class to provide true v1 (time based) and 
 v3/v5 (namespace based) identifier generation. Additionally, a number of 
 useful supporting utilities are provided to support serialization and 
 manipulation of these UUIDs in a simple, efficient manner.

 Why is it useful?

 The JVM UUID class only provides a constructor for random (v4) and 
 (non-namespaced) pseudo-v3 UUID's. Where appropriate, this library does use 
 the internal JVM UUID implementation. The benefit with this library is that 
 clj-uuid provides an easy way to get v1 and true namespaced v3 and v5 
 UUIDs.  v1 UUIDs are really useful because they can be generated faster 
 than v4's as they don't need to call a cryptographic random number 
 generator.  v5 UUID's are necessary because many of the interesting 
 things that you can do with UUID's require namespaced identifiers.
 http://danlentz.github.io/clj-uuid/
 http://github.com/danlentz/clj-uuid/


 Best,
 Dan Lentz


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: calling functions that accepts keyword arguments with a map

2015-02-13 Thread Francis Avila
Not fundamentally different from your approach:

(apply set-style (apply concat {:color red :cursor pointer}))

On Friday, February 13, 2015 at 11:30:44 AM UTC-6, Wilker wrote:

 Hi guys,

 I'm trying to find the best way to call a function that accepts keyword 
 arguments (in my case it's the set-style! on Enfocus library) with a map.

 So, an example of the regular call:

 (set-style :color red :cursor pointer)

 I would like to call with a map (because that way I can manage the map 
 data before using it) but I found no very easy way to do it... The best way 
 I could found is like this:

 (apply set-style (flatten (seq {:color red :cursor pointer})))

 But that's a bit overwhelming, I wonder if there is a simpler way to 
 handle this situation.

 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: Question about ClojureScript Testing

2015-02-12 Thread Francis Avila
There is also a jar of v8 
(https://github.com/circleci/clj-v8 https://clojars.org/clj-v8) which can 
run js scripts in a v8 subprocess. With some plumbing code in Clojure you 
could run your tests in v8 as a jar, but again you won't be able to test 
anything that requires a browser stack.

If you need a browser stack phantomjs is probably the best choice (fastest, 
most mature, largest community, etc). However there are some other options: 
https://gist.github.com/evandrix/3694955 Some are java-based (e.g. 
HtmlUnit) and are likely to have maven packages. However you are going off 
the beaten path and depending on what you are testing you may not be 
adequately testing in real-world browser conditions.

On Wednesday, February 11, 2015 at 7:22:54 PM UTC-6, David Nolen wrote:

 You can run tests in any REPL that ships with ClojureScript - we include 
 two JVM based ones Rhino and Nashorn. Rhino is older and more mature. 
 Nashorn probably needs some further work to be good for testing. Patches 
 welcome. Both of these options suffer from different forms of slowness 
 (Rhino is just slow, Nashorn is slow to start) so I'm not sure I'd 
 recommend them wholeheartedly. But they are there and and I'm happy to see 
 them improved by the community for your purposes in whatever way they can 
 reasonably be.

 David

 On Wed, Feb 11, 2015 at 8:16 PM, Elric Erkose elric@gmail.com 
 javascript: wrote:

 Thanks, I've seen figwheel. It doesn't address what I'm asking. 

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




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: var args with recur

2015-01-20 Thread Francis Avila
The difference is how rest args are handled. From the recur documentation:

In particular, if the recursion point was the top of a variadic fn method, 
 there is no gathering of rest args - a single seq (or null) should be 
 passed.


So your two calls are not the same. f1 calls (recur x some-seq) which is 
the same as (apply f1 x some-seq). f2 calls f1 without apply, so f1's args 
are at that moment x and a seq of one item containing the seq used to call.

To get the results you expect, change f2 to

(defn f2 [x  ys]  (if x(apply f2 (not x) ys)ys))


On Tuesday, January 20, 2015 at 4:17:58 AM UTC-6, Hello Funk wrote:

 This stumped a few of us on #clojure, with a debate as to whether this is 
 a compiler error or has a legitimate explanation.

 My initial examination:

 https://www.refheap.com/96295

 A more minimal example:

 https://www.refheap.com/96296

 What's going on?

 Andrew


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: CLJS-in-CLJS; building ClojureScript from source; and stuff

2015-01-19 Thread Francis Avila
You will probably have more luck getting help in the Clojurescript group.

The clojurescript-in-clojurescript project you found is defunct. In the 
meantime normal Clojurescript has gotten much closer to being self-hosted 
and work towards that end is probably best done on Clojurescript itself 
instead of a work. This page outlines the work 
remaining: 
https://github.com/clojure/clojurescript/wiki/Bootstrapping-the-Compiler 
It's still not an insignificant amount of work.

However, are you really sure you can't keep a jvm around for compiling 
clojurescript? Sure it'd be nice if it were self-hosted, but I think people 
exaggerate how necessary it is.

If it really is an absolute requirement, consider WISP 
https://github.com/Gozala/wisp which is clojure-ish and hosted on js, but 
does *not* have clojure's fancy immutable data structures. (Those data 
structures are at least 80% of the reason to use Clojure IMO.) You can use 
other JS libraries to get them back, but they won't be native to WISP. E.g. 
immutable-js from facebook, or mori (which is really clojurescript compiled 
as a js library, hah!)

scripts/compile is a red herring. You need script/bootstrap. Read here to 
get started: https://github.com/clojure/clojurescript/wiki/Quick-Start

The clojurescript wiki in general is a good place to get 
oriented. https://github.com/clojure/clojurescript/wiki


On Saturday, January 17, 2015 at 7:13:04 PM UTC-6, Adam Avramov wrote:

 I'm working on a multimedia framework targeting Node.js (and, at some 
 point in the future, sooner rather than later, browsers). Since I need the 
 homoiconicity of a Lisp for my intended feature set, ClojureScript is 
 pretty much my only option -- and it's a very enjoyable language anyway. 
 I'm using this version of ClojureScript 
 https://github.com/kanaka/clojurescript, which seems to be the most 
 recent one; yet, apparently, it is still massively outdated. For example, 
 namespaces and module imports don't seem to work (as far as I can tell 
 anyway), leaving me to resort to reading each file with (eval-print) or 
 similar. I'd like to devote some effort towards bringing 
 ClojureScript-in-ClojureScript up to date, however I'm a bit confused. 
 Honestly I'm at a complete loss about where to start. I can't even seem to 
 build the code from the master branch of the clojure/clojurescript repo 
 https://github.com/clojure/clojurescript (scripts/compile fails by a 
 NullPointerException in compiler.clj). Can I please have a few pointers on 
 doing things right?


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


Re: core async and transducers in Clojure 1.6.0

2014-12-29 Thread Francis Avila
It will be inconvenient to use transducer functions without the transducer 
support added in 1.7.0, but there's nothing magical about transducers that 
requires Clojure 1.7.

Core.async 0.1.346.0-17112a-alpha does not depend on clojure 1.7 (it only 
depends on Clojure 1.6) and you don't need anything special to create a 
transducing function. We use the transducer features of core.async with 
Clojure 1.6 in production.

All you need to do is provide the core async channel with a function that 
has the transducer structure: a function accepting a transforming-function 
(supplied by core.async) and returning a function with three arities for 
initialization, finalization, and the reduction step.

(fn [xf]
  (fn
([] (xf))
([r] (xf r))
([r v] (xf r v)))

We use an as-transducer function as a convenience to make these:

https://gist.github.com/favila/ecdd031e22426b93a78f

On Monday, December 29, 2014 10:38:05 AM UTC-6, Udayakumar Rayala wrote:

 Hi,

 We are currently using clojure 1.6.0 and using async channels version 
 0.1.346.0-17112a-alpha. 
 I see that the (chan) function accepts a transducers but transducers are 
 not available in Clojure 1.6.0. 

 Is there any option other than upgrading to Clojure 1.7.0-alpha4? If not, 
 how safe it is right now to use Clojure 1.7.0-alpha4 in production? We 
 really want to use transducers as it makes our code readable.

 Thanks,
 Uday.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: parsing and chunking large xyz files

2014-12-26 Thread Francis Avila
If you need parallelism, you need to do an indexing pass first to determine 
the group boundaries. Then you can process them in parallel because you 
know the units-of-work.

Iota is an ok fit for this, so I suggest trying it first. (You may have to 
dial down the parallelism of r/fold to avoid stressing your OS's mmap.)

Unfortunately this file format makes it impossible to determine chunk 
boundaries in parallel: there's no (easy) way to distinguish atom count and 
comment lines without knowing the state of previous lines, so you cannot 
index in parallel. However you can cache the index or even write it to disk 
for iota to read later.

I wrote a small gist to demonstrate the basic 
procedure: https://gist.github.com/favila/035718ab762c6adfc8dc


On Friday, December 26, 2014 10:00:57 AM UTC-6, cej38 wrote:

 Line-by-line is the problem.  I need groups of lines at a time.




 On Friday, December 26, 2014 10:33:27 AM UTC-5, Jony Hudson wrote:

 I think clojure.csv reads CSV files lazily, line-by-line, so might be 
 useful to take a look at:

 https://github.com/clojure/data.csv


 Jony

 On Friday, 26 December 2014 14:49:59 UTC, cej38 wrote:

 In molecular dynamics a popular format for writing out the positions of 
 the atoms in a system is the xyz file format (see: 
 http://en.wikipedia.org/wiki/XYZ_file_format and/or 
 http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/xyzplugin.html). 
  The format allows for storing the positions of the atoms at different 
 snapshots in time (aka time step).  You may have a few to millions of 
 atoms in your system and you may have thousands of time steps represented 
 in the file.  It is easy to end up with a single file that is many GB in 
 size.  Here is a shell command that will create a very simple, and very 
 small, test file (note that the positions of the atoms are completely 
 unrealistic-they are all sitting on top of each other)

 perl -e 'open(F, test1.xyz); for( $t= 1; $t  11; $t = $t +1){print 
 F 10\n\n; for( $a = 1; $a  11; $a = $a + 1 ){print F C  0.000 0.000 
 0.\n;}}; close(F);'


 Here is a shell command that will produce a more complicated file 
 structure (note that depending on who wrote the code that output the file 
 there may be other columns of data at the end of each row, also the number 
 of decimal places kept and the type of spacing between elements may 
 change), this file has a different number of atoms with each time step :

 perl -e 'open(F, test2.xyz); for( $t= 1; $t  5; $t = $t +1){my $s= 
 $t + 10; print F $s \n; my $color  = substr (abcd efghij klmno pqrs tuv 
 wxyz, int(rand(10)), int(rand(10))); print F $color; print F \n ;for( $a 
 = 1; $a  (11 +$t); $a = $a + 1 ){print F C10.00   10.0   
 10.0   $a\n;}}; close(F);'
 perl -e 'open(F, test2.xyz); for( $t= 1; $t  5; $t = $t +1){my $s= 
 $t + 10; print F $s \n; myperl -e 'open(F, test2.xyz); for( $t= 1; $t 
  5; $t = $t +1){my $s= $t + 10; print F $s \n; my

 Ok, that is the background to get to my question.  I need a way to parse 
 these files and group the lines into time steps.  I currently have 
 something that works but only in cases where the file size is relatively 
 small-it reads the whole file into memory.  I would like to use something 
 like iota that will allow me lazily parse the file and run reducers on the 
 data.  Any help would be really appreciated.






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


Re: Clojure and IBM JVM

2014-12-18 Thread Francis Avila
For completeness and internet posterity, this issue produced the following 
ticket and resolution: http://dev.clojure.org/jira/browse/CLJ-1620

On Thursday, December 18, 2014 9:16:06 AM UTC-6, Alex Miller wrote:

 The problem is in the static initializer (which is gigantic), not the 
 particular 2-liner, which is being called when the class loads.

 Here's the disassembled bytecode: 
 https://gist.github.com/puredanger/40dd3ec22fdb5836d1eb

 On a first pass through it's not obvious to me what's causing the bloat 
 but thought this would be useful if others are looking...


 On Thursday, December 18, 2014 8:22:11 AM UTC-6, Laurent PETIT wrote:

 Hello, 

 A Counterclockwise user reports that it cannot use the IBM Rational tool 
 with Counterclockwise.

 The error is that a function, in a counterclockwise namespace, cannot be 
 compiled, because one of its method size is too large.

 The function is a 2 liner, accessing a java static method via interop.

 The resulting class file is indeed quite big, 497kb, and it seems to 
 contain a hge static initializer embedding lots of things.

 I have tweaked the clojure compiler so the class file is saved on disk 
 even though it's not AOT compilation that's involved.

 You can find the file at the following URL: 
 http://updatesite.ccw-ide.org/bug/eclipse$goto_editor_line.class

 I really don't understand what's happening, and why the problem occurs 
 only within the IBM environment.


 -- 
 Laurent Petit
  


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


Re: Is there a tool to display all the references to a symbol in a project?

2014-12-03 Thread Francis Avila
Cursive Clojure can do this: alt-f7 the symbol. (But it's not a lightweight 
tool if that's what you mean by not emacs.)

On Wednesday, December 3, 2014 9:16:52 AM UTC-6, Yehonathan Sharvit wrote:

 Is there a tool to display all the references to a symbol in a project?

 Preferably without using emacs.

 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: Core.async unordered pipeline-blocking ?

2014-11-28 Thread Francis Avila
I had a need for this too some time ago. It's not very hard to write 
yourself. Whatever trickiness there is in these functions is in handling 
exceptions and orchestrating shutdown.

I put my version up in a gist with some other async utility functions I 
wrote: https://gist.github.com/favila/8e7ad6ea5b01bd7466ff
You are looking for fast-pipeline-blocking.

On Thursday, November 27, 2014 3:32:43 PM UTC-6, Niels van Klaveren wrote:

 Recently in creating load testing I've been in need of throttling certain 
 mixed IO/CPU bound processes and have been using claypoole.core/upmap for 
 those situations

 (require '[com.climate.claypoole :as cp])

 (defn wait-and-return
   [w]
   (Thread/sleep (* 1000 w))
   w)

 (def to-sort
   [38 20 22 24 36 2 30 18 32 0 4 34 14 28 6 16 12 26 8 10])

 (def timesorted
   (time (doall (cp/upmap 20 wait-and-return to-sort

 timesorted
 Elapsed time: 38004.512729 msecs
 = (var clay.core/timesorted)
 = (0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38)


 This is just an example to show blocking processes returning in a 
 different order, while being restricted to a certain number of threads. I 
 know this won't work with a threadpool smaller than to-sort.

 Other parts of these tests would benefit from core.async techniques, but I 
 haven't found a satisfactory combination of the two. What I'm really 
 looking for is a way to use core.async pipeline-blocking syntax, which 
 takes a fixed number of parallel processes, a from channel, a transducer 
 and a to channel, but returns the results from the transducers unordered 
 (ie. fasted delivered first. Something like this, but with an ordered 
 outcome.

 (require '[clojure.core.async :as a])

 (def to-sort
   (a/to-chan [38 20 22 24 36 2 30 18 32 0 4 34 14 28 6 16 12 26 8 10]))

 (defn wait-and-return
   [w]
   (Thread/sleep (* 1000 w))
   w)

 (def sorted
   (a/chan))

 (def xwait
   (map wait-and-return))

 (def sorter
   (a/pipeline-blocking 20 sorted xwait to-sort))

 (time (a/!! (a/into [] sorted)))


 Is there a function like that, or would there be a recommended way to do 
 something like this in core.async ?

 Regards,

 Niels


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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: Preventing url-encoding of POST body in http-kit.client

2014-11-14 Thread Francis Avila
What you are describing is not url-encoding but xml-entity-quoting. The 
problem is not with the http-kit client but somewhere else in your stack.

On my system (http-kit 2.1.16) I get the expected result:

In a terminal:

$ nc -l localhost -p 


In a repl:

@(org.httpkit.client/post http://localhost:; {:body foobar/foo})




Back in the terminal, I see:

GET / HTTP/1.1
Host: localhost:
Accept: */*
User-Agent: http-kit/2.0
Accept-Encoding: gzip, deflate
Content-Length: 14


foobar/foo


On Friday, November 14, 2014 6:47:23 AM UTC-6, Saju Ravindran Pillai wrote:

 Hi, 

 I need to POST an XML body to an http endpoint, which replies back with a 
 xml response. 

 I do this .. 
 (org.httpkit.client/post uri {:body (str “foobar/foo”)}) 

 but the client is encoding the xml tags to gt;  lt; 

 I then tried : 

 (org.httpkit.client/post uri {:body (str “foobar/foo”) 
  :content-type 
 application/octet-stream 
  :content-encoding 
 application/octet-stream” 
  :mime-type 
 “application/octet-stream” 
  :body-encoding 
 “application/octet-stream”}) 

 .. hoping that one of those options will do the trick — but no luck. 

 How do I prevent http-kit from url-encoding the post body? 

 -srp 
 ps: 

 The following works … 

  curl -X POST -d @file http://uri/ 
 $ cat file 
 foobarfoo 

  

 This e-mail message is authorized for use by the intended recipient only 
 and may contain information that is privileged and confidential. If you 
 received this message in error, please call us immediately at (425) 
 590-5000 and ask to speak to the message sender. Please do not copy, 
 disseminate, or retain this message unless you are the intended recipient. 
 In addition, to ensure the security of your data, please do not send any 
 unencrypted credit card or personally identifiable information to this 
 email address. Thank you. 


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


Re: loop problems

2014-11-12 Thread Francis Avila
Your loop pattern should work. (I've used this pattern before.)

Just a sanity check: you *are* running this function in a different thread, 
right? Because whatever thread calls this function *will* block forever, 
whether the queue is empty or not. And unless you provide some 
side-effecting process-fn there will be no evidence that the thread is 
doing anything. (I.e. your first function will hang forever and appear to 
do nothing.)


On Wednesday, November 12, 2014 10:43:57 AM UTC-6, Sam Raker wrote:

 I'm using Twitter's HBC library to read from Twitter's public stream. HBC 
 stores results in a LinkedBlockingQueue, from which you can then `.take` 
 tweets and do stuff to them (in my case, doing some 
 processing/normalization, then storing them in CouchDB). I've been 
 struggling with how exactly best to do this, though. I tried `doseq`, but 
 it stops when the queue is empty, which isn't what I want. Since my code is 
 basically entirely IO, `map` and other lazy stuff causes me problems. Next, 
 I reached for `loop`:

 (defn process-stream-nores
([in-queue]
   (process-stream-nores in-queue identity))
([in-queue process-fn]
   (loop [res (.take in-queue)]
  (process-fn (parse-string res true))
  (recur (.take in-queue)


 (where `in-queue` is a LinkedBlockingQueue). Unfortunately, this just 
 hangs, even when the LinkedBlockingQueue isn't empty (I'd expect it to hang 
 when the queue is empty, since the queue blocks until it gets something). 

 I've also tried

 ...
(while true (process-fn (parse-string (.take in-queue) true))
 ...

 but that 1) also hangs, and 2) seems profoundly un-idiomatic.

 I want to continuously take from the queue, process the tweet, and then 
 put it in CouchDB. (I'm planning on putting this in a Thread that I can 
 stop when I have enough tweets.) I feel like loop is the right way to go, 
 but I don't understand it very well, and can't get it to work. Any help 
 would be greatly appreciated.


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


Re: Clojure In HTML

2014-10-28 Thread Francis Avila
There is nothing *exactly* like this for clojurescript. The problem is 
clojurescript compiler is implemented in Clojure and thus requires a JVM to 
compile the code. Brython's compiler is implemented in js so it can run in 
the browser.

There was a cljs-in-cljs (self-hosted clojurescript) compiler project but 
it's not under active development: http://clojurescript.net
It works, but its nearly a year behind clojurescript mainline. It's 
organized about repl usage (like the website), but with some glue code I'm 
sure it could read script tags instead.

An alternative is to have a clojurescript compiler service and submit the 
content of script tags to it for compilation and evaluate the returned js 
in the browser. This is basically how http://cljsfiddle.net/ works.

Another idea is to run the clojurescript compiler in an applet. (I'm pretty 
sure no one has tried this.)

On Tuesday, October 28, 2014 11:12:04 AM UTC-5, Asim Jalis wrote:

 Is it possible to embed Clojure in HTML using the approach used in Brython 
 for Python?

 https://news.ycombinator.com/item?id=4923530

 Here is the correct link to the site: http://www.brython.info/

 The idea is to embed Python code in the HTML and then have an interpreter 
 that translates it to JavaScript on the fly. Here is what it looks like.

 script type=text/javascript src=brython.js/script
 script type=text/python
 from browser import document as doc
 from browser import alert
 def echo(*args):
   alert(Hello %s ! %doc[zone].value)
 doc[test].bind(click, echo)
 /script
 pYour name is : input id=zonebutton id=testclic !/button

 From an efficiency point of view this is not as optimal as the 
 compiler-based approach that ClojureScript uses—however, from the 
 perspective of lower-the-barrier-to-entry this approach wins hands down. It 
 is great for writing quick one-off scripts that over time can evolve into 
 more sophisticated applications.

 Asim


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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 can I add meta to an object that doesn't implement IObj?

2014-08-30 Thread Francis Avila
It would probably help if you said more about the source of this 
atom-holding object. Is it a plain Java class? A deftype/defrecord? Is it 
final?


If you can control the construction of this object and its class is not 
final, you can subclass it and add an IObj implementation. (Note that most, 
maybe all clojure ways of creating classes create final classes, so this 
technique won't work.) The easiest way to subclass is with `proxy`:

(defn meta-AtomHolder [atom-value metadata]
  (proxy [AtomHolderClass clojure.lang.IObj] ;; [superclass, new interfaces]
 [atom-value] ;; constructor args
(meta [] metadata) ;; subclass method
(withMeta [newmeta] (meta-AtomHolder newmeta
= (var user/meta-AtomHolder)
(meta-AtomHolder (atom x) {})
= #AtomHolderClass$IObj$40298964 
user.proxy$AtomHolderClass$IObj$40298964@302c28cc
(meta (meta-AtomHolder (atom x) {}))
= {}
(meta (with-meta (meta-AtomHolder (atom x) {}) {:a 1}))
= {:a 1}  

If the parent class is final or you can't construct the object yourself, 
you need to delegate method calls from one instance to this object 
instance. I think this is hard-but-not-impossible in java, but I'm not sure.

(Clojurescript has `specify`, which does exactly what you want, but only 
exists because delegation between instances in javascript is trivial.)

On Friday, August 29, 2014 10:16:05 PM UTC-5, Atamert Ölçgen wrote:

 Obviously I can't.

 But I need to add this capability to an object. During testing I attach 
 meta to this object that contains an atom. Then I pass this object to other 
 functions, known in runtime. I can't use a dynamic var because all this 
 happens within a mock function that may be retried and run in different 
 threads.

 I have seen this: 
 http://stackoverflow.com/questions/20724219/simplest-possible-clojure-object-that-can-accept-a-primitive-and-metadata
  
 but can't deref it since I can't change the functions that will use it 
 later. If I wrap this object I need to be able to delegate all of its 
 functionality to the original object.

 I hope this all is not too vague. The code I'm working on is not online 
 yet. But it's for clecs (https://github.com/muhuk/clecs/), I'm adding 
 quickcheck to compare different world implementations.


 -- 
 Kind Regards,
 Atamert Ölçgen

 -+-
 --+
 +++

 www.muhuk.com
  

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


Re: ANN: ClojureScript 0.0-2277

2014-07-30 Thread Francis Avila
FYI, using the :psuedo-names compiler option is very handy for debugging 
advanced-compile munging issues, e.g.:

 :compiler {:optimizations :advanced
:pseudo-names true
...}



On Wednesday, July 30, 2014 10:11:17 AM UTC-5, Thomas Heller wrote:
 Geez, 2277 actually works just fine. 2234 doesn't work, but it actually 
 doesn't work with either closure-library version. Forgot that I reverted to 
 2234 due to the keyword issue.
 
 
 
 2277 + [org.clojure/google-closure-library 0.0-20140718-946a7d39]
 
 
 
 seems fine, except for that keyword issue.
 
 
 
 Sorry about the confusion, I will shut up now until I have something solid.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email 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.