[JOB] CLJ/CLJS Developer(FL/Remote) - Swarmify putting an end to video buffering

2016-01-08 Thread Nathan
Looking for a mid to senior level developer with experience in Clojure and 
Clojurescript to join our team and help put an end to video buffering and 
failures. Would be joining an innovative early stage company with strong 
venture backing and product already in production. Work on a solution that 
improves video streaming which is forecast to be 90% of all Internet 
traffic by 2018. 

We need smart can-do team members who are able to take ownership of their 
projects and deliver results. Work hard, play hard, and MOAR CAT VIDEOS for 
all.

The position is in SpaceCoast, FL, but open to remote work with occasional 
onsite meetings.

Full job description here: 
https://swarmify.com/jobs/#op-58685-software-engineer

You can apply through our website or send your resume directly to me: 
nat...@swarmify.com

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


Re: Zipper & Local Context?

2008-12-05 Thread Nathan Kitchen

Could you achieve this through a combination of clojure.zip/node and
get-in/assoc-in/update-in? Of course the missing piece is going back
from nodes to locs.

-- Nathan

On Dec 5, 2:54 pm, Randall R Schulz <[EMAIL PROTECTED]> wrote:
> Hi,
>
> I looked at the Clojure implementation of Huet's Zipper and it looks
> great. I like how it delegates construction and dissection of the tree
> structure to client-supplied functions so that it is generic w.r.t. to
> any types (especially for me, pre-existing, non-Clojure Java types)
> that can be deemed to encode a tree structure.
>
> However, I would like to be able to examine the tree in the locality of
> the current traversal point through path or position specifications.
> This approach is commonly used in describing algorithms about logical
> formulas (which are inherently tree-structured). If you're not familiar
> with the notion, these paths / positions are directly analogous to file
> system path names, except that one uses integers to label the arcs,
> said integers being ordinals in the child sequence of a given node.
>
> It seems to me that being able to access local context using such paths
> during a tree traversal would be far more convenient in many cases to
> having to navigate locally to determine whether a particular structural
> pattern was present.
>
> As far as I can tell, there's no provision for this sort of local tree
> access in the current Zipper code. Is there any reason such a
> capability could not (or should not) be added to the existing Zipper??
>
> Randall Schulz
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Gorilla: Release of Version 1.1.0

2008-12-12 Thread Nathan Kitchen



On Dec 12, 2:29 pm, Randall R Schulz  wrote:
> > > I think I may have asked this before, but what Vim version
> > > requirements
> > > does Gorilla have?
>
> > ..
>
> I guess what you should say at least is that it requires Ruby and the
> Vim Ruby module / extension / whatever. Unfortunately, neither of the
> systems I use have that in their Vim builds.
>
> SuSE Linux 10.0:
>
> % vim --version |head -1
> VIM - Vi IMproved 6.3 (2004 June 7, compiled Aug 15 2007 23:30:49)
>
> % vim --version |egrep ruby
> +path_extra -perl +postscript +printer -python +quickfix +rightleft -ruby
>
> openSUSE Linux 10.3:
>
> % vim --version |head -1
> VIM - Vi IMproved 7.1 (2007 May 12, compiled Dec 12 2007 14:09:38)
>
> % vim --version |egrep ruby
> -python +quickfix +reltime +rightleft -ruby +scrollbind +signs +smartindent

I believe that you can get ruby support in Vim in openSUSE 10.3 by
installing the gvim or vim-enhanced packages. I would guess that
something similar should work for SuSE 10.0.

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: yet another Clojure snake

2009-01-07 Thread Nathan Kitchen

On Jan 7, 7:01 am, "Mark Volkmann"  wrote:
> On Wed, Jan 7, 2009 at 3:13 AM, Tom Ayerst  wrote:
> > Hi Mark,
>
> > I'm afraid I don't like the "big let" style and I found it hard to follow
> > some of your code, that may just be a personal thing but a lot of the vars
> > defined in let are only used once and could be inlined.
>
> I agree they could be inlined, but I find that style easier to read.
> For example, these are equivalent.
>
> (defn make-cookies-1 [flower baking-soda salt button sugar eggs]
>   ; let describes the step-by-step process for making cookies.
>   (let [bowl (find-bowl :small)
>          bowl (add-ingredients bowl flower baking-soda salt)
>          batter (mix bowl)
>          batter (add-and-beat batter eggs flour)
>          baking-sheet (find-baking-sheet)
>          baking-sheet (make-dough-balls baking-sheet batter)]
>     (bake baking-sheet)))
>
> (def make-cookies-2 [flower baking-soda salt button sugar eggs]
>   (bake (make-dough-balls
>     (find-baking-sheet)
>     (add-and-beat (mix (add-ingredients (find-bowl) flower aking-soda
> salt) eggs flour
>
> Which of these is easier to understand?

You can avoid the big let while still keeping the order of operations
clear by using the -> macro:

(defn make-cookies [flour baking-soda salt butter sugar eggs]
  (let [batter (-> (find-bowl :small)
 (add ingredients flour baking-soda salt)
 (mix)
 (add-and-beat eggs flour))]
(-> (find-baking-sheet)
(make-dough-balls batter)
(bake

In my opinion, this little macro is a brilliant idea.

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Eval with local bindings

2009-01-17 Thread Nathan Kitchen

On Sat, Jan 17, 2009 at 11:06 AM, Greg Harman  wrote:
>
> Meta: This thread is a revival and continuation of last month's
> discussion at:
> http://groups.google.com/group/clojure/browse_thread/thread/e1226810b6ac7bfc/8e0f53c141c26fcc?lnk=gst&q=eval+binding#8e0f53c141c26fcc
>
> ---
>
> Nathan, did you ever come up with a better way to do this than using a
> global var?
>
> One solution is to use (binding), which still requires a global var,
> but gives each eval it's own binding of that var:
>
> user=> (def x)
> #'user/x
> user=> (def expr '(+ x 4))
> #'user/expr
> user=> (binding [x 3] (eval expr))
> 7
> user=> x
> java.lang.IllegalStateException: Var user/x is unbound.
> (NO_SOURCE_FILE:0)

I tried this approach with (binding) and I also tried creating
anonymous functions from the expressions:

(eval (list 'fn '[x] expr))

Creating functions didn't work for me because I used up the PermGen
space in the garbage collector with all the
classes created to implement them. As best I remember, I got the same
outcome with (binding), even though I wasn't creating new functions.

The approach that worked for me was to create my own recursive
evaluation function:

(defn eval-expr [expr]
 (cond
   (seq expr)
 (let [[op & args] expr]
   (apply @(resolve op) (map eval-expr args)))
   (= expr 'x) x
   :else expr))

I'm still using the var x, but it's not inherent to the approach; you
could easily add a map of symbols to values as an additional argument.

-- Nathan

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: how to know which version of clojure?

2009-01-19 Thread Nathan Kitchen

On Jan 18, 11:48 am, wubbie  wrote:
> Hi,
> Just tried a piece of code from here...
> (defn my-deref [x]
>   (if (or (isa? clojure.lang.Ref (class x))
>           (isa? clojure.lang.Agent (class x))
>           (isa? clojure.lang.Atom (class x)))
>     @x
>     x))
> java.lang.ClassNotFoundException: clojure.lang.Atom (NO_SOURCE_FILE:
> 22)
>
> But I think I used atom before and working...
> If my version is older I may have to download newer one.
> I think I downloaded about a month ago.

Atoms used to be implemented using
java.util.concurrent.AtomicReference before the clojure.lang.Atom
class was created. If you don't have the file Atom.java in clojure/src/
jvm/clojure/lang, you can try using the old class name in the
definition of my-deref. Personally, I think it would be better to
update to a newer version of clojure because you'll get bug fixes and
other recent improvements.

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Binding values in a list of symbols and evaluating as code

2009-01-23 Thread Nathan Kitchen

On Jan 23, 1:47 pm, Zak Wilson  wrote:
> And it's now working perfectly, producing a new generation every
> second. Now I actually have to tweak it to produce good results.

It's great that this is working for you.  I tried the same approach in
a genetic programming project of my own, and I eventually got an
OutOfMemoryError.  Clojure creates a new class for each (fn ) form
that you evaluate, and if you create enough functions those classes
eventually fill up the PermGen space in the heap.

Other approaches that don't run into the PermGen problem were
suggested in this thread:

http://groups.google.com/group/clojure/t/ead8a3a8ff009a8f

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: A nil puzzle

2009-01-24 Thread Nathan Kitchen



On Jan 24, 7:31 am, e  wrote:
> Then again, I already chimed in.  a list isn't a set.  You said so in the
> introduction.  Maybe set's need there own print representation, like <>
> . uh oh, starting to look like C++

Like this?:

user=> (hash-set 1 2 3)
#{1 2 3}

> On Sat, Jan 24, 2009 at 3:43 AM, Mark Engelberg 
> wrote:
> > Anyone want to try to convince me otherwise?  If you think my logic is
> > flawed, I'd love to hear your take on this problem.

My intuition is that the subsets returned by powerset should have the
same type as the argument:

user=> (powerset #{1 2})
(#{} #{1} #{2} #{1 2})

user=> (powerset [1 2])
([] [1] [2] [1 2])

user=> (powerset '(1 2))
(() (1) (2) (1 2))

For non-set collections, the name "powerset" might be misleading.
Maybe the right name for the concept is something more like
"subcolls".

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Macro defining Macros issue.

2009-02-05 Thread Nathan Cunningham

Yup, that solves it.
A while back the blah# didn't support working in nested back ticks. I
hadn't realized they fixed it. Or for that matter added condp :)

Thanks!

On Feb 5, 1:42 pm, Meikel Brandmeyer  wrote:
> Hi,
>
> first things first: what you want to do is available as condp in
> the core library of Clojure. That said, here some things I
> noticed in your macro.
>
> You should not capture variables in your macros. That's bad style and
> might lead to clashes of names. Clojure provides the foo# notation
> to generate new symbols via gensym. This makes a call to gensym
> almost always unnecessary.
>
> Your pair-seq function may be written using the partition function
> from the seq-library: (pair-seq the-seq) <=> (partition 2 the-seq).
>
> One may specify a map between the argument vector and the docstring
> of functions and macros. This map becomes part of the metadata.
> Here this may be used to get some nice argument names in the
> doc output for the generated macro instead of the gensym names.
>
> Here we go:
>
> (defmacro def-casemacro [casename test]
>    "Defines a macro named casename that uses test to compair the  
> result of
>    form to each key/result pair"
>    `(defmacro ~casename
>       ~(format "Evaluates form and finds the first key/result pair  
> that %s is
>    true for, evaluates it and returns the result. Error if none is  
> found."
>                (print-str test))
>       {:arglists '([~'form ~'key-result-pairs])}
>       [form# & key-result-pairs#]
>       (let [key-gen#  (gensym "key__")
>             kr-pairs# (partition 2 key-result-pairs#)]
>         `(let [~key-gen# ~form#]
>            (cond
>              ~@(mapcat (fn [[key# result#]]
>                          `((~'~test ~key-gen# ~key#) ~result#)) kr-
> pairs#)
>              true
>              (throw (new Error (format ~(str "No %s for key: %s")
>                                        ~~(name casename)
>                                        (str ~key-gen#)
>
> This works for me at least for the case (def-casemacro case =).
>
> Hope this helps.
>
> Sincerely
> Meikel
>
>  smime.p7s
> 5KViewDownload
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: map-method

2009-02-05 Thread Nathan Kitchen

Or anonymous function literals?

user=> (map #(.length %) ["mary" "had" "a" "little" "lamb"])
(4 3 1 6 4)

user=> (map #(.indexOf % (int \a)) ["mary" "had" "a" "little" "lamb"])
(1 1 0 -1 1)

On Feb 5, 5:05 pm, Jeffrey Straszheim 
wrote:
> Would memfn not work for you?
>
> http://clojure.org/java_interop
>
> On Thu, Feb 5, 2009 at 7:24 PM, kyle smith  wrote:
>
> > I often need to call a java method on each element in a collection.  I
> > didn't find anything on the group, so I wrote a macro.
>
> > (defmacro map-method [method coll & args]
> >  "Calls the given method on each item in the collection."
> >  `(map (fn [x#] (. x# ~@(if args
> > (concat (list method) args)
> > (list method ~coll))
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: how can i do this in clojure

2009-02-19 Thread Nathan Kitchen

On Feb 19, 2:39 pm, Phil Hagelberg  wrote:
> linh  writes:
> > # ruby code
> > def foo(x, y)
> >   x + y
> > end
>
> > def bar
> >   [1, 2]
> > end
>
> > foo(*bar) # this is fine, the result will be 3
> > foo(bar) # this is not ok, will raise exception
>
> > bar returns an array of size 2, but foo expects 2 parameters not an
> > array.
>
> In Clojure, this would look something like:
>
>   (defn foo [x, y]
> (+ x y))
>   (def bar [1, 2])
>
>   (apply foo bar) ;; becomes (foo 1 2), or 3
>   (foo bar)   ;; errors out
>
> Pretty close to Ruby, actually. The apply function calls the first
> argument (a function) with the rest of the arguments to apply becoming
> the argument list to the first function. In Clojure you see functions
> being passed as arguments to other functions a lot; this is the biggest
> difference from the Ruby version.

In this particular example, bar is a constant, but I suspect that linh
may be interested in a more general solution. Of course the difference
is slight:

;; foo as defined above
(defn bar [k] [k (* k 2)])

(apply foo (bar 3)) ;; => 9
(foo (bar 3)) ;; => throws IllegalArgumentException

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Parameter ordering on map/reduce

2009-03-31 Thread Nathan Sorenson

First of all, I would like to thank Rich and this community for
producing such a pleasurable language, and for putting up with with
all the unpleasant nit-picking of new users. That being said...

I am curious as to why the function parameter is specified before the
collection parameter in map/reduce. I have never used a lisp before,
and may not be aware of idiomatic style, but it seems to be the
convention elsewhere in Clojure (assoc, conj, .method calls, etc...)
to have the "altered" data structure be the first parameter.

Would this not allow mixing map into a threaded expression:

(-> [1 2 3]
 (map inc)
 (assoc 0 4)
 (reduce +)
 (conj :anotherthing))

Perhaps this style is rare in practice? Certainly it is easy enough to
write a custom map/reduce which acts this way, so I suppose my
question is mostly philosophical.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Parameter ordering on map/reduce

2009-03-31 Thread Nathan Sorenson

The let-> macro looks very useful. Thank-you!
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: A syntax feature request: splitting literal strings

2009-04-06 Thread Nathan Kitchen

On Apr 4, 4:16 pm, Stuart Sierra  wrote:
> This can be macro-ized:
>
> (defmacro bigstr [& strings]
>   "Concatenates strings at compile time."
>   (apply str strings))
>
> user> (macroexpand-1 '(bigstr "This is a really long string "
>   "that I just felt like using "
>   "in my program."))
> "This is a really long string that I just felt like using in my
> program."

Umm...how is bigstr different from str itself?

-- Nathan
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



constructing maps

2009-05-04 Thread Nathan Hawkins

Possibly I'm going about this wrong. I'm trying to understand how best 
to construct maps from sequences, by applying a function which returns a 
key / value pair.

Something like this:

(ns test (:use clojure.contrib.str-utils))

(def test-str "foo=1;bar=2;baz=3")

(defn split-kv [text]
 (let [[k v] (re-split #"=" text )]
   {k v}))

(defn split-pairs [text]
 (re-split #";" text))

(map split-kv (split-pairs test-str))

-> ({"foo" "1"} {"bar" "2"} {"baz" "3"})


Doesn't really do what I had in mind. And yeah, I figured out that I can 
convert that to a hash-map in various ways, but I had expected map to be 
able to do this. So I wrote this:


(defn map-assoc
 "Returns a map consisting of f applied to coll, where f is a function 
returning a key and value. f can return either a sequence with two 
values or a single item map."
 [f coll]
 (loop [map {}
s (seq coll)]
   (if s
 (let [item (f (first s))]
   (recur (if (associative? item)
(conj map item)
(assoc map (first item) (second item)))
  (next s)))
 map)))


This seems a little bit more like what I expected:

(map-assoc split-kv (split-pairs test-str))

-> {"baz" "3", "bar" "2", "foo" "1"}


Am I overlooking some already existing function hidden away someplace 
that does this?

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: constructing maps

2009-05-04 Thread Nathan Hawkins

On Mon, 4 May 2009 16:07:06 +0200
Christopher Taylor  wrote:

> 
> Hi Nathan,
> 
> On 04.05.2009, at 15:47, Nathan Hawkins wrote:
> 
> >
> > On Mon, 4 May 2009 06:16:14 -0700 (PDT)
> > Drew Raines  wrote:
> >>
> >> Whoops, that (seq) is a debugging artifact.  You can remove that:
> >>
> >> (let [test-str "foo=1;bar=2;baz=3"]
> >>  (reduce conj {}
> >>  (map #(apply hash-map (.split % "="))
> >>   (.split test-str ";"
> >
> > Ok, my example seems to have misled. You're missing the point a
> > little bit:
> >
> > 1. I was trying to avoid the (reduce conj {} ...), by having the map
> > function do it. Why even build a list that's only going to get
> > thrown away when I want a hash-map at the end?
> 
> you're not actually building a list. The function map returns a
> (lazy) *sequence*, which is an instance of ISeq. This just means
> you're getting something that supports the operations first and rest.
> So, since map returns a sequence and you want a Map (i.e. key/value
> data structure), you'll have to turn it into one by using (conj
> {} ...) or (into {} ...).

There's the source of my misunderstanding. I knew map returned a
sequence, but hadn't quite connected "lazy" to the problem at hand.

I had stumbled on a couple different ways of converting the sequence to
a hash-map (I found (into {} ...), (apply hash-map ...) and (reduce conj
{} ...)), but I was thinking in terms of how I'd solve the problem in
Common Lisp so I thought that running map and then converting the
result to a hash-map was going to iterate the list twice, as well as
cons the results twice.

Thanks for clearing that up.

Nathan

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: constructing maps

2009-05-04 Thread Nathan Hawkins

On Mon, 4 May 2009 06:16:14 -0700 (PDT)
Drew Raines  wrote:

> 
> On May 4, 8:05 am, Drew Raines  wrote:
> 
> > user> (let [test-str "foo=1;bar=2;baz=3"]
> >         (reduce conj {}
> >            (map #(apply hash-map (seq (.split % "=")))
> >                (.split test-str ";"
> 
> Whoops, that (seq) is a debugging artifact.  You can remove that:
> 
> (let [test-str "foo=1;bar=2;baz=3"]
>   (reduce conj {}
>   (map #(apply hash-map (.split % "="))
>(.split test-str ";"

Ok, my example seems to have misled. You're missing the point a little
bit:

1. I was trying to avoid the (reduce conj {} ...), by having the map
function do it. Why even build a list that's only going to get thrown
away when I want a hash-map at the end?

2. The functions used to split the strings were not important, only an
example. It could just as easily be a function to extract fields from a
java object.


To some extent, I guess I'm thinking in terms of Common Lisp, where I'd
build an a-list with mapcar and cons.

Nathan

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: constructing maps

2009-05-04 Thread Nathan Hawkins

On Mon, 04 May 2009 16:31:21 +0200
Christophe Grand  wrote:

> 
> Nathan Hawkins a écrit :
> > Ok, my example seems to have misled. You're missing the point a
> > little bit:
> >
> > 1. I was trying to avoid the (reduce conj {} ...), by having the map
> > function do it. Why even build a list that's only going to get
> > thrown away when I want a hash-map at the end?
> >
> > 2. The functions used to split the strings were not important, only
> > an example. It could just as easily be a function to extract fields
> > from a java object.
> >
> >
> > To some extent, I guess I'm thinking in terms of Common Lisp, where
> > I'd build an a-list with mapcar and cons.
> >   
> 
> With f a function that return a [key value] pair (or a (key value)
> pair but not a {key value} pair):
>   (reduce #(apply assoc %1 (f %2)) {} coll)
> 
> if you want to have f return a map you can
>   (reduce #(merge %1 (f %2)) {} coll)
> 

This is exactly what I was trying to, but I hadn't thought of using
reduce.

Thank you.

Nathan

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: constructing maps

2009-05-05 Thread Nathan Hawkins

On Tue, 05 May 2009 09:39:21 +0200
Christophe Grand  wrote:

> 
> Kevin Downey a écrit :
> > (into {} (apply map vector
> > '((cars bmw chevrolet ford peugeot)
> >   (genres adventure horror mystery
> >
> > {ford mystery, chevrolet horror, bmw adventure, cars genres}
> >   
> 
> or:
> user=> (apply zipmap '((cars bmw chevrolet ford peugeot) (genres 
> adventure horror mystery)))
> 
> {ford mystery, chevrolet horror, bmw adventure, cars genres}
> 
> But I'm unsure it's what Michel was after. I thought an alist was a
> list of pointed pairs (or a list of 2-elts lists) but I may be wrong
> since I come from Javaland.
> 
> user=> (into {} (map vec '((a 1) (b 2) (c 3
> {c 3, b 2, a 1}
> 
> 
> Christophe
> >
> > On Mon, May 4, 2009 at 4:03 PM, Michel S. 
> > wrote: 
> >>
> >> Yes, me too. The design is a bit unfortunate, as I cannot convert a
> >> Scheme-style association list to a map easily:
> >>
> >> user=> (into {} '((cars bmw chevrolet ford peugeot)
> >> (genres adventure horror mystery)))
> >>
> >> java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
> >> java.util.Map$Entry (NO_SOURCE_FILE:0)
> >>
> >> --
> >> Michel
> >> 
> 
> 


In Common Lisp, an alist is something like this:

((cars . genres) (bmw . adventure) (chevrolet . horror) (ford .
mystery))

Where (cars . genres) is a cons cell with values in both slots. So an
alist is a list of key/value pairs where order is significant and keys
could appear more than once. Not much different than:

[[cars genres] [bmw adventure] [chevrolet horror] [ford mystery]]

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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 as a Java lib documentation / examples?

2009-05-21 Thread Nathan Hawkins

Try here:

http://code.google.com/p/clojure/source/browse/


Brett Morgan wrote:
> Hi guys,
>
> I have some evil thoughts of using Clojure as a java library so that i
> can use both the STM and the persistent data structures in projects
> that my team of java developers can work with.
>
> As much as I'd like to get the team coding in Clojure properly, I have
> enough trouble selling the idea of using immutable data structures. If
> I hide the clojure magic behind interfaces, I can have the team coding
> in plain java, and wrap what they do in clojure transactions and what
> not. I'd like to do this in a way that the clojure repl can still be
> used to interact with the running server.
>
> So where do I start reading? =)
>
>   


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: What books have helped you wrap your brain around FP and Clojure?

2009-06-06 Thread Nathan Hawkins

Higher Order Perl. While I don't want to use Perl anymore, I do know it 
very well, and it provided a good introduction to FP in a more familiar 
language. YMMV.

Robert Campbell wrote:
> Going beyond the language-specific Programming Clojure book, what
> other books have best helped you make the (sometimes mind-bending)
> transition from OOP thinking to FP thinking? My bookshelf is piled
> high with OOP books like Design Patterns, Domain Driven Design,
> Analysis Patterns, etc. I've recently ordered:
>
> - Concepts, Techniques, and Models of Computer Programming (mentioned
> on this/compojure's list)
> - Structure and Interpretation of Computer Programs (highly
> recommended on Stackoverflow, lectures posted online)
>
> Any others?
>
> >
>   


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: What books have helped you wrap your brain around FP and Clojure?

2009-06-08 Thread Nathan Hawkins

Programming Erlang is also good. The syntax and message passing
emphasis aren't relevant to Clojure, but Erlang also uses immutable
data, and is definitely a functional language.

On Sat, 6 Jun 2009 13:12:16 +0200
Robert Campbell  wrote:

> 
> Going beyond the language-specific Programming Clojure book, what
> other books have best helped you make the (sometimes mind-bending)
> transition from OOP thinking to FP thinking? My bookshelf is piled
> high with OOP books like Design Patterns, Domain Driven Design,
> Analysis Patterns, etc. I've recently ordered:
> 
> - Concepts, Techniques, and Models of Computer Programming (mentioned
> on this/compojure's list)
> - Structure and Interpretation of Computer Programs (highly
> recommended on Stackoverflow, lectures posted online)
> 
> Any others?
> 
> > 

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

2009-06-10 Thread Nathan Hawkins

On Wed, 10 Jun 2009 12:44:00 -0600
Daniel Lyons  wrote:
> On Jun 10, 2009, at 12:03 PM, Toralf Wittner wrote:
> > On Wed, 2009-06-10 at 10:22 -0600, Daniel Lyons wrote:
> >> If the actions are executed serially, what is the benefit of having
> >> multiple threads per agent?
> >
> > There is none. Did anybody say there are multiple threads per agent?
> > There are two thread pools shared by all agents - a cached thread
> > pool where actions enqueued via send-off go into and a fixed thread
> > pool for
> > actions enqueued via send. The actions of all agents are submitted
> > to these two pools and all together run interleaved in different
> > threads. However at a given point in time there is only one thread
> > for a given Agent. And an agent's actions run one after another.
> 
> 
> This makes more sense, actually. For some reason I thought each
> agent got its own thread pool.
> 
> However, I still feel like I am not understanding when agents should  
> be used or what an appropriate use of them would constitute, though.

When you need to update shared state, but you don't want to block the
current thread.

I'm looking at them to simplify request processing in network
applications with lots of state machines. Agents let me write
state machines in functional style with multi-methods dispatching on
the current state and the type of input. I also don't have to write the
code to put the messages on a queue and manage a thread pool myself.

Nathan

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

2009-06-25 Thread Nathan Hawkins

On Thu, 25 Jun 2009 11:29:24 +0530
Baishampayan Ghose  wrote:

> 
> Their concerns are thus:
> 
> 1. How do you get Clojure programmers? Lisp is not for the faint
> hearted.

You can always ask on this list. I'd guess that at any given point
in time there are probably several people who'd rather being
working with Clojure in their day job than whatever they're actually
doing now. (Me, for instance...)
 
> 2. What about the performance of Clojure? Is it fast?

It can be faster than a lot of other popular choices, like Ruby or
Python. I wish it compiled to native code instead of Java, but that's
mostly because I don't like Java.

> 3. People who want to use this are more academically inclined and are
> not practical. This will make the whole project fail.

Many innovative ideas in computer science tend to in academia
and only slowly make their way into more mainstream, practical
environments.

Consider garbage collection, or relational databases. Both very
"academic" at one time, and now they're everywhere.

Point being, really practical people use the best ideas they can,
regardless of where they came from.

Nathan

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

2009-07-08 Thread Nathan Kitchen

On Jul 7, 5:02 am, Mike  wrote:
> (not sure where my reply to Chouser et al. went, but basically I said
> that I was writing a macro and I might be overdoing it.  I was right!)
>
> Here's what I was trying to accomplish, but in functions, not macros:
>
> (defn slice
>   "Returns a lazy sequence composed of every nth item of
>    coll, starting from offset."
>   [n offset coll]
>   (if (= offset 0)
>     (take-nth n coll)
>     (take-nth n (drop offset coll
[snip]

Your slice function looks similar to the built-in partition:

(defn slice [n offset coll]
  (apply concat (partition 1 n (drop offset coll
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Newbie question about peepcode server "Address already in use error"

2009-08-02 Thread Nathan Lefler
Try either killing your Java process or changing the port you're binding on.
Nathan

On Sun, Aug 2, 2009 at 8:21 AM, Leotis buchanan wrote:

> Guys,
>
> I going through the peepcode tutorial, I am trying to run the code shown
> below, but  I keep getting :
> *Address already in
> use
>   [Thrown class java.net.BindException]  *
>
> I am using ubuntu, is there someway I can specify the bind address to fix
> this problem.
>
> Thanks
>
> (ns
> mire
>
>   (:use [mire
> commands])
>
>   (:use [clojure.contrib server-socket
> duck-streams]))
>
>
>
>
> (def port   ( * 1
> 4445))
> (def prompt ">
> ")
>
>
>
>
>
> (defn mire-handle-client [in
> out]
>   (binding [*in* (reader
> in)
> *out* (writer
> out)]
> (print prompt
> (flush)
>
>
> (loop [input
> (read-line)]
>
>   (println (execute
> input))
>   (print
> prompt)
>
>
> (flush)
>
>   (recur
> (read-line))
>
>
>
>
>
> (def server (create-server port mire-handle-client))
>
>
>
>
>
>
>
> On Sat, Aug 1, 2009 at 10:15 PM, Chad Harrington <
> chad.harring...@gmail.com> wrote:
>
>> I have a newbie question about anonymous functions.  Why does the first
>> form below work and the second form does not?
>>
>> user> ((fn [] "foo"))
>> "foo"
>>
>> user> (#("foo"))
>> ; Evaluation aborted.
>>
>> Thanks,
>>
>> Chad
>>
>>
>>
>
>
> --
> Leotis Buchanan
> Manager/Electronic Design Systems Engineer
> Exterbox.com
>
> >
>

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



with-out-str assumes Unix line ends

2009-08-07 Thread Nathan Kitchen
Anne's recent attempt to start a new thread for this question seems not to
have worked. I'd hate for her and ataggart to be frustrated by further
back-and-forth over the identity of the thread he started, so I'm starting a
new thread for her question.

=== begin content from Anne ===

Sorry for the confusion - I read this list on an email feed. Turns out
replying to a message from there and changing the subject isn't
sufficient to start a new thread. Apparently it renames the thread.
(suboptimal).

original question:
(use 'clojure.contrib.duck-streams)
(spit "C:\\test.txt"
(with-out-str
  (println "foo")
  (println "bar")
  (flush)))
On my XP Tablet OS computer results in a file with unix line endings.
Is this proper behavior?

Mike Hinchey's response:
What does this return on Windows?  (with-out-str (.println
(java.io.PrintWriter. *out*)))

If it's "\r\n", then maybe (newline) should be changed to print
(System/getProperty "line.separator") instead of \newline as it does
now.
Thoughts?
-Mike
===

On XP tablet
user=> (seq (with-out-str (.println (java.io.PrintWriter. *out*
(\return \newline)

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



Strange little difference with the reader and the java float parsers

2009-11-27 Thread Nathan Cunningham
I was working on a system that used the reader / pprint to load and
save data too and from the disk and I ran into a strange issue when I
reloaded my work from a JTable

Apparently there are cases where read will return a slightly different
float then the Float constructor will. For example:

(- (new Float "1786.28") (read-string "1786.28"))
2.929687502728484E-5

I'm not sure if its just my machine or not, (Ubuntu 9.04, AMD 64
Athlon X2, Using the Sun VM 6 and JDK 6)
any ideas or links?

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

2009-11-28 Thread Nathan Hawkins
Stefan Kamphausen wrote:
> Hi,
>
> On Nov 28, 2:20�pm, John Harrop  wrote:
>   
>> One benefit of having a REPL: it makes regular expressions usable. So easy
>> to test and tweak your RE compared to the traditional compile/test/debug
>> cycle! I never even bothered with the java.util.regex package before Clojure
>> as it was too painful to use.
>> 
>
> I wonder how hard it would be in Clojure to implement something like
> Edi Weitz' RegexpCoach
> http://weitz.de/regex-coach/.  I know Perl programmer who regularly
> create their (un)regular expressions with the help of that
> software. ;-)
>   
Really? Why would they need to do that? I always just used the perl 
REPL, perl -d. Ironically, that
experience made it easier to learn Lisp, especially after reading Higher 
Order Perl.

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


[ANN] Introducing pulley.cps

2015-02-19 Thread Nathan Davis


Dear Fellow Clojurians, 

I'm pleased to annouce release 0.1.0 of pulley.cps, a tool for transforming 
Clojure code into Continuation-Passing-Style. You can find it at 
http://github.com/positronic-solutions/pulley.cps. 

While this is not the first attempt at such a tool, to the best of my 
knowledge it is the most complete to date. The rather lengthy Readme (which 
for now also doubles as User Guide, API Documentation, and design document) 
goes into more detail, but here's a quick run-down of features: 

   - Two macros, cps and cps-fn, serve as primary entry points for 
   transforming code. 
   - Transformed code can call native code (non-transformed functions and 
   Java methods) and vice versa. 
   - Due to the nature of CPS, we get tail-call optimization for free 
   (i.e., all tail-calls within transformed code are naturally TCO'd). Of 
   course, calls from CPS to native code still consume Java stack space, and 
   non-tail calls within transformed code will consume *heap* space. 
   - Dynamic bindings are fully supported, and do not interfere with TCO (
   binding is fully tail-call optimizable). set! is not currently implement 
   for dynamic vars, but due to some recent changes to the way dynamic 
   environments are implemented should be trivial to support. 
   - Since with CPS we explicitly pass the continuation around, it is easy 
   to expose the current continuation to the user. This is accomplished via 
   the function call-cc and its macro analog let-cc. 
   - Exceptions are not currently implemented. However, they are actively 
   being worked on. The expectation here is that exceptions will work pretty 
   much seamlessly with native exceptions, and you will be able to use the 
   same forms (throw, try, catch, finally) as you would in regular Clojure 
   code. 
   - The ability to override native functions with a CPS implementation, in 
   order to provide an optimal experience. For example, clojure.core/apply 
   is overridden to provide an optimized implementation when invoked from CPS 
   code. So if you call apply with a CPS function, continuations, TCO, etc. 
   will still work. 

 Overall, the goal is to be able to automatically transform as much 
"regular clojure code" into CPS while maintaining seamless interoperation 
with "native" Clojure code. The one area I don't think we'll manage to do a 
satisfactory job on are forms that create Java types (reify, deftype, 
genclass, etc.). These forms are currently completely unsupported, and any 
potential future support will most likely consist of simply escaping the 
transformation process when these forms are encountered. Other than that, 
once exception support is completed, I think this goal will be within 
reach. 

Near-term development goals are first to implement exceptions. Then I'd 
like to explore expanding platform support beyond the JVM, namely 
ClojureCLR and ClojureScript. 

Anyway, feel free to give things a try. I greatly treasure your feedback, 
including bug reports and if you have trouble navigating the documentation. 

Have fun, 

Nathan Davis 

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

2015-02-24 Thread Nathan Davis
Sure, you can write code in CPS style by hand.  Javascript developers do it
all the time.  But it's a very tedius, mechanical transformation.  And
tedius, mechanical transformations are what Lisps excel at ;-)

We could also ask why we would want (reified) continuations?  From a
theoretical point of view, continuations are the fundamental basis for
control flow.  If continuations are reified as a first-class construct,
then we have a basis for implementing all sorts control-flow constructs.
For example, cooperative multitasking (green threads) is almost trivial to
implement with continuations.  Mitchell Wand's Continuation-Based
Multiprocessing <ftp://ftp.ccs.neu.edu/pub/people/wand/papers/hosc-99.ps>
is a good read for this application.

Finally, the combination of CPS with thunking and trampolining gives us
tail call optimization for free.  This allows us to express many complex
iterative processes in a recursive, functional, manner while retaining
space efficiency.  Some people find this more natural than iterative
alternatives, such as state machines.  Again, this can be done by hand, but
is very tedious.

Nathan Davis

On Tue, Feb 24, 2015 at 3:03 AM, Vladimir Bokov 
wrote:

> Hi, Nathan
>
> Would you like to describe shortly, why one would need such transformation.
> What are the benefits and what prevents to write code in CPS style by hand?
>
> p.s. sorry, I'm far from being expert in this field :)
>
> четверг, 19 февраля 2015 г., 23:45:10 UTC+6 пользователь Nathan Davis
> написал:
>
>> Dear Fellow Clojurians,
>>
>> I'm pleased to annouce release 0.1.0 of pulley.cps, a tool for
>> transforming Clojure code into Continuation-Passing-Style. You can find it
>> at http://github.com/positronic-solutions/pulley.cps.
>>
>> While this is not the first attempt at such a tool, to the best of my
>> knowledge it is the most complete to date. The rather lengthy Readme (which
>> for now also doubles as User Guide, API Documentation, and design document)
>> goes into more detail, but here's a quick run-down of features:
>>
>>- Two macros, cps and cps-fn, serve as primary entry points for
>>transforming code.
>>- Transformed code can call native code (non-transformed functions
>>and Java methods) and vice versa.
>>- Due to the nature of CPS, we get tail-call optimization for free
>>(i.e., all tail-calls within transformed code are naturally TCO'd). Of
>>course, calls from CPS to native code still consume Java stack space, and
>>non-tail calls within transformed code will consume *heap* space.
>>- Dynamic bindings are fully supported, and do not interfere with TCO
>>(binding is fully tail-call optimizable). set! is not currently
>>implement for dynamic vars, but due to some recent changes to the way
>>dynamic environments are implemented should be trivial to support.
>>- Since with CPS we explicitly pass the continuation around, it is
>>easy to expose the current continuation to the user. This is accomplished
>>via the function call-cc and its macro analog let-cc.
>>- Exceptions are not currently implemented. However, they are
>>actively being worked on. The expectation here is that exceptions will 
>> work
>>pretty much seamlessly with native exceptions, and you will be able to use
>>the same forms (throw, try, catch, finally) as you would in regular
>>Clojure code.
>>- The ability to override native functions with a CPS implementation,
>>in order to provide an optimal experience. For example,
>>clojure.core/apply is overridden to provide an optimized
>>implementation when invoked from CPS code. So if you call apply with
>>a CPS function, continuations, TCO, etc. will still work.
>>
>>  Overall, the goal is to be able to automatically transform as much
>> "regular clojure code" into CPS while maintaining seamless interoperation
>> with "native" Clojure code. The one area I don't think we'll manage to do a
>> satisfactory job on are forms that create Java types (reify, deftype,
>> genclass, etc.). These forms are currently completely unsupported, and
>> any potential future support will most likely consist of simply escaping
>> the transformation process when these forms are encountered. Other than
>> that, once exception support is completed, I think this goal will be within
>> reach.
>>
>> Near-term development goals are first to implement exceptions. Then I'd
>> like to explore expanding platform support beyond the JVM, namely
>> ClojureCLR and ClojureScript.
>>
>> Anyway, feel free to give things a

[ANN] Specter: a library for deep introspection and transformation of nested data

2015-02-26 Thread Nathan Marz
It's been far too long since I've open sourced anything, so today I'm happy
to open source a small library that I use extremely heavily:
https://github.com/nathanmarz/specter

Specter lets you write code like this:

user> (select [ALL :a even?]
  [{:a 1} {:a 2} {:a 4} {:a 3}])
[2 4]

user> (update [(filterer odd?) LAST]
  inc
  [2 1 3 6 9 4 8])
[2 1 3 6 10 4 8]

user> (select [:a ALL :b ALL odd?]
  {:c [1 2 3] :a [{:b [3 4 5]} {:c 1 :b [1 2]}]})
[3 5 1]

More information can be found on the README.

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

2015-03-24 Thread Nathan B
We use https://github.com/ejlo/lein-externs for this and it seems to work 
pretty well for our purposes.

On Monday, March 23, 2015 at 10:42:40 PM UTC-4, james borden wrote:
>
> Is there a way to automatically generate externs files for js libraries 
> for use with the cljs advanced compilation mode? 
>
> I am having problems using a cljsjs package because its extern file does 
> not contain all of the methods of an object I need to complete the 
> introductory tutorial for the js library. My workaround is to create a 
> separate extern file and include the method I need. However, there seems to 
> be many more methods/properties missing from the cljsjs extern file and I 
> would like to just generate a new one and make a pull request.
>
> Is there currently a method someone is using to automatically generate 
> one? It seems tedious and prone to error to generate extern files manually.
>

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


Streaming Media East NYC Mini-Meetup 5/10

2015-05-02 Thread Nathan B
If any Clojurians will be at Streaming Media East or just local to NYC and 
would like to do a mini-meetup at the New York Hilton Midtown on 5/10 in 
the evening let me know. Would be nice to meet up and have a few drinks and 
talk Clojure. I can organize if there is some interest.

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

2015-06-10 Thread Nathan ToddStone
Awesome!

On Tuesday, June 9, 2015 at 7:35:33 AM UTC-7, Michael Drogalis wrote:
>
> I'm happy to announce that Onyx 0.6.0 is officially out!
>
> Blog post: 
> http://michaeldrogalis.github.io/jekyll/update/2015/06/08/Onyx-0.6.0:-Going-Faster.html
> GitHub: https://github.com/onyx-platform/onyx
> Website: www.onyxplatform.org
> Chat: https://gitter.im/onyx-platform
>
> Thanks to all the contributors that helped make this happen!
>

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


Running test.check and cljs.test tests under Clojurescript

2015-06-30 Thread Nathan Marz
I'm trying to get Specter's tests running under ClojureScript. I can run
the tests manually in a REPL just fine, but I cannot figure out a
straightforward way to run all the tests like you can in Clojure with "lein
test".

Here are the tests I'm trying to run, which are a mix of tests defined
using test.check and cljs.test:
https://github.com/nathanmarz/specter/blob/cljs/test/com/rpl/specter/core_test.cljc

I've tried the instructions in
http://abratukhin.blogspot.com/2015/03/how-to-set-up-unit-tests-in.html but
the cemerick.cljs.test package does not seem to run test.check tests
defined with defspec.

How can I set up a runner to run my tests with a one line command at the
terminal?

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

2015-06-30 Thread Nathan Marz
I figured out a way to do it by manually launching a ClojureScript REPL, 
writing a test runner script, and then invoking that script at the REPL, 
like so: https://github.com/nathanmarz/specter/blob/cljs/DEVELOPER.md

Still wondering if there's a more straightforward way to do this.


On Tuesday, June 30, 2015 at 7:20:58 PM UTC-4, Nathan Marz wrote:
>
> I'm trying to get Specter's tests running under ClojureScript. I can run 
> the tests manually in a REPL just fine, but I cannot figure out a 
> straightforward way to run all the tests like you can in Clojure with "lein 
> test". 
>
> Here are the tests I'm trying to run, which are a mix of tests defined 
> using test.check and cljs.test: 
> https://github.com/nathanmarz/specter/blob/cljs/test/com/rpl/specter/core_test.cljc
>
> I've tried the instructions in 
> http://abratukhin.blogspot.com/2015/03/how-to-set-up-unit-tests-in.html 
> but the cemerick.cljs.test package does not seem to run test.check tests 
> defined with defspec. 
>
> How can I set up a runner to run my tests with a one line command at the 
> terminal?
>
>
>

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

2014-12-16 Thread Nathan Smutz
Hi Daniel,

I just wanted to thank you and say how much I've appreciated your Android REPL. 
In learning Clojure, it's been an amazing resource to have.  Studying books 
away from a computer, or just being comfortable at home: it's been a great 
learning multiplier to launch your app on the spur of the moment and try 
things, or just pull up source/docs for core functions.  Thank you again. 
Please let us know if there's a way to help.

Very best,
Nathan

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

2021-06-03 Thread Nathan Marz
Derek – we have a bunch of open-source on our Github 
<https://github.com/redplanetlabs>. I'd like to release our new language 
one day, but that won't be for a long time. When I release it I want to do 
it the right way – extensive documentation, academic papers, and a 
commitment to supporting the language in broader usage. At our early stage 
we just don't have the bandwidth for that as we're working hard to get our 
first product out the door. Plus at the moment out language is our "secret 
weapon" :)

Leandro – I started working on this codebase well before spec was released. 
Had spec existed when I started I would have explored it more thoroughly, 
but Schema has met our needs very gracefully. As for deterministic 
simulation, it's orthogonal to techniques like test.check. I suggest you 
check our our earlier blog post 
<https://tech.redplanetlabs.com/2021/03/17/where-were-going-we-dont-need-threads-simulating-distributed-systems/>
 
on the subject. 

On Thursday, June 3, 2021 at 3:09:28 PM UTC-10 ldoc...@gmail.com wrote:

>
>
> On Thu, 3 Jun 2021, 15:06 natha...@gmail.com,  wrote:
>
> Please give the post a read, and I'm happy to answer any questions.
>>
>
> Nice article, Nathan. Definitely, it would be nice to see the code :-)
>
> Just curious...
>
> 1) You mention using Schema for data definition and validation. Did you 
> consider using other options for this, such as clojure.spec? What's your 
> experience with it/them?
>
> 2) You mention using "deterministic simulation". Did you consider using 
> other options for this, such as test.check? What's your experience with 
> it/them?
>
> Best,
> Leandro
>
>>

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


Re: Tour of our 250k line Clojure codebase

2021-06-03 Thread Nathan Marz
Probably not in the near future. Once we're close to being ready for 
production usage, we'll be releasing a preview post demonstrating how our 
product works through an example of using it to replicate a widely-used 
service in a comparatively minuscule amount of code. Though we're already 
able to build and run arbitrary applications at scale, we still have a lot 
of work to do on operational features to enable the fault-tolerance 
necessary for production usage.  

On Thursday, June 3, 2021 at 5:24:00 PM UTC-10 Robert P. Levy wrote:

> Great post on the technical choices made in developing this platform.  Do 
> you plan on writing a post that describes in detail the system architecture 
> that is the bread and butter of the product/platform itself?
>
> The website intriguingly states, "Red Planet Labs is pioneering a 
> radically new kind of software tool. It's not just for the initial 
> construction of an application, but also encapsulates deployment, 
> monitoring, and maintenance. It implements the first truly cohesive model 
> for building software applications – a set of abstractions that can build 
> any application at any scale with greatly reduced engineering cost."
>
> It seems like a full article expanding on the infrastructure-level design, 
> and the approach to generalizing and abstracting infrastructure, would be 
> very interesting.
>
>
> On Thu, Jun 3, 2021 at 7:12 PM Nathan Marz  wrote:
>
>> Derek – we have a bunch of open-source on our Github 
>> <https://github.com/redplanetlabs>. I'd like to release our new language 
>> one day, but that won't be for a long time. When I release it I want to do 
>> it the right way – extensive documentation, academic papers, and a 
>> commitment to supporting the language in broader usage. At our early stage 
>> we just don't have the bandwidth for that as we're working hard to get our 
>> first product out the door. Plus at the moment out language is our "secret 
>> weapon" :)
>>
>> Leandro – I started working on this codebase well before spec was 
>> released. Had spec existed when I started I would have explored it more 
>> thoroughly, but Schema has met our needs very gracefully. As for 
>> deterministic simulation, it's orthogonal to techniques like test.check. I 
>> suggest you check our our earlier blog post 
>> <https://tech.redplanetlabs.com/2021/03/17/where-were-going-we-dont-need-threads-simulating-distributed-systems/>
>>  
>> on the subject. 
>>
>> On Thursday, June 3, 2021 at 3:09:28 PM UTC-10 ldoc...@gmail.com wrote:
>>
>>>
>>>
>>> On Thu, 3 Jun 2021, 15:06 natha...@gmail.com,  
>>> wrote:
>>>
>>> Please give the post a read, and I'm happy to answer any questions.
>>>>
>>>
>>> Nice article, Nathan. Definitely, it would be nice to see the code :-)
>>>
>>> Just curious...
>>>
>>> 1) You mention using Schema for data definition and validation. Did you 
>>> consider using other options for this, such as clojure.spec? What's your 
>>> experience with it/them?
>>>
>>> 2) You mention using "deterministic simulation". Did you consider using 
>>> other options for this, such as test.check? What's your experience with 
>>> it/them?
>>>
>>> Best,
>>> Leandro
>>>
>>>> -- 
>> 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.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/clojure/70353370-6dd2-4ddc-af82-2fce32ee6bden%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/clojure/70353370-6dd2-4ddc-af82-2fce32ee6bden%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

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


Re: Tour of our 250k line Clojure codebase

2021-06-09 Thread Nathan Marz
Continuations in our language are expressed very differently than has 
existed before (e.g. like in Scheme). They fit intuitively within the 
overall paradigm our language implements. Far from being complex or hard to 
comprehend, continuations are the key construct that enables us to avoid 
mountains of complexity that exist otherwise in distributed systems. I know 
this from personal experience building distributed systems in the past. The 
degree to which continuations help write asynchronous, reactive, and 
parallel code is huge. It would be clear if you saw the language in action, 
but we're keeping it under wraps for now.

We use deps.edn just for dependency resolution via 
lein-tools-deps.plugin/resolve-dependencies-with-deps-edn. We use lein as a 
test runner and for launching repls from the command line. Our build's not 
too complicated, but it's not ideal.

That's right. Since tests run sequentially, using with-redefs is safe. We 
parallelize our build by running it as multiple Jenkins stages, where each 
stage runs a subset of the tests sequentially in separate processes. Any 
with-redefs we do are at the beginning of tests and thus global to its 
execution. 

with-redefs + no-op functions is extremely lightweight. We do use component 
overrides for other things, but that requires: a) the component system map 
is accessible where you want to capture events, b) non-trivial overhead in 
adding a new component and threading it to the spot in the code you care 
about. For events we want to capture in low-level implementation functions 
the with-redefs + no-op functions approach is simple, easy, doesn't affect 
production, and avoids bloating our component system maps with tons of 
things which are irrelevant to production.

The only testing method we use internally that might be relevant to users 
of our product is deterministic simulation. We're unlikely to expose that 
for v1, but we may expose it in the future. For v1 we'll be exposing an "in 
process cluster" abstraction for testing which runs things in parallel on 
multiple threads.


On Wednesday, June 9, 2021 at 10:57:40 AM UTC-10 Leif wrote:

> Hi Nathan.  Interesting post.  Here are some questions that I wrote down 
> while
> reading it.  
>
> First-class continuations + distributed programming sounds like a 
> nightmare that
> would wake me up in a cold sweat.  Like if a void pointer was bitten by a 
> radioactive goto.  Does your language have restrictions that make such a 
> pairing
> comprehensible to average programmers like myself?  I assume so, so my real
> question is: what distributed programming languages / paradigms is your 
> language
> inspired by?
>
> The usage of leiningen *and* deps.edn is interesting.  How are they 
> combined?   
> Do you handle all deps with deps.edn, and use lein as a task runner, or...?
> (After reading the post comments, it seems somewhat more complicated.
> Complicated build processes: I am shocked.  Shocked, I tell you.)
>
> Using with-redefs + concurrency has bitten me before.  Is it not a problem
> because your tests are high-level and run sequentially, so the per-test 
> redefs
> don't interfere with each other? (I think this is mostly answered by the
> "Deterministic simulation" section, but answer if you'd like.)
>
> The "no-op functions as a structured event log" pattern is interesting.  
> Did you
> try out any other methods, like implementing the event logging as separate
> components, or directly redef'ing the side-effecting code?  If so, what 
> are the
> pros & cons you considered?
>
> Are these testing methods just for internal use, or are you planning to 
> make 
> them easy to use by the end-users of your language? I have a lot of 
> questions
> about your language, actually, but I'll just wait for your demo.
>
> It *is* an ambitious project, and I hope it succeeds.  (Since most 
> software
> nowadays becomes part of "distributed systems" and they are, frankly, a 
> PITA.)
>
> Cheers,
> Leif
>
>
> On Friday, June 4, 2021 at 7:53:43 PM UTC-6 brent@gmail.com wrote:
>
>> Haven't read the article yet but thanks for the work, will definitely 
>> give it a read asap. After hearing (already a while ago) that Storm moved 
>> to Java, I'm happy to hear Clojure is still actively used (and even 
>> instrumental) in your current work.
>>
>> On Thursday, June 3, 2021 at 11:42:36 PM UTC-4 natha...@gmail.com wrote:
>>
>>> Probably not in the near future. Once we're close to being ready for 
>>> production usage, we'll be releasing a preview post demonstrating how our 
>>> product works through an example of using it to replicate a widely-used 
>>

Re: Tour of our 250k line Clojure codebase

2021-06-10 Thread Nathan Marz
It all comes down to the programming paradigm in which the continuations 
are expressed. In our language continuations fit intuitively within the 
normal ways in which computation happens, whereas in a language like Scheme 
continuations are "abnormal" relative to run-of-the-mill Scheme concepts. 
Continuations were never an original goal for me and implementing them was 
sort of an accident – while looking at the compiler code one day I realized 
if I switched a couple fields I had continuations. It was only later that I 
learned what a powerful primitive they are for building distributed 
systems. 

That's about as much illumination as I can give without showing example 
code. 

On Wednesday, June 9, 2021 at 5:45:16 PM UTC-10 tbald...@gmail.com wrote:

> On Wed, Jun 9, 2021 at 6:14 PM Nathan Marz  wrote:
>
>> Continuations in our language are expressed very differently than has 
>> existed before (e.g. like in Scheme). They fit intuitively within the 
>> overall paradigm our language implements. Far from being complex or hard to 
>> comprehend, continuations are the key construct that enables us to avoid 
>> mountains of complexity that exist otherwise in distributed systems. I know 
>> this from personal experience building distributed systems in the past. The 
>> degree to which continuations help write asynchronous, reactive, and 
>> parallel code is huge. It would be clear if you saw the language in action, 
>> but we're keeping it under wraps for now.
>>
>
> Could you expound on that for those of us who are familiar with 
> continuations in many forms, and languages? While delimited, multi-prompt, 
> multi-shot continuations are certainly helpful in reducing complexity 
> compared to traditional full continuations, they still result in spaghetti 
> code unless coupled with some sort of typing and/or algebraic effect 
> system. Most research in this space shows some promise, so I’m interested 
> in seeing how you’ve solved the many well documented problems with these 
> approaches.
>
> -- 
> “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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/915e2e8a-58eb-4ba8-9842-a1a5755bb307n%40googlegroups.com.


Announcing Clojure API for Rama: build end-to-end scalable backends in 100x less code

2023-10-11 Thread Nathan Marz
I'm happy to announce we've released a Clojure API for Rama in the latest 
release. We've published an introductory blog post 
 
that culminates in building a scalable auction application with timed 
listings, bids, and notifications in only 100 lines of code.

Rama is a new programming platform that enables end-to-end scalable 
backends to be built in their entirety in 100x less code than otherwise. 
It's a "programmable datastore on steroids" where you mold your datastore 
to fit your application rather than the other way around.

When we announced Rama in August, we demonstrated its power by building and 
operating a Twitter-scale Mastodon instance in only 10k lines of code. This 
is 100x less code than the 1M lines of code Twitter wrote to do the 
equivalent at scale. The instance had 100M bots posting 3,500 times per 
second at 403 average fanout, as well as a highly unbalanced social graph 
with some users having over 22M followers.

We've also published reference documentation 
 and API docs 
 for the Clojure API. 
Happy to answer questions here, on the rama-user 
 Google group, or on the #rama 
channel on Clojurians.

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


Re: Avoiding nested ifs...

2016-05-26 Thread Nathan Davis
First off, I should say that you should first consider alternative 
approaches before considering the options below.  For example, cond seems 
well-suited for this particular case:


(defn verify-position[pos type]
 (cond (nil? pos) true
   (or (> pos 90)
   (< pos 0)) false

   .
   .
   .

   :else true))


However, sometimes you really do want imperative-style control flow.  Two 
possibilities come to mind here:

   1. Monads (e.g., algo.monads <https://github.com/clojure/algo.monads>)
   2. Continuations (e.g., pulley.cps 
   <https://github.com/positronic-solutions/pulley.cps>)

In fact, monads and (delimited) continuations are isomorphic.  The main 
difference is one of view-point -- the essence of monads is the composition 
of computations; the essence of continuations is control flow.

For a monadic approach, I would start with something like the "Maybe" 
monad, but add a monadic 'bail' operator (to use your terminology and avoid 
conflicting with the common use of 'return' as one of the fundamental 
operators on monads).  Essentially, 'bail' would be constructed to abort 
the "current computation".  Then if you implement a function in terms of 
the 'bailing' monad (and encapsulate the effect to that function), you can 
use 'bail' to effectively return a value from the function at any point in 
the computation.

With continuations, all you need is an "abortive" continuation back to the 
call-site of the function.  With pulley.cps, this is easily accomplished 
using call-cc / let-cc.  For example, here's your first example in terms of 
let-cc:


;; Note:  This must be wrapped in an`cps` form,
;;or use `def` along with `cps-fn`
(defn verify-position[pos type]
 (let-cc [return]
   (when(nil? pos)
 (return true))

(when (or (> pos 90)
  (< pos 0))
  (return false))

.
.
.

true))


Basically, we just wrap the function's body in let-cc.  This gives us 
access to the current continuation of function (i.e., the place where the 
function was called).  In this case, we bind that continuation to the name 
return.  By invoking return, we abort the current continuation at that 
point and restore the captured continuation.  I've used when instead of if 
to check for conditions that return, because it more clearly conveys that 
effects are used.  But in any case, it's a pretty straight-forward 
conversion from the python code.

Using continuations you can build more complex control flows as well.  For 
instances, you can "return" not just from a function but from any point in 
the computation -- all you need to do is have access to the continuation at 
that point.  And since pulley.cps makes continuations first-class objects, 
you can bind them to variables (including dynamic vars), pass/return them 
to/from functions, etc.

Hopefully this helps.  Like I said, explore other options first, but 
continuations and/or monads are there if you decide to use them.

Nathan Davis

On Thursday, May 26, 2016 at 9:50:24 AM UTC-5, John Szakmeister wrote:
>
> I'm very much a fan of bailing out early in imperative 
> programming as it helps to avoid a bunch of nested if conditions 
> that are to follow and read.  This typically comes up when 
> checking arguments to ensure that they're valid (in range, of 
> acceptable values, etc).  One of the major stumbling blocks 
> I've had when writing Clojure is to find a good way to keep code 
> concise, but readable. 
>
> For instance, take a snippet like this: 
>
> def verify_position(pos, type): 
> # It's acceptable to have a None value--it just means don't 
> # change the position for the axis. 
> if pos is None: 
> return True 
>
> # Anything outside our limits is invalid. 
> if (pos > 90) or (pos < 0): 
> return False 
>
> if type == 'switched' and pos not in (0, 90): 
> # Switched axes only allow 0 and 90, and nothing in 
> # between. 
> return False 
>
> if type == 'dual': 
> # We can't control the value on this axis, so anything 
> # other than None is invalid. 
> return False 
>
> return True 
>
>
> I find this very readable in that along the way, I can start 
> throwing things off the raft: after the first condition, I don't 
> need to worry about None being present.  After the second, I 
> know the value is within limits, etc.  I have a hard time 
> translating the above into (what I believe) is readable Clojure. 
> Here's my stab at it: 
>
> (defn verify-pos [pos axis-type] 
>   (if (nil? pos) 
> ;; nil means don't move the axis. 
> true 
> (case axis

Re: reader conditional not handling defmacro?

2016-05-26 Thread Nathan Davis
I can't reply to the thread on the Dev list, but here's my take.

Unless I'm missing something, it seems to me that most these issues could 
be resolved by having a dynamic var that gets set during macro expansion 
according to the target platform.  For instance, *compiler-target* is set 
to :clj or :cljs, depending on whether we're compiler for the JVM or 
Javascript.  If we want to be a little more sophisticated, *compiler-target* 
could 
be a set whose members are the same keywords that were "active" at 
read-time.  That would have the additional convenience that 
*compiler-target* would act as a predicate, indicating whether a particular 
"feature" is available for the target platform.

Then if a macro needs to be expanded in a certain way for certain 
platforms, it can just consult *compiler-target*.

Anyway, that's my 2-cents.

Nathan Davis


On Sunday, May 22, 2016 at 5:57:14 PM UTC-5, Herwig Hochleitner wrote:
>
> This thread just came up, while I was in the process of composing a mail 
> on this topic to clojure-dev: 
> https://groups.google.com/d/msg/clojure-dev/f6ULUVokXrU/3uue5okSAgAJ
>
> 2016-05-20 23:22 GMT+02:00 Dan Burton >
> :
>
>> What about something like
>>
>> (def obj #?(:clj Object :cljs js/Object))
>>
>
> Unfortunately, doesn't work for cases, where you need to generate 
> different syntax, eg `(try .. (catch Throwable e ...))` vs `(try ... (catch 
> :default e ...))`.
>
>

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

2016-05-27 Thread Nathan Davis
Alex,

On the Dev list, you mentioned you had discussed this several times with 
Rich and others, but were unable to reach concensus.  May I ask what the 
hangup is (i.e., what reservations / objections were expressed) and what 
other options came out of those discussions?

Nathan Davis

On Friday, May 27, 2016 at 7:39:15 AM UTC-5, Alex Miller wrote:
>
> That is one option and is in the ballpark of 
> http://dev.clojure.org/jira/browse/CLJ-1750.
>
> On Thursday, May 26, 2016 at 11:47:09 PM UTC-5, Nathan Davis wrote:
>>
>> I can't reply to the thread on the Dev list, but here's my take.
>>
>> Unless I'm missing something, it seems to me that most these issues could 
>> be resolved by having a dynamic var that gets set during macro expansion 
>> according to the target platform.  For instance, *compiler-target* is 
>> set to :clj or :cljs, depending on whether we're compiler for the JVM or 
>> Javascript.  If we want to be a little more sophisticated, 
>> *compiler-target* could be a set whose members are the same keywords 
>> that were "active" at read-time.  That would have the additional 
>> convenience that *compiler-target* would act as a predicate, indicating 
>> whether a particular "feature" is available for the target platform.
>>
>> Then if a macro needs to be expanded in a certain way for certain 
>> platforms, it can just consult *compiler-target*.
>>
>> Anyway, that's my 2-cents.
>>
>> Nathan Davis
>>
>>
>> On Sunday, May 22, 2016 at 5:57:14 PM UTC-5, Herwig Hochleitner wrote:
>>>
>>> This thread just came up, while I was in the process of composing a mail 
>>> on this topic to clojure-dev: 
>>> https://groups.google.com/d/msg/clojure-dev/f6ULUVokXrU/3uue5okSAgAJ
>>>
>>> 2016-05-20 23:22 GMT+02:00 Dan Burton :
>>>
>>>> What about something like
>>>>
>>>> (def obj #?(:clj Object :cljs js/Object))
>>>>
>>>
>>> Unfortunately, doesn't work for cases, where you need to generate 
>>> different syntax, eg `(try .. (catch Throwable e ...))` vs `(try ... (catch 
>>> :default e ...))`.
>>>
>>>

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

2016-05-31 Thread Nathan Marz
Specter is a library for querying and transforming nested data structures 
concisely and efficiently. The 0.11.0 release is a huge milestone that 
implements something which for the better part of the past year I wasn't 
sure was possible. In summary: now you don't have to do anything special to 
make Specter run fast. The prior work of manually precompiling your paths 
for performance is now seamlessly automated.

As part of the release, wrote up a detailed guide to how Specter achieves 
its high performance. Should also be an interesting read for anyone curious 
about the design of a very powerful Clojure library. 
https://github.com/nathanmarz/specter/wiki/Specter-0.11.0:-Performance-without-the-tradeoffs

Note that there are some backwards incompatible changes in this release, so 
please read the changelog below. The core select/transform/etc. functions 
have changed to macros, and there have been some name updates to clean up 
the terminology. Updating your projects to the new changes should be very 
easy.



Changes:

* New `path` macro does intelligent inline caching of the provided path. 
The path is factored into a static portion and into params which may change 
on each usage of the path (e.g. local parameters). The static part is 
factored and compiled on the first run-through, and then re-used for all 
subsequent invocations. As an example, `[ALL (keypath k)]` is factored into 
`[ALL keypath]`, which is compiled and cached, and `[k]`, which is provided 
on each execution. If it is not possible to precompile the path (e.g. [ALL 
some-local-variable]), nothing is cached and the path will be compiled on 
each run-through.

* BREAKING CHANGE: all `select/transform/setval/replace-in` functions 
changed to macros and moved to com.rpl.specter.macros namespace. The new 
macros now automatically wrap the provided path in `path` to enable inline 
caching. Expect up to a 100x performance improvement without using explicit 
precompilation, and to be within 2% to 15% of the performance of explicitly 
precompiled usage.

* Added `select*/transform*/setval*/replace-in*/etc.` functions that have 
the same functionality as the old `select/transform/setval/replace-in` 
functions.

* Added `must-cache-paths!` function to throw an error if it is not 
possible to factor a path into a static portion and dynamic parameters.

* BREAKING CHANGE: `defpath` renamed to `defnav`

* BREAKING CHANGE: `path` renamed to `nav`

* BREAKING CHANGE: `fixed-pathed-path` and `variable-pathed-path` renamed 
to `fixed-pathed-nav` and `variabled-pathed-nav`

* Added `must` navigator to navigate to a key if and only if it exists in 
the structure

* Added `continous-subseqs` navigator

* Added `ATOM` navigator (thanks @rakeshp)

* Added "navigator constructors" that can be defined via 
`defnavconstructor`. These allow defining a flexible function to 
parameterize a defnav, and the function integrates with inline caching for 
high performance.

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

2016-05-31 Thread Nathan Marz
No, because that global mutable variable would need to be specifiable by 
Specter on usage of the library. For example, if you wrote:

(defn foo []
  (select [:a :b] {:a {:b 1}}))

`select` has no ability to control anything outside the context of its 
form. It certainly can't wrap `foo` to put a volatile field in its closure. 
So for the static-field idea, it would expand to something like:

(defn foo []
  (static-field [pathcache]
 (if-not pathcache (set! pathcache ...))
 ...
 ))



On Tuesday, May 31, 2016 at 3:15:26 PM UTC-4, puzzler wrote:
>
> In your writeup, you say that there would be further speed benefits if you 
> could have a global mutable variable within the context of a function (like 
> a static field).
>
> Can't you effectively accomplish that already in Clojure like this?:
>
> (let [mycache (volatile! nil)]
>   (defn foo []
>   ...)))
>

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

2016-05-31 Thread Nathan Marz
Great idea on interning a var at macro-time and then using it later! I did 
something similar for the ClojureScript implementation of inline caching 
but for some odd reason didn't think of doing it for the Clojure version. 
I'm seeing a big performance improvement for the [:a :b :c] benchmark from 
my post - about 15% faster than before and now very close to full manual 
precompilation.

Here's the 
commit: 
https://github.com/nathanmarz/specter/commit/fbca7ab99c84d93a28f7773f1c56be12e1a939a3


On Tuesday, May 31, 2016 at 9:33:29 PM UTC-4, puzzler wrote:
>
> I think this is an interesting problem, so here are some additional 
> brainstorms on the issue that may or may not be useful...
>
> One strategy to create a global mutable variable from inside the function 
> would be to use def at macroexpansion time to create a var, and then just 
> refer to it in the expansion, like this:
>
> (defmacro expand-to-something-with-mutable-global []
>   ; At macroexpansion time, create a (private) var containing a volatile.
>   (let [global-name (gensym "cache")]
> (eval `(def ^:private ~global-name (volatile! nil)))
> ; Now macro can refer to this var, can use as a cache, etc.
> `(if-let [cache-contents# (deref ~global-name)] 
>(do-something-with cache-contents#)
>(reset! ~global-name init-value-for-cache
>
> Not sure if this would be any faster than ConcurrentHashMap, but I would 
> guess that it would be if Clojure resolves the location of the var in 
> memory once, at compile-time.
>
> A related technique would be for Specter to maintain an ArrayList of 
> volatiles.  At macroexpansion time, you add a fresh volatile to the end of 
> the ArrayList, noting the index of its location, and then inside the macro 
> you hardcode a lookup in the ArrayList at the specific index to retrieve 
> the volatile containing the cache for this particular expansion.  I would 
> expect this to be faster than looking up in a hash map, although there'd be 
> some additional concurrency/locking details to worry about that I assume 
> ConcurrentHashMap handles for you.
>
> Or just use an ArrayList's slot directly as the cache (rather than storing 
> a volatile to add a level of indirection), but then the concurrency 
> logistics would be even more complicated.
>
> On Tue, May 31, 2016 at 12:50 PM, Nathan Marz  > wrote:
>
>> No, because that global mutable variable would need to be specifiable by 
>> Specter on usage of the library. For example, if you wrote:
>>
>> (defn foo []
>>   (select [:a :b] {:a {:b 1}}))
>>
>> `select` has no ability to control anything outside the context of its 
>> form. It certainly can't wrap `foo` to put a volatile field in its closure. 
>> So for the static-field idea, it would expand to something like:
>>
>> (defn foo []
>>   (static-field [pathcache]
>>  (if-not pathcache (set! pathcache ...))
>>  ...
>>  ))
>>
>>
>>
>> On Tuesday, May 31, 2016 at 3:15:26 PM UTC-4, puzzler wrote:
>>>
>>> In your writeup, you say that there would be further speed benefits if 
>>> you could have a global mutable variable within the context of a function 
>>> (like a static field).
>>>
>>> Can't you effectively accomplish that already in Clojure like this?:
>>>
>>> (let [mycache (volatile! nil)]
>>>   (defn foo []
>>>   ...)))
>>>
>> -- 
>> 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.


[ANN] Specter 0.11.1 released

2016-06-08 Thread Nathan Marz
Released Specter 0.11.1 with bug fixes and performance improvements. It 
also has a new README which I hope provides a better introduction to the 
project. https://github.com/nathanmarz/specter

The navigators are now very intelligent about using the best means possible 
for traversing data structures. For example, ALL uses mapv on vectors, 
reduce-kv on small maps, and reduce-kv in conjunction with transients on 
larger maps.

Full changelog below:

* More efficient inline caching for Clojure version, benchmarks show inline 
caching within 5% of manually precompiled code for all cases
* Added navigators for transients in com.rpl.specter.transient namespace 
(thanks @aengelberg)
* Huge performance improvement for ALL transform on maps and vectors
* Significant performance improvements for FIRST/LAST for vectors
* Huge performance improvements for `if-path`, `cond-path`, `selected?`, 
and `not-selected?`, especially for condition path containing only static 
functions
* Huge performance improvement for `END` on vectors
* Added specialized MAP-VALS navigator that is twice as fast as using [ALL 
LAST]
* Eliminated compiler warnings for ClojureScript version
* Dropped support for Clojurescript below v1.7.10
* Added :notpath metadata to signify pathedfn arguments that should be 
treated as regular arguments during inline factoring. If one of these 
arguments is not a static var reference or non-collection value, the path 
will not factor. 
* Bug fix: `transformed` transform-fn no longer factors into `pred` when an 
anonymous function during inline factoring
* Bug fix: Fixed nil->val to not replace the val on `false`
* Bug fix: Eliminate reflection when using primitive parameters in an 
inline cached path

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

2016-06-27 Thread Nathan Davis
One common problem we deal with in programming goes like this:

I have certain inputs.  I desire a certain output.  What function (or 
combination of functions) will give me the desired output?

Since a relation makes no distinction between "inputs" and "outputs", 
relational programming is one way we can approach this problem.  All we 
need is a relation that relates a program, its input(s), and its output.  
Then, by fixing the inputs and output, we can generate programs that 
produce the desired output.

We could use such a tool as an aid to guide us in writing programs.  I.e., 
we can basically write queries to find core functions (and combinations 
thereof) that produce the desired output.  But we can take this even 
further.  In general, we can write specifications for functions.  From this 
specification, we can generate programs that conform to the specification.

But we don't have to stop there.  Instead of specifying (either entirely or 
in part) the inputs and output, we can fix and leave free any components of 
the relation to any degree.  For example, we might (partially) specify a 
program and its output.  We can then generate inputs that result in the 
given output.

So, at least in theory, a relational lisp interpreter would give us (in 
many respects) the "ultimate" development tool.  If we leave everything 
free (i.e., no restrictions on the programs, its inputs, or the output), 
then we can generate every possible lisp program.  This isn't very useful 
per se.  But by partially specifying one or more components of the 
relation, we provide a priori knowledge to help guild the process.  Even if 
it is not enough to produce the desired result immediately, we might be 
able to gain further insight into the specific problem we are trying to 
solve.  From this, we can refine the specification.  We can iterate this 
process until we arrive at an acceptable solution.  This gives us a 
development process where human and machine "collaborate" to derive a 
program.

Unfortunately, the power of relational programming comes at a cost.  That 
cost is divergence (non-termination of the search algorithm).  It is 
extremely tricky to write relations in a way that guarantee (when there are 
a fininte number of solutions) that (a) all soutions will be found in a 
finite amout of time, and (b) if there are no (more) solutions, the search 
terminates in a finite amount of time.  This largely boils down to limiting 
the search space to a finite domain (while ensuring no valid results are 
excluded).  This seems simple, but is far from trivial in practice (see, 
for instance, the chapter on relational arithmetic in Byrd's thesis).

The possibility of infinite results sets presents its own problems, such as 
how to output such an infinite set.  core.logic uses Clojure's lazy seqs 
for this.  Minikanren's original implementation in Scheme requires limiting 
the number of results rendered from an inifinite result set.

Furthermore, whether the solution set is inifinite or finite, it can be 
difficult to separate "interesting" solutions from "mundane" solutions.  
Minikanren's interleaving search can help with this (especially when the 
solution set is infinite), but is not a panacea.

In the case of generating programs, it would also be desirable that the 
*generated* programs are guaranteed to terminate.  However, is has been 
shown that there algorithm that is capable of determining (for all possible 
programs) if a given program always terminates for any input.  So it would 
appear that we must choose between the possibility of non-terminating 
programs and limiting the range of generated programs to those which (the 
generative system) can prove to be terminating.  Different situations may 
call for different choices.

Hopefully this helps highlight some of the (theoretical) use-cases of a 
relational lisp interpreter, as well as provide some insight into 
the difficulties in implementing such an interpreter.

 

>
> On Wednesday, June 22, 2016 at 9:22:35 PM UTC-5, Ashish Negi wrote:

One usecase of a "relational" lisp interpretter 
>
>
>
> I am reading joy of clojure. In the "forward to second edition" William E 
> Byrd and Daniel P Firedman says :
>
>
>
> *As with recursion, the art of defining little languages encourages—and 
> rewards—wishful thinking. You might think to yourself, “If only I had a 
> language for expressing the rules for legal passwords for my login system.” 
> A more involved example—a story, really—started several years ago, when we 
> thought to ourselves, “If only we had the right relational language, we 
> could write a Lisp interpreter that runs backward.”[2] 
>  
> What does this mean? *
>
>
> *An interpreter can be thought of as a function that maps an input 
> expression, such as (+ 5 1), onto a value—in this case, 6. We wanted to 
> write an interpreter in the style of a relational database, in which eit

Specter 0.12.0 released

2016-08-05 Thread Nathan Marz
Specter 0.12.0 has been released with many new features, performance 
improvements, and bug fixes. There are a few highlights:

1. Performance of `select` has been greatly improved. Specter no longer 
creates intermediate vectors during navigation and has performance very 
close to transducers (for overlapping use cases).

2. A new `traverse` operation has been added that lets you do 
high-performance reductions over nested elements in a data structure. It 
does so without materializing any intermediate sequences. For example, this 
code adds up all the even values for :a keys in a sequence of maps:

(reduce + (traverse [ALL :a even?] [{:a 1} {:a 2 :b 3} {:a 4}]))
;; => 6

3. `multi-transform` operation has been added for doing multiple 
transformations at one time. This leads to better performance when the 
transforms overlap a lot in how they navigate to their values. For example:

(multi-transform
  [ALL
   ALL
   MAP-VALS
   (multi-path [:a (terminal inc)]
   [:b :c (terminal-val 99)])]
  data)
  


Note that this release changes the semantics of the select* path for 
navigators, so if you have custom navigators those may need to be updated. 
Otherwise, no updates are needed. See the docstring on the Navigator 
protocol for more details.


Full list of changes:


* BREAKING CHANGE: Changed semantics of `Navigator` protocol `select*` in 
order to enable very large performance improvements to `select`, 
`select-one`, `select-first`, and `select-one!`. Custom navigators will 
need to be updated to conform to the new required semantics. Codebases that 
do not use custom navigators do not require any changes. See the docstring 
on the protocol for the details. 

* Added `select-any` operation which selects a single element navigated to 
by the path. Which element returned is undefined. If no elements are 
navigated to, returns `com.rpl.specter/NONE`. This is the fastest selection 
operation.

* Added `selected-any?` operation that returns true if any element is 
navigated to.

* Added `traverse` operation which returns a reducible object of all the 
elements navigated to by the path. Very efficient.

* Added `multi-transform` operation which can be used to perform multiple 
transformations in a single traversal. Much more efficient than doing the
transformations with `transform` one after another when the transformations 
share a lot of navigation. `multi-transform` is used in conjunction with 
`terminal` and `terminal-val` – see the docstring for details.

* Huge performance improvements to `select`, `select-one`, `select-first`, 
and `select-one!`

* Huge performance improvement to `multi-path`

* Added META navigator (thanks @aengelberg)

* Added DISPENSE navigator to drop all collected values for subsequent 
navigation

* Added `collected?` macro to create a filter function which operates on 
the collected values.

* Error now thrown if a pathedfn (like filterer) is used without being 
parameterized

* Performance improvement for ALL and MAP-VALS on small maps for Clojure by 
leveraging IMapIterable interface

* Added low-level `richnav` macro for creating navigators with full 
flexibility

* Bug fix: multi-path and if-path now work properly with value collection

* Bug fix: END, BEGINNING, FIRST, LAST, and MAP-VALS now work properly on 
nil

* Bug fix: ALL and MAP-VALS now maintain the comparator of sorted maps

* Bug fix: Using value collection along with `setval` no longer throws 
exception

* Bug fix: Fix error when trying to use Specter along with AOT compilation

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


grouping and mapping

2016-08-14 Thread Nathan Smutz
Just to put the basic Clojure out there:

(->> (group-by first foos) 
 (map (fn [[key col]] 
  [key (mapv (comp clojure.string/upper-case second) 
 col)]))
 (into {})

Kudos to Moe,Christopher and Simon.

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

2016-09-06 Thread Nathan Marz
Specter 0.13.0 has been released. Specter is a library that supercharges 
your ability to query and transform regular data structures.
https://github.com/nathanmarz/specter

The new version rewrites the core nearly from scratch to make Specter 
faster and more dynamic. This post gives a detailed explanation of why and 
how Specter's implementation changed: 
https://github.com/nathanmarz/specter/wiki/Specter's-inline-caching-implementation

Also published a benchmark along with the release comparing Specter against 
various manual ways of doing common operations. This includes comparisons 
with lazy operations, transducers, transients, clojure.walk, and other 
miscellaneous functions/interfaces. 
https://gist.github.com/nathanmarz/b7c612b417647db80b9eaab618ff8d83

The full changelog for the release is here: 
https://github.com/nathanmarz/specter/blob/master/CHANGES.md

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


Random xxxx-init.clj files created in root of project.

2016-09-24 Thread Nathan Smutz
I have a Figwheel project that kept generating files with random names 
ending in -init.clj when "lein figwheel" was run.  The files have code 
related to figwhee-sidecar and starting up the REPL.
i followed some breadcrumbs ( 
https://github.com/emezeske/lein-cljsbuild/issues/394 ) suggesting it's to 
do with Lein and an environment variable.
I've confirmed that the files don't appear in the root of my project when I 
unset the environment variable LEIN_FAST_TRAMPOLINE.
Does anyone have any insight on what's going on with that?

Evidently, something I've installed likes that set (LightTable? Cider? 
Spacemacs?); as it seems to be set on startup.  I'm sure other people have 
similar stuff.  
Might there be anything I can fix in my project itself so it doesn't piddle 
into it's root directory when I share it with someone else?


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


[ANN] pulley.thread-local 0.1.0

2016-10-04 Thread Nathan Davis
Hello everyone,

I'm please to announce the release of a new project, pulley.thread-local 
<https://github.com/positronic-solutions/pulley.thread-local/tree/release-0.1.0>.
  
This is a simple project that brings Java's ThreadLocal and Clojure's IAtom 
interface together.  The result is an atom-like interface for thread-local 
bindings.

Due to the simplicity of the project, I decided to experiment with Literate 
Programming.  All the code is contained within Readme.org.  Feedback / 
advice on this structure (and other areas of the project too) are 
definitely welcome.

Nathan Davis

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


Re: any? in clojure 1.9.0 alpha

2016-11-13 Thread Nathan Smutz
Is there a Tricky Names for Nubies page?
We might save some stack-overflow searches.

In the spirit of Honest Trailers: if we named functions for what they do:
or-> first-truthy
some  -> first-satisfying
some? -> not-nil?
any?  -> return-true

Are there others?

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

2016-12-04 Thread Nathan Smutz
If you're new to tooling, and want to try Clojure right away, I strongly 
recomend Oakes' Nightcode.  Install the JDK and Nightcode, and you'll have 
Clojure with its popular build tools (Leiningen and Boot) built in, 
beginner-friendly parenthesis management, LightTable-like instant evaluation in 
the margins, and a connected REPL when you run your project.
https://sekao.net/nightcode/

Stack-vomit error messages are the main reason I'd have to think hard before 
recommending Clojure as a first/educational language.  
Apart from the clarity of the smidge of relevant info in there, there's the 
aggravation of having to stop thinking about your problem to play Where's 
Waldo, the Line-Number Edition.

I've heard there have been some attempts at error-mesaage translators.  Does 
anyone have a recommendation?

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


Specter 0.13.2 released

2016-12-21 Thread Nathan Marz
Specter 0.13.2 has been released, available from 
Clojars https://clojars.org/com.rpl/specter

Specter supercharges your ability to work with regular data structures. 
This release contains a few bug fixes and is likely the last release before 
1.0.

Changes:

* Bug fix: Fix race condition relating to retrieving path from cache and 
AOT compilation
* Bug fix: LAST no longer converts lists to vectors
* Bug fix: Workaround issue with aot + uberjar

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


core.logic: faking sets and "sufficient" results

2016-12-28 Thread Nathan Smutz
Hi All,

I work for a university and I've been commissioned to write a program that 
proves whether majors can be reasonably completed in 4 years.  core.logic 
has seemed the obvious tool.  The output should be a set of scheduled 
course-offerings satisfying major requirements, course-prereqs, etc. It 
looks like CLP(Set) is still on the wishlist.  
Could someone point me to the current best-practice for faking sets? 
The obvious thing seem to use membero operations on some list L while 
declaring (distincto L) and forcing an ordering so you get combinations 
instead of permutations.  I'm sure there's a better way than (pred L #(= % 
(some-sort-function %)).  If that's the way it's gotta be, then I suppose 
you'd sort on the object IDs to be generic.  (I recall somewhere seeing a 
function returning unique IDs for Clojure objects.)

A further goal would be to output workable education plans without any 
superfluous courses.
I have constraints like "6 credits from any of courses A, B, C, D..." In 
that case if course A is 4 credits and course B is 3 credits, then you want 
[A B] represented in the solution (one more than the six credits required; 
but both are necessary) but you don't want [A B C] for some course C (two 
courses enough and the third is noise).  The ideas I have for that seem 
kind of brute-force.  Is there a built in behavior for this I might not be 
aware of?

The more I think of it, the more complicated this kludge seems to get.  Am 
I barking up the wrong tree?

Best,
Nathan

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


Re: Cyclic namespace dependencies!

2016-12-30 Thread Nathan Davis

On Friday, December 30, 2016 at 10:13:49 AM UTC-6, Mars0i wrote:
>
> I love Clojure.  But:  My number one complaint about it is that the 
> compiler won't allow cyclic namespace dependencies.  I am not a 
> compiler-writer, but as far as I can tell the only reason for this 
> restriction is ... philosophical.  It forces bad code organization, and it 
> wastes time.  Those who think that cyclic code is an evil are free to 
> encourage its avoidance.  I'm happy to avoid it!  But sometimes I can't.  I 
> absolutely hate the cyclic namespace restriction.  Drives me crazy when I 
> am forced to encounter it.
>
>
First of all, there is no such restriction.  So there is no reason for it, 
philosophical or otherwise.  It is true that if you declare all your 
dependencies in ns forms, you will get an exception with cyclic 
namespaces.  That's a *good* thing -- the result probably wouldn't be what 
you want anyway.  However, there's no requirement that all dependencies be 
declared using ns -- you can use require at any time.

What *is* required is that all the vars a form uses exist when it is 
compiled.  The reason for this is purely technical -- resolving symbols to 
vars at compile time means less work (more efficiency) at run time.
 

> My latest case is that I'm trying to debug a weird Java interop 
> problem--something that works in one app I've written, in which I ended up 
> putting most of the application into one file, but doesn't work in the one 
> I'm working on now.   And I had finally come up with a clever way of 
> avoiding sticking most of the code into one namespace.  I'd worked around 
> the conflict between Clojure's requirements and the requirements of the 
> Java library I'm using.  But now there's this one problem, and I want to 
> try an experiment to see whether it fixes the problem.  It looks like I'm 
> going to have to pack all of the code into one file and rewrite everything 
> that that necessitates just for this purpose. Aghh.
>
>
Perhaps if you provided a coherent description the specifics of your 
problem, someone would be able to suggest a satisfactory solution.
 

> I have sometimes ranted a bit in this group, and in the end some of my 
> rants were unreasonable.  I don't think this is unreasonable.  The cyclic 
> dependency restriction is absurd.  I'm not trying to start a flame ware.  I 
> feel strongly about this, and I'm frustrated.
>
>
What would be reasonable is asking questions about things until you 
understand them well enough to be in a position to make an informed 
opinion.  In this case:


   1. Clojure does allow namespaces to refer to each other (just maybe not 
   how you've tried).
   2. There are plenty of technical considerations when it comes to mixing 
   dynamic languages and cyclic references.  Cyclic namespaces are a subset of 
   this problem.  So describing restrictions on cyclic namespaces (whether 
   real or imagined) as "absurd" is absurd.


A rant is just a rant, regardless of whether a problem actually exists.  If 
you feel strongly about something and only rant about it, don't be 
surprised when you feel frustrated.  Frustration can be relieved by 
solutions.  If you don't understand the problem enough to present a 
solution, ask questions until you do.  Don't expect others to do all the 
work -- *especially* after ranting about it.

 

> What I want: I'm not trying to make everyone sit around tapping their 
> fingers while code to goes through multi-pass compliations.  All I'm asking 
> for is a compiler option that will allow cyclic dependencies when requested.
>
>
I don't think multi-pass compilation would play well with things like 
macros or REPL-based development, so I doubt we'll have to worry about that.
 

> I'm pretty sure that the way I've put things above illustrates some 
> ignorance on my part, but still ... how hard can this be?  It's a 
> reasonable thing to ask of a sophisticated compiler.
>
>
Questions like "How hard can this be?" are not only unconstructive, but 
they also belie your sincerity in resolving your self-claimed ignorance. 

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


Contribute Specter to Clojure core?

2017-02-14 Thread Nathan Marz
One of the most common questions I get about Specter is whether it will 
ever become part of Clojure core. I think it's an interesting proposal and 
would like to see what the community and core team thinks.

The primary reason for contributing would be that Specter makes Clojure a 
stronger language. For a language that embraces simplicity, I've always 
viewed the complexity of dealing with nested data structures a glaring 
weakness of Clojure. The existing stuff in Clojure, like clojure.walk, 
zippers, update-in, etc., just doesn't cut it. This problem is very common, 
and Specter completely solves it with near-optimal performance.

The main thing that makes me hesitate to suggest this is getting 
bottlenecked on Clojure's dev process. However, Specter is very well 
developed at this point so it doesn't need to move fast anymore.

Please share your thoughts.

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

2017-02-15 Thread Nathan Marz
Alex – care to elaborate? When I get this question it would be nice to be 
able to tell people why the core team isn't interested.

Beau – new navigators can easily be provided in external libraries. The 
core of Specter (navigator composition and inline compilation/caching) is 
very stable at this point so I don't anticipate it needing much change.


On Tuesday, February 14, 2017 at 8:19:20 PM UTC-5, Beau Fabry wrote:
>
> > The main thing that makes me hesitate to suggest this is getting 
> bottlenecked on Clojure's dev process.
>
> Imo this is a big deal. I like the way specter has the ability to add new 
> generally useful navigators and paths with new versions as people 
> "discover" them, I don't think that's a great fit for the overhead of a 
> language release process.
>
> On Wednesday, February 15, 2017 at 8:02:55 AM UTC+11, Nathan Marz wrote:
>>
>> One of the most common questions I get about Specter is whether it will 
>> ever become part of Clojure core. I think it's an interesting proposal and 
>> would like to see what the community and core team thinks.
>>
>> The primary reason for contributing would be that Specter makes Clojure a 
>> stronger language. For a language that embraces simplicity, I've always 
>> viewed the complexity of dealing with nested data structures a glaring 
>> weakness of Clojure. The existing stuff in Clojure, like clojure.walk, 
>> zippers, update-in, etc., just doesn't cut it. This problem is very common, 
>> and Specter completely solves it with near-optimal performance.
>>
>> The main thing that makes me hesitate to suggest this is getting 
>> bottlenecked on Clojure's dev process. However, Specter is very well 
>> developed at this point so it doesn't need to move fast anymore.
>>
>> Please share your thoughts.
>>
>

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

2017-03-01 Thread Nathan Marz
Specter is a library that supercharges your ability to work with regular 
Clojure data structures. Happy to announce I just released 1.0, a huge 
milestone for the project.

I also wrote a post about why I consider Specter to be Clojure's missing 
piece: http://nathanmarz.com/blog/clojures-missing-piece.html

This release implements the most requested feature for Specter, which is 
the ability to easily remove values from maps or sequences. Examples:

(setval [ALL nil?] NONE [1 2 nil 3 nil]) => [1 2 3]
(setval [:a (nthpath 1)] NONE {:a [1 2 3]}) => {:a [1 3]}
(setval [MAP-VALS even?] NONE {:a 1 :b 2 :c 3 :d 4}) => {:a 1 :c 3}
(setval FIRST NONE [1 2 3]) => [2 3]

This release also provides full integration with Clojure's transducers, 
allowing you to express many transducer operations much more elegantly:

;; Using Vanilla Clojure
(transduce
  (comp (map :a) (mapcat identity) (filter odd?))
  +
  [{:a [1 2]} {:a [3]} {:a [4 5]}])
;; => 9

;; The same logic expressed with Specter
(transduce
  (traverse-all [:a ALL odd?])
  +
  [{:a [1 2]} {:a [3]} {:a [4 5]}])

See the release notes and blog post for more details.



Release notes:

* Transform to `com.rpl.specter/NONE` to remove elements from data 
structures. Works with `keypath` (for both sequences and maps), `must`, 
`nthpath`, `ALL`, `MAP-VALS`, `FIRST`, and `LAST`
* Add `nthpath` navigator
* Add `with-fresh-collected` higher order navigator
* Added `traverse-all` which returns a transducer that traverses over all 
elements matching the given path.
* `select-first` and `select-any` now avoid traversal beyond the first 
value matched by the path (like when using `ALL`), so they are faster now 
for those use cases.
* Add `MAP-KEYS` navigator that's more efficient than `[ALL FIRST]`
* Add `NAME` and `NAMESPACE` navigators
* Extend `srange`, `BEGINNING`, `END` to work on strings. Navigates to a 
substring.
* Extend `FIRST` and `LAST` to work on strings. Navigates to a character.
* Add `BEFORE-ELEM` and `AFTER-ELEM` for prepending or appending a single 
element to a sequence
* Add `NONE-ELEM` to efficiently add a single element to a set
* Improved `ALL` performance for PersistentHashSet
* Dynamic navs automatically compile sequence returns if completely static
* Eliminate reflection warnings for clj (thanks @mpenet)
* Bug fix: Collected vals now properly passed to subpaths for `if-path`, 
`selected?`, and `not-selected?`
* Bug fix: `LAST`, `FIRST`, `BEGINNING`, and `END` properly transform 
subvector types to a vector type

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


Re: Contribute Specter to Clojure core?

2017-03-05 Thread Nathan Marz
To answer a few comments/misconceptions on this thread:

- Specter is not a DSL. Things like ALL and MAP-VALS are first class 
objects that implement the underlying navigator interface. Specter's core 
is a high-performance method of composing implementations of that 
interface. It makes zero assumptions about what kinds of data it will be 
used for. I think any DSL for this problem would ultimately either not be 
generic enough or would be overly complex. 
- If you want to use a number as a navigator, then extend the ImplicitNav 
protocol on numbers and return (nthpath this).
- Zippers are an advanced form of navigation, and Specter integrates them 
fully in the com.rpl.specter.zipper namespace. However, zippers add 
significant overhead and indirection, and 99.9% of the time you don't need 
them (but they do have the occasional use).
- I wrote at length about why I think Specter fills a major hole in 
Clojure: http://nathanmarz.com/blog/clojures-missing-piece.html


On Saturday, March 4, 2017 at 9:55:49 PM UTC-5, Herwig Hochleitner wrote:
>
> 2017-03-05 0:25 GMT+01:00 Didier >: 
> > I'm not too sure what the contribs are. Are they simply packages 
> maintained 
> > by the Clojure team itself, or are they actually part of the standard 
> > library? 
>
> As I understand it, they aren't any more sanctioned than any 
> third-party library, but the goal is to provide a stock of clojure 
> libraries under the same license as clojure itself. Also they provide 
> a common CI and path into maven central. 
>
> 2017-03-04 22:52 GMT+01:00 Gregg Reynolds  >: 
> > it's easy to imagine a more xsl-like (or even css-like) syntax with the 
> same 
> > functionality 
>
> I don't know how it squares up against specter in terms of 
> performance, but I've always been fond of the selector-engine in 
> enlive, from an engineering elegance POV, as an interface for tree 
> query and update. 
> It utilizes zippers, but only ever does a single pass (save for some 
> weird selectors). Can specter substantially improve on zippers for 
> this workload? 
> Is there an underlying abstraction, that could sit next to clojure.zip 
> or clojure.data.zip? 
>

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

2017-03-09 Thread Nathan Marz
Edwin, these personal comments about me are extremely inappropriate. Your 
claim that I ignore the work of others is just plain wrong, and that you 
would make such comments out of the blue is truly incomprehensible.

You claim Specter is "deeply un-Clojure-y" without providing a single 
example. This makes your argument boil down to "I don't like the way 
Specter makes me feel", which is no different than the complaints 
non-Lispers make about Lisp's parentheses.

Specter's core is just a simple interface and a high-performance way of 
composing implementations of that interface together. Everything else in 
Specter (the navigators) is built on top of that interface. So if you only 
want to use the "lens-like" functionality, you can literally ignore 
everything else because it doesn't affect you in any way. Additionally, 
supporting those other use cases does not make the basic use cases more 
complex or verbose.

I've found that Clojure programmers find Specter to be very intuitive. What 
they have trouble grasping is the full scope with which Specter can be 
applied, because thinking about data structures in terms of navigation is a 
new mindset. This is exactly the blub paradox as famously written about by 
Paul Graham back in the day. 

Finally, suggestions that more research and experimentation is needed in 
this area must be paired with at least one example of how Specter is 
deficient. Otherwise, it's an empty discussion. 


On Thursday, March 9, 2017 at 9:00:37 AM UTC-5, Edwin Watkeys wrote:
>
> puzzler,
>
> I guess I haven't said this, but I think it's worth saying that I have 
> nothing against Specter. Godspeed to people who want to use it. And I don't 
> think it should be judged against some other facility in another language; 
> human progress would cease if for every Y, Y has to be a better X than X. 
> Lenses, though, are one way that humans have tried to cope with accessing 
> and updating nested data structures, and they're worth thinking about. 
> Rich's hammock driven development talk influenced me powerfully because his 
> espoused methodology ran so counter to my code-first-think-later instincts, 
> and so I have the zeal of the converted with respect to the "do some 
> research" step of HDD.
>
> What you point out—the power and expressiveness of Specter—some people 
> might consider kitchen-sink-y. My interest is in uncovering ways of dealing 
> with the 90% of situations where something like Specter might be used and 
> making them as ridiculously simple and Clojure-y as possible. That 90% of 
> usage maps to, in my experience, maybe 25% of the feature set of Specter. 
> (YMMV, of course.) I want to facilitate the writing of code that a typical 
> Clojure developer will intuitively understand.
>
> Edwin
>
> On Thursday, March 9, 2017 at 3:10:50 AM UTC-5, puzzler wrote:
>>
>> Just finished reading through Racket's lens library to compare.  Specter 
>> can do everything that Racket's lens library can do, but the converse is 
>> not true.  Specter's navigators can do more than lenses.
>>
>> The lens-like navigators are the most obviously useful parts of Specter, 
>> and maybe for some people that's all they need and they would prefer to 
>> hide the other functionality.  If so, it looks to me like it would be 
>> trivial to build a lens library like Racket's out of Specter, and it would 
>> almost certainly be higher performance than the "obvious" implementation of 
>> lenses.
>>
>> But I don't agree at all with the claim that Specter is some sort of 
>> offbeat, ill-researched version of lenses.  It is something more advanced.  
>> If Nathan had constrained his thinking to these other approaches, Specter 
>> wouldn't have such richness of functionality and pragmatic performance 
>> considerations.  
>>
>>
>> On Wed, Mar 8, 2017 at 5:35 PM, Brandon Bloom  
>> wrote:
>>
>>> Responsible adults sometimes needs to access and modify deeply nested 
>>>> data structures
>>>
>>>
>>> So far, my experience has been that it is almost always better to build 
>>> a pair of flattening and unflattening transforms on the data. Especially 
>>> since you frequently want only one flattening, but potentially many 
>>> un-flattenings. The "unflattened" form (aka "documents") is usually an 
>>> end-point where data goes to die; assuming it isn't immediately displayed 
>>> on the screen.
>>>
>>> However, having said that, path-dependent / context-sensitive query is a 
>>> very rich and interesting space that does have meani

[ANN] Specter 1.0.2 released

2017-06-12 Thread Nathan Marz
Specter supercharges your ability to use and manipulate data structures in 
Clojure and ClojureScript. 1.0.2 contains minor 
improvements. https://github.com/nathanmarz/specter


Full changelog:

* Added `pred=`, `pred<`, `pred>`, `pred<=`, `pred>=` for filtering using 
common comparisons
* Add `map-key` navigator
* Add `set-elem` navigator
* Add `ALL-WITH-META` navigator
* `walker` and `codewalker` can now be used with `NONE` to remove elements
* Improve `walker` performance by 70% by replacing clojure.walk 
implementation with custom recursive path
* Extend `ALL` to work on records (navigate to key/value pairs)
* Add ability to declare a function for end index of `srange-dynamic` that 
takes in the result of the start index fn. Use `end-fn` macro to declare 
this function (takes in 2 args of [collection, start-index]). Functions 
defined with normal mechanisms (e.g. `fn`) will still only take in the 
collection as an argument.
* Workaround for ClojureScript bug that emits warnings for vars named the 
same as a private var in cljs.core (in this case `NONE`, added as private 
var to cljs.core with 1.9.562)
* For ALL transforms on maps, interpret transformed key/value pair of size 
< 2 as removal
* Bug fix: Fix incorrect inline compilation when a dynamic function 
invocation is nested in a data structure within a parameter to a navigator 
builder

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


"GC overhead limit exceeded": Deceptive message?

2017-08-07 Thread Nathan Smutz
In the course of processing thousands of XML files (maximum size 388kb; but 
I am doing a lot of operations with zippers) I got this message:
OutOfMemoryError GC overhead limit exceeded 
 com.sun.org.apache.xerces.internal.xni.XMLString.toString

I can process about 2,100 before that pops up.  I set up a transducer 
sequence and I can run count over 2100 of the seq "(count (take 2100 
requirement-seq))" without triggering the error; but much more and I get 
that Garbage Collector message.  If it's just the garbage collector, I'd 
think it should be able to stop between processing elements in the sequence 
and do it's thing.

Does this message sometimes present because the non-garbage data is getting 
too big?

Best,
Nathan




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

2017-08-08 Thread Nathan Smutz
The one thing I'm aware of holding on to is a filtered file-seq: 
(def the-files (filter #(s/ends-with? (.getName %) ".xml" ) (rest (file-seq 
(io/file dw-path)
There are 7,000+ files; but I'm assuming the elements there are just 
file-references and shouldn't take much space.

The rest of the process is a transducer sequence:
(def requirement-seq (sequence 
 (comp
   (map xml-zip-from-file)
   (remove degree-complete?)
   (map student-and-requirements))
 the-files))

Those functions are admittedly space inefficient (lots of work with 
zippers); but are pure.  What comes out the other end is a sequence of 
Clojure maps.  Could holding on to the file references prevent all that 
processing effluvia from being collected?  

The original files add up to 1.3 gigs altogether.  I'd expect the gleaned 
data to be significantly smaller; but I'd better check into how close 
that's getting to the default heap-size.

Best,
Nathan

On Tuesday, August 8, 2017 at 1:20:21 AM UTC-7, Peter Hull wrote:
>
>
> On Tuesday, 8 August 2017 06:20:56 UTC+1, Nathan Smutz wrote:
>
>> Does this message sometimes present because the non-garbage data is 
>> getting too big?
>>
> Yes, it's when most of your heap is non-garbage, so the GC has to keep 
> running but doesn't succeed in freeing much memory each time.
> See 
> https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html
>  
> <https://www.google.com/url?q=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F8%2Fdocs%2Ftechnotes%2Fguides%2Ftroubleshoot%2Fmemleaks002.html&sa=D&sntz=1&usg=AFQjCNG_3-bT-oubFsBYZ7opNG51ndT1jQ>
>  
> You can increases the heap but that might only defer the problem.
>
> As you process all your files, are you holding on to references to objects 
> that you don't need any 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: "GC overhead limit exceeded": Deceptive message?

2017-08-09 Thread Nathan Smutz
Thanks @Paulus, @Gary and @Peter,

Rearranging the process to let go of the head is good advice.

I believe the problem (should I need to keep all elements in memory) may 
ultimately be lazy collections inside the maps I'm producing. 
I saved 1,917 of these elements to disk and it took only 3 megabytes.

An inner functions creates a lot of lazy sequences, I believe, closing over 
large zipper structures.  
If that's the case, then I need to wrap those sequences in (doall) 
expressions or refactor to something more explicitly eager.

Best,
Nathan





On Tuesday, August 8, 2017 at 9:39:21 AM UTC-7, Paulus Esterhazy wrote:
>
> For background on "holding onto the head of a sequence" type problems, see 
>
> https://stuartsierra.com/2015/04/26/clojure-donts-concat 
>
> and 
>
> https://stackoverflow.com/questions/15994316/clojure-head-retention 
>
> On Tue, Aug 8, 2017 at 6:19 PM, Nathan Smutz  > wrote: 
> > The one thing I'm aware of holding on to is a filtered file-seq: 
> > (def the-files (filter #(s/ends-with? (.getName %) ".xml" ) (rest 
> (file-seq 
> > (io/file dw-path) 
> > There are 7,000+ files; but I'm assuming the elements there are just 
> > file-references and shouldn't take much space. 
> > 
> > The rest of the process is a transducer sequence: 
> > (def requirement-seq (sequence 
> >  (comp 
> >(map xml-zip-from-file) 
> >(remove degree-complete?) 
> >(map student-and-requirements)) 
> >  the-files)) 
> > 
> > Those functions are admittedly space inefficient (lots of work with 
> > zippers); but are pure.  What comes out the other end is a sequence of 
> > Clojure maps.  Could holding on to the file references prevent all that 
> > processing effluvia from being collected? 
> > 
> > The original files add up to 1.3 gigs altogether.  I'd expect the 
> gleaned 
> > data to be significantly smaller; but I'd better check into how close 
> that's 
> > getting to the default heap-size. 
> > 
> > Best, 
> > Nathan 
> > 
> > On Tuesday, August 8, 2017 at 1:20:21 AM UTC-7, Peter Hull wrote: 
> >> 
> >> 
> >> On Tuesday, 8 August 2017 06:20:56 UTC+1, Nathan Smutz wrote: 
> >>> 
> >>> Does this message sometimes present because the non-garbage data is 
> >>> getting too big? 
> >> 
> >> Yes, it's when most of your heap is non-garbage, so the GC has to keep 
> >> running but doesn't succeed in freeing much memory each time. 
> >> See 
> >> 
> https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html
>  
> >> 
> >> You can increases the heap but that might only defer the problem. 
> >> 
> >> As you process all your files, are you holding on to references to 
> objects 
> >> that you don't need any more? 
> > 
> > -- 
> > 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.


[ANN] Specter 1.0.3

2017-08-14 Thread Nathan Marz
Specter supercharges your ability to query and manipulate regular Clojure 
data structures. https://github.com/nathanmarz/specter

1.0.3 includes navigators for navigating to the index of an element in a 
sequence, a so far unexplored area of the problem space. Some examples of 
the new functionality:

(setval (index-nav 3) 1 [:a :b :c :d :e])
;; => [:a :d :b :c :e]

(select INDEXED-VALS [:a :b :c])
;; => [[0 :a] [1 :b] [2 :c]]

(setval [INDEXED-VALS FIRST] 0 [:a :b :c :d])
;; => [:d :c :b :a]

(setval (before-index 2) :a '(0 1 2 3 4))
;; => (0 1 :a 2 3 4)


Full changelog:

* Added `before-index` navigator for inserting a single element into a 
sequence.
* Added `index-nav` navigator for moving an element in a sequence to a new 
index, shifting other elements in the process.
* Added `INDEXED-VALS` navigator for navigating to every element of a 
sequence as [index elem] pair. Transform on index portion works the same as 
`index-nav`.
* Workaround for ClojureScript regression that causes warnings for record 
fields named "var" or other reserved names

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


Clojure.org

2017-09-22 Thread Nathan Fisher
Hi All,

I'm probably dense but I didn't see the source for clojure.org 
on https://github.com/clojure. It looks like it's served out of S3 based on 
at the response headers so I'm guessing it's a static site of some sort...

While I don't necessarily subscribe to "everyone else is doing it" I was 
thinking it would be nice to add a sample snippet of "hello world" code on 
the home page similar to Go and Ruby's site. I'd see it placed just above 
the "Learn More" section.

I wanted to make a PR with a snippet like:

(ns cool.clojure
  (:gen-class))

(defn -main []
  (prn "Hello world!"))

Underneath it could link to a page "so you've decided to learn Clojure 
here's how you map common idioms from OO/imperative to Clojure" obviously 
it'll need something a little snappier.

Kind regards,
Nathan

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

2017-09-22 Thread Nathan Fisher
Hi Alex,

Understood, thanks for the quick reply! I recently came across Steve
Yegge's rant on Clojure accessibility to newbies and was reflecting on how
it could be improved. Thought it was a little thing but could be a nice
addition to ease people in and give them a flavour for the language.

Totally understand that a home page is an important space and you don't
want the kitchen sink thrown in peoples faces. :)

Cheers!
Nathan

On Fri, 22 Sep 2017 at 16:57 Alex Miller  wrote:

> It's there at: https://github.com/clojure/clojure-site
>
> We considered this when building the site and decided not to include it on
> the front page, so probably not interested in including it now. I expect
> we'll look at front page updates at some point though and we'll consider it
> again.
>
> Alex
>
>
> On Friday, September 22, 2017 at 10:51:18 AM UTC-5, Nathan Fisher wrote:
>>
>> Hi All,
>>
>> I'm probably dense but I didn't see the source for clojure.org on
>> https://github.com/clojure. It looks like it's served out of S3 based on
>> at the response headers so I'm guessing it's a static site of some sort...
>>
>> While I don't necessarily subscribe to "everyone else is doing it" I was
>> thinking it would be nice to add a sample snippet of "hello world" code on
>> the home page similar to Go and Ruby's site. I'd see it placed just above
>> the "Learn More" section.
>>
>> I wanted to make a PR with a snippet like:
>>
>> (ns cool.clojure
>>   (:gen-class))
>>
>> (defn -main []
>>   (prn "Hello world!"))
>>
>> Underneath it could link to a page "so you've decided to learn Clojure
>> here's how you map common idioms from OO/imperative to Clojure" obviously
>> it'll need something a little snappier.
>>
>> Kind regards,
>> Nathan
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

Working to create a minimal test case but upgrading from alpha19 to beta1
seems to have broken lein-cljsbuild.

I get the following error:

>>>>>> snip >>>>>>

*SEVERE:
/Users/nathanfisher/workspace/mklpq/target/cljsbuild-compiler-0/cljs/core.js:3579:
ERROR - Parse error. primary expression expected*

*case ##Inf:*

*  ^*


*Sep 28, 2017 3:23:10 PM com.google.javascript.jscomp.LoggerErrorManager
printSummary*

*WARNING: 1 error(s), 0 warning(s)*

*ERROR: JSC_PARSE_ERROR. Parse error. primary expression expected at
/Users/nathanfisher/workspace/mklpq/target/cljsbuild-compiler-0/cljs/core.js
line 3579 : 6*
<<<<<< snip <<<<<<

Changes in my project.clj deps are as follows:

*- [org.clojure/clojure "1.9.0-alpha19" :scope "provided"]*

*+ [org.clojure/clojure "1.9.0-beta1" :scope "provided"]*

A revert on my project.clj to alpha19 eliminates the error.

Cheers!

Nathan

On Thu, 28 Sep 2017 at 15:00 Stuart Halloway 
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.
>
-- 
- sent from my mobile

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

Looks like any project using lein-cljsbuild will be affected.

I forked and bumped the Clojure and ClojureScript version to latest and got
the same error with their simple project:

See Commit:
https://github.com/nfisher/lein-cljsbuild/commit/5df5d3c5bb447b51a75abbbccdc72447814883a0

STR

1. git clone https://github.com/nfisher/lein-cljsbuild
2. cd lein-cljsbuild/example/projects/simple
3. lein cljsbuild once

Patch attached if you want to apply directly to
https://github.com/emezeske/lein-cljsbuild

Cheers,
Nathan

On Thu, 28 Sep 2017 at 16:13 Stuart Halloway 
wrote:

> Hi Nathan,
>
> I suspect that is the same as
> https://github.com/clojure/clojurescript/commit/89914d2ead964122f99e638edda0cd96d330cb66.
> I don't have a sense of how many CLJS project this is going to cascade
> into, or what all will be needed. Anyone?
>
> Stu
>
> On Thu, Sep 28, 2017 at 10:44 AM, Nathan Fisher 
> wrote:
>
>> Hi Stuart,
>>
>> Working to create a minimal test case but upgrading from alpha19 to beta1
>> seems to have broken lein-cljsbuild.
>>
>> I get the following error:
>>
>> >>>>>> snip >>>>>>
>>
>> *SEVERE:
>> /Users/nathanfisher/workspace/mklpq/target/cljsbuild-compiler-0/cljs/core.js:3579:
>> ERROR - Parse error. primary expression expected*
>>
>> *case ##Inf:*
>>
>> *  ^*
>>
>>
>> *Sep 28, 2017 3:23:10 PM com.google.javascript.jscomp.LoggerErrorManager
>> printSummary*
>>
>> *WARNING: 1 error(s), 0 warning(s)*
>>
>> *ERROR: JSC_PARSE_ERROR. Parse error. primary expression expected at
>> /Users/nathanfisher/workspace/mklpq/target/cljsbuild-compiler-0/cljs/core.js
>> line 3579 : 6*
>> <<<<<< snip <<<<<<
>>
>> Changes in my project.clj deps are as follows:
>>
>> *- [org.clojure/clojure "1.9.0-alpha19" :scope "provided"]*
>>
>> *+ [org.clojure/clojure "1.9.0-beta1" :scope "provided"]*
>>
>> A revert on my project.clj to alpha19 eliminates the error.
>>
>> Cheers!
>>
>> Nathan
>>
>> On Thu, 28 Sep 2017 at 15:00 Stuart Halloway 
>> 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.
>>>
>> --
>> - sent from my mobile
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, s

Re: ANN: ClojureScript 1.9.946

2017-10-03 Thread Nathan Fisher
Hi David!

I'm seeing an issue in one of my larger projects. Will try to isolate
tomorrow and get back to you.

The simple project in lein-cljsbuild works fine for me with beta1 and this
release.

Saludos!
Nathan

On Tue, 3 Oct 2017 at 22:52 David Nolen  wrote:

> ClojureScript, the Clojure compiler that emits JavaScript source code.
>
> README and source code: https://github.com/clojure/clojurescript
>
> Leiningen dependency information:
>
> [org.clojure/clojurescript "1.9.946"]
>
> This release contains many bug fixes and addresses feedback from the
> 1.9.908
> release. Important changes include parity with Clojure 1.9.0-beta1 and an
> updated Google Closure Compiler dependency. The later one in particular now
> means that ClojureScript has a dependency on JDK 8.
>
> As always feedback welcome!
>
> 1.9.946
>
> ### Changes
> * CLJS-2300: Delegate clojure.string/capitalize to goog.string/capitalize
> * CLJS-2374: Print js/Infinity, js/-Infinity, js/NaN using new reader
> literals
> * bump tools.reader (1.1.0)
> * CLJS-2372: update hash to use the new infinity literals
> * CLJS-2364: Bump Closure Compiler to the Sep 2017 version
> * CLJS-2340: Have js-keys delegate directly to good.object/getKeys
> * CLJS-2338: Support renamePrefix{Namespace} closure compiler option
>
> ### Fixes
> * CLJS-1576: fix source-map string encoding by applying encodeURIComponent
> and fixing string/replace call
> * CLJS-2294: Always use opts with implicit opts added
> * CLJS-2166: Add uri? predicate
> * CLJS-2368: Self-host: Never compile macro namespaces with
> `:optimize-constants true
> * CLJS-2367: Self-host: :def-emits-var leaks into loaded namespace
> processing
> * CLJS-2352: Emit valid JS for NaN etc. even when used w/ CLJ >=
> 1.9.0-alpha20
> * CLJS-2339: Significant code reload slowdown with :npm-deps
> * CLJS-2361: Self-host: circular dependency detection doesn't handle REPL
> self-require
> * CLJS-2356: Self-host: circular dependency detection is not correct
> * CLJS-2354: Self-host: `compile-str` doesn't handle `clojure` -> `cljs`
> aliasing
> * CLJS-2353: use portable `node-module-dep?` function in analyze-deps
> * CLJS-2345: escape paths emitted as args to cljs.core.load_file
> * CLJS-2349: Port reset-vals! and swap-vals! over from Clojure
> * CLJS-2336: Call alength once in areduce and amap
> * CLJS-2335: Avoid alength on strings
> * CLJS-2334: Also gather dependencies from foreign-libs that are modules
> * CLJS-2333: module-deps.js doesn't correctly compute `main` if aliased in
> browser field
> * CLJS-2332: module_deps.js doesn't process `export from` correctly
> * CLJS-2330: Don't set `"browser"` field for Closure if target is :nodejs
> * CLJS-2326: Indexing node_modules can't find `main` when it doesn't have
> an extension
> * CLJS-2328: Args are not provided to *main-cli-fn* with optimizations
> advanced
> * CLJS-2327: module_deps.js doesn't know about browser field advanced usage
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2017-10-07 Thread Nathan Fisher
You could use exceptions, is that a hard requirement or are you working to
transition your mental model for Java code to Clojure?

If you can catch the exceptions or not throw them to begin with there’s
some other options;

Another way you could do it is using core.async and channels as some others
have mentioned.

Yet another way would be using cats.

A similar solution to what the problem you described is outlined partway
through this article (there’s a lot there):

https://blog.skyliner.io/fourteen-months-with-clojure-beb8b3e4bf00

A friend of mine used to say “get it writ, then get it right”. As long as
you encapsulate the desired behaviour in the function you can try all of
the different suggestions and take a decision of what feels more readable
to you and others on your team.

On Sat, 30 Sep 2017 at 23:14, Didier  wrote:

> I'm curious how others handle this use case, which I feel should be pretty
> common.
>
> Given you have a series of business process steps, where the flow is too
> complex for the arrow macros, and you also like to name the step results
> descriptively, so you use let:
>
> (let [a (do-a ...)
>   b (do-b . a . .)
>   c (do-c . a . b)]
>   (log/info "Success" {:a a
>:b b
>:c c})
>   c)
>
> Now, say each steps could possibly throw an exception. So you want to
> try/catch the let bindings:
>
> (try
>   (let [a (do-a ...)
> b (do-b . a . .)
> c (do-c . a . b)]
> (log/info "Success" {:a a
>  :b b
>  :c c})
> c)
>   (catch Exception e
> (log/error "Failed" {:a a
>  :b b
>  :c c})
> (throw e)))
>
> But, inside the catch, you need access to the let bindings a,b,c, in order
> to recover from the failure, or like in my example, just to log so that
> debugging of the issue is easier.
>
> Now the catch will not be in scope of the bindings, and this won't even
> compile: "Can not find symbol a,b,c in context...".
>
> What would be the idomatic thing to do here?
>
> Is there another way to execute a set of complex steps which does not rely
> on let and can be try/catched in the manner I describe?
>
> Or is there a way to re-write the let that satisfies my case, and remains
> idiomatic, and does not add accidental complexities?
>
> Thank You.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
-- 
- sent from my mobile

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

2017-10-12 Thread Nathan Fisher
Hi!

Can you change one of the variables? Specifically can you replicate this on
your local machine? If it happens locally then I would focus on something
in the JVM eco-system.

If you can't replicate it locally then it's possibly AWS specific. It
sounds like you're using a t2.large or m4.xlarge. If it's the prior you may
very well be contending between with your network bandwidth. EC2's host
drive (EBS) is a networked drive which is split between your standard
network traffic and the drive volume. If that's the issue then you might
need to look at provisioned IOPs. A quick(ish) way to test that hypothesis
is to provision a host with high networking performance and provisioned
IOPs.

Cheers,
Nathan

On Fri, 13 Oct 2017 at 00:05  wrote:

> Daniel Compton, good suggestion. I've increased the memory to see if I can
> postpone the GCs, and I'll log that more carefully.
>
>
> On Wednesday, October 11, 2017 at 8:35:44 PM UTC-4, Daniel Compton wrote:
>
>> Without more information it's hard to tell, but this looks a like it
>> could be a garbage collection issue. Can you run your test again and add
>> some logging/monitoring to show each garbage collection? If my hunch is
>> right, you'll see garbage collections getting more and more frequent until
>> they take up nearly all the CPU time, preventing much forward progress
>> writing to the queue.
>>
>> If it's AWS based throttling, then CloudWatch monitoring
>> http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-volume-status.html#using_cloudwatch_ebs
>>  might
>> show you some hints. You could also test with an NVMe drive attached, just
>> to see if disk bandwidth is the issue.
>>
>> On Thu, Oct 12, 2017 at 11:58 AM Justin Smith  wrote:
>>
> a small thing here, if memory usage is important you should be building
>>> and running an uberjar instead of using lein on the server (this also has
>>> other benefits), and if you are doing that your project.clj jvm-opts are
>>> not used, you have to configure your java command line in aws instead
>>>
>>> On Wed, Oct 11, 2017 at 3:52 PM  wrote:
>>>
>> I can't figure out if this is a Clojure question or an AWS question. And
>>>> if it is a Clojure question, I can't figure out if it is more of a general
>>>> JVM question, or if it is specific to some library such as durable-queue. I
>>>> can redirect my question elsewhere, if people think this is an AWS
>>>> question.
>>>>
>>>> In my project.clj, I try to give my app a lot of memory:
>>>>
>>>>   :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])
>>>>
>>>> And the app starts off pulling data from MySQL and writing it to
>>>> Durable-Queue at a rapid rate. (
>>>> https://github.com/Factual/durable-queue )
>>>>
>>>> I have some logging set up to report every 30 seconds.
>>>>
>>>> :enqueued 370137,
>>>>
>>>> 30 seconds later:
>>>>
>>>> :enqueued 608967,
>>>>
>>>> 30 seconds later:
>>>>
>>>> :enqueued 828950,
>>>>
>>>> It's a dramatic slowdown. The app is initially writing to the queue at
>>>> faster than 10,000 documents a second, but it slows steadily, and after 10
>>>> minutes it writes less than 1,000 documents per second. Since I have to
>>>> write a few million documents, 10,000 a second is the slowest speed I can
>>>> live with.
>>>>
>>>> The queues are in the /tmp folder of an AWS instance that has plenty of
>>>> disk space, 4 CPUs, and 16 gigs of RAM.
>>>>
>>>> Why does the app slow down so much? I had 4 thoughts:
>>>>
>>>> 1.) the app struggles as it hits a memory limit
>>>>
>>>> 2.) memory bandwidth is the problem
>>>>
>>>> 3.) AWS is enforcing some weird IOPS limit
>>>>
>>>> 4.) durable-queue is misbehaving
>>>>
>>>> As to possibility #1, I notice the app starts like this:
>>>>
>>>> Memory in use (percentage/used/max-heap): (\"66%\" \"2373M\" \"3568M\")
>>>>
>>>> but 60 seconds later I see:
>>>>
>>>> Memory in use (percentage/used/max-heap): (\"94%\" \"3613M\" \"3819M\")
>>>>
>>>> So I've run out of allowed memory. But why is that? I thought I gave
>>>> this app 7 gigs:
>>>>

Re: possibly a Clojure question or possibly an AWS question: slow writes to durable-queue

2017-10-13 Thread Nathan Fisher
It sounds like you have a memory leak. I would look at addressing that
before any performance tricks.
On Fri, 13 Oct 2017 at 05:35,  wrote:

> Following Daniel Compton's suggestion, I turned on logging for GC. I don't
> see it happening more often, but the slow down does seem related to the
> moment when the app hits the maximum memory allowed. It had been running
> with 4G, so I increased that to 7G, so it goes longer now before it hits
> 98% memory usage, but it does hit it eventually and then everything crawls
> to a very slow speed. Not sure how much memory I would have to use to avoid
> using up almost all of the memory. I suppose I'll figure that out via trial
> and error. Until I can figure that out, nearly all other performance tricks
> seems a bit besides the point.
>
>
>
> On Thursday, October 12, 2017 at 9:01:23 PM UTC-4, Nathan Fisher wrote:
>
>> Hi!
>>
>> Can you change one of the variables? Specifically can you replicate this
>> on your local machine? If it happens locally then I would focus on
>> something in the JVM eco-system.
>>
>> If you can't replicate it locally then it's possibly AWS specific. It
>> sounds like you're using a t2.large or m4.xlarge. If it's the prior you may
>> very well be contending between with your network bandwidth. EC2's host
>> drive (EBS) is a networked drive which is split between your standard
>> network traffic and the drive volume. If that's the issue then you might
>> need to look at provisioned IOPs. A quick(ish) way to test that hypothesis
>> is to provision a host with high networking performance and provisioned
>> IOPs.
>>
>> Cheers,
>> Nathan
>>
>> On Fri, 13 Oct 2017 at 00:05  wrote:
>>
>>> Daniel Compton, good suggestion. I've increased the memory to see if I
>>> can postpone the GCs, and I'll log that more carefully.
>>>
>>>
>>> On Wednesday, October 11, 2017 at 8:35:44 PM UTC-4, Daniel Compton wrote:
>>>
>>>> Without more information it's hard to tell, but this looks a like it
>>>> could be a garbage collection issue. Can you run your test again and add
>>>> some logging/monitoring to show each garbage collection? If my hunch is
>>>> right, you'll see garbage collections getting more and more frequent until
>>>> they take up nearly all the CPU time, preventing much forward progress
>>>> writing to the queue.
>>>>
>>>> If it's AWS based throttling, then CloudWatch monitoring
>>>> http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-volume-status.html#using_cloudwatch_ebs
>>>>  might
>>>> show you some hints. You could also test with an NVMe drive attached, just
>>>> to see if disk bandwidth is the issue.
>>>>
>>>> On Thu, Oct 12, 2017 at 11:58 AM Justin Smith 
>>>> wrote:
>>>>
>>> a small thing here, if memory usage is important you should be building
>>>>> and running an uberjar instead of using lein on the server (this also has
>>>>> other benefits), and if you are doing that your project.clj jvm-opts are
>>>>> not used, you have to configure your java command line in aws instead
>>>>>
>>>>> On Wed, Oct 11, 2017 at 3:52 PM  wrote:
>>>>>
>>>> I can't figure out if this is a Clojure question or an AWS question.
>>>>>> And if it is a Clojure question, I can't figure out if it is more of a
>>>>>> general JVM question, or if it is specific to some library such as
>>>>>> durable-queue. I can redirect my question elsewhere, if people think this
>>>>>> is an AWS question.
>>>>>>
>>>>>> In my project.clj, I try to give my app a lot of memory:
>>>>>>
>>>>>>   :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])
>>>>>>
>>>>>> And the app starts off pulling data from MySQL and writing it to
>>>>>> Durable-Queue at a rapid rate. (
>>>>>> https://github.com/Factual/durable-queue )
>>>>>>
>>>>>> I have some logging set up to report every 30 seconds.
>>>>>>
>>>>>> :enqueued 370137,
>>>>>>
>>>>>> 30 seconds later:
>>>>>>
>>>>>> :enqueued 608967,
>>>>>>
>>>>>> 30 seconds later:
>>>>>>
>>>>>> :enqueued 828

[ANN] Specter 1.0.4

2017-10-17 Thread Nathan Marz
Specter fills in the holes in Clojure's API for manipulating immutable 
data, allowing data manipulation to be done concisely and with near-optimal 
performance.

Specter 1.0.4 has minor changes. The biggest highlight since the last 
release is the greatly improved documentation courtesy of contributions by 
Michael Fogleman. The following wiki pages are either new or significantly 
fleshed out:

https://github.com/nathanmarz/specter/wiki/Using-Specter-Recursively
https://github.com/nathanmarz/specter/wiki/List-of-Navigators
https://github.com/nathanmarz/specter/wiki/List-of-Macros
https://github.com/nathanmarz/specter/wiki/Using-Specter-With-Zippers

Project link: https://github.com/nathanmarz/specter
Changelog: https://github.com/nathanmarz/specter/blob/master/CHANGES.md

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


Officially Supported JDKs?

2017-10-25 Thread Nathan Fisher
Hi All,

Curious what JDKs are officially supported?

Is it safe to assume the JDKs in Jenkins Clojure-test-matrix are the
officially supported jdks?

Is there any plans to deprecate support of EOL JDKs?

Cheers!
Nathan
-- 
- sent from my mobile

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

2017-11-16 Thread Nathan Marz
Specter fills in the holes in Clojure's API for manipulating immutable 
data, allowing data manipulation to be done concisely and with near-optimal 
performance. Specter is especially powerful for working with nested and 
recursive data. 

Specter 1.0.5 adds `regex-nav` which navigates to substrings matching a 
regex. For example:

(transform (regex-nav #"<[a-zA-Z]*>") (comp str count) "Match 1 length: 
, Match 2 length: ")
;; => "Match 1 length: 3, Match 2 length: 7"

Regexes implicitly convert to `regex-nav`, so the above can be written as:

(transform #"<[a-zA-Z]*>" (comp str count) "Match 1 length: , Match 2 
length: ")

The other highlight of the release is adding implicit keypath navigation 
for all primitive types.  Now you can write code like:

(select-any [0 "a" 1] [{"a" [1 2 3]} :b :c])
;; => 2

(transform ["a" 'b \c] inc {"a" {'b {\c 1}}})
;; => {"a" {b {\c 2}}}


Project link: https://github.com/nathanmarz/specter
Changelog: https://github.com/nathanmarz/specter/blob/master/CHANGES.md

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

2017-12-02 Thread Nathan Fisher
 Also take a look at re-frame (cljs) redux (js) libraries.
On Sat, 2 Dec 2017 at 10:18, Moe Aboulkheir  wrote:

> It may make sense to familiarise yourself with the architecture of a
> Clojurescript + React web application, if that's not something you've
> recently investigated.  Regardless of whether the techniques are directly
> applicable to your problem, I think the relationship between the state and
> the UI is something to aspire to.
>
> It may also be worth looking at https://github.com/halgari/fn-fx which is
> trying to do something similar with JavaFX.
>
> Take care,
> Moe
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2017-12-23 Thread Nathan Fisher
Thanks Alex!

Agreed I don’t think there is any easy quick win aside from putting a
conditional around the server section that’s controlled by an environment
variable.

There might be some optimisations that could be done by front loading
classes, similar to a prefetch in HTTP. Class loads from jars aren’t cheap
once it’s in the JVM code cache it isn’t expensive though. In RT.load the
getResource classfile and cljs is 38ms as an example. I was able to shave
off startup time in cljbuck by packing all of the class loading together
early. The extensive use of static initialisation could make this erroneous
though.

I started a branch that refactors the static methods and initialisation
into instance methods of another class. It uses a singleton factory to
maintain the behaviour of the RT ABI. With instances it would provide
isolation which could enable deterministic parallel builds, better core
test isolation, and possibly provide benefits to REPLs.

The refer ticket in particular is interesting.

Cheers,
Nathan

On Sat, 23 Dec 2017 at 11:23, Alex Miller >
wrote:

> Some related tickets:
>
> Server load (open) - https://dev.clojure.org/jira/browse/CLJ-1891
>
> Spec load (closed but some more info) -
> https://dev.clojure.org/jira/browse/CLJ-2108
>
> refer perf (open) - https://dev.clojure.org/jira/browse/CLJ-1730
>
> However, all of these are really just some easy one- time wins (can shave
> about 0.2 s maybe) and don’t give you any qualitatively different
> experience.
>
> For that something more is needed. If you are aot compiling, then
> aot+direct linking+lazy vars (patch is on the page you linked as an
> attachment) work together to load and run significantly less bytecode. If
> not aot, then the additional costs are primarily in reading and compiling
> (about 50/50) iirc. It’s unclear how to make those substantially faster.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2018-01-02 Thread Nathan Marz
Specter fills in the holes in Clojure's API for manipulating immutable 
data, allowing data manipulation to be done concisely and with near-optimal 
performance. Specter is especially powerful for working with nested and 
recursive data. 

Project link: https://github.com/nathanmarz/specter

Excited to be releasing Specter 1.1.0 today. It's not often I discover how 
to do something new with Specter, but this release includes the `compact` 
navigator which utilizes a new composition technique. 

If you look at the JIRA for a proposed `dissoc-in` function 
(https://dev.clojure.org/jira/browse/CLJ-1063), you can see a discussion 
about whether empty subvalues should be kept or discarded. This is further 
complicated by the fact that `dissoc-in` must operate on vectors. 
Ultimately, there is no right answer, as the manipulation needs can differ 
from usage to usage. You may even want to remove some empty subvalues along 
the path but not others. The JIRA discussion looks to handle the most 
common use case instead of handling all use cases.

Specter's paths, on the other hand, can specify much richer behavior. The 
new `compact` navigator allows you to concisely specify which values along 
the path should be removed if emptied:

(setval [:a (compact :b :c)] NONE {:a {:b {:c 1}}})
;; => {}

(setval [:a (compact :b :c)] NONE {:a {:b {:c 1} :d 2}})
;; => {:a {:d 2}}

(setval [:a :b (compact :c)] NONE {:a {:b {:c 1}}})
;; => {:a {}}

It works with sequences too:

(setval [1 (compact 0)] NONE [:a [:b] :c])
;; => [:a :c]

And like all navigators, it works recursively as well:

(def TREE-VALUES
  (recursive-path [] p
(if-path vector?
  [(compact ALL) p]
  STAY
  )))

(setval [TREE-VALUES even?] NONE [1 [2 3] [4] [5 [[6)
;; => [1 [3] [5]]

`compact` is very efficient and has a beautiful implementation: 
https://github.com/nathanmarz/specter/blob/1.1.0/src/clj/com/rpl/specter.cljc#L1459

The new composition technique is utilizing terminal navigation points 
inside a reusable navigator. Terminal points were originally conceived for 
`multi-transform` operations, but to my pleasant surprise turn out to be 
very useful beyond that.

I don't usually expound on releases like this, but the `compact` navigator, 
a composition of already existing components, excited me because it shows 
Specter is more powerful than even I knew. 

The full changelog for the release is here: 
https://github.com/nathanmarz/specter/blob/master/CHANGES.md

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


Illustrated Guide to Clojure Start-up Timings

2018-01-02 Thread Nathan Fisher
Hi All,

Over the holiday's I started to write up my analysis of the trace output I
mentioned previously. The article is posted below;

https://news.ycombinator.com/item?id=16056522

Cheers,
Nathan


-- 
- sent from my mobile

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

2018-01-07 Thread Nathan Fisher
Great work Alex!

Not sure I would want to see duplicates either. If my code breaks because
of an old dependency I’d rather that than make the false assumption that
I’m running securely with the latest version of a lib.

On Fri, 5 Jan 2018 at 16:20, Gary Trakhman  wrote:

> Congrats on the release! It's exciting to see this vision move forward.
> Wondering if the logical next step is the npm style of trees of duplicate
> transitive git deps.  In general, how is this going to work for transitive
> deps?
>
> On Fri, Jan 5, 2018 at 1:49 PM Alex Miller  wrote:
>
>> Pleased to announce some new functionality for clj and tools.deps!
>>
>> https://clojure.org/news/2018/01/05/git-deps
>>
>> Additionally, there have been new releases of:
>> - Brew clojure formula (to get it: brew upgrade clojure)
>> - Linux clojure installer (see https://clojure.org/guides/getting_started
>> for info)
>> - tools.deps.alpha 
>> - NEW tools.gitlibs 
>>
>> Other than git deps, "clj -Spom" for pom generation has some fixes and an
>> addition to add Maven repositories if needed.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2018-01-07 Thread Nathan Fisher
Im probably not typical for this but I really value the ability to override
the location of where they’re placed. I actually commit my deps to SCM for
production code. The internet is fast enough these days that i don’t care
about a common code cache. I’m more interested in a reproducible build.

On Sat, 6 Jan 2018 at 11:25, Alex Miller  wrote:

>
>
> > On Jan 6, 2018, at 5:43 AM, Khalid Jebbari 
> wrote:
> >
> > Great news, great work ! Soon running Clojure will be dead easy.
> >
> > 2 questions :
> > - where do dependencies get downloaded ? `~/.m2` ? It depends on the
> procurer (mvn/git/etc.)
>
> It depends. Maven deps go to .m2, git deps go to .gitlibs.
>
> > - does it work for Cljs ? What does it mean for Cljs ?
>
> This is targeted at launching Clojure programs. ClojureScript itself is a
> Clojure program, so it’s relevant in that sense.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2018-01-07 Thread Nathan Fisher
Hi Alex,

Sounds great!

I strongly agree with your decision of “pick the latest”. While I do
understand multiple active versions can make it easier for a developer I
don’t think that’s the “right” decision. Besides I can only imagine how
much of a pain it would be to implement reliably. I’d expect if I specify a
patched version of struts that a transitive dependency wouldn’t have the
ability to override that for its own purpose.

Cheers,
Nathan

On Sun, 7 Jan 2018 at 20:51, Alex Miller  wrote:

>
> On Sunday, January 7, 2018 at 3:41:34 PM UTC-6, Nathan Fisher wrote:
>>
>>
>> Not sure I would want to see duplicates either. If my code breaks because
>> of an old dependency I’d rather that than make the false assumption that
>> I’m running securely with the latest version of a lib.
>>
>
> Encountering duplicate libs in the transitive tree is common to almost
> every dependency trees (for example, it's typical to see multiple versions
> of Clojure as a dependency in *every* transitive tree). clj, like every
> other dependency tool, will continue to make choices about which version to
> include and tools to control which one is included.
>
> I do plan to add better tools to understand the tree and the choices made.
>
>> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2018-01-08 Thread Nathan Fisher
You could do it by “rooting” the package (aka change the package path).
Most JVM languages root their dependencies to avoid collisions with user
space dependencies. ASM is the most common Clojure does and I think Kotlin
and Scala do as well. I think Guavas murmur3 is rooted in Clojure as well
for the maps.
On Mon, 8 Jan 2018 at 05:47, Gary Verhaegen 
wrote:

> Have you considered adding an equivalent to lein’s pedantic option, i.e.
> an option that would die on ambiguous versions rather than make a choice,
> thereby forcing users to make that choice explicit as a top-level entry?
> (Or through exclusions etc.)
>
> As an aside, is it even possible on the JVM to have multiple versions of a
> dependency loaded? Wouldn’t the last version loaded override all the common
> classes, leaving you with a sort of hybrid that doesn’t correspond to any
> single version? I’d really like a dependency system that makes each dep’s
> transitive dependencies only visible to itself, so there would never be any
> reason to resolve dependencies.
>
> Also, how realistic do you think it is today to expect all of our
> transitive dependencies to be developed according to that growth mindset
> you mention? It’s one thing to adopt it in my code, but quite another to
> assume it’s followed correctly by all of the underlying Java libs.
>
> On 8 Jan 2018, at 01:24, Alex Miller  wrote:
>
>
> On Sun, Jan 7, 2018 at 6:53 PM, Nathan Fisher 
> wrote:
>
>
>> I strongly agree with your decision of “pick the latest”. While I do
>> understand multiple active versions can make it easier for a developer I
>> don’t think that’s the “right” decision. Besides I can only imagine how
>> much of a pain it would be to implement reliably. I’d expect if I specify a
>> patched version of struts that a transitive dependency wouldn’t have the
>> ability to override that for its own purpose.
>>
>
> I guess I didn't mention that top-level deps always win, so if desired you
> are always able to decide the specific version in your project.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from 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: If Clojure is to blame for the majority of the startup time, why doesn't ClojureScript proportionally slow down the JavaScript startup time also?

2018-01-25 Thread Nathan Fisher
It's not a huge contributor but Class loading isn't free and Clojure could
optimise it in a couple of places. I think with a couple of months effort
in optimisation you might be able to get it down to 500ms for a simple
"hello world". I'm doubtful you can get it much lower than that. TBH I'm
not sure if the engineering effort would necessarily be worth it for many
users.

I wanted to test dynamic loading and docker before I shared the article
more broadly but here's the results from implementing prefetching in
Clojure;

https://junctionbox.ca/2018/01/04/clojure-class-prefetching.html

It's a part of a series that I'm slowly plodding through as I have time. I
hope to cover off the 4 items from the conclusion of this article;

https://junctionbox.ca/2017/12/26/clojure-startup-walkthrough.html#conclusions

Cheerio!
Nathan


On 26 January 2018 at 01:51, Timothy Baldridge  wrote:

> I would suggest everyone here read this document: https://dev.clojure.
> org/display/design/Improving+Clojure+Start+Time It goes into a lot of
> detail on prior work in this area, and I'd say the benchmarks on it should
> be quite informative.
>
> But let me also go into a bit more detail into how CLJS differs from CLJ
> in how it accesses global function definitions:
>
> In CLJs, clojure core contains a lot of definitions that look something
> like this:
>
> clojure.core.conj = function () {... clojure.core.some_fn(...) . }
>
> The cost of creating that global function is then the cost of 2 lookups
> (clojure in the global namespace, core in clojure), the creating of a JS
> function object, and the assigning of that function to the core object. The
> internal call to some_fn doesn't matter at load-time because of
> Javascript's late binding.
>
> In the JVM this happens:
>
> 1) A class is loaded that implements the IFn or AFn interfaces
> 2) The methods on this class must be loaded and the bytcode parsed, and
> validated
> 3) The static constructor on this method is run
> 4) Inside the static constructor there are calls to find Vars. In the case
> of the above function this would be a lookup to clojure.core.some_fn. This
> is done for every var referenced by this function
> 5) Any non-native constants must be new'd up. This includes hashmaps,
> vectors, lists, keywords (which must be interned), symbols, etc.
> 5) The clojure.core.conj var is created
> 6) The contents of the var are set to the function that was loaded (and
> new'd). Synchronization doesn't matter here as there are no other threads
> that can see this Var.
> 7) The metadata for the function is created. Most of the time this
> includes creating a hashmap with at least 2-3 values.
> 8) The metadata for the var is set.
>
> The systems in play here are completely different. So I re-state what I
> said before: it's apples-to-oranges.
>
> But I'd love to see more benchmarks in this thread, so far we only have
> opinions.
>
>
> On Thu, Jan 25, 2018 at 9:37 PM, Timothy Baldridge 
> wrote:
>
>> >> If Var reification is part of the slowness of Clojure startup over
>> Java's
>>
>> It's really not. If you completely removed vars from Clojure on the JVM,
>> Clojure wouldn't be faster by any measurable amount. If someone has
>> benchmarks that say that Vars themselves are the cause of Clojure JVM's
>> slower startup, then I'd love to see those benchmarks, because there's most
>> likely a serious flaw in the measurements.
>>
>> On Thu, Jan 25, 2018 at 9:34 PM, Didier  wrote:
>>
>>> Really, any comparisons between JS and JVM startup times are not useful
>>>> at all.
>>>
>>>
>>> I'd say its useful to me, if anything because I've learned quite a few
>>> things already from this comparison, and I hope to learn more.
>>>
>>> If Var reification is part of the slowness of Clojure startup over
>>> Java's, and ClojureScript managed without it, yet it delivered 90% of the
>>> practical benefits of Var reification, I could see a potential here maybe.
>>> Something similar to a dynamic or AOT. Flagging some Vars which need not be
>>> reified, or compiling to non reified Vars if fast startup time is what the
>>> user would rather have. I could see this being desirable for use cases like
>>> AWS Lambda, or small scripts, if it had a drastic startup improvement.
>>>
>>> The concurrency issue is interesting, and would definitely be unique to
>>> Clojure over ClojureScript. First time I hear about this being a possible
>>> bottleneck for startup time. Are the concurrency checks java's?

Re: If Clojure is to blame for the majority of the startup time, why doesn't ClojureScript proportionally slow down the JavaScript startup time also?

2018-01-26 Thread Nathan Fisher
Hi Alex,

That’s cool!

I was looking to explore alternatives optimisations to what you had already
outlined and which I could potentially do with little effort. I started
writing something to do parallel loads back in Sept/Oct. and was
replicating some of what Buck/Blaze/Basel do in terms of a DAG. I wanted
“pristine” Clojure VMs for each node in the dependency graph but startup
time was an issue and I couldn’t see an easy way to bring it down.

For point one I was noticing some amount of non-trivial latency in Var
interning and RT map. Agree Java CAS performance won’t be the issue but (I
think) there’s something in Clojure that I’m working to improve my
understanding. For the map I noticed once I eliminated class loading via
prefetching the map initialisation in RT was a non-trivial amount of time
(double digit ms). Not something that I think needs prioritisation by any
means but just a “huh wonder why that is?”.

Justin in terms of Java it’s not a matter of JIT or anything like that.
It’ll be relatively efficient out of the box, it’s a handful of cpu
instructions to execute and is around 20 CPU cycles per try (eg
nanoseconds). It should succeed on or about the first time within the
context of Clojure startup. An atomic load side depends on how far up the
memory chain it has to go but shouldn’t be “too expensive” either, more
expensive than a local variable for sure but not enough to worry about in
most cases.

Cheers,
Nathan
On Fri, 26 Jan 2018 at 15:38, Justin Smith  wrote:

> a nitpick on point 1 - I would assume you can't expect hotspot to improve
> anything in the timescale of a program startup
>
> am I missing something here?
>
> On Fri, Jan 26, 2018 at 10:32 AM Alex Miller  wrote:
>
>> With a few custom patches (which are pending in jira) + AOT + direct
>> linking + lazy vars + var meta elision + jvm flags, I have gotten raw
>> startup as low as ~450 ms. Past that, radical changes are probably required
>> which are unlikely to be worth doing.
>>
>> On your conclusions:
>>
>> 1. minimize CAS'es - I'm doubtful this would make much difference.
>> Hotspot is usually pretty good at optimizing that stuff in single-threaded
>> uncontended scenarios. I will wave in the general direction of immutable
>> namespaces to a place that I think is an opportunity to improve a range of
>> issues like this.
>>
>> 2. Lazy vars effectively do this (in tandem with AOT and direct linking)
>> and it can help 20-30% (presuming you have compiled stuff to use). However,
>> most startup cases don't have AOT compiled code to work with and thus this
>> won't help at all.
>>
>> 3. Prefetching - as you found, I would not expect this to be useful
>> enough to be worth the pain and fragility involved.
>>
>> 4. jaotc - I think this *is* likely to be useful for cases where you can
>> pre-stage stuff like this, in particular core itself is a perfect
>> opportunity. People have already tested this (
>> https://mjg123.github.io/2017/10/04/AppCDS-and-Clojure.html) and found
>> it useful. But again, requires pre-AOT'ed code.
>>
>> I don't think most of these changes help at all though in the most common
>> case where you are spinning up a project with a lot of non-AOT'ed code -
>> the 10s of seconds of read/compile/init times dwarf this stuff. Rich and I
>> working on an idea to help with this.
>>
>> On Thursday, January 25, 2018 at 11:47:32 PM UTC-6, Nathan Fisher wrote:
>>>
>>> It's not a huge contributor but Class loading isn't free and Clojure
>>> could optimise it in a couple of places. I think with a couple of months
>>> effort in optimisation you might be able to get it down to 500ms for a
>>> simple "hello world". I'm doubtful you can get it much lower than that. TBH
>>> I'm not sure if the engineering effort would necessarily be worth it for
>>> many users.
>>>
>>> I wanted to test dynamic loading and docker before I shared the article
>>> more broadly but here's the results from implementing prefetching in
>>> Clojure;
>>>
>>> https://junctionbox.ca/2018/01/04/clojure-class-prefetching.html
>>> <https://www.google.com/url?q=https%3A%2F%2Fjunctionbox.ca%2F2018%2F01%2F04%2Fclojure-class-prefetching.html&sa=D&sntz=1&usg=AFQjCNGztHxa9E7A5PbzIdoK_5PK_bqzVw>
>>>
>>> It's a part of a series that I'm slowly plodding through as I have time.
>>> I hope to cover off the 4 items from the conclusion of this article;
>>>
>>>
>>> https://junctionbox.ca/2017/12/26/clojure-startup-walkthrough.html#conclusions
>>> <https://www.google.c

Re: If Clojure is to blame for the majority of the startup time, why doesn't ClojureScript proportionally slow down the JavaScript startup time also?

2018-01-26 Thread Nathan Fisher
Also what I was referencing in terms of the CAS was deferring submission
until the namespace is fully initialised. Something akin to a SQL
transaction where it could use mutable state and then transform it to the
immutable map at commit (eg end of the file). Until a ns fully parsed and
processed (by a single thread) there wouldn’t be any need for the
intermediate data structure to be thread-safe. Kind of like Guava data
structures but for Namespaces.
On Fri, 26 Jan 2018 at 16:57, Nathan Fisher  wrote:

> Hi Alex,
>
> That’s cool!
>
> I was looking to explore alternatives optimisations to what you had
> already outlined and which I could potentially do with little effort. I
> started writing something to do parallel loads back in Sept/Oct. and was
> replicating some of what Buck/Blaze/Basel do in terms of a DAG. I wanted
> “pristine” Clojure VMs for each node in the dependency graph but startup
> time was an issue and I couldn’t see an easy way to bring it down.
>
> For point one I was noticing some amount of non-trivial latency in Var
> interning and RT map. Agree Java CAS performance won’t be the issue but (I
> think) there’s something in Clojure that I’m working to improve my
> understanding. For the map I noticed once I eliminated class loading via
> prefetching the map initialisation in RT was a non-trivial amount of time
> (double digit ms). Not something that I think needs prioritisation by any
> means but just a “huh wonder why that is?”.
>
> Justin in terms of Java it’s not a matter of JIT or anything like that.
> It’ll be relatively efficient out of the box, it’s a handful of cpu
> instructions to execute and is around 20 CPU cycles per try (eg
> nanoseconds). It should succeed on or about the first time within the
> context of Clojure startup. An atomic load side depends on how far up the
> memory chain it has to go but shouldn’t be “too expensive” either, more
> expensive than a local variable for sure but not enough to worry about in
> most cases.
>
> Cheers,
> Nathan
> On Fri, 26 Jan 2018 at 15:38, Justin Smith  wrote:
>
>> a nitpick on point 1 - I would assume you can't expect hotspot to improve
>> anything in the timescale of a program startup
>>
>> am I missing something here?
>>
>> On Fri, Jan 26, 2018 at 10:32 AM Alex Miller  wrote:
>>
>>> With a few custom patches (which are pending in jira) + AOT + direct
>>> linking + lazy vars + var meta elision + jvm flags, I have gotten raw
>>> startup as low as ~450 ms. Past that, radical changes are probably required
>>> which are unlikely to be worth doing.
>>>
>>> On your conclusions:
>>>
>>> 1. minimize CAS'es - I'm doubtful this would make much difference.
>>> Hotspot is usually pretty good at optimizing that stuff in single-threaded
>>> uncontended scenarios. I will wave in the general direction of immutable
>>> namespaces to a place that I think is an opportunity to improve a range of
>>> issues like this.
>>>
>>> 2. Lazy vars effectively do this (in tandem with AOT and direct linking)
>>> and it can help 20-30% (presuming you have compiled stuff to use). However,
>>> most startup cases don't have AOT compiled code to work with and thus this
>>> won't help at all.
>>>
>>> 3. Prefetching - as you found, I would not expect this to be useful
>>> enough to be worth the pain and fragility involved.
>>>
>>> 4. jaotc - I think this *is* likely to be useful for cases where you can
>>> pre-stage stuff like this, in particular core itself is a perfect
>>> opportunity. People have already tested this (
>>> https://mjg123.github.io/2017/10/04/AppCDS-and-Clojure.html) and found
>>> it useful. But again, requires pre-AOT'ed code.
>>>
>>> I don't think most of these changes help at all though in the most
>>> common case where you are spinning up a project with a lot of non-AOT'ed
>>> code - the 10s of seconds of read/compile/init times dwarf this stuff. Rich
>>> and I working on an idea to help with this.
>>>
>>> On Thursday, January 25, 2018 at 11:47:32 PM UTC-6, Nathan Fisher wrote:
>>>>
>>>> It's not a huge contributor but Class loading isn't free and Clojure
>>>> could optimise it in a couple of places. I think with a couple of months
>>>> effort in optimisation you might be able to get it down to 500ms for a
>>>> simple "hello world". I'm doubtful you can get it much lower than that. TBH
>>>> I'm not sure if the engineering effort would necessarily be worth it for
>&g

Re: Bazel as Clojure build tool

2018-01-29 Thread Nathan Fisher
Hi Kiril,

I think you’d need to set your expectations. Faster builds are unlikely to
be one of the benefits. A unified build tool is one.

I’ve seen a few similar attempts with Buck which was inspired by Bazel.
They either generate lein projects on the fly or call into the Clojure
compiler directly.

I think Clojure’s build model works against these tools in part because
it’s a dynamic language, in part because it doesn’t implicitly forward
declare functions, in part because (I believe) it does breadth first
traversal if dependencies, and in part it’s non-trivial/inefficient to
create a clean Clojure VM per dependency in the build graph.

Typical usage of these build tools is to have a build file per directory
with one or more targets in each file. In order to get the speed that the
build tool promises you need the ability to efficiently parse the ABI of
each file and only build its dependents when the ABI has changed.

I’m not certain you can do that with Clojures compiler but someone else
might be able to chime in with a way that you could.

Cheers,
Nathan

On Mon, 29 Jan 2018 at 13:16, Kiril Videlov  wrote:

> Hello,
> I have been looking at the Bazel <https://bazel.build> build tool for a
> multi-language mono-repo and I was wondering if anybody has tried it in the
> context of Clojure projects. I have only found the lein-monolith
> <https://github.com/amperity/lein-monolith/> plugin which appears to
> address a similar use case sans the polyglot requirement. Do you think
> there is any value in attempting to build a rule set
> <https://docs.bazel.build/versions/master/skylark/rules.html> similar to
> the bazel rules for Scala <https://github.com/bazelbuild/rules_scala>?
>
> Regards,
> Kiril Videlov
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from 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.
>
-- 
- sent from my mobile

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

2018-04-19 Thread Nathan Fisher
I was thinking it would be interesting to “remove” the use of Java interop
in core instead replacing it with a reserved namespace that maps to
whatever the underlying runtime/reader wants to. I suppose you can do the
same with the exisiting RT stuff but naively feels like it would be
cleaner/provide easier porting if it were one namespace which could have
Clojure docs generated for it.

On Thu, Apr 19, 2018 at 2:55 PM, Timothy Baldridge 
wrote:

> GraalVM does a lot of things, and I think it's important to separate these
> terms.
>
> GraalVM - most often this is used to refer to a project that was
> originally designed to be a implementation of the JVM in Java. So when
> people ask "does X run on GrallVM" the question is really "does X run in
> the JVM". Clojure runs on the JVM therefore it runs on GraalVM. I've done
> this, and it's not that hard to setup.
>
> Truffle - is an AST interpreter framework that allows for highly dynamic
> languages to run efficiently on GraalVM. Truffle is valid Java code, so you
> can run Truffle on a stock JVM, but it's much faster on GraalVM (or on JVM
> of version >= 9). Notice my use of "highly dynamic" earlier. Surprisingly,
> Clojure is mostly static, so there's no clear win here to translating
> Clojure to Truffle. The exception to this is primitive math, and situations
> that use lots of HOF where Truffle could perhaps offer more localized
> optimizations that fit into the Clojure programming model. However, you pay
> for all this with some rather massive startup time penalties. Most examples
> I've seen show Truffle adding seconds on to the startup time of a language.
>
> SubstrateVM - (aka native-image), SubstrateVM attempts to improve the
> performance of a Truffle based language by doing image freezing. This
> method has been used in other languages, and has existed in the PyPy
> toolchain (RPython) for well over a decade. The idea is that you write an
> interpreter, then hand SVM a pointer to the start of your interpreter (the
> main() function). The framework then analyzes the data needed by that
> function and all the functions it calls. All data required by those
> functions are also recorded. Then the call graph required to run all these
> functions is written out (normally to C or C++) and compiled. The
> side-effect is that all the startup time is removed since the interpreter
> is "frozen" in a started state. In the terms of Clojure this means that
> metadata would be serialized as-is, instead of running the code to create
> that metadata on every startup.
>
> Polyglot VM - so in truffle you can have multiple type systems, and
> multiple languages all running on Truffle. The framework then allows cheap
> interop between these languages. So when GraalVM docs talk about "zero
> overhead interop" what they mean is that it's possible to inline a Truffle
> based function inside any other truffle based function. Since Truffle
> implementations exist for Ruby, Python, LLVM bytecode (think C/C++),
> JavaScript, etc. It's easy to see how its possible to have all of these
> languages efficiently calling each other on the same VM.
>
> It's not all awesome though. By using SubstrateVM you give up Java
> reflection/interop, or have to find a way to embed a full JVM as a Truffle
> language (this is being worked on), but every language you add into your
> SVM image comes at a cost of startup times, memory usage etc. So most of
> the time SVM images stick to a few languages. TruffleRuby for example only
> uses Ruby and LLVM (for c interop).
>
> To finish, I think Clojure on Truffle is possible, but it would take a TON
> of work. Basically most of clojure.lang.RT would need to be rewritten from
> scratch, and I'm not sure how much more in clojure.lang.* would also need
> to be rewritten. So the tradeoff is:
>
> A. Current state
> - Good enough performance
> - Fast enough startup (Clojure starts quickly, it's the deps/tooling that
> are slow)
> - Requires type hinting to avoid reflection
>
> B. Clojure on Truffle
> - More-or-less the same performance
> - Faster un-type-hinted math
> - (Possibly) Faster transducers/HOF over primitive collections
> - No need for type hints
> - Massive rewrite
> - Huge startup time penalty
> - Requires a modern/uncommon JVM (JVM9+ or GraalVM)
>
> Comparing these side-by-side, it looks to me to be a wash. And because of
> that I doubt we'll see a TruffleClojure any time soon.
>
> Timothy
>
> On Thu, Apr 19, 2018 at 4:00 AM, Khalid Jebbari 
> wrote:
>
>> Hello,
>>
>> Oracle has just announced GraalVM 1.0 release candidate:
>> https://blogs.oracle.com/developers/announcing-graalvm
>>
>> It mentions a few JVM-based language but not Clojure (maybe just because
>> of popularity).
>> - Does it mean Clojure is not "compatible" with GraalVM ?
>> - Does it mean Clojure needs to be reimplemented in terms of GraalVM's
>> Truffle framework ?
>> - Does it mean Clojure can be run as a native binary with fast startup
>> time and minimized memory footprint ?
>

Re: Understanding GraalVM and Clojure

2018-04-28 Thread Nathan Fisher
Another interesting post on Clojure and Graal

https://www.innoq.com/en/blog/native-clojure-and-graalvm/
On Sat, Apr 28, 2018 at 10:01 AM, Khalid Jebbari 
wrote:

> Thank you for the link.
>
> Le sam. 28 avr. 2018 à 00:35, Egg Syntax  a écrit :
>
>> Karin Meier has done some experimentation using Clojure on GraalVM to
>> call R and Python, and has a blog post
>> 
>>  and repo
>> 
>>  that
>> you may find interesting.
>>
>>
>> On Thursday, April 19, 2018 at 6:00:14 AM UTC-4, Khalid Jebbari wrote:
>>>
>>> Hello,
>>>
>>> Oracle has just announced GraalVM 1.0 release candidate:
>>> https://blogs.oracle.com/developers/announcing-graalvm
>>>
>>> It mentions a few JVM-based language but not Clojure (maybe just because
>>> of popularity).
>>> - Does it mean Clojure is not "compatible" with GraalVM ?
>>> - Does it mean Clojure needs to be reimplemented in terms of GraalVM's
>>> Truffle framework ?
>>> - Does it mean Clojure can be run as a native binary with fast startup
>>> time and minimized memory footprint ?
>>>
>>> If someone with some knowledge could explain to me the relationships
>>> between Clojure and GraalVM ? Bonus points if Alex Miller answers and share
>>> the plans, if any, about their integration/interaction.
>>>
>>> Thanks a lot in advance. really curious to understand 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 a topic in the
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/clojure/iBY6hwqqp5c/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> clojure+unsubscr...@googlegroups.com.
>
>
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
-- 
- sent from my mobile

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

2018-04-30 Thread Nathan Fisher
Is there a runnable language test suite that is used to verify CLJ, CLJS,
and CLR compatibility? Thinking something similar to RubySpec that could be
used to validate the completeness/gaps in a particular implementation (eg
GraalVM).
On Sun, Apr 29, 2018 at 7:16 AM, Khalid Jebbari 
wrote:

> I've read it, it's really interesting. Alex Miller mentioned on Twitter
> that they'll work on removing some limitations over time. @Alex, can you
> confirm and expand a bit more ?
>
> Le sam. 28 avr. 2018 à 23:14, Nathan Fisher  a
> écrit :
>
>> Another interesting post on Clojure and Graal
>>
>> https://www.innoq.com/en/blog/native-clojure-and-graalvm/
>> On Sat, Apr 28, 2018 at 10:01 AM, Khalid Jebbari <
>> khalid.jebb...@gmail.com> wrote:
>>
>>> Thank you for the link.
>>>
>>> Le sam. 28 avr. 2018 à 00:35, Egg Syntax  a écrit :
>>>
>>>> Karin Meier has done some experimentation using Clojure on GraalVM to
>>>> call R and Python, and has a blog post
>>>> <http://gigasquidsoftware.com/blog/2017/10/22/embedded-interop-between-clojure-r-and-python-with-graalvm/>
>>>>  and repo
>>>> <https://github.com/gigasquid/graal-test/blob/master/src/graal_test/core.clj>
>>>>  that
>>>> you may find interesting.
>>>>
>>>>
>>>> On Thursday, April 19, 2018 at 6:00:14 AM UTC-4, Khalid Jebbari wrote:
>>>>>
>>>>> Hello,
>>>>>
>>>>> Oracle has just announced GraalVM 1.0 release candidate:
>>>>> https://blogs.oracle.com/developers/announcing-graalvm
>>>>>
>>>>> It mentions a few JVM-based language but not Clojure (maybe just
>>>>> because of popularity).
>>>>> - Does it mean Clojure is not "compatible" with GraalVM ?
>>>>> - Does it mean Clojure needs to be reimplemented in terms of GraalVM's
>>>>> Truffle framework ?
>>>>> - Does it mean Clojure can be run as a native binary with fast startup
>>>>> time and minimized memory footprint ?
>>>>>
>>>>> If someone with some knowledge could explain to me the relationships
>>>>> between Clojure and GraalVM ? Bonus points if Alex Miller answers and 
>>>>> share
>>>>> the plans, if any, about their integration/interaction.
>>>>>
>>>>> Thanks a lot in advance. really curious to understand 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 a topic in the
>>>> Google Groups "Clojure" group.
>>>> To unsubscribe from this topic, visit
>>>> https://groups.google.com/d/topic/clojure/iBY6hwqqp5c/unsubscribe.
>>>> To unsubscribe from this group and all its topics, send an email to
>>>> clojure+unsubscr...@googlegroups.com.
>>>
>>>
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
>> - sent from my mobile
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" gr

Re: Bazel as Clojure build tool

2018-06-04 Thread Nathan Fisher
It's not something that as a user you'd be exposed to. The easiest way to 
demonstrate the impact is to write a library and test target in two 
different ways for a Java project.

1. using java_library target for the library.
2. using genrule for the library that calls out to javac.

Run the test target, introduce whitespace into the library, and run the 
test target again. It should only do a full execution in the 2nd example.

On Sunday, 15 April 2018 17:09:12 UTC-3, Gregg Reynolds wrote:
>
>
>
> On Mon, Jan 29, 2018, 2:07 PM Nathan Fisher  > wrote:
>
>> ...
>
>>  In order to get the speed that the build tool promises you need the 
>> ability to efficiently parse the ABI of each file and only build its 
>> dependents when the ABI has changed.
>>
>
> Can you please elaborate on this a bit? I've been using Bazel for a 
> project that involve C and Java, with cross-compiles, and ABI parsing has 
> never come up. It just works.
>
>>
>> I’m not certain you can do that with Clojures compiler but someone else 
>> might be able to chime in with a way that you could.
>>
>
> I like boot for clojure stuff, not sure Bazel offers any advantage. 
> Clojurescript may be a different story, tho.
>
> So far I cannot see a good reason to switch from boot to Bazel for 100% 
> clojure projects. Mixed language - clojure, clojurescript, js, Java, 
> kotlin, JNI,etc - may be a different story, still not sure.
>
> Then there's remote caching: 
> https://docs.bazel.build/versions/master/remote-caching.html. a hyge 
> win for many scenarios, not so sure about clojure.
>
> G
> G
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from 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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Nathan Marz
If you want to be able to arbitrarily manipulate your data structures, you 
should look at Specter. I recommend reading my introductory blog post on 
it: http://nathanmarz.com/blog/clojures-missing-piece.html The 
`BEFORE-ELEM` and `AFTER-ELEM` navigators are what you use for 
prepending/appending. 

Things get a lot worse in Clojure when dealing with nested/recursive data 
structures. These use cases were the main motivators for developing 
Specter, and the navigation concept naturally ended up solving the more 
basic manipulations like prepend / append / mid-sequence insertion. 


On Wednesday, July 18, 2018 at 11:21:32 AM UTC-4, Gary Trakhman wrote:
>
> Well, actually, concat returns a seq, not a list. For all practical 
> purposes, it looks like a list, but it isn't one.  Practically, the 
> difference is laziness, which is a whole thing on its own. Also the count 
> operation is linear when lists just keep track of their length, and can do 
> it in constant-time.
>
> On Wed, Jul 18, 2018 at 11:17 AM Christian Seberino  > wrote:
>
>> Actually I was just kicked out of paradise.  concat always returns a list 
>> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>>
>> cs
>>
>> ___
>>
>> Christian Seberino, Ph.D.
>> Phone: (936) 235-1139
>> Email: cseb...@gmail.com  
>> ___
>>
>>
>>
>> On Wed, Jul 18, 2018 at 2:16 AM, Didier > 
>> wrote:
>>
>>> It's never a good idea to use the wrong data structure for the job.
>>>
>>> And thus Clojure takes the stance that it won't make bad ideas easy for 
>>> you to use. Yet, it will never prevent you from doing anything.
>>>
>>> If you want to do something bad, you'll need to get your own hands dirty.
>>>
>>> That's why slow data structure access functions don't exist as standard. 
>>> That's why data transforms are lazy by default. And why the non lazy 
>>> variant (transducers) do loop fusion for you. That's why mutability is ugly 
>>> and requires you to wrap things in extra verbosity. That's why OOP isn't 
>>> there, and forces you to use the host interop if you want it. That's why 
>>> there's only recursive loops. Etc.
>>>
>>> The Clojure standard lib is opinionated. It's not trying to make 
>>> everything easy and convenient. It's trying to make things simple to reason 
>>> about, and promote Rich Hickeys opinion of what is a good idea, and what 
>>> isn't.
>>>
>>> But, it can afford to be this way, because it made itself a Lisp, 
>>> meaning it gave you all the power needed to disagree and make your own 
>>> core, which follows your own opinions of good and bad.[1]
>>>
>>> Now, I recommend that everyone should have a core library of their own 
>>> that they keep around for cases like this, where they disagree.
>>>
>>> And for beginners, I mean, what are you trying to teach them? What 
>>> problem requires them to add items to the beginning and end of an ordered 
>>> collection?
>>>
>>> Anyways, my advice is to teach them concat. It's even nicer then 
>>> append/prepend. You just give it the arguments where you want them to go.
>>>
>>> (concat [1] [2 3])
>>>
>>> (concat [1 2] [3])
>>>
>>> And it works for any type of ordered collections, even arrays.
>>>
>>> Also, this blog I think does a great job at teaching all this to a 
>>> beginner 
>>> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>>>
>>>
>>>
>>> [1] Except for reader macros. Rich didn't want you to be able to change 
>>> the whole program syntax in unconstrained ways. That's probably a good 
>>> thing to at least keep the foundation universal accross code bases.
>>>
>>> -- 
>>> 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 em

Re: Webassembly as a Clojure target platform

2018-07-26 Thread Nathan Fisher
Think Rust and Golang both have the ability to target WASM now too. I'm not
sure how well Java Byte-Code to WASM would work in practise. Found this
project that seems able to transpile from Java ByteCode to JS/WASM;

http://teavm.org/

On Thu, 26 Jul 2018 at 12:34 Bo Yao  wrote:

> Not true.Wasm is a a kind of assembly and it's browser runtime:
> https://webassembly.github.io/spec/. The emscripten project is doing
> compile c/c++ to wasm. There's a another team working on rust to wasm
> compiler and toolchains: https://webassembly.github.io/spec/
>
> On Friday, September 15, 2017 at 3:08:18 AM UTC-4, Nur Azhar wrote:
>>
>> Correct me if I am wrong, webassembly is just a compiler currently only
>> supports C,C++ and rust and we might be able to compile clojure to
>> webassembly in the far future?
>>
>> On Thursday, September 14, 2017 at 5:03:25 AM UTC+8, Hlöðver Sigurðsson
>> wrote:
>>>
>>> https://github.com/AssemblyScript/assemblyscript
>>>
>>>
>>> Looks like the Typescript people are attempting exactly this.
>>>
>>> On Monday, 4 April 2016 08:50:06 UTC+2, JvJ wrote:

 Is there any plan in the future to have clojure (or some dialect of
 clojure) compile to webassembly?  I can't say for sure if it is the "next
 big thing" for the web, but it is a very interesting concept.

 I suppose that, if Java bytecode could cross-compile to Webassembly, we
 would essentially get this for free, but I'm not sure if that will happen.

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

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


  1   2   3   >