Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-20 Thread Ghadi Shayban
I tried using proxy+ for one of the proxy implementations in clojure.core, 
but I ran into an issue where a "too many matching methods" got thrown at 
macroexpansion time. The proxy I tried to replicate was PrintWriter-on 
.
 
The exception-data contained two "write" methods that matched arity but 
didn't match param types. Repro below.

(require '[com.rpl.proxy-plus :refer [proxy+]]))

(defn ^java.io.PrintWriter proxy+test
  [flush-fn close-fn]
  (let [sb (StringBuilder.)]
(-> (proxy+ []
  java.io.Writer
  (flush [this]
 (when (pos? (.length sb))
   (flush-fn (.toString sb)))
 (.setLength sb 0))
  (close [this]
 (.flush this)
 (when close-fn (close-fn))
 nil)
  (write [this ^chars str-cbuf off len]
 (when (pos? len)
   (.append sb str-cbuf ^int off ^int len
java.io.BufferedWriter.
java.io.PrintWriter.)))

On Monday, January 13, 2020 at 11:47:06 AM UTC-5, Nathan Marz wrote:
>
> proxy+ is a replacement for Clojure's proxy that's faster and more usable. 
> proxy has a strange implementation where it overrides every possible method 
> and uses a mutable field to store a map of string -> function for 
> dispatching the methods. This causes it to be unable to handle methods with 
> the same name but different arities.
>
> proxy+ fixes these issues with proxy. Usage is like reify, and it's up to 
> 10x faster.
>
> *Repository: *https://github.com/redplanetlabs/proxy-plus
>

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


Re: core.async: Unbound channels

2019-07-03 Thread Ghadi Shayban
(chan) is not a channel with an unbounded buffer. It is a channel with *no* 
buffer and needs to rendezvous putters and takers 1-to-1.  (Additionally it 
will throw an exception if more than 1024 takers or putters are enqueued 
waiting)

On Wednesday, July 3, 2019 at 7:14:46 AM UTC-4, Ernesto Garcia wrote:
>
> You can create a unbound channel with (chan), but not if you use a 
> transducer; (chan nil (filter odd?)) will raise an error that no buffer 
> is provided. Why is this the case?
>
> Why the enforcement of all channels to be bound? In a program, there will 
> be channels that propagate to other channels, so only channels at the 
> boundaries would require to be bound?
>
> Channel limits are also much dependent on the particular process and 
> environment. How would we write generic code that creates channels, if 
> those need to be bound to limits unknown?
>
> Thanks,
> Ernesto
>

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


[ANN] Clojure core.async 0.4.500 released

2019-06-11 Thread Ghadi Shayban
Release 0.4.500 on 2019.06.11 
   
   - ASYNC-227  cljs alts! 
   isn't non-deterministic
   - ASYNC-224  Fix bad 
   putter unwrapping in channel abort
   - ASYNC-226  Fix bad 
   cljs test code

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


Re: Use invokedynamic instead of the reflection API when possible

2019-05-22 Thread Ghadi Shayban
Hi Rémi! What a pleasant surprise to see your name here.  The whole 
community owes you a great deal of gratitude for your work.

I'm hoping to be at JVMLS this summer to talk about some indy/condy 
experiments. Alex summed up the philosophy well: we don't do stuff just 
because it's possible to do, but because it satisfies some objective that 
seems worth doing.  There are others, but improving peak performance (which 
is already quite good, thanks to Rich's design and HotSpot) and improving 
startup time are two interesting objectives.

One complaint often heard in the community is long startup time.  Clojure 
can be AOT compiled, which helps.  We could also cache bytecode in a way 
that is sensitive to Maven or git dependencies.  The rest of this post 
assumes that we have bytecode and not raw s-exprs.  We could probably 
improve startup by 30-50% with bytecode changes alone, but I don't think 
that is a big enough number to assuage complaints, and personally I don't 
think this is one of the "large challenges" that Clojure programmers face 
day-to-day. It is important for containerization and AWS Lambda to have 
strategies for fast startup, maybe that needs more assistance from either 
the JVM (Class Data Sharing, Application CDS, etc.) or execution substrates 
like AWS Lambda. (The #1 way to help with startup is to depend on fewer 
dependencies and load fewer classes, and that's is a cultural thing that 
you can't solve in a compiler.) Some users are looking toward Graal 
native-image for fast startup, but there are so many restrictions with that 
tool that I don't even know what to say. A Lisp with eval is an open-world 
assumption, native-image is closed world, and it's Not Java.

That being said, if you look at Clojure bytecode, in general a lot work 
happens in  that can be deferred until an indy instruction 
bootstraps. (The current strategy predates indy and certainly condy). For 
example, in 
https://gist.github.com/ghadishayban/72a87c8e12cd66b0f4e285c1754157f5 there 
are two constants (a Pattern and a Var) which get initialized in  
and stuffed into final fields. During the load of Clojure namespaces, we 
load a lot of similar, larger datastructures that serve as Var's metadata.

Another constant example is 
https://gist.github.com/ghadishayban/f7b4c2206836f29d7e9f8cd614cdd2d1
With condy, ldc's can take bootstrap methods, so we can get rid of the 
array construction and defer the  work, making the meat of the code 
degenerate to: 

ldc `:id` (Keyword.class)
aload 1
ldc `:byte` 
aload 2
ldc `:is`
aload 3
invokestatic IPersistentMap.of(Object,Object,Object,Object,Object,Object) 
(this API doesn't exist, but should!)
areturn

We can significantly reduce the bytecode size of regular Clojure functions, 
which is a proxy for better inlining+peak performance, and defer all the 
clinit setup, improving startup.

(Aside: notice that three of the six components in the map are static, only 
the right hand side is dynamic. We could pre-fab an array factory indy that 
has the static parts filled in already.  I've tried this, and it didn't pay 
off except with larger maps.)

There are a couple of other invocation types (protocol invokes and keyword 
invokes) that open-code a PIC in the bytecode, with static fields for the 
caches.  There are various strategies like MutableCallSite with GWTs to 
handle this, but hey you wrote the cookbook on this subject.

In Clojure 1.8, the compiler learned "direct linking", which made calls to 
Clojure functions call a static method.  *Previously*:

getstatic clojure.lang.Var
invokevirtual clojure.lang.Var.getRawRoot()
checkcast clojure.lang.IFn
push arguments...
invokeinterface clojure.lang.IFn.invoke(.)

*With direct linking:*
push arguments
invokestatic someFunction.invokeStatic()

Direct linking is not the default except for clojure.core itself comes 
direct linked, but direct linking traded away dynamicity for performance. 
(You can't reload things that are direct linked)  Since a Var is 
essentially a box around a volatile field, there are other ways of getting 
the performance of the invokestatic without losing the dynamicity.

Reflection is another use-case, but as Alex mentioned, the general 
suggestion to users is: don't write reflective code. One of the few 
compiler flags that exist is: (set! *warn-on-reflection* true)

Anyways, thanks for starting this discussion

On Wednesday, May 22, 2019 at 9:47:53 PM UTC-4, Alex Miller wrote:
>
> Hi Rémi! Thanks for all your work on ASM and other JVM stuff over the 
> years by the way.
>
> We have of course been poking at indy off and on over the years and there 
> have been a number of experiments with it. Ghadi Shayban has probably done 
> the most work on that and he probably has more useful feedback than I would 
> on the technical aspects of the code.
>
> Based on where we are in the release cycle right now, I expect that we 
> probably aren't rea

Re: GraalVM's native-image incompatible with Clojure's eval?

2018-11-26 Thread Ghadi Shayban
Substrate makes a closed world assumption.  jaotc is open world, and also based 
on Graal.

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

2018-10-26 Thread Ghadi Shayban
Verification time should go down with JDK8 level bytecode, which improves 
cold startup of clojure.jar by about 5%. (This benefit is negated by the 
module system in 9+ though.)

On Friday, October 26, 2018 at 12:27:44 PM UTC-4, Alex Miller wrote:

> Likely the biggest performance gain is that compatibility fixes allow you 
> to run up to Java 11, thus reaping any benefits from newer JVMs.
>
> On Friday, October 26, 2018 at 11:09:39 AM UTC-5, Sean Corfield wrote:
>>
>> I don’t have any hard evidence about performance but when we first 
>> updated to the 1.10 build that generated the new bytecode, it _*felt*_ 
>> faster – our test suite seemed to run faster locally (so maybe the compiler 
>> got faster?). We have not seen any measurable difference in production (but 
>> we’ve had a lot of other changing going to production lately that have 
>> changed the performance dynamic of three of our servers, so any performance 
>> boost from 1.10 and the 8+ bytecode would likely have been swamped by other 
>> changes).
>>
>>  
>>
>> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
>> An Architect's View -- http://corfield.org/
>>
>> "If you're not annoying somebody, you're not really alive."
>> -- Margaret Atwood
>>
>

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


[ANN] depstar: a clj-based uberjarrer

2018-03-12 Thread Ghadi Shayban
My workflow has generally changed to one based on clj and tools.deps 
wherever possible. I continue to use lein for uberjarring, so I wrote this 
tool to jar up the classpath.

depstar has no dependencies, and uses the JVM classpath instead of reading 
deps.edn directly.

It handles merging multiple data_readers.clj & Java service loader 
manifests.  It does not handle AOTing nor specifying a main class. (Though 
the README has a suggestion about how to include web assets or AOT -- tldr 
specify :extra-paths in deps.edn)

https://github.com/healthfinch/depstar

Include it in deps.edn (either in your project or your 
$HOME/.clojure/deps.edn):

  :aliases {:depstar
  {:extra-deps
 {com.healthfinch/depstar {:git/url 
"https://github.com/healthfinch/depstar.git;
   :sha 
"4aa7b35189693feebc7d7e4a180b8af0326c9164"

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

2018-02-25 Thread Ghadi Shayban
Clojure always worked on Java 9 but lein and boot were broken for a while. Now 
they're fixed.

The only remaining defect is the inability for Clojure to call static interface 
methods which are a new thing in Java 8. The bytecode verifier in Java 9 added 
a small backwards incompatible check that made those static interface calls 
break. (They have to be encoded a slightly different way) You can use Java 
reflection to make those calls.

http://dev.clojure.org/jira/browse/CLJ-2284

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


Re: Help ship Clojure 1.9!

2017-09-28 Thread Ghadi Shayban
Clojure 1.9 has been great for me so far. I think it's worth considering 
the problem Luke brought up regarding the REPL caught handler [1], 
especially since the compiler now checks macro specs. Having a slightly 
better knob for that might be nice, since it's an integration point.  (This 
is not an issue for socket REPL.) There are only 14 JIRAs tagged with 
rel1.9 that are not spec related [2].

[1] https://dev.clojure.org/jira/browse/CLJ-2040
[2] JIRA query: project = CLJ AND resolution = Unresolved AND fixVersion = 
"Release 1.9"  and labels != 'spec' ORDER BY priority DESC

On Thursday, September 28, 2017 at 10:00:16 AM UTC-4, stuart@gmail.com 
wrote:
>
> Clojure 1.9 has been quite stable throughout the alpha period, and we now 
> hope to release after a very short beta. Please test your existing programs 
> on the latest beta (see below), and respond on this thread ASAP if you 
> discover anything you believe to be a regression.
>
> Thanks!
> Stu
>
> ;; Clojure deps.edn
> org.clojure/clojure {:mvn/version "1.9.0-beta1"}
>
> ;; lein & boot
> [org.clojure/clojure "1.9.0-beta1"]
>
>

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

2017-09-18 Thread Ghadi Shayban
Congrats everyone! What a major release.

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

2017-09-12 Thread Ghadi Shayban
One thing slowing you down is that your function "parallel-process" is 
calling fold on a line-seq, which is not a foldable source, so you won't 
get any parallelism.  It devolves to a sequential reduce.

As an alternative, consider partitioning the lines into batches of a few 
thousand, then pipelining the calculation over batch, then calling 
(merge-with +) on all the intermediate results. clojure.core.async/pipeline 
is a useful function for this.


On Tuesday, September 12, 2017 at 12:43:58 PM UTC-4, darren...@gmail.com 
wrote:
>
> Hi, 
>
> I am a researcher of Natural Language Processing.
> My team want to know how well does Clojure parallelize and how much time 
> is reduced compared by Java single thread version.
>
> The problem we want to solve is, 
> there is a big corpus file (just now 500MB).
> Reading sentences line by line, find all patterns and their occurrence 
> count on length 1 through 12.
>
> It is a very simple problem and It doesn’t care of order of processing.
> We want to make just a big hash-map. (Key is a pattern string, Value is a 
> occurrence count.)
> Ex) { “father” 1000 “mother” 1000 … }
>
> Comparing performance between Java and Clojure, if Clojure version is 
> better than Java, 
> then we’ll change our code base to Clojure, if not, we cannot help staying 
> Java. 
>
> Anyway my first prototype is very very slow. I’m a novice.  :( 
>
> Please give me some advices.
> Thanks.  
>
> (ns parallel-test.core
>  (:require [clojure.java.io :as jio]
>[clojure.core.reducers :refer [fold]])
>  (:gen-class))
>
> (def corpus-file-url "resources/korean.txt")
> (def OC (atom nil))
> (def MPL 12)
> (def each-size 1)
>
> (defn add-pattern-to-hashmap
>  [h-map ^String ptn ^Integer ptn-oc]
>  (let [h-ptn-oc (get h-map ptn)
>n-ptn-oc (if (nil? h-ptn-oc)
>  ptn-oc
>  (+ h-ptn-oc ptn-oc))]
>   (assoc h-map ptn n-ptn-oc)))
>
> (defn merge-hash-map
>  ([] (hash-map))
>  ([& hs]
>   (reduce (fn [l-map r-map]
>(reduce (fn [[ptn ptn-oc]]
> (add-pattern-to-hashmap l-map ptn ptn-oc))
>r-map))
>   hs)))
>
> (defn cal-line-oc
>  ([] (hash-map))
>  ([h-map ^String line]
>   (let [line-length (count line)]
>(loop [i 0
>   i-map h-map]
> (if (>= i line-length)
>  i-map
>  (recur (inc i)
> (loop [j 1
>j-map i-map]
>  (let [end-index (+ i j)]
>   (if (or (> j MPL) (> end-index line-length))
>j-map
>(recur (inc j)
>   (add-pattern-to-hashmap j-map (subs line i end-index) 
> 1)))
>
> (defn parallel-process
>  [combine-fn reduce-fn input-file]
>  (with-open [rdr (jio/reader input-file)]
>   (fold each-size
> combine-fn
> reduce-fn
> (line-seq rdr
>
> (defn -main [& args]
>  (println "start")
>  (reset! OC (parallel-process merge-hash-map cal-line-oc corpus-file-url))
>  (println "end"))
>
>

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

2017-08-20 Thread Ghadi Shayban
You have the right idea with s/and.  I would name & defn the predicate to 
something meaningful like increasing?.  Defining and thus naming it is 
essential so that you can get reuse, and also so that consumers of your 
spec, whether it's you or someone else, don't have to interpret the code in 
the brain.  Btw, the impl can be simplified, but I still wouldn't inline it.

(defn increasing? [coll]
  (apply < coll))
#'user/increasing?
user=> (increasing? [1 2 3])
true
user=> (increasing? [1 2 2])
false
(s/and (s/coll-of number?) increasing?)


On Sunday, August 20, 2017 at 7:53:48 PM UTC-4, Mark wrote:
>
> What's the 'right' way to spec relationship between values in a sequence? 
>  For example, the following spec defines a sequence of number in increasing 
> order:
>>
>>
>>
>> (s/conform (s/and (s/coll-of number?)
>>   #(->> %
>> (partition 2 1)
>> (map (fn [[a b]] (< a b)))
>> (every? true?)))
>>[1 2 3])
>>
>> It feels like there ought to be a more elegant solution - especially as 
> the relationships become more complex.  Is there another approach?
>

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

2017-05-05 Thread Ghadi Shayban
Maybe I don't understand the problem at hand yet -- you can almost 
certainly do this without language help.   Can you help out with a concrete 
example or problematic code?

On Friday, May 5, 2017 at 2:18:17 PM UTC-4, Brian Craft wrote:
>
> This looks like a partial solution:
>
> https://github.com/pjstadig/scopes
>
> perhaps inspired by this discussion:
>
> https://dev.clojure.org/display/design/Resource+Scopes
>
>
>
> On Friday, May 5, 2017 at 5:10:27 AM UTC-7, Herwig Hochleitner wrote:
>>
>> 2017-05-04 19:35 GMT+02:00 Brian Craft :
>>>
>>> If there's only one with-open it can be reasonably simple to pass the 
>>> consumer into that context (though from ring it's pretty convoluted, due to 
>>> needing to pass control to ring first).
>>>
>>
>> Creating streamed ring responses can be kind of tricky. In my experience, 
>> there are two patterns, that work well:
>>
>> 1) Feeding a PipedInputStream from a new thread:
>>
>> (let [os (PipedOutputStream.)
>>   is (PipedInputStream. os)]
>>   (future (with-open [rs ...]
>> (write-to! os rs)))
>>   {:body is})
>>
>> 2) Use a ring adapter that allows some form of asynchronous response. 
>> E.g. with the new ring 1.6 model
>>
>> {:body (reify ring.core.protocols/StreamableResponseBody
>>  (write-body-to-stream [_ _ output-stream]
>> (with-open [rs ...
>> os output-stream]
>> (write-to! os rs}
>>  
>>
>

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

2017-05-04 Thread Ghadi Shayban
Hi Brian,
Both plain seqs or reducibles can be consumed without realizing the whole 
thing in memory, especially important (as you note) when the whole thing is 
humongous and dwarfs available memory.  To do it with a lazy seq, as in 
clojure.java.jdbc, you have to care of a few things. You must override 
:result-set-fn from clojure.java.jdbc/query [1] so that you can control 
realization through doseq or reduce.

Forbidden things: calling `doall` on the seq, or pouring it into a vector, 
or realizing the whole seq while still hanging on its head, or making a let 
binding of the resultset that you use more than once, or leak carelessly to 
some helper.  

If you have multiple bindings, my guess is that there is some unit of work 
for every item of a seq realized from a large 'main' query.  The same 
advice would apply here too, you just have to take care on many more 
queries to allow the garbage collector to do its job.  If you have a lot of 
"layers" perhaps you could decompose that into some simpler computations, 
or use a work queue mechanism or core.async channel.  Do you have a 
concrete example of the multiple bindings scenario?

Make sure that the underlying JDBC driver is not working against you by 
buffering the whole thing!  MySQL's JDBC driver, for example, requires a 
few magical settings [2] to prevent it from buffering internally 
[1] http://clojure.github.io/java.jdbc/#clojure.java.jdbc/query

[2] From 
https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-implementation-notes.html:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
  java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

The combination of a forward-only, read-only result set, with a fetch size 
of Integer.MIN_VALUE serves as a signal to the driver to stream result sets 
row-by-row. After this, any result sets created with the statement will be 
retrieved row-by-row. 


On Thursday, May 4, 2017 at 1:35:48 PM UTC-4, Brian Craft wrote:
>
> The with-open style is used a lot in the jdbc lib, and elsewhere. It's 
> pretty simple when data is very small, as you can just evaluate the entire 
> result with doall, etc.
>
> How do you deal with larger data, where you need to evaluate iteratively? 
> If there's only one with-open it can be reasonably simple to pass the 
> consumer into that context (though from ring it's pretty convoluted, due to 
> needing to pass control to ring first). But if there are multiple with-open 
> you have to nest them, with a continuation passing style, or middleware 
> pattern, or something, which quickly becomes onerous as it affects all the 
> code surrounding the with-open.
>
> Is there some simpler pattern?
>

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

2016-12-20 Thread Ghadi Shayban
swap! takes as its arguments the atom and the function to transition the 
state inside the atom.  It implicitly calls the function on the state:
(swap! data replace-value)

It also can accept trailing arguments too...  

https://www.conj.io/store/v1/org.clojure/clojure/1.8.0/clj/clojure.core/swap%21

On Tuesday, December 20, 2016 at 11:04:11 AM UTC-5, Rickesh Bedia wrote:
>
> I have
> (def data {:headers ["A" "B" "C" "D"]
>  :rows [["1" "2" "3" "4"] ["5" "6" "7" "8"] ["9" "10" "11" 
> "12"]]})
>
> And I have a function
> (defn replace-value [struct] 
> (clojure.walk/prewalk-replace {"3" "hello"} (struct :rows)))
>
> When I do
> (replace-value @data) > [["1" "2" "hello" "4"] ["5" "6" "7" "8"] ["9" "10" 
> "11" "12"]]
>
> which is what I am expecting.
>
> However I want to achieve this same result using swap! So I tried
> #(swap! data (replace-value %))
>
> but I get the error #object[user$eval1308$fn__1309 0x6caeefd7 
> "user$eval1308$fn__1309@6caeefd7"]
>
> I don't know what this error means nor how to resolve 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.


Re: Elegant way to do lazy infinite list with custom step

2016-12-14 Thread Ghadi Shayban
If you really want to have _exactly_ what Haskell does (derives the range 
from an example) -- yes, you could do a macro.  Clojure's new spec facility 
(in 1.9-alphas) makes the macro arguments checked at load time too, which 
is extra nice:

(set! *print-length* 5) ;; avoid printing infinite lists

(defmacro haskell-like-range [lower next dots]
  `(range ~lower Long/MAX_VALUE ~(- next lower)))

(require '[clojure.spec :as s])
(s/fdef haskell-like-range :args (s/cat :lower int? :next int? :dots 
'#{...}))

;; these will fail at load time with a really nice error message
(haskell-like-range :foo 42 ...)
(haskell-like-range 4 6 ..) ;; needs three dots according to the spec

;; this will succeed
(haskell-like-range 2 6 ...)


On Wednesday, December 14, 2016 at 1:02:38 AM UTC-5, tbc++ wrote:
>
> Ah! I knew there was a way to do it via iterate, but it was 9:30pm at the 
> time and I was tired. Nice example though.
>
> On Tue, Dec 13, 2016 at 10:03 PM, Ghadi Shayban <gsha...@gmail.com 
> > wrote:
>
>> A common way to do it in Clojure is `iterate`, no macros necessary. As of 
>> Clojure 1.7 this doesn't allocate a list at all if you reduce/fold over it:
>> (iterate #(+ % 2) 4)
>>
>>
>> On Tuesday, December 13, 2016 at 11:27:28 PM UTC-5, tbc++ wrote:
>>>
>>> I'm not aware of such a construct, but it's trivial enough to write 
>>> something like this using `range` or perhaps write a function that will 
>>> yield a lazy seq:
>>>
>>> (defn inf-list
>>>   ([x y]
>>> (cons x (cons y (inf-list x y 2
>>>   ([x y c]
>>> (cons (+ x (* c (- y x)))
>>>   (lazy-seq (inf-list x y (inc c))
>>>
>>> No macros required
>>>
>>> On Tue, Dec 13, 2016 at 9:14 PM, bill nom nom <hellomot...@gmail.com> 
>>> wrote:
>>>
>>>> In Haskell, I can get an infinite lazy list that is incremented by two 
>>>> by, starting at 4
>>>> [4,6..]
>>>>
>>>> which yields the result
>>>> [4,6,8,10...]
>>>>
>>>> the more general form
>>>> [x,y..] produces [x, x + (y-x), x + 2 * (y-x), x + 3 * (y-x)...]
>>>>
>>>> Is there a way to make a macro of this in clojure, or is there 
>>>> something already as elegant? 
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with 
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to clojure+u...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>>
>>> -- 
>>> “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 clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> “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 the Google Groups 
"Clojure" group.
To unsubscribe from 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: Elegant way to do lazy infinite list with custom step

2016-12-13 Thread Ghadi Shayban
A common way to do it in Clojure is `iterate`, no macros necessary. As of 
Clojure 1.7 this doesn't allocate a list at all if you reduce/fold over it:
(iterate #(+ % 2) 4)


On Tuesday, December 13, 2016 at 11:27:28 PM UTC-5, tbc++ wrote:
>
> I'm not aware of such a construct, but it's trivial enough to write 
> something like this using `range` or perhaps write a function that will 
> yield a lazy seq:
>
> (defn inf-list
>   ([x y]
> (cons x (cons y (inf-list x y 2
>   ([x y c]
> (cons (+ x (* c (- y x)))
>   (lazy-seq (inf-list x y (inc c))
>
> No macros required
>
> On Tue, Dec 13, 2016 at 9:14 PM, bill nom nom  > wrote:
>
>> In Haskell, I can get an infinite lazy list that is incremented by two 
>> by, starting at 4
>> [4,6..]
>>
>> which yields the result
>> [4,6,8,10...]
>>
>> the more general form
>> [x,y..] produces [x, x + (y-x), x + 2 * (y-x), x + 3 * (y-x)...]
>>
>> Is there a way to make a macro of this in clojure, or is there something 
>> already as elegant? 
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> “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 the Google Groups 
"Clojure" group.
To unsubscribe from 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: finding clojure functions from the mangled names

2016-12-09 Thread Ghadi Shayban
The stacktrace should be pointing to the correct file & line number -- no 
need to reverse engineer the mangling.  If it's not for some reason, file a 
bug.  (It's helpful to eliminate nREPL / lein middleware in case something 
is transforming the printing of traces)
If you are missing a trace when the JVM JITs your code, run with -XX:-
*OmitStackTraceInFastThrow* 

On Friday, December 9, 2016 at 6:25:24 PM UTC-5, Brian Craft wrote:
>
> Yes, but not very practical: since I don't know which one to change, this 
> would be a huge rewrite of code to eliminate #() and (fn []).
>
>
> On Friday, December 9, 2016 at 3:16:06 PM UTC-8, Alex Engelberg wrote:
>>
>> If you're seeing "fn_123", it's probably coming from an anonymous 
>> function. Giving those functions a name with the (fn my-name [] ...) syntax 
>> will make the stack trace a little easier to decipher:
>>
>> user=> ((fn [] (/ 1 0)))
>>
>> ArithmeticException Divide by zero  clojure.lang.Numbers.divide 
>> (Numbers.java:158)
>>
>> user=> (pst)
>>
>> ArithmeticException Divide by zero
>> clojure.lang.Numbers.divide (Numbers.java:158)
>> clojure.lang.Numbers.divide (Numbers.java:3808)
>> user/eval20851/fn--20852 (form-init8836862334241327650.clj:1)
>> ​...​
>>
>> nil
>> user=> ((fn my-fn-with-a-name [] (/ 1 0))
>>
>> ArithmeticException Divide by zero  clojure.lang.Numbers.divide 
>> (Numbers.java:158)
>> user=> (pst)
>> ArithmeticException Divide by zero
>> clojure.lang.Numbers.divide (Numbers.java:158)
>> clojure.lang.Numbers.divide (Numbers.java:3808)
>> user/eval20857/my-fn-with-a-name--20858 
>> (form-init8836862334241327650.clj:1)
>> ​...​
>>
>> nil
>>
>> On Fri, Dec 9, 2016 at 3:00 PM, Brian Craft  wrote:
>>
>>> Trying to profile some code, and the stack traces look like
>>>
>>> clojure.something0
>>>   clojure.something1
>>>clojure.something2
>>>  
>>>   clojure.something100
>>>  foo$fn_1000$fn_1002$fn_10003.invoke()
>>>
>>>
>>> How can I figure out what that last function is? I can access the symbol 
>>> from the repl, but no idea how to connect it to my code.
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> --- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

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


Re: [ANN] Clojure 1.9.0-alpha4

2016-06-02 Thread Ghadi Shayban
Let bindings from thbe macroexpansion of (let [[x & xs] v] ...)

;; old macroexpand
[G__1   v
 vec__2 G__1
 x  (nth vec__2 0 nil)
 xs (nthnext vec__2 1)]

;; new macroexpand
[G__6   v
 vec__7 G__6
 seq__8(seq vec__7)
 first__9  (first seq__8)
 seq__8(next seq__8)
 x first__9
 xsseq__8]

On Wednesday, June 1, 2016 at 7:49:00 PM UTC-4, Frank Castellucci wrote:
>
>
> How was this accomplished?
>
> On Wednesday, June 1, 2016 at 10:17:14 AM UTC-4, Rich Hickey wrote:
>>
>> To give people an idea of the update-in and seq destructuring 
>> improvements: 
>>
>> (let [d3 {:a {:b {:c 2}}}] 
>>   (dotimes [_ 10] 
>> (time (dotimes [_ 1000] 
>> (update-in d3 [:a :b :c] inc) 
>>
>> ;;; 1.9 alpha3 ;; 
>> user=> "Elapsed time: 6489.189065 msecs" 
>> "Elapsed time: 6501.518961 msecs" 
>> "Elapsed time: 6479.994554 msecs" 
>> "Elapsed time: 6477.236659 msecs" 
>> "Elapsed time: 6490.542382 msecs" 
>> "Elapsed time: 6494.044657 msecs" 
>> "Elapsed time: 6475.188285 msecs" 
>> "Elapsed time: 6498.734628 msecs" 
>> "Elapsed time: 6486.312312 msecs" 
>> "Elapsed time: 6476.566904 msecs" 
>> nil 
>>
>> ;;; 1.9 alpha4 ;; 
>> user=> "Elapsed time: 1613.631053 msecs" 
>> "Elapsed time: 1614.271583 msecs" 
>> "Elapsed time: 1607.393994 msecs" 
>> "Elapsed time: 1605.966032 msecs" 
>> "Elapsed time: 1605.731867 msecs" 
>> "Elapsed time: 1605.836779 msecs" 
>> "Elapsed time: 1617.090363 msecs" 
>> "Elapsed time: 1611.065741 msecs" 
>> "Elapsed time: 1611.249945 msecs" 
>> "Elapsed time: 1624.351585 msecs" 
>> nil 
>>
>> (let [v (into [] (range 100))] 
>>   (dotimes [_ 10] 
>> (time (dotimes [_ 10] 
>> (loop [[x & xs] v] 
>>   (if xs 
>> (recur xs) 
>> x)) 
>>
>> ;;; 1.9 alpha3 ;; 
>> user=> "Elapsed time: 1531.858419 msecs" 
>> "Elapsed time: 1521.997662 msecs" 
>> "Elapsed time: 1499.931748 msecs" 
>> "Elapsed time: 1499.745901 msecs" 
>> "Elapsed time: 1496.63342 msecs" 
>> "Elapsed time: 1499.363234 msecs" 
>> "Elapsed time: 1506.309383 msecs" 
>> "Elapsed time: 1514.943316 msecs" 
>> "Elapsed time: 1534.90731 msecs" 
>> "Elapsed time: 1524.550125 msecs" 
>> nil 
>> ;;; 1.9 alpha4 ;; 
>> user=> "Elapsed time: 155.544283 msecs" 
>> "Elapsed time: 131.861647 msecs" 
>> "Elapsed time: 141.774727 msecs" 
>> "Elapsed time: 238.939786 msecs" 
>> "Elapsed time: 294.832594 msecs" 
>> "Elapsed time: 278.476703 msecs" 
>> "Elapsed time: 133.259029 msecs" 
>> "Elapsed time: 139.917267 msecs" 
>> "Elapsed time: 137.444001 msecs" 
>> "Elapsed time: 147.852057 msecs” 
>> nil 
>>
>>
>> The code now produced for [x & xs] style destructuring is now as good as 
>> the best first/next code you could write by hand, while the code produced 
>> for [x y z] destructuring of indexed items is the same (fast, indexed) as 
>> always. 
>>
>> Rich 
>>
>> > On May 31, 2016, at 11:41 AM, Stuart Halloway  
>> wrote: 
>> > 
>> > Clojure 1.9.0-alpha4 is now available. 
>> > 
>> > Try it via 
>> > 
>> > - Download: 
>> https://repo1.maven.org/maven3/org/clojure/clojure/1.9.0-alpha4 
>> > - Leiningen: [org.clojure/clojure "1.9.0-alpha4"] 
>> > 
>> > 1.9.0-alpha4 includes the following changes since 1.9.0-alpha3: 
>> > 
>> > - fix describe empty cat 
>> > - improve update-in perf 
>> > - optimize seq (&) destructuring 
>> > 
>> > 
>> > -- 
>> > You received this message because you are subscribed to the Google 
>> > Groups "Clojure" group. 
>> > To post to this group, send email to clo...@googlegroups.com 
>> > Note that posts from new members are moderated - please be patient with 
>> your first post. 
>> > To unsubscribe from this group, send email to 
>> > clojure+u...@googlegroups.com 
>> > For more options, visit this group at 
>> > http://groups.google.com/group/clojure?hl=en 
>> > --- 
>> > You received this message because you are subscribed to the Google 
>> Groups "Clojure" group. 
>> > To unsubscribe from this group and stop receiving emails from it, send 
>> an email to clojure+u...@googlegroups.com. 
>> > For more options, visit https://groups.google.com/d/optout. 
>>
>>

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


Re: Welcome the new maintainer of Loom: Paul Snyder

2016-02-15 Thread Ghadi Shayban
You're going to be a great maintainer, Paul.

On Monday, February 15, 2016 at 5:30:04 PM UTC-5, Paul L. Snyder wrote:
>
> On Mon, 15 Feb 2016, Gregg Reynolds wrote: 
>
> > On Feb 11, 2016 6:19 AM, "Aysylu Greenberg"  > wrote: 
> > > 
> > > I'm pleased to announce that Paul Snyder 
> > (@pataprogramming, pataprogramming on Github) has joined me in 
> maintaining 
> > Loom. I'm excited for the coming year for Loom, with more excellent 
> > contributions accepted faster. 
> > 
> > Your Readme doesn't even bother to say what loom is. 
>
> Hi, Gregg, 
>
> Thanks for pointing out an area where additional clarification would be 
> helpful to potential users of Loom. 
>
> Who is the 'you' that this criticism is intended to address? Aysylu, who's 
> been serving as maintainer for this library over the last years? Justin, 
> who originally created it? The over two dozen contributors who have helped 
> build its functionality? Suggesting that they didn't "even bother" with 
> something is, frankly, rude and unproductive. 
>
> I'm happy we don't see much of this sort of casual disrespect in the 
> Clojure community (with the exception of occasional bad actors on the 
> mailing list). The worst of what we do see is, largely, aimed at those who 
> contribute the most: the team that maintains Clojure itself. 
>
> People who are willing to invest their time to make and share useful tools 
> are a resource. They should be allowed to direct their energy toward 
> making 
> those tools better, rather than having it drained by jerky interactions. 
> Whether we find a project personally useful or not, we owe Open Source 
> authors, at a minimum, politeness. This is at least partially in our own 
> interest: we want them to keep making those tools, rather than burning out 
> and switching to a more rewarding activity. 
>
> Here's an article on framing feedback in a less confrontational and 
> accusatory manner. 
>
>   http://personalexcellence.co/blog/constructive-criticism/ 
>
> "Thanks for sharing Loom. There's a lot of information in the README, but 
> I found it difficult to figure out what the library actually does. It 
> would be helpful to have a concise, up-front description of its purpose." 
>
> Regards, 
> Paul 
>

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

2016-02-11 Thread Ghadi Shayban
Btw, ever looked at Macaroons?  Apparently Google uses them internally.

http://research.google.com/pubs/pub41892.html
http://hackingdistributed.com/2014/05/21/my-first-macaroon/

Ghadi

On Thursday, February 11, 2016 at 1:29:56 PM UTC-5, Michael Ball wrote:
>
> Thanks! Yes I looked at JWE, but it just seemed a bit heavy for the need 
> to only store a simple identifier. Interoperability isn't a concern, as 
> tickets rarely if ever shared. I just wanted a simple self contained and 
> easy to use way to package and retrieve identifiers with appropriately 
> chosen encryption and signing algorithms for the common web-app case.
>
>
> On Thursday, February 11, 2016 at 1:36:53 AM UTC-8, Andrey Antukh wrote:
>>
>> Hi Michael!
>>
>> Firstly: nice work!
>>
>> Do you know about JWE? It does just the same thing but in a 
>> standarized/interoperable way: 
>> https://funcool.github.io/buddy-sign/latest/#introduction
>>
>> Andrey
>>
>> On Thu, Feb 11, 2016 at 8:21 AM, Michael Ball  wrote:
>>
>>> Ticket helps create and read encrypted tickets/cookies with expiration 
>>> dates packaged inside. Feedback and security reviews are welcomed.
>>>
>>> https://github.com/mikeball/ticket
>>>
>>> Mike
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> --- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> -- 
>> Andrey Antukh - Андрей Антух - 
>> http://www.niwi.nz
>> https://github.com/niwinz
>>
>

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


Re: clojure.compiler.disable-locals-clearing memory leak?

2016-01-25 Thread Ghadi Shayban
It's explicitly to help a debugger. Best to not use that option except when 
debugging.  (It disables certain bytecode patterns that help to avoid 
OutOfMemory errors)

On Monday, January 25, 2016 at 1:49:03 AM UTC-5, Mars0i wrote:
>
> In my  application, I seem to get a memory leak when I use 
> -Dclojure.compiler.disable-locals-clearing=true in Clojure 1.7.0 and 1.8.0, 
> but not in 1.6.0.  (i.e. I get "java.lang.OutOfMemoryError: GC overhead 
> limit exceeded" with the more recent versions).
>
> Any guesses about why this might happen?  Just curious.  
>
> (I think I can live without disabling locals-clearing.  I don't fully 
> understand it.  Not sure why I started using it.  I don't use a debugger.)
>

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

2015-11-25 Thread Ghadi Shayban
While in memory before writing, are the hash codes for the "duplicate" keys 
the same?   You can call (hash) on the keys.  I'm thinking there is perhaps 
an issue with unicode string serialization...  Are the question marks a 
particular character?

If you can find the similar strings in memory, before they are written, 
call:
(map int  the-string)
To see the actual unicode characters for the question marks.

On Wednesday, November 25, 2015 at 11:07:34 PM UTC-5, Dave Kincaid wrote:
>
> The number of keys in the map is 8,054,160.
>
> On Wednesday, November 25, 2015 at 10:04:11 PM UTC-6, Dave Kincaid wrote:
>>
>> I have something very strange going on when I try to write a map out to a 
>> file and read it back in. It's a perfectly fine hash-map with ? 
>> key/values (so it's pretty big). When I write the map out to a file using
>>
>> (spit "/tmp/mednotes6153968756847768349/repl-write.edn" (pr-str phrases))
>>
>> and then read it back in with
>>
>> (edn/read (PushbackReader. (io/reader 
>> "/tmp/mednotes6153968756847768349/repl-write.edn")))
>>
>> I am getting a duplicate key exception indicating that "? 5" is 
>> duplicated. phrases is a clojure.lang.PersistentHashMap. The keys of the 
>> map are strings and the values are numbers. When I get the value for "? 5" 
>> from the map it returns 352.
>>
>> I tried to grep the file to find the occurrences of the key "? 5" (and 
>> the 30 characters before and after it) and it seems to return 4 of them. 
>> The second one is the right one from the map, but I have no idea where the 
>> other 3 are coming from.
>>
>> [/tmp/mednotes6153968756847768349]> egrep -o ".{30}\"\? 5\" .{30}" 
>> repl-write.edn 
>> hasing a toothbrush for" 160, "? 5" 32, ". ) during his /" 32, "to
>>  "is intact with sutures" 32, "? 5" 352, "4.81 pounds" 128, "ceren
>> udden" 32, "being up all" 32, "? 5" 32, "limited financial means" 
>> , "count , everytime she" 32, "? 5" 32, "had a partial mandibulect
>>
>> Does anyone have an idea what might be happening when the map is written 
>> out to the file? How is that key getting duplicated?
>>
>> I have tried a few slightly different ways of writing to the file 
>> including
>>
>> (spit "/tmp/mednotes6153968756847768349/repl-write.edn" (binding 
>> [*print-dup* true] (pr-str phrases)))
>>
>> and
>>
>> (spit "/tmp/mednotes6153968756847768349/repl-write.edn" (.toString 
>> phrases))
>>
>> based on some StackOverflow answers I found. They all seem to do the same 
>> thing.
>>
>> Here is the exception stack trace.
>>
>> 1. Caused by java.lang.IllegalArgumentException
>>Duplicate key: ? 5
>>
>> PersistentHashMap.java:   67 
>>  clojure.lang.PersistentHashMap/createWithCheck
>>RT.java: 1538  clojure.lang.RT/map
>> EdnReader.java:  631 
>>  clojure.lang.EdnReader$MapReader/invoke
>> EdnReader.java:  142  clojure.lang.EdnReader/read
>> EdnReader.java:  108  clojure.lang.EdnReader/read
>>edn.clj:   35  clojure.edn/read
>>edn.clj:   33  clojure.edn/read
>>   AFn.java:  154  clojure.lang.AFn/applyToHelper
>>   AFn.java:  144  clojure.lang.AFn/applyTo
>>  Compiler.java: 3623 
>>  clojure.lang.Compiler$InvokeExpr/eval
>>  Compiler.java:  439  clojure.lang.Compiler$DefExpr/eval
>>  Compiler.java: 6787  clojure.lang.Compiler/eval
>>  Compiler.java: 6745  clojure.lang.Compiler/eval
>>   core.clj: 3081  clojure.core/eval
>>   main.clj:  240  clojure.main/repl/read-eval-print/fn
>>   main.clj:  240  clojure.main/repl/read-eval-print
>>   main.clj:  258  clojure.main/repl/fn
>>   main.clj:  258  clojure.main/repl
>>RestFn.java: 1523  clojure.lang.RestFn/invoke
>> interruptible_eval.clj:   58 
>>  clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn
>>   AFn.java:  152  clojure.lang.AFn/applyToHelper
>>   AFn.java:  144  clojure.lang.AFn/applyTo
>>   core.clj:  630  clojure.core/apply
>>   core.clj: 1868  clojure.core/with-bindings*
>>RestFn.java:  425  clojure.lang.RestFn/invoke
>> interruptible_eval.clj:   56 
>>  clojure.tools.nrepl.middleware.interruptible-eval/evaluate
>> interruptible_eval.clj:  191 
>>  clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
>> interruptible_eval.clj:  159 
>>  clojure.tools.nrepl.middleware.interruptible-eval/run-next/fn
>>   AFn.java:   22  clojure.lang.AFn/run
>>ThreadPoolExecutor.java: 1142 
>>  java.util.concurrent.ThreadPoolExecutor/runWorker
>>ThreadPoolExecutor.java:  617 
>>  java.util.concurrent.ThreadPoolExecutor$Worker/run
>>Thread.java:  745  

Re: Duplicate key exception reading map that was written to a file

2015-11-25 Thread Ghadi Shayban
Does the phrases value in memory exactly match the payload roundtripped through 
Avro?

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

2015-11-22 Thread Ghadi Shayban
Not possible.  A type/record should not implement a protocol incompletely 
(though the compiler won't bark at you).  It can be an indication that the 
protocol is too large/ill-conceived.

Inspecting types is antithetical to using protocols...

On Sunday, November 22, 2015 at 2:28:07 PM UTC-5, Timur wrote:
>
> Hi,
>
> A record realizes a protocol but does not implement all functions of it. 
> Is there a function to find out if a specific one is implemented or not?
>
> Simple example:
>
> (defprotocol IPro
>(fn1 [_] )
>(fn2 [_] ))
>
>
> (defrecord MyRecord []
>IPro
>(fn1 [_] "Test1|))
>
> I want to check if MyRecord realizes fn2 or not. 
>

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


Re: [ANN] pex, a powerful PEG parsing library

2015-11-20 Thread Ghadi Shayban
The performance baseline was a pleasant surprise, but does get me thinking: 
How complex is Jackson?  It's thousands of lines of code.  I know I just 
wrote this library to help avoid writing recursive descent parsers 
manually, but maybe for JSON specifically an approach like Go's scanner [1] 
is worth pursuing in Java.

As for Pex itself, lots of areas of potential optimization:
1) Better char matchers -- like int-mask based ones.  Initial profiling 
suggested this.
2) Perhaps aggressive inlining of rules
3) Find out what Roberto Ierusalimschy did when he built a JIT for LPEG. 
 He said it improved perf by 3x, but it's not in mainline.
4) Implement the TestChar and TestCharset bytecodes from the LPEG paper -- 
I have the AST to be able to do it.  (It helps prevent call stack churn 
when you immediately jump into a rule and then fail because the first char 
doesn't match.)  There is a valuable match capture optimization to perform 
too.
5) Perhaps tear apart the StackEntry object into int[].  VM debugging was 
such a PITA, I would have never finished it if I did that at the outset.

[1] https://github.com/golang/go/blob/master/src/encoding/json/scanner.go

On Thursday, November 19, 2015 at 3:58:47 PM UTC-5, Colin Fleming wrote:
>
> I'm really impressed by how fast it is out of the box with basically no 
> optimisations. Tatu Saloranta is fanatical about Jackson performance, 
> getting to within 6x on the first attempt is very promising.
>
> On 20 November 2015 at 02:43, Ghadi Shayban <gsha...@gmail.com 
> > wrote:
>
>> Thanks for taking a look.
>>
>> User-level bytecode allows me an easier choice to build a JIT or tracing 
>> infrastructure, while being far less complex than writing out JVM bytecode 
>> during grammar compile.
>>
>> Christophe has certainly been a help offline with design choices.  I 
>> wanted PEG, no ambiguity, unlike instaparse or parsnip.  Most of the API 
>> inspiration was from LPEG & Scala's Parboiled2.  Some of the VM internals 
>> are close to JRuby's Joni regex engine.
>>
>>
>>
>> On Thursday, November 19, 2015 at 8:24:37 AM UTC-5, bernardH wrote:
>>>
>>> This is interesting !
>>> It reminds me of Parsnip from C.Grand [0], have you considered it when 
>>> desining pex ? As your parser is focusing of characters, I am wondering : 
>>> could the operations triggered by the execution of your pex code be simple 
>>> enough to warrant actual compiling to JVM bytecode (at run time, with ASM 
>>> [1]) for maximum performance ?
>>>
>>> Best Regards,
>>>
>>> Bernard
>>>
>>> [0] https://github.com/cgrand/parsnip/
>>> [1] http://asm.ow2.org/
>>>
>>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

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


Re: [ANN] pex, a powerful PEG parsing library

2015-11-19 Thread Ghadi Shayban
Thanks for taking a look.

User-level bytecode allows me an easier choice to build a JIT or tracing 
infrastructure, while being far less complex than writing out JVM bytecode 
during grammar compile.

Christophe has certainly been a help offline with design choices.  I wanted 
PEG, no ambiguity, unlike instaparse or parsnip.  Most of the API 
inspiration was from LPEG & Scala's Parboiled2.  Some of the VM internals 
are close to JRuby's Joni regex engine.


On Thursday, November 19, 2015 at 8:24:37 AM UTC-5, bernardH wrote:
>
> This is interesting !
> It reminds me of Parsnip from C.Grand [0], have you considered it when 
> desining pex ? As your parser is focusing of characters, I am wondering : 
> could the operations triggered by the execution of your pex code be simple 
> enough to warrant actual compiling to JVM bytecode (at run time, with ASM 
> [1]) for maximum performance ?
>
> Best Regards,
>
> Bernard
>
> [0] https://github.com/cgrand/parsnip/
> [1] http://asm.ow2.org/
>
>

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


[ANN] pex, a powerful PEG parsing library

2015-11-16 Thread Ghadi Shayban
Here is a compliant JSON parser in 99 LOC, implemented with *pex, a new 
parsing library*. [1]

This is alpha software.

Hot off the heels of Colin Fleming's Conj talk on PEGs [2], I'm making 
public an early version of pex [3], a parsing library in the PEG family. 
 For those of you familiar with Lua's LPEG library, this is similar, but 
with a Clojure-y twist.  Like LPEG, pex uses a virtual machine to parse 
rules (as opposed to combinators or packrat.)  Unlike Colin's talk, pex 
operates on traditional character types, not generic sequences/data 
structures.

Why? Parsing Expression Grammars are simpler than most other grammar types, 
but more powerful than regular expressions. They do not introduce ambiguity 
-- you get one valid parse or none.  There exists a nice space *in between 
regexes (yuck) and **instaparse (power but ambiguity)*.

Here is a tiny *example* grammar to match floating point numbers:

(def Number '{number  [digits (? fractional) (? exponent)]
  fractional ["." digits]
  exponent   ["e" (? (/ "+" "-")) digits]
  digits [(class num) (* (class num))]})

The only other input this particular grammar needs is to let pex know what 
a `num` character class is.  (There is an interface that you can implement 
to match things, and several helpers.  I'm planning to have several common 
ones out of the box.)  Well, you also need to tell the grammar compiler 
what rule to start with (number).

The grammar format has user defined *macros* which let you hide a lot of 
boilerplate, or make higher order rules.  For example, it's very common to 
chew whitespace after rules, so hiding that is useful.  There are also 
*captures* and *actions* that operate on a virtual "Value Stack".  For 
example, while parsing a JSON array, you push all the captured values from 
the array onto the stack, then reduce them into a vector with an action.

It's very early, but pex's completely unoptimized engine can parse a 1.5MB 
file in ~58ms vs ~9ms for Cheshire/Jackson, which is a handwritten 
highly-tuned parser with many thousands of lines of code behind it.  I plan 
on closing that gap by a) implementing some of LPEG's compiler 
optimizations and b) improving some of the terribly naive impls in the 
parser. The win here is *high expressive power per unit of performance*, 
not raw performance... 

Internally, the grammar data structure is analyzed, compiled into special 
parsing bytecode, and then subsequently run inside a virtual machine [4].

Hope you can find this useful in your data munging endeavors.  Next up is 
to make CSV & EDN example parsers, tune the performance, make grammar 
debugging better, and write more docs & tests.  I encourage any feedback.

[1] 
https://github.com/ghadishayban/pex/blob/master/src/com/champbacon/pex/examples/json.clj#L7-L39
[2] https://www.youtube.com/watch?v=kt4haSH2xcs
[3] https://github.com/ghadishayban/pex
[4] 
https://github.com/ghadishayban/pex/blob/master/src-java/com/champbacon/pex/impl/PEGByteCodeVM.java#L247-L280

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

2015-11-10 Thread Ghadi Shayban
Never mind the first point.  I've been pointed to the fact that 
Tuple/create returns a PV [1]

[1] 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Tuple.java#L22

On Tuesday, November 10, 2015 at 1:15:44 PM UTC-5, Ghadi Shayban wrote:
>
> Two points of feedback:
>
>
> 1) One of the reason tuples were disabled was that they polluted dispatch 
> paths.  Shouldn't we make sure that they are completely inactive?
>
>Map entries (everywhere: c.l.Persistent*, records, gvec, bean) still 
> use them.
>
> 2) I get the rationale behind direct linking, but I'm lacking evidence 
> that the benefits are achieved.
>
>
>
> On Tuesday, November 10, 2015 at 12:30:47 PM UTC-5, Alex Miller wrote:
>>
>> Clojure 1.8.0-RC1 is now available. *This build is a "release 
>> candidate"!* We would appreciate any and all testing you can do on your 
>> own libraries or internal projects to find problems. If no problems are 
>> found, we expect to make this the 1.8.0 final release! 
>>
>> Try it via
>>
>>- Download: 
>>https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0-RC1
>>- Leiningen: [org.clojure/clojure "1.8.0-RC1"]
>>
>> Below is the only change since 1.8.0-beta2. See the full 1.8 change log 
>> here: https://github.com/clojure/clojure/blob/master/changes.md.
>>
>>- CLJ-1845 <http://dev.clojure.org/jira/browse/CLJ-1845> Make 
>>clojure.core/load dynamic so it can be redef'ed even with direct linking
>>
>>
>>

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

2015-11-10 Thread Ghadi Shayban
Two points of feedback:


1) One of the reason tuples were disabled was that they polluted dispatch 
paths.  Shouldn't we make sure that they are completely inactive?

   Map entries (everywhere: c.l.Persistent*, records, gvec, bean) still use 
them.

2) I get the rationale behind direct linking, but I'm lacking evidence that 
the benefits are achieved.



On Tuesday, November 10, 2015 at 12:30:47 PM UTC-5, Alex Miller wrote:
>
> Clojure 1.8.0-RC1 is now available. *This build is a "release candidate"!* 
> We would appreciate any and all testing you can do on your own libraries or 
> internal projects to find problems. If no problems are found, we expect to 
> make this the 1.8.0 final release! 
>
> Try it via
>
>- Download: 
>https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0-RC1
>- Leiningen: [org.clojure/clojure "1.8.0-RC1"]
>
> Below is the only change since 1.8.0-beta2. See the full 1.8 change log 
> here: https://github.com/clojure/clojure/blob/master/changes.md.
>
>- CLJ-1845  Make 
>clojure.core/load dynamic so it can be redef'ed even with direct linking
>
>
>

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

2015-10-14 Thread Ghadi Shayban
Marc,
Any changes up or down in run-time performance (post-startup)?

On Wednesday, October 14, 2015 at 5:11:20 PM UTC-4, Marc O'Morain wrote:
>
> I just ran the CircleCI code-base under 1.8 beta 1 to see if there were 
> any gains in compile time (which is in the region of 90 seconds for our 
> main app). The clj-ssh issue was the only third-party lib that didn't work.
>
> Here is our compile time on Clojure 1.7 and 1.8:
>
> Clojure 1.7:
> real 1m30.622s user 1m32.535s sys 0m4.182s
> real 1m33.238s user 1m36.139s sys 0m4.381s
>
> Clojure 1.8 beta 1:
> real 1m31.001s user 1m41.139s sys 0m4.432s
> real 1m34.107s user 1m42.723s sys 0m4.742s
>
> Marc
>
>
> On 14 October 2015 at 20:56, Mike Rodriguez  > wrote:
>
>> Just a heads up, I tried upliftign to Clojure 1.8.0-beta1 today and had a 
>> failure that is originating from potemkin "0.4.1".  I think the issue may 
>> be in its dependent project riddley "0.1.10".
>> I logged an issue there at https://github.com/ztellman/riddley/issues/18.
>>
>> I haven't tracked down the cause of this problem right now.  I figure 
>> this may affect more people though, since I often read of people using 
>> potemkin in their projects.  These issues didn't seem to exists when I ran 
>> against some older potemkin versions (e.g. "0.3.2" was my test case).
>>
>> On Tuesday, October 13, 2015 at 9:01:06 AM UTC-5, Alex Miller wrote:
>>>
>>> Clojure 1.8.0-beta1 is now available.
>>>
>>> Try it via
>>>
>>>- Download: 
>>>https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0-beta1
>>>- Leiningen: [org.clojure/clojure "1.8.0-beta1"]
>>>
>>> Below is a list of the other changes included in beta1. See the full 
>>> change log here: 
>>> https://github.com/clojure/clojure/blob/master/changes.md.
>>>
>>>
>>>- CLJ-1456  Compiler 
>>>now errors if too few or too many arguments to throw
>>>- CLJ-1282  quote now 
>>>throws if passed more or less than one arg
>>>- CLJ-1210  Improved 
>>>error message for (clojure.java.io/reader nil)
>>>- CLJ-1414  sort and 
>>>sort-by now indicate sort is stable in docstring
>>>- CLJ-1765  areduce 
>>>performance improvements
>>>- CLJ-1724  Remove 
>>>unnecessary call to seq() in LazySeq.hashCode()
>>>- CLJ-1295  Improved 
>>>array-map dissoc performance
>>>- CLJ-1277  Speed up 
>>>printing of time instants with type hints
>>>- CLJ-1259  Speed up 
>>>pprint and cl-format with type hints
>>>- CLJ-668  Improve slurp 
>>>performance by using StringWriter and jio/copy
>>>- CLJ-1810  ATransientMap 
>>>now marked public
>>>- CLJ-1653  str of an 
>>>empty list should be "()"
>>>- CLJ-1567  Removed 
>>>unused local in condp implementation
>>>- CLJ-1351  Unused 
>>>swapThunk method was being emitted for fns with keyword callsites
>>>- CLJ-1329  Removed 
>>>unused local in PersistentVector.cons()
>>>- CLJ-1380  3-arg 
>>>ExceptionInfo constructor permitted nil data
>>>- CLJ-1226  set! of a 
>>>deftype field using field-access syntax caused ClassCastException
>>>
>>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

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

Re: JDK versions for clojure 1.7

2015-10-02 Thread Ghadi Shayban
1.6 and later.

On Friday, October 2, 2015 at 8:12:58 PM UTC-4, webber wrote:
>
> Hi,
>
> I'd like to ask a question.
> Which versions of JDK does Clojure 1.7 support ?
>
> 1.6 or later, 1.7 or later ?
>
> Thanks,
> MH
>
>

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

2015-06-30 Thread Ghadi Shayban
The example is wrong.  There are now two flavors of support for reduce 
through interfaces, IReduce and IReduceInit.  The first one allows you to 
call reduce without an initial value.  Eduction doesn't support that 
interface, but only IReduceInit.  Reduce without an initial value is now 
discouraged.

On Tuesday, June 30, 2015 at 1:04:20 PM UTC-4, Вук Мировић wrote:

 As Clojure 1.7 is finally released, I tried to wet my feet with 
 transducers. 
 I tried eduction example from official site http://clojure.org/transducers 
 http://www.google.com/url?q=http%3A%2F%2Fclojure.org%2Ftransducerssa=Dsntz=1usg=AFQjCNGAIDS1RcAkD0WaPpJg2sgEoA4Suw
  
 but it's not working:

 user= (def xf (comp (filter odd?) (map inc)))
 #'user/xf
 user= (def iter (eduction xf (range 5)))
 #'user/iter
 user= (reduce + iter)
 ClassCastException clojure.core.Eduction cannot be cast to 
 clojure.lang.IReduce 
  clojure.core.protocols/fn--6502 (protocols.clj:75)
 ;; 6 expected

 But

 user= (reduce + 0 iter)
 6

 So is example wrong or this is a bug?


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

2015-06-23 Thread Ghadi Shayban
Good question.

Clojure's evaluation semantics dictate that the arguments are evaluated 
(computed) *before* calling the function. So(set coll) is computed before 
being passed to `partial`.  Partial receives a function (a value) and 
arguments (also values) and returns back a new function that saves those 
original arguments (which happen to be stuffed away in Java final fields).

All three of your filters return a transducer.  All three of the inputs to 
`remove` are a partial function.  Each of the arguments to the call to 
partial is a set.  They are all essentially equivalent, and should perform 
the same.  (Except filter3 happens to create the set twice; once in the 
let, and once as the arg to partial).  So over a billion item collection, 
the set in your examples will only be computed once, once, and twice 
respectively.

Note however that sets *are* functions that evaluate whether the argument 
is in the set. This means you could remove the call to partial and shorten 
to:

(defn filter-contains1 [edn-file]
  (remove (set (read-edn-file edn-file


Tangentially:
(remove even?)
Will be faster than
(remove (fn [i] (even? i)))
because in the first case the dereference of the var 'even?' happens only 
once and the value inside the var will be passed to `remove` at the outset. 
 In the second example the var dereference happens for every single item 
(though it's very cheap).  The second example is equivalent to writing (remove 
#'even?)

On Tuesday, June 23, 2015 at 6:07:06 PM UTC-4, Sam Raker wrote:

 Let's say that, as part of an xf, I want to filter out everything in a 
 sequence that's also in some other sequence. Here are some ways of doing 
 that:

 (defn filter-contains1 [edn-file] (remove (partial contains? (set (read-
 edn-file edn-file)

 (defn filter-contains2 [coll] (remove (partial contains? (set coll

 (def filter-contains3 [coll] (let [coll-as-set (set coll)] (remove (
 partial contains? (set coll)

 I have the strong suspicion that `filter-contains3` is the best of the 3, 
 and `filter-contains1` the worst. The internal mechanics of transduce are a 
 bit of a mystery to me, however: if `filter-contains2` were to be used on a 
 collection of, say, a million items, would `coll` be cast to a set a 
 million times, or is Clojure/the JVM smarter than that? I'm also wondering 
 if anyone has any best practices (or whatever) they can share relating to 
 this kind of intersection of transducers/xfs and closures. It seems to me, 
 for example, that something like

 (defn my-thing [coll  stuff]
   (let [s (set coll)]
   ...
   (comp
 ...
(map foo)
(filter bar)
(remove (partial contains? s))
...

 is awkward, but that a lot of limited-use transducer factory functions 
 (like the ones above) aren't exactly optimal, either.


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

2015-05-22 Thread Ghadi Shayban
This commit [1] for CLJ-1589 changed dispatch for InternalReduce, causing a 
bug similar to CLJ-1237 [2].

[1] 
https://github.com/clojure/clojure/commit/1242c4878f3d4ef30535a22f6c74144637504fbe
[2] http://dev.clojure.org/jira/browse/CLJ-1237

On Friday, May 22, 2015 at 5:01:25 PM UTC-4, Jason Wolfe wrote:

 Just deployed to our staging environment and ran into an unexpected stack 
 overflow error.  Here's a reduced test case:
  
 user (- (range 1) (mapcat (fn [_] (java.util.ArrayList. (range 
 10 (reduce (constantly nil)))

 java.lang.StackOverflowError: 
RT.java:509 clojure.lang.RT.seq
   core.clj:135 clojure.core/seq
   core.clj:698 clojure.core/concat[fn]
LazySeq.java:40 clojure.lang.LazySeq.sval
LazySeq.java:49 clojure.lang.LazySeq.seq
ChunkedCons.java:59 clojure.lang.ChunkedCons.chunkedNext
   core.clj:671 clojure.core/chunk-next
  protocols.clj:119 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:152 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:122 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:152 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:122 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:152 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:122 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:152 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
   protocols.clj:31 clojure.core.protocols/seq-reduce
   protocols.clj:75 clojure.core.protocols/fn
   protocols.clj:13 clojure.core.protocols/fn[fn]
  protocols.clj:122 clojure.core.protocols/fn
   protocols.clj:19 clojure.core.protocols/fn[fn]
 

 On Thursday, May 21, 2015 at 9:31:08 AM UTC-7, Alex Miller wrote:

 Clojure 1.7.0-RC1 is now available.

 Try it via
 - Download: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-RC1/
 - Leiningen: [org.clojure/clojure 1.7.0-RC1]

 The only change since 1.7.0-beta3 is CLJ-1706, which makes reader 
 conditional splicing an error at the top level (previously it would 
 silently drop all but the first spliced element).

 For a full list of changes since 1.6.0, see:
 https://github.com/clojure/clojure/blob/master/changes.md

 Please give it a try and let us know if things are working (or not). The 
 more and quicker feedback we get, the sooner we can release 1.7.0 final!

 - 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: [CFP] JavaOne - Clojure submissions welcomed and recommended

2015-05-04 Thread Ghadi Shayban
Just as a (final) reminder, the CFP ends Wednesday night!

https://www.oracle.com/javaone/call-for-proposals.html


On Thursday, March 26, 2015 at 2:56:50 PM UTC-4, Ghadi Shayban wrote:

 Clojurists,
 The JavaOne conference, a huge gathering, is taking place in San Francisco 
 on October 25-29th.  The Call for Proposals is now open [1], and I 
 encourage you to submit a proposal related to Clojure.  There are many 
 different tracks and session formats available.  Specifically of interest 
 to you though:

 *Java and Emerging Languages*

 The languages track reviewers will be especially interested in submissions 
 that deal with new thoughts and experiments, rather than the typical 
 introduction to my cool language topics. Think, for example, of how the 
 language integrates with other technologies and what it has to offer to the 
 current hot topics in the programming scene.


 I've seen many wonderful presentations and speakers at previous Clojure 
 conferences, and many things that fit this bill, so propose something!

 Please contact speaker-services...@oracle.com (or me) if you have any 
 questions regarding the CFP.

 [1] https://www.oracle.com/javaone/call-for-proposals.html#general


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


[CFP] JavaOne - Clojure submissions welcomed and recommended

2015-03-26 Thread Ghadi Shayban
Clojurists,
The JavaOne conference, a huge gathering, is taking place in San Francisco 
on October 25-29th.  The Call for Proposals is now open [1], and I 
encourage you to submit a proposal related to Clojure.  There are many 
different tracks and session formats available.  Specifically of interest 
to you though:

*Java and Emerging Languages*

The languages track reviewers will be especially interested in submissions 
that deal with new thoughts and experiments, rather than the typical 
introduction to my cool language topics. Think, for example, of how the 
language integrates with other technologies and what it has to offer to the 
current hot topics in the programming scene.


I've seen many wonderful presentations and speakers at previous Clojure 
conferences, and many things that fit this bill, so propose something!

Please contact speaker-services...@oracle.com (or me) if you have any 
questions regarding the CFP.

[1] https://www.oracle.com/javaone/call-for-proposals.html#general

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

2015-01-22 Thread Ghadi Shayban
Protocol call sites build an inline cache to optimize dispatch.  The 
benchmark is running many times and reaping benefit from the cache. 
 satisfies? looks up the object's class in the protocol's implementation 
map [1], and the benchmark is stressing this.  You'll see that code checks 
if the protocol has the backing interface first, then checks for the 
object's class, then if necessary walks up the superclass chain.

[1] 
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L507-L516



On Thursday, January 22, 2015 at 8:36:23 PM UTC-5, Michael Blume wrote:

 Extends seems to be defeated by superclassing. ie:

 (extends? my-protocol (class {})) = false

 because my-protocol is extended to IPersistentMap and (class {}) isn't 
 IPersistentMap it's PersistentArrayMap (which implements IPersistentMap but 
 extends? doesn't care)

 On Thu Jan 22 2015 at 5:28:30 PM Timothy Baldridge tbald...@gmail.com 
 javascript: wrote:

 The logic of extends? is much simpler, so try that. IIRC it's something 
 like extends? returns true if any method on the protocol is implemented by 
 x, satisfies? returns true if all methods of a protocol are implemented 
 by x. 

 The docs don't seem to give much help here, so play with it in the repl a 
 bit. 

 Timothy

 On Thu, Jan 22, 2015 at 6:14 PM, Michael Blume blume...@gmail.com 
 javascript: wrote:

 (defprotocol my-protocol
   (foo [this]))

 (extend-protocol my-protocol
   clojure.lang.IPersistentMap
   (foo [this] hello from map))

 (criterium.core/quick-bench
   (satisfies? my-protocol {}))

 (criterium.core/quick-bench
   (foo {}))

 Simply calling foo on an empty map takes 7 ns,
 but checking whether the map satisfies my-protocol takes 22 µs, 3000 
 times longer.

 It seems like to call foo, some mechanism has to look up an 
 implementation of my-protocol for maps -- how is it we can do that so 
 quickly for a call and so slowly for satisfies?

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




 -- 
 “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 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: Satisfies? seems strangely slow

2015-01-22 Thread Ghadi Shayban
Clojure is caching protocol implementations explicitly with extra 
bytecodes, not the JVM.  And it is very efficient.

I don't think satisfies? is worth optimizing as using ton of it seems 
antithetical to protocols.  It signals to me that a caller does in fact 
care about the implementation, whereas protocols are about not caring. 
 Like your PR, if you want to ensure a protocol's coverage, you can also 
extend a protocol to Object and/or nil.  Not sure what a valid use case 
would be for calling satisfies? on a hot path would be.

On Thursday, January 22, 2015 at 11:46:02 PM UTC-5, Michael Blume wrote:

 Wait isn't this caching? 
 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L480

 On Thu Jan 22 2015 at 8:44:09 PM Bobby Eickhoff beic...@gmail.com 
 javascript: wrote:

 Clojure isn't doing the caching.  The JVM is doing the caching.  In this 
 case, Clojure just has mechanical sympathy for how the JVM operates.


 On Thursday, January 22, 2015 at 11:10:56 PM UTC-5, Michael Blume wrote:

 It sounds like basically dispatch is fast because we bothered to make it 
 fast (by caching) and satisfies? is slow because we didn't. Is it worth 
 throwing caching at satisfies? to make it fast or should satisfies? just 
 not be on the critical path for Clojure code?

 (To give a motivating example, satisfies? is on the critical path for 
 honeysql and will be until this pull is merged: https://github.com/
 jkk/honeysql/pull/38)


 On Thu Jan 22 2015 at 5:52:13 PM Ghadi Shayban gsha...@gmail.com 
 wrote:

 Protocol call sites build an inline cache to optimize dispatch.  The 
 benchmark is running many times and reaping benefit from the cache. 
  satisfies? looks up the object's class in the protocol's implementation 
 map [1], and the benchmark is stressing this.  You'll see that code checks 
 if the protocol has the backing interface first, then checks for the 
 object's class, then if necessary walks up the superclass chain.

 [1] https://github.com/clojure/clojure/blob/master/
 src/clj/clojure/core_deftype.clj#L507-L516



 On Thursday, January 22, 2015 at 8:36:23 PM UTC-5, Michael Blume wrote:

 Extends seems to be defeated by superclassing. ie:

 (extends? my-protocol (class {})) = false

 because my-protocol is extended to IPersistentMap and (class {}) isn't 
 IPersistentMap it's PersistentArrayMap (which implements IPersistentMap 
 but 
 extends? doesn't care)

 On Thu Jan 22 2015 at 5:28:30 PM Timothy Baldridge tbald...@gmail.com 
 wrote:

 The logic of extends? is much simpler, so try that. IIRC it's something 
 like extends? returns true if any method on the protocol is implemented 
 by 
 x, satisfies? returns true if all methods of a protocol are 
 implemented 
 by x. 

 The docs don't seem to give much help here, so play with it in the 
 repl a bit. 

 Timothy

 On Thu, Jan 22, 2015 at 6:14 PM, Michael Blume blume...@gmail.com 
 wrote:

 (defprotocol my-protocol
   (foo [this]))

 (extend-protocol my-protocol
   clojure.lang.IPersistentMap
   (foo [this] hello from map))

 (criterium.core/quick-bench
   (satisfies? my-protocol {}))

 (criterium.core/quick-bench
   (foo {}))

 Simply calling foo on an empty map takes 7 ns,
 but checking whether the map satisfies my-protocol takes 22 µs, 3000 
 times longer.

 It seems like to call foo, some mechanism has to look up an 
 implementation of my-protocol for maps -- how is it we can do that so 
 quickly for a call and so slowly for satisfies?

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.

 To post to this group, send email to clo...@googlegroups.com


 Note that posts from new members are moderated - please be patient 
 with your first post.
 To unsubscribe from this group, send email to

 clojure+u...@googlegroups.com


 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.

 To unsubscribe from this group and stop receiving emails from it, 
 send an email to clojure+u...@googlegroups.com.


 For more options, visit https://groups.google.com/d/optout.




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

Re: Extend causes error in servlet container?

2015-01-06 Thread Ghadi Shayban
Btw, if you own the defrecord, extend a protocol to it directly in its 
definition, rather than in a separate extend or extend-protocol form. 
 Doing it inline makes the record implement the protocol's backing 
interface, which will be much more efficient. (If it's not your record you 
don't really have a choice.)

(defrecord FooRecord [msg]
  FooProtocol
  (foo [_] ...))


On Tuesday, January 6, 2015 5:20:17 PM UTC-5, Michael Blume wrote:

 On further investigation, it looks like you're suffering from 
 http://dev.clojure.org/jira/browse/CLJ-979 -- if I apply the patch for 
 this bug to clojure and recompile your project everything works fine. It 
 looks like this patch *is* slated to make it into Clojure 1.7.0, so that 
 should also make your problem go away.

 On Tue Jan 06 2015 at 1:29:39 PM Michael Blume blume...@gmail.com 
 javascript: wrote:

 TL;DR: If you wait for that lein-ring pull to get merged, you can upgrade 
 lein-ring and your problem will go away. If you wait for Clojure 1.7.0 it's 
 possible your problem will go away, though I'm less confident here (the 
 current alpha doesn't have a fix). If you want your problem to go away 
 *right now* then you want your ring handler listed in your project.clj to 
 be in a namespace that *doesn't import any of the rest of your project*. 
 That's what 
 https://github.com/MichaelBlume/extend-test/blob/6a676e6e326a91a1003e76b219b94a2664175587/src/extend_test/core/shim.clj
  
 does. It has an initialize! function which, at run-time, rather than at 
 compile-time, manually imports your real handler and sticks it in an atom. 
 Then the handler exposed to ring just reads the real handler out of the 
 atom and applies it to the incoming request.


 On Tue Jan 06 2015 at 1:24:40 PM Michael Blume blume...@gmail.com 
 javascript: wrote:

 lein-ring uses AOT compilation to build war files. AOT compilation in 
 clojure is, well, problematic sometimes. Fortunately it can almost always 
 be avoided using clever indirection.

 For example: https://github.com/pdenhaan/extend-test/pull/1 builds a 
 war that works =)

 I've got a pull open against lein-ring that will use this trick by 
 default and avoid AOT in war builds, I'm hoping it'll get merged/released 
 soon.

 There's a couple open bugs in Clojure right now to do with AOT that have 
 patches that should land in 1.7.0. It's possible one of them will solve 
 your problem, I'm poking at them now to check.


 On Tue Jan 06 2015 at 8:08:41 AM peter@qficonsulting.com 
 javascript: wrote:

 I'm a relative newcomer to Clojure, and I'm puzzled by problems I have 
 using extend in a webapp. Any help would be hugely appreciated.

 My use case is basically this:

 (defrecord FooRecord [msg])


 (defprotocol FooProtocol
   (bar [foo] to use with extend-type))


 (extend FooRecord
   FooProtocol
   {:bar (fn [foo] (str Test  (:msg foo)))})

 I'm calling bar on a newly created FooRecord:

 (bar (-FooRecord Successful))

 This works in a REPL, and also works great in a web application on ring 
 server-headless:

 Test Successful


 But the moment I package the code in a war and deploy to Jetty 8 or 
 Tomcat 7, it fails:

 java.lang.IllegalArgumentException: No implementation of method: 
 :bar of protocol: #'extend-test.core.handler/FooProtocol found for 
 class: extend_test.core.handler.FooRecord
 clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:544)
 extend_test.core.handler$eval44$fn__45$G__35__50.invoke(hand
 ler.clj:8)
 extend_test.core.handler$fn__65.invoke(handler.clj:16)
 compojure.core$make_route$fn__1431.invoke(core.clj:104)
 ...


 I searched this group and the web for clues. It smells of a 
 classloading/aliasing problem, but I could not find any information to 
 indicate that this behaviour is expected when deploying to a servlet 
 container, or what I can do about it apart from avoid using extend.

 If you'd like to check out the full code or run it yourself, I've 
 created a Github project with a minimal test case 
 https://github.com/pdenhaan/extend-test.

 The problem has me altogether stumped for the moment. Thanks for 
 reading.

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

Playing around with transducers, what about the zero-arity of the reducing function

2014-09-16 Thread Ghadi Shayban
Call 'transduce without an init value, and it will use the 0-arity return as 
init.  Same for reduce but in different scenarios (some IReduce/CollReduce 
collections)

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

2014-09-16 Thread Ghadi Shayban
I was sloppy with details. A reducing function like f may be transformed though 
by a transducer (a priori), and a transducer must preserve the contract.

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

2014-09-16 Thread Ghadi Shayban
I was sloppy with details. A reducing function like f may be transformed though 
by a transducer (a priori), and a transducer must preserve the contract.

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

2014-09-14 Thread Ghadi Shayban
Nice useful demonstration, Stathis.  Thanks!

On Sunday, September 14, 2014 3:35:16 AM UTC-4, Stathis Sideris wrote:

 Hello all,

 There is some functionality in cider (C-c C-w) that can potentially save 
 you a lot of typing when transforming Clojure code and I haven't seen many 
 people using it, so I made a screencast to demonstrate:

 http://www.youtube.com/watch?v=LXhWW1Yqpt0

 Hopefully you'll find it useful.

 Thanks,

 Stathis



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

2014-09-08 Thread Ghadi Shayban
If anything let's add more bangs to the name. Unlike any of atom/ref/agent, 
volatile! is not really part of the familiar state model. Yes it applies 
a function to a thing, changing the thing.  Like Luc says, not atomically.

The linux hdparm tool has the –yes-i-know-what-i-am-doing and 
--please-destroy-my-drive flags. Those could be useful.  Maybe (binding 
[*please-randomly-break-my-application* true] ...)

On Monday, September 8, 2014 3:22:48 PM UTC-4, Luc wrote:

 +1 for the ! 

 No atomic changes here, no coordination whatsoever. 

 At the mercy of the caller... 

  I asked Rich and he said making a volatile is as dangerous as any ! 
 op. 
  
  Some people have also asked about vswap! being a macro instead of a 
 method 
  on Volatile. The issue there is that vswap! takes a variadic number of 
  update function args. If implemented as a method, you'd need to provide 
  multiple arities or eventually use apply (like in Atom's swap! 
  
 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L79)
  

  - doing it in a macro lets that expansion take place at compile time to 
  provide better performance without the apply. 
  
  
  
  
  
  On Mon, Sep 8, 2014 at 1:36 PM, Jozef Wagner jozef@gmail.com 
 javascript: wrote: 
  
   FYI the ticket about volatile is at 
   http://dev.clojure.org/jira/browse/CLJ-1512 and the same question was 
   raised there. 
   
   On Mon, Sep 8, 2014 at 4:25 PM, Frantisek Sodomka fsod...@gmail.com 
 javascript: 
   wrote: 
Hello, 
I posted a question about volatiles on the github commit: 

   
 https://github.com/clojure/clojure/commit/60440977823752f13a3fec3637538e9a1d68c5d4
  

I don't know if anybody noticed, so... why is volatile created with 
   function 
volatile! and not volatile ? Atoms, refs and agents don't have 
exclamation mark in their constructor functions. 

Should I think about volatiles as mutable locals?  :-) 

František 


On Friday, September 5, 2014 4:26:53 PM UTC+2, Alex Miller wrote: 

Clojure 1.7.0-alpha1 is now available. 

Try it via 
- Download: 
http://central.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ 
- Download securely: 
https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha2/ 
- Leiningen: [org.clojure/clojure 1.7.0-alpha2] 

Highlights below, full change log here: 
https://github.com/clojure/clojure/blob/master/changes.md 

For users of Clojure 1.7.0-alpha1, there have been a few important 
   changes 
in transducers since alpha1: 
- Removed flatmap transducer 
- Added cat transducer 
- mapcat 1-arity is now a transducer, specifically: (comp (map f) 
 cat) 
- The completing function has been lifted to be public 

Clojure 1.7.0-alpha2 has the changes below from 1.6.0: 

## 1 New and Improved Features 

### 1.1 Transducers 

Transducers is a new way to decouple algorithmic transformations 
 from 
their 
application in different contexts. Transducers are functions that 
transform 
reducing functions to build up a recipe for transformation. 

Also see: 
   http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming 

Many existing sequence functions now have a new arity (one fewer 
   argument 
than before). This arity will return a transducer that represents 
 the 
   same 
logic but is independent of lazy sequence processing. Functions 
 included 
are: 

* conj (conjs to []) 
* map 
* mapcat 
* filter 
* remove 
* take 
* take-while 
* drop 
* drop-while 
* cycle 
* take-nth 
* replace 
* partition-by 
* partition-all 
* keep 
* keep-indexed 

Additionally some new transducer functions have been added: 

* cat - concatenates the contents of each input 
* de-dupe - removes consecutive duplicated values 
* random-sample - returns items from coll with random probability 

And this function can be used to make completing transforms: 

* completing 

There are also several new or modified functions that can be used 
 to 
   apply 
transducers in different ways: 

* sequence - takes a transformation and a coll and produces a lazy 
 seq 
* transduce - reduce with a transformation (eager) 
* iteration - returns an iterable/seqable/reducible seq of 
 applications 
   of 
the transducer to items in coll. Applications are re-performed with 
   every 
iterator/seq/reduce. 
* run! - run the transformation for side effects on the collection 

There have been a number of internal changes to support 
 transducers: 

* volatiles - there are a new set of functions (volatile!, vswap!, 
vreset!, volatile?) to create and use volatile boxes to hold 
 state in 
stateful transducers. Volatiles are faster than atoms but give up 
   atomicity 

Re: Strange behavior with alts! and :default in core async

2014-08-14 Thread Ghadi Shayban
What Daniel said.  The call is incorrect, its args are alt-shaped, but it 
calls alt*s*.

alt is the macro that is shaped like cond.
alts is the function that takes a vector

Both take splatted options at the end.

Can never use single bang* except within go.*

go = !
thread = !!

Unfortunately if the two are confused, the exception will happen... 
probably elsewhere.

On Thursday, August 14, 2014 2:46:22 PM UTC-4, Eric Normand wrote:

 Hi there,

 The :default option is for a *value* that should be returned if none of 
 the channels are available. The expression is evaluated *before* the 
 async/alts! call happens (just like normal parameters).

 I think you are misunderstanding alts!. It should be used like this

 (let [[val ch] (async/alts! [[inner-chan e]] :default :default)]
   (if (= :default val)
 (println inner-chan was not ready)
 (if val
   (println did the put to inner-chan)
   (println inner-chan is closed

 I hope that helps. Let me know if you have any more questions.

 Eric

 On Thursday, August 14, 2014 11:03:01 AM UTC-5, dgrnbrg wrote:

 When I use alts!, it seems that both the put and :default action run 
 every time. I've included the code sample below:

 (let [inner-chan (async/chan (async/buffer 1000))
   mult (async/mult inner-chan)
   (async/thread
 (while true
   (let [e (.take linked-blocking-queue)]
 (async/alts!
   [[inner-chan e]] (println did the put)
   :default (println failed to put)
   :priority true)


 Elsewhere in the code, I tap the mult before I start putting elements 
 onto the linked-blocking-queue. For every element I put onto the LBQ, I see 
 both messages: did the put and failed to put. What is going on 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: Clojure 1.7 and invokeStatic

2014-08-06 Thread Ghadi Shayban
Var indirection is not super cheap, as it has a volatile field, which is a 
memory fence.  I have been working on Clojure with invokedynamic, and I 
have a demonstrable improvement on microbenchmarks.  Obviously your 
application will have IO and myriad other costs, but I just want to echo 
that it isn't a trivial cost.

On Wednesday, August 6, 2014 2:58:48 PM UTC-4, Mike Thvedt wrote:

 It's worth pointing out that var indirection is already cheap in Java--it 
 is generally dominated by IO, memory access, object construction, dynamic 
 dispatch... The JIT compiler will inline any var access if the var doesn't 
 visibly change, and only needs to check one word of memory per var each 
 time the JIT compiled function is invoked. I've replaced vars with Java 
 methods and found a 0% speedup.

 On Wednesday, August 6, 2014 5:54:32 AM UTC-5, Robin Heggelund Hansen 
 wrote:

 Just read this blog post about Oxen (
 http://arrdem.com/2014/08/05/of_oxen,_carts_and_ordering/?utm_source=dlvr.itutm_medium=twitter).
  
 In it is mentioned that Rich is re-introducing invokeStatic to achieve a 
 possible 10% performance increase for Clojure 1.7.

 I couldn't find any information about this. Anyone know where I can find 
 out more?



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

2014-06-10 Thread Ghadi Shayban
This is so cool and extremely useful.  Thank you so much for this!

Ghadi

On Tuesday, June 10, 2014 11:39:12 AM UTC-4, Francesco Bellomi wrote:

 Hello everyone,

 http://crossclj.info

 I've been working on CrossClj for some time now, and I feel it has grown 
 usable (and useful) enough to make a public announcement.

 CrossClj is a tool to explore the whole Clojure(-script) open-source 
 ecosystem as an interconnected codebase.

 The source code of Leiningen projects published as Clojars artifacts is 
 rendered as a hypertext; each var occurrence is linked to its definition 
 (namespaces belonging to different artifacts are resolved using maven 
 coordinates), and each reference to a method/class of the standard Java JDK 
 lib is linked to the Oracle documentation.

 Starting from a var definition, it is possible to list all the qualified 
 occurrences of the var across all the indexed projects; or it is possible 
 to search all namespaces in all projects for vars with a given name.

 A project should be automatically listed, provided that the following 
 conditions are met:
 - The project is deployed on Clojars under a public group (not a 
 org.clojars.* user group)
 - The project uses Leiningen and provides a project.clj with a description.
 - The project has at least one non-SHAPSHOT release.
 - Source code is incuded into project's artifact, and hosted publicly on 
 GitHub (i.e. there is a github reference on the project's POM under the url 
 or scm/connection fields). This almost ensures that the source code license 
 is compatible with CrossClj's usage.

 Some examples illustrating various features:


 http://crossclj.info/ns/org.clojure/tools.analyzer/0.2.1/clojure.tools.analyzer.html#_macroexpand
 http://crossclj.info/fun/clojure.core/reduce.html
 http://crossclj.info/search?q=map
 http://crossclj.info/ns/ring/ring-core/1.3.0/project.clj.html
 http://crossclj.info/ns/org.clojure/clojure/1.6.0/clojure.core.html
 http://crossclj.info/ns/garden/1.1.7/garden.stylesheet.cljs.html

 The cross-reference index and the website content is updated daily, by 
 looking at Clojars' feed (http://clojars.org/repo/feed.clj.gz), and by 
 fetching the new artifacts that match the above constraints. The impact in 
 terms of bandwidth is negligible.
 The update process is designed to be fully automated, but as of today it 
 is still initiated manually because there are some quality issues that 
 needs to be worked out.

 There are some scattered defects in the code analysis, due to my not yet 
 perfect use of the tools.analyzer.* toolchain. 
 Clojurescript macros definitions aren't yet cross-references.

 The fact that the open source Clojure ecosystem still has a manageable 
 size (about 3500 projects are indexed now) makes this kind of tools very 
 cheap to operate, and opens up many possibilities for the future, like 
 batch-executing other static analysis tools.

 Francesco Bellomi
 @fbellomi
 @crossclojure


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

2014-04-22 Thread Ghadi Shayban
Howdy Charles,
For a static mix of sources there's async/merge [1], and it behaves the 
almost exactly way you describe, impl here [2].

Stepping back, the source chan-of-chans being closed represents value 
production being fully in flight, while the merged channel being closed 
represents consumption being finished, and are distinctly different events 
w.r.t. this particular process.  Can you have the producer explicit for 
whoever is producing chans to signal explicitly, and for the consumer to 
consume the merge? If you want to terminate early upon the producer chan, 
listen to that explicit signal -- produced by some proc that has a more 
knowledge (! done)

I'm not sure that async/mix is the right abstraction for your stated needs 
because a mix doesn't terminate except when something closes the merged 
channel.  A mix is 'alive' even when there is nothing to read or nothing 
left to read (which is btw the initial state of all mixes), and contradicts 
the stated goal.  For your goal, just alts! on the input channel + the 
already read channels.

(defn merge-from-chan [input]
  (let [out (chan)]
(go-loop [reads [input]]
  (when (pos? (count reads))
(let [[v sc] (alts! reads)]
  (if (= input sc)
 (if (some? v)
   (recur (conj reads v))  ;; new source
   (recur (filterv #(not= input %) reads)))  ;; input done, 
take it out of action
 (if (some? v)  ;; value from elsewhere
(do (! output) (recur reads))
(recur (filterv #(not= sc %) reads))
out))

Hope this helps,

[1] https://clojure.github.io/core.async/#clojure.core.async/merge
[2] 
https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L931-L947

On Tuesday, April 22, 2014 5:35:24 PM UTC-4, Charles Duffy wrote:

 Howdy --

 Trying to use core.async's mix facility, one difficulty I've run into is 
 the lack of a means to close the output channel only after al inputs have 
 been exhausted. In the interim, I've ended up using the below instead -- 
 which lacks some of the facilities provided by the mix interface (muting, 
 pausing, soloing, etc), but has the advantage of cleanly closing its output 
 channel if and only if all inputs (including the channel from which other 
 channels are read) have been flushed.

 That said, looking at core.async's code, it certainly seems possible to 
 extend the mix abstraction to handle this use case -- for instance, adding 
 a (close-on-empty! [mix]) call which would set a flag causing the the 
 output channel to close whenever all inputs are unmixed, whether by user 
 interaction or end-of-input, would be another solution.

 Thoughts? Should I publish the below (and related tooling -- such as an 
 N-way split helper used to create such channels of channels) as a separate 
 library? Submit patches to core.async adding appropriate functionality to 
 the mix implementation? Or is there already a better way of achieving the 
 desired effect?

 Thanks!

 (defn merge-channels
   Given a channel which yields other channels, combine output from all of 
 these into a single output channel.

   Close output channel and exit when both the input channel and all 
 channels read from that channel have closed.
   [in-chan]
   (let [out-chan (chan)]
 (go
   (loop [open-channels #{}, in-chan-open? true]
 (let [all-chans (if in-chan-open?
   (conj open-channels in-chan)
   open-channels)
   [v c] (when-not (empty? all-chans) (alts! (vec all-chans)))]
   (cond

(empty? all-chans)
nil

(= c in-chan)
(if v
  (recur (conj open-channels v) true)
  (recur open-channels false))

(nil? v)
(do
  (recur (disj open-channels c) in-chan-open?))

:else
(do
  (! out-chan v)
  (recur open-channels in-chan-open?))
 out-chan))


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

2014-04-15 Thread Ghadi Shayban
Dredging this back up, you've read the scenario properly.  Timers are 
coalesced a particular resolution.

Use cases needing more than 1024 active handles on a channel can use a 
mult.  For example, if you had to timeout every request at a same time 
exactly 5 minutes in the future, (mult (timeout 30)) and then give 
every request a fresh tap of that.

The fixed 100 case I think you're getting lucky, whereas the random window 
you're getting unfavorable coalescing, which seems counterintuitive.


On Friday, March 28, 2014 9:52:47 AM UTC-4, Peter Taoussanis wrote:

 One thing I'm not clear on: if I've understood your explanation correctly, 
 I would expect the 100ms timeout to produce this error _more_ (not less) 
 often.

 So can I just confirm some things here?

 1. `async/timeout` calls can (always?) get cached to the nearest 
 TIMEOUT_RESOLUTION_MS.
 2. In this tight loop example, that means that `!` is sometimes getting 
 called against the same (cached) timeout channel.
 3. It's happening sufficiently often (do to the high loop count+speed) to 
 overflow the [unbuffered] timeout channel's implicit take buffer.

 Is that all right?

 If so, why isn't the fixed `(async/timeout 100)` channel producing the 
 same (or worse) behaviour? Is something preventing it from being cached in 
 the same way?


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


Re: Lazy evaluation

2014-04-01 Thread Ghadi Shayban
And Happy April Fools' everyone.  Nicely done Pradip.


On Tuesday, April 1, 2014 3:58:34 PM UTC-4, Jozef Wagner wrote:

 Reducers should be given IMO a more attention, support and importance and 
 I'm actually experimenting on a hypothesis that reducers can replace lazy 
 seqs in most cases (excluding simple stuff, e.g. destructuring). Imagine a 
 core API where functions like map, filter, rseq, range etc. are working 
 with reducers by default and falling back to seqs only in rare cases or by 
 explicit request.

 Jozef

 On Tuesday, April 1, 2014 9:28:49 PM UTC+2, tbc++ wrote:

 The question is replace them with what? I remember with not so fond 
 memories the days of using IEnumerable in C#, there was no immutability and 
 no caching. So if you created a massive chain of data and iterated over it 
 twice you would have to execute the entire chain of functions twice. With 
 LazySeqs the data would be evaluated once and the final result stored for 
 each iterator. 

 It's a trade off, but I'm constantly amazed at how wickedly fast LazySeqs 
 are. 

 Also, reducers are a good option when LazySeqs aren't fast enough. 

 Timothy


 On Tue, Apr 1, 2014 at 1:17 PM, Andy Fingerhut andy.fi...@gmail.comwrote:

 Back of the envelope meaning that you thought about the implementation 
 and are estimating, or you have measurements?

 Either way, I agree that there are definitely use cases where non-lazy 
 processing can give performance improvements.  Probably even relatively 
 common use cases.

 Cases where lazy sequences have advantages (not intended to be an 
 exhaustive list):

 + if you determine that you do not need the whole sequence, portions of 
 it need not be generated at all (perhaps large portions)

 + I do not have measurements for this use case to quantify the potential 
 performance benefits, but if you have a 'pipeline' of lazy operations, e.g. 
 a map on function f1 whose result is fed into a map on function f2, then a 
 filter on function f3, etc., the time order of execution will typically 
 have f1 called on an item in the sequence, then f2, then f3, etc., and only 
 after that is done will you go back and call f1, f2, f3, ... on the next 
 item of the original sequence.  There can be performance benefits from 
 keeping those intermediate results in a processor's cache while doing f1, 
 f2, f3, etc., rather than a whole pass of applying f1, then going back to 
 the beginning and doing a whole pass of f2, etc.  This is primarily an 
 issue with sequences that are large enough that they do not fit into the 
 cache.

 Andy



 On Tue, Apr 1, 2014 at 11:19 AM, Pradip Caulagi pra...@wwstay.comwrote:

 I am just a newbie who has been hanging around and it is rather late in 
 the day to bring this up but...

 should we remove lazy sequences and lazy evaluation from Clojure?  Back 
 of the envelope calculations show that we can get 2x performance 
 improvements.

 Thanks,
 Pradip

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


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




 -- 
 “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 the Google Groups 

Re: Porting parsley paredit.clj to Clojurescript: Crazy, or inevitable?

2014-04-01 Thread Ghadi Shayban
I can't speak to the implementation of any of this, but I have to link to a 
favorite demo [1] of structural editing.  The animations are really slick, 
but the way he's designed moving up and down the abstraction hierarchy is 
brilliant.  Cue an Emacs user telling me it's already possible with some 
elisp magic...

[1] https://www.youtube.com/watch?v=tztmgCcZaM4

On Tuesday, April 1, 2014 9:26:51 PM UTC-4, kovasb wrote:

 I really want legitimate paredit in the browser. 

 Looking through the source for parsley  paredit.clj, I'm halfway 
 convinced that maybe its not so hard to port these to clojurescript. 

 Anyone have input in either direction? 

 Most of the Java interop seems to be 
 1. ArrayList (in parsley) 
 2. Various string methods (.endsWith, .indexOf, etc) 
 3. Regular expressions 

 Is there something I'm missing that would require structural change? 


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

2014-03-23 Thread Ghadi Shayban
You've piqued my curiosity.  Could I trouble you to post the benchmark 
results on -RC2 with 96f5b5bdc reverted?


On Friday, March 21, 2014 7:47:00 PM UTC-4, Stefan Kamphausen wrote:



 On Saturday, March 22, 2014 12:41:55 AM UTC+1, Andy Fingerhut wrote:

 That is odd.  This is a shot in the dark, and probably unhelpful because 
 I do not know a good way to verify whether my guess is true, but perhaps 
 the seqFrom method went from being small enough to be inlined by your JIT 
 before that change, to being too large to consider for inlining after the 
 change?  It isn't a big change in the code, so it would have to have been 
 close to the threshold if this is true.


 if there is anything I can do to test this, just let me know.

 Best,
 stefan 


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

2014-03-11 Thread Ghadi Shayban
Comparing CSP and promises is apples-to-oranges.  I'd love to see a minimal 
sample of problematic code.

On Tuesday, March 11, 2014 1:39:54 PM UTC-4, Эльдар Габдуллин wrote:

 Each go block is executed via thread pool. On a channel side, producers 
 and consumers are also decoupled.
 Such decoupling costs around 10-20 us per async operation. For the cases 
 when your async
 values are immediately available (e.g. from cache), or when you designed 
 an async
 API just because your operations may block for a long but not necessary 
 do, those are huge numbers.

 For example, I recently worked on a dependency injection 
 containerhttps://github.com/dar-clojure/core which 
 supports async computations.
 Asynchrony in one place means that all you API will be async everywhere. 
 Natural way to go with implementation is to just
 wrap everything in a go block. However, after doing that I found that 
 container became 50 times slower. 5 us overhead for a
 typical task turned into 250 us.

 As a solution I forked https://github.com/dar-clojure/async core.async 
 and replaced channels with lightweight promises and removed thread pool 
 dispatch from
 everywhere. Now async container implementation is only 5 times slower than 
 its sync version, which is probably acceptable.

 I'd like to hear what others think about this issue, especially members of 
 the core team. 



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

2014-02-20 Thread Ghadi Shayban
Jules,
For recombination of parallel reductions into a vector, have you looked at 
foldcathttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L314-L318?
  
It works really well, and it's one of those wonderful gems in clojure.core 
waiting to be noticed.  It gives you back a structure that is counted, 
seqable, and re-foldable - which covers probably 99% of use cases.  The 
returned structure is not indexed, that is intentional.

It's definitely conceivable to have the equivalent of a 'transient merge' 
op for maps, and a design doc on clojure 
wikihttp://dev.clojure.org/dashboard.actionis definitely warranted.

I echo the recommendation for RRB-trees when you need efficient combination 
that returns an indexed structure.  If you don't, foldcat = delicious.  
Jean is right about the many ways a superstructure can degrade.

Ghadi

On Thursday, February 20, 2014 8:09:26 PM UTC-5, Jean Niklas L'orange wrote:

 Hi Jules,

 On Thursday, February 20, 2014 11:59:03 PM UTC+1, Jules wrote:

 Subvec provides a view on a subseq of a vector that behaves like a full 
 vector. Supervec provides a similar view that makes two vectors behave like 
 a single one


 This data structure (supervec) is usually known as a rope, and your 
 implementation degrades the *~O(1)* to worst case *O(k)* time for 
 lookups, assoc, conj and pop, where *k* is the amount of concatenations 
 performed. A good rope implementation can reduce that factor down to *O(log 
 k)* through balancing, but it will still break the performance guarantees 
 a persistent vector is supposed to have. If you try to use this in the 
 reducers library, the amount of concatenations fork/join performs might 
 actually show notable performance degradation for those operations. 
 Further, passing it around to code which might perform more concatenations 
 will lead to even worse performance, which may be hard to debug for people 
 not knowing Clojure internals.

 However, it is a very nice solution if you know there will be limited 
 concatenations, that the concatenations result in a balanced tree, and you 
 don't pass this vector around to other people. :)

 For a small discussion on this vs. RRB-trees, see Section 1.1 in 
 http://infoscience.epfl.ch/record/169879/files/RMTrees.pdf.

 Hopefully I'm not destroying your fun playing around with these 
 things—that is not the intent at all. I'm just saying that these things are 
 (sadly?) harder than it first looks like.

 -- JN


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


Re: ! on channels that are not yet closed

2014-01-14 Thread Ghadi Shayban
This code actually results in a subtle race condition as channels need to 
be locked internally.  It also won't work for other implementations of 
channel, of which there are several in core.async besides 
ManytoManyChannel. (For example, map returns a reified channel.)  Knowing 
whether a channel is closed at put-time (with some restrictions) is a 
current work item in core.async.


On Monday, January 13, 2014 5:12:58 AM UTC-5, t x wrote:

 (let [c (async/chan 10)]
   (println @(.-closed c))
   (async/close! c)
   (println @(.-closed c)))


 And we're done. Sorry for the spam. Last message send in case someone 
 finds my question via Google.


 On Mon, Jan 13, 2014 at 2:11 AM, t x txre...@gmail.com javascript:wrote:

 Is there anyway, to pierce the deftype


 https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/channels.clj#L31

 to read the closed field of the ManytoMany Channel?

 That's basically all I need to do.


 On Mon, Jan 13, 2014 at 1:47 AM, t x txre...@gmail.com javascript:wrote:

 Hi,

   I have the following problem:

   I have a set of channels #{ ... }

   some of the channels are closed, some of the channels are open

   * for the channels that are open, I want to (! chan msg)

   * for the channels that are closed, I want to remove the channel from 
 the hash-set


 ## Problems:

 (1) (! ... ...) always returns nil, regardless of whether the channel 
 is open or closed, and thus useless

 (2) I could use (! ... ) to read from the channel to see if it's nil, 
 but then would remove an item from the channel, which I don't want to do


 ## Question:

 Thus, without changing the state of the channel, is there a way to see 
 if the channel is open/closed?

 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/groups/opt_out.


Re: [ANN] Clojure.Joda-Time 0.1.0

2013-12-26 Thread Ghadi Shayban
I think your usage of simple check is interesting.  What bugs did 
simple-check find inside Joda and can you speak about that process in 
general?

On Wednesday, December 25, 2013 6:19:18 AM UTC-5, dm3 wrote:

 Hello,

 I would like to announce the first release of 
 Clojure.Joda-Timehttps://github.com/dm3/clojure.joda-time - 
 an ambitiously named wrapper for the Joda-Time date and time library.

 Main goals of Clojure.Joda-Time:

 * Provide a consistent API for common operations with instants, 
 date-times, periods, partials and intervals.
 * Provide an escape hatch from Joda types to clojure datastructures and 
 back where possible.
 * Avoid reflective calls (this is a problem, because many types in 
 Joda-Time have similar functionality hidden under similarly named and 
 overloaded methods with no common interfaces).
 * Provide an entry point into Joda-Time by freeing the user from importing 
 most of the Joda-Time classes.

 Compared to clj-time https://github.com/clj-time/clj-time, this library 
 is not DateTime-centric. If you tend to use local dates in most of your 
 projects, meaning you don't care about time zones, there's no purpose in 
 using DateTime at all. You should be using various Partials provided by 
 Joda-Time, most common being LocalDate and LocalDateTime. This also means 
 that date-times created through Clojure.Joda-Time are not converted to the 
 UTC timezone by default, as they are in clj-time.

 There's quite a comprehensive README on github: 
 https://github.com/dm3/clojure.joda-time
 as well as the API-docs: http://dm3.github.io/clojure.joda-time/

 This is pretty much an experiment, albeit a very elaborate one (and time 
 consuming). Feel free to suggest improvements/rant about deficiencies :)

 Fun facts:
 * first release may be treated as a Christmas present
 * while testing the library with simple-check ~10 bugs were identified 
 (most of them already fixed) in the Joda-Time itself
 * library contains an implementation partial intervals (e.g. interval of 
 LocalDates)


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


Re: What does IOC in terms of core.async mean?

2013-08-20 Thread Ghadi Shayban
A normal function just runs naturally through its code -- it can't 
abort/suspend/pause/defer evaluation. (Only the JVM or kernel can suspend 
things for you safely.) The inversion of control macros enable such 
capabilities for Clojure code while preserving normal semantics. It allows  
code to *yield* a thread to other code when a blocking channel operation is 
encountered [! ! alt!].  Now the specific *mechanism* that core.async 
uses internally to acheive this happens to be a state machine with 
callbacks, but that's implementation detail.

IOC just means letting something else control the evaluation of the 
function's code. There is an example of another simpler IOC controller in 
the core.async tests, called 'runner'.  Others are possible... preserving 
semantics is the key.

(ioc [Ordinary code can be written many ways, like in a haiku])
=
[[Ordinary code]
 [can be written many ways]
[like in a haiku]]

On Monday, August 19, 2013 6:42:01 AM UTC-4, Michal Till wrote:

 I kinda understand the whole problem and I also understand that this has 
 nothing to do with the OO IOC pattern, but I still don't exactly get what 
 is meant by this term. What is inverting what and where? What does 
 control refer to exactly - compared to callbacks?

 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, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: core.async: faulty rebinding of loop-bindings in go blocks

2013-08-03 Thread Ghadi Shayban
Fixed -- should make it to maven within an hour.

On Thursday, August 1, 2013 12:47:16 PM UTC-4, Ghadi Shayban wrote:

 It's a nasty bug, seems like a local symbol scope issue.  I will take a 
 look at it.  Thanks for the report.

 On Thursday, August 1, 2013 6:05:59 AM UTC-4, Kemar wrote:

 There seems to be an issue with the rebinding of loop-bindings using 
 loop/recur in go blocks,
 specifically when you are just changing the order of the original 
 bindings in a recur call.

 Take this snippet for example:


 (require '[clojure.core.async :refer [go timeout]])
 (go (loop [a :black, b :white]  
   (println a b)
   (! (timeout 1000))
   (recur b a)))


 Instead of repeatedly printing

 :black :white
 :white :black
 :black :white 
 :white :black
 (...)


  it actually prints

 :black :white
 :white :white
 :white :white
 :white :white
 (...)

  
 Note however, that 
  

 (require '[clojure.core.async :refer [go timeout]])
 (go (loop [a :black, b :white]  
   (println a b)
   (! (timeout 1000))
   (recur (identity b) (identity a


 works correctly.

 Any ideas as to what's causing this?


 Cheers,
 Kevin



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




Re: core.async: faulty rebinding of loop-bindings in go blocks

2013-08-01 Thread Ghadi Shayban
It's a nasty bug, seems like a local symbol scope issue.  I will take a 
look at it.  Thanks for the report.

On Thursday, August 1, 2013 6:05:59 AM UTC-4, Kemar wrote:

 There seems to be an issue with the rebinding of loop-bindings using 
 loop/recur in go blocks,
 specifically when you are just changing the order of the original bindings 
 in a recur call.

 Take this snippet for example:


 (require '[clojure.core.async :refer [go timeout]])
 (go (loop [a :black, b :white]  
   (println a b)
   (! (timeout 1000))
   (recur b a)))


 Instead of repeatedly printing

 :black :white
 :white :black
 :black :white 
 :white :black
 (...)


  it actually prints

 :black :white
 :white :white
 :white :white
 :white :white
 (...)

  
 Note however, that 
  

 (require '[clojure.core.async :refer [go timeout]])
 (go (loop [a :black, b :white]  
   (println a b)
   (! (timeout 1000))
   (recur (identity b) (identity a


 works correctly.

 Any ideas as to what's causing this?


 Cheers,
 Kevin



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




Re: invokedynamic instructions in Clojure

2013-04-17 Thread Ghadi Shayban
Brandon,
Not really, but I don't want to deter anyone from exploration as its own 
goal. There are a lot of interesting ways that Clojure can leverage indy, 
this was an experiment.  I'm going to try to put it in more high value 
places, and let the ideas marinate. This modification does nothing but 
actually use the instruction and pass all the tests. Obviously a lot of the 
really useful call sites for indy require much rework (and will break ABI 
and JVM compatibility, ick).  The microarchitecture of how a language 
runtime can interact with its host platform is fascinating to explore.
Btw, Attila Szegedi wrote the dynalink [1] library that has some 
abstractions over a lot of the machinery inside java.lang.invoke, 
definitely worth a look through.

I think that performance is something exciting for developers, and I think 
indy will help with that...eventually. This needs hammock time, Clojure is 
definitely not slow today.

[1] https://github.com/szegedi/dynalink/wiki/User-Guide-0.5

Ghadi
@smashthepast


On Tuesday, April 16, 2013 10:58:50 PM UTC-4, Brandon Bloom wrote:

 Do you have any measurements, results, or conclusions to report?

 On Tuesday, April 16, 2013 12:12:15 PM UTC-4, Ghadi Shayban wrote:

 I've added a very minimal usage of invokedynamic to the compiler.  
 Basically the smallest delta without having to change internals of ObjExpr 
 or break ABI compatibility.  This is minimal and raw.  There are many many 
 usages of indy that will really help the Clojure runtime, this ain't one of 
 them.  No benchmarks here, it's probably slower.

 In current Clojure mainline, a Fn has reference slots to any vars it 
 needs in its constant pool, like a cache. Anytime a non-dynamic Var's value 
 needs to be accessed, the Var goes from the constant pool to the stack, and 
 getRawRoot() is invoked on it.

 With this change, an invokedynamic instruction instead creates a 
 ConstantCallSite, which closes over a looked-up Var, and then binds the 
 call site to invoke getRawRoot() on it directly.  This is only for 
 non-dynamic Vars.

 Simple todos:
 cache the CallSite as a member on the Var itself so that all identical 
 indy lookup instructions have fast bootstrapping.
 emit a similar call for dynamic vars
 remove the emission of Vars into the constant pool of a class

 Lots of really interesting use cases for invokedynamic and all the 
 associated combinators in java.lang.invoke:

 Better protocol callsite caching
 CallSite middleware for things like CLJ specific instrumentation
 equality could be a special instruction
 KeywordCallSite could be its own instruction as well
 (apply) argument spreading/varargs array collection (through the 
 combinators)
 potentially removing IFn.invoke(*) and using MethodHandle invocation 
 instead (fat chance)

 You can pull down the changes at github.com/ghadishayban/clojure.
 mvn clean package, tested on OpenJDK 1.7



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




invokedynamic instructions in Clojure

2013-04-16 Thread Ghadi Shayban
I've added a very minimal usage of invokedynamic to the compiler.  
Basically the smallest delta without having to change internals of ObjExpr 
or break ABI compatibility.  This is minimal and raw.  There are many many 
usages of indy that will really help the Clojure runtime, this ain't one of 
them.  No benchmarks here, it's probably slower.

In current Clojure mainline, a Fn has reference slots to any vars it needs 
in its constant pool, like a cache. Anytime a non-dynamic Var's value needs 
to be accessed, the Var goes from the constant pool to the stack, and 
getRawRoot() is invoked on it.

With this change, an invokedynamic instruction instead creates a 
ConstantCallSite, which closes over a looked-up Var, and then binds the 
call site to invoke getRawRoot() on it directly.  This is only for 
non-dynamic Vars.

Simple todos:
cache the CallSite as a member on the Var itself so that all identical indy 
lookup instructions have fast bootstrapping.
emit a similar call for dynamic vars
remove the emission of Vars into the constant pool of a class

Lots of really interesting use cases for invokedynamic and all the 
associated combinators in java.lang.invoke:

Better protocol callsite caching
CallSite middleware for things like CLJ specific instrumentation
equality could be a special instruction
KeywordCallSite could be its own instruction as well
(apply) argument spreading/varargs array collection (through the 
combinators)
potentially removing IFn.invoke(*) and using MethodHandle invocation 
instead (fat chance)

You can pull down the changes at github.com/ghadishayban/clojure.
mvn clean package, tested on OpenJDK 1.7

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




Re: Clojure 1.5.1

2013-03-10 Thread Ghadi Shayban
fyi - Rich's .idea/ crept in on the bug fix commit.

On Sunday, March 10, 2013 8:35:34 PM UTC+2, Stuart Halloway wrote:

 Clojure 1.5.1 fixes a memory leak in Clojure 1.5, discussed here:

 https://groups.google.com/d/msg/clojure-dev/uAFM0Ti4AcQ/GmnKmphF1BgJ

 Getting Clojure:

   Web:  http://clojure.org/downloads
   Lein/Maven:   :dependencies [[org.clojure/clojure 1.5.1]]

 Note that it will take a few hours for the links above to become live,
 as the completed build moves into Maven Central.

 Thanks,

 Stu Halloway
 Clojure/core


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




Clojure Stored Procedure

2011-11-19 Thread Ghadi Shayban

I'm trying to load and execute an Oracle Java Stored Procedure...
written in Clojure.

Has anyone successfully managed to do this?  Are you done throwing
up?  I would appreciate any direction

I have a little clj that is AOT compiled, and I load the whole jar
into the DB successfully.

What I'm running into is half of the classfiles inside clojure.jar
including RT get marked as invalid by the database class resolver.
They have a 30-char max on pkg/class names, and anything longer gets
entered into a lookup table.

This seems to be a good reference
http://download.oracle.com/docs/cd/E11882_01/java.112/e10588/chtwo.htm#autoId18

I'm not too familiar with custom class loaders, and I'm not sure
that's what I'd need.

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


Re: Clojure Stored Procedure

2011-11-19 Thread Ghadi Shayban
Your code calls an existing stored procedure on the database.  I'm
wondering about *creating* a native Java stored procedure *inside* the
database.  Oracle supports Java 1.5 inside the DB, might as well use
clojure.

On Nov 19, 3:34 pm, willyh wheine...@gmail.com wrote:
 Here's how I do it with clojure.java.jdbc:

 (defn do-stored
   Executes an (optionally parameterized) SQL callable statement on
   the open database connection. Each param-group is a seq of values
   for all of the parameters.
   [sql  param-groups]
   (with-open [stmt (.prepareCall (sql/connection) sql)]
     (doseq [param-group param-groups]
       (doseq [[index value] (map vector (iterate inc 1) param-group)]
         (.setObject stmt index value))
       (.addBatch stmt))
     (sql/transaction
      (seq (.executeBatch stmt)

 (defn insert-sample-log
   [process-code
    csid
    sample-id
    container-id
    container-well
    tube-barcode
    username
    comment]
   (do-stored {call
 bsms_owner.Add_Sample_Log(?, ?, ?, ?, ?, ?, ?, ?)}
              [process-code
               csid
               sample-id
               container-id
               container-well
               tube-barcode
               username
               comment]))

 Hope that helps.

 Cheers,

 Willy

 On Nov 19, 3:14 pm, Ghadi Shayban gshay...@gmail.com wrote:







  I'm trying to load and execute an Oracle Java Stored Procedure...
  written in Clojure.

  Has anyone successfully managed to do this?  Are you done throwing
  up?  I would appreciate any direction

  I have a little clj that is AOT compiled, and I load the whole jar
  into the DB successfully.

  What I'm running into is half of the classfiles inside clojure.jar
  including RT get marked as invalid by the database class resolver.
  They have a 30-char max on pkg/class names, and anything longer gets
  entered into a lookup table.

  This seems to be a good 
  referencehttp://download.oracle.com/docs/cd/E11882_01/java.112/e10588/chtwo.ht...

  I'm not too familiar with custom class loaders, and I'm not sure
  that's what I'd need.

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


Re: ClojureScript

2011-07-25 Thread Ghadi Shayban
It will be a only a matter of time before people realize it doesn't
matter whether jQuery integrates or not. The examples/blog posts
coming out already are spectacular.

On Jul 24, 1:44 pm, Peter Taoussanis ptaoussa...@gmail.com wrote:
 Just want to throw in on this real quick. I am -dumbfounded- by how
 cool ClojureScript is.

 It was about 2AM my time when I first heard the announcement and I
 stayed up another 3 hours after that watching Rich's talk and playing
 with the samples. As I see it right now, this is a Big Deal. For lots
 of reasons. And I suspect it might take some time for the whole
 concept and its wide ramifications to fully digest for everyone.

 Like many (I'm guessing), my first question was: will it work with
 jQuery? I'd never even heard of Google Closure. Suffice it to say it
 didn't take much time looking into it to get me excited. And for it to
 click just how smart this whole approach seems it might just be.

 I am, literally, deploying this to my web app right now. I've got a
 Compojure route setup for a the resulting output of memoized
 ClojureScript compile call. I can work on the ClojureScript directly
 from my project. When something changes, I re-evaluate the memoized fn
 on my dev box (or on the production server through an SSH tunnel) and
 boom: I have a fully-optimized script going out to users. Add in a
 content-hash of the compiled script to automatically expire the old
 resource, and I have a workflow that I couldn't imagine being much
 better.

 Client-side side stuff I've wanted to do with my app but couldn't even
 begin to have the patience to implement- now suddenly seem trivial in
 principle. Having access to the reader for transmitting native data
 structures between the server and client... I don't even have the
 words.

 And this is just the stuff that touches me directly and that's
 obvious. I can't wait to see what people are going to do with this in
 time.

 Thank you: awesome job, guys. And what an awesome surprise!

 --
 Peter

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


Immutable Piece-table

2011-07-12 Thread Ghadi Shayban

I put up a simple demo that implements a piece table data structure in
Clojure

(This is totally an excuse to use finger trees, which Chris Houser
implemented and excellently presented at the first conj)

A piece table is good for buffer management in a text editor, as it
gets around making changes in place.  All changes are made to a
separate append-only buffer.

I'll spare you the details but if you look at the code you'll see why
a finger tree is a good base structure...
Each piece in the table has a different weight (the length of the
piece), and you need to find a point without traversing the whole
sequence.

https://github.com/ghadishayban/piece-table/blob/master/src/piecetable/core.clj

More about piece-tables
http://www.cs.unm.edu/~crowley/papers/sds.pdf

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


Recipe for using two databases with contrib.sql

2010-12-09 Thread Ghadi Shayban
I'm using contrib,sql to clean rows from one DB and insert them into
another.

I was thinking something like (pseudo-code

(sql/with-connection db1
  .
  (doseq [x (map rs)] (insert-into-other x)))


(defn insert-into-other [r]
(sql/with-connection db2
 ...))

But this obviously will open/close a connection to db2 for each row.

Can someone assist with an idiomatic solution?  Do I need to bind *db*?

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