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


Re: Tour of our 250k line Clojure codebase

2021-06-09 Thread Nathan Marz
eady 
>>> 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_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/75b98a55-39cd-4b5c-8f17-4b0c0390b655n%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_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-03 Thread Nathan Marz
Derek – we have a bunch of open-source on our Github 
. 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 

 
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.


[JOB] Software Engineer | Red Planet Labs | Fully distributed team

2020-02-20 Thread Nathan Marz
We're a well-funded startup building a new kind of software development 
tool that will radically change the economics of software development. 
We're backed by some amazing investors including Max Levchin, Naval 
Ravikant, and Alexis Ohanian.

Since our first round of hiring last year we've gotten the hang of 
operating as a fully distributed team and are now ready to grow the team 
further.

Our technology is entirely in Clojure, and it pushes the boundaries of 
what's possible with compilers, databases, and distributed systems. If 
you'd be interested in joining, please reach out!

*Website*: https://redplanetlabs.com/
*Blog post introducing company*: 
https://medium.com/red-planet-labs/introducing-red-planet-labs-2a0304a67312
*How we operate as a fully distributed team*: 
https://medium.com/red-planet-labs/why-fully-distributed-is-by-far-the-best-way-to-run-a-software-team-d99abfc0c700

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


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

2020-01-20 Thread Nathan Marz
Thanks. It doesn't currently use type hints to distinguish between multiple 
methods of the same arity. Opened an issue: 
https://github.com/redplanetlabs/proxy-plus/issues/1

On Monday, January 20, 2020 at 11:57:31 AM UTC-5, Ghadi Shayban wrote:
>
> I tried using proxy+ for one of the proxy implementations in clojure.core, 
> but I ran into an issue where a "too many matching methods" got thrown at 
> macroexpansion time. The proxy I tried to replicate was PrintWriter-on 
> <https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj#L559-L581>.
>  
> The exception-data contained two "write" methods that matched arity but 
> didn't match param types. Repro below.
>
> (require '[com.rpl.proxy-plus :refer [proxy+]]))
>
> (defn ^java.io.PrintWriter proxy+test
>   [flush-fn close-fn]
>   (let [sb (StringBuilder.)]
> (-> (proxy+ []
>   java.io.Writer
>   (flush [this]
>  (when (pos? (.length sb))
>(flush-fn (.toString sb)))
>  (.setLength sb 0))
>   (close [this]
>  (.flush this)
>  (when close-fn (close-fn))
>  nil)
>   (write [this ^chars str-cbuf off len]
>  (when (pos? len)
>(.append sb str-cbuf ^int off ^int len
> java.io.BufferedWriter.
> java.io.PrintWriter.)))
>
> On Monday, January 13, 2020 at 11:47:06 AM UTC-5, Nathan Marz wrote:
>>
>> proxy+ is a replacement for Clojure's proxy that's faster and more 
>> usable. proxy has a strange implementation where it overrides every 
>> possible method and uses a mutable field to store a map of string -> 
>> function for dispatching the methods. This causes it to be unable to handle 
>> methods with the same name but different arities.
>>
>> proxy+ fixes these issues with proxy. Usage is like reify, and it's up to 
>> 10x faster.
>>
>> *Repository: *https://github.com/redplanetlabs/proxy-plus
>>
>

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


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

2020-01-14 Thread Nathan Marz
The speedup comes from proxy+ directly overriding methods with the provided 
implementation, while Clojure's proxy has additional indirection. For 
example, if you do (proxy [Object] [] (toString [] "hello")), the bytecode 
for toString is:

  public java.lang.String toString();

 0  aload_0 [this]

 1  getfield user.proxy$java.lang.Object$ff19274a.__clojureFnMap : 
clojure.lang.IPersistentMap [16]

 4  ldc  [52]

 6  invokestatic clojure.lang.RT.get(java.lang.Object, 
java.lang.Object) : java.lang.Object [36]

 9  dup

10  ifnull 28

13  checkcast clojure.lang.IFn [38]

16  aload_0 [this]

17  invokeinterface clojure.lang.IFn.invoke(java.lang.Object) : 
java.lang.Object [55] [nargs: 2]

22  checkcast java.lang.String [57]

25  goto 33

28  pop

29  aload_0 [this]

30  invokespecial java.lang.Object.toString() : java.lang.String [59]

33  areturn

Clojure keeps the implementations in a map, and for every dispatch it does 
a map lookup by the method name. This is also why it can't handle 
overriding the same method name with different arities.

For (proxy+ [] Object (toString [this] "hello")), the bytecode is:

  public java.lang.String toString();

 0  aload_0 [this]

 1  getfield user.proxy_plus5358.toString5357 : clojure.lang.IFn [19]

 4  aload_0 [this]

 5  invokeinterface clojure.lang.IFn.invoke(java.lang.Object) : 
java.lang.Object [30] [nargs: 2]

10  checkcast java.lang.String [32]

13  areturn

The implementation function is stored as a field, so the cost of dispatch 
is a field get rather than a map lookup.

Clojure's proxy also overrides *every* available method in all 
superclasses/interfaces, while proxy+ only overrides what you specify. So 
proxy+ generates much smaller classes than proxy.


On Tuesday, January 14, 2020 at 10:30:32 AM UTC-5, Brent Millare wrote:
>
> I skimmed the code, I don't really understand how it makes it faster over 
> proxy. Is it the generated ASM is better? What's the in-a-nutshell 
> description of how it works?
>
> On Monday, January 13, 2020 at 1:28:46 PM UTC-5, Nathan Marz wrote:
>>
>> No differences in behavior except for API being like reify. It integrates 
>> with AOT and can be consumed just like any other class. No idea how it 
>> interacts with Graal.
>>
>> On Monday, January 13, 2020 at 12:29:35 PM UTC-5, John Newman wrote:
>>>
>>> Bravo 
>>>
>>> Are there any differences in behavior to be aware of? AOT, Graal, 
>>> consuming proxy+ classes from vanilla clojure classes?
>>>
>>> On Mon, Jan 13, 2020, 11:47 AM Nathan Marz  wrote:
>>>
>>>> proxy+ is a replacement for Clojure's proxy that's faster and more 
>>>> usable. proxy has a strange implementation where it overrides every 
>>>> possible method and uses a mutable field to store a map of string -> 
>>>> function for dispatching the methods. This causes it to be unable to 
>>>> handle 
>>>> methods with the same name but different arities.
>>>>
>>>> proxy+ fixes these issues with proxy. Usage is like reify, and it's up 
>>>> to 10x faster.
>>>>
>>>> *Repository: *https://github.com/redplanetlabs/proxy-plus
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to 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
>>>> clo...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to clo...@googlegroups.com.
>>>> To view this discussion on the web visit 
>>>> https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com
>>>>  
>>>> <https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com?utm_medium=email_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/6793548f-0bc9-4c10-8e5c-cf235aaaccce%40googlegroups.com.


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

2020-01-13 Thread Nathan Marz
No differences in behavior except for API being like reify. It integrates 
with AOT and can be consumed just like any other class. No idea how it 
interacts with Graal.

On Monday, January 13, 2020 at 12:29:35 PM UTC-5, John Newman wrote:
>
> Bravo 
>
> Are there any differences in behavior to be aware of? AOT, Graal, 
> consuming proxy+ classes from vanilla clojure classes?
>
> On Mon, Jan 13, 2020, 11:47 AM Nathan Marz  > wrote:
>
>> proxy+ is a replacement for Clojure's proxy that's faster and more 
>> usable. proxy has a strange implementation where it overrides every 
>> possible method and uses a mutable field to store a map of string -> 
>> function for dispatching the methods. This causes it to be unable to handle 
>> methods with the same name but different arities.
>>
>> proxy+ fixes these issues with proxy. Usage is like reify, and it's up to 
>> 10x faster.
>>
>> *Repository: *https://github.com/redplanetlabs/proxy-plus
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to 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
>> clo...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clo...@googlegroups.com .
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com?utm_medium=email_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/a39e0803-2a07-447c-ba8b-7c47f243d83b%40googlegroups.com.


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

2020-01-13 Thread Nathan Marz
proxy+ is a replacement for Clojure's proxy that's faster and more usable. 
proxy has a strange implementation where it overrides every possible method 
and uses a mutable field to store a map of string -> function for 
dispatching the methods. This causes it to be unable to handle methods with 
the same name but different arities.

proxy+ fixes these issues with proxy. Usage is like reify, and it's up to 
10x faster.

*Repository: *https://github.com/redplanetlabs/proxy-plus

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


[ANN] nippy-serializable-fns: Serialize and deserialize Clojure functions

2020-01-06 Thread Nathan Marz
We've open-sourced some code for serializing and deserializing Clojure 
functions across processes that share the same code version. It's 
implemented as an extension for Nippy and is quite fast!

*Blog post:*
 
https://tech.redplanetlabs.com/2020/01/06/serializing-and-deserializing-clojure-fns-with-nippy/
*Repository:* https://github.com/redplanetlabs/nippy-serializable-fns

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


Re: [ANN] defexception 0.1.0: a library for dynamically defining exception types in Clojure

2019-09-16 Thread Nathan Marz
We don't want such a tiny library to pull in any other dependencies. The 
subset of ASM used by defexception is so core and so minimal that we think 
it's extremely unlikely to ever break. A dependency collision with an ASM 
used by another library seems far more likely.


On Saturday, August 24, 2019 at 8:41:19 AM UTC-4, Alex Miller wrote:
>
> The clojure.asm namespaces are an internal vendored version of the asm 
> library. It is NOT considered to be part of the public Clojure API. We 
> periodically update it and have no control over that API, which does 
> sometimes include breaking changes.
>
> External users of Clojure should never depend on it directly. Instead they 
> should make their dependency on asm visible by declaring a dependency on 
> the asm library and using their public api.
>

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


[ANN] defexception 0.1.0: a library for dynamically defining exception types in Clojure

2019-08-22 Thread Nathan Marz
Authored by Bruce Hauman, defexception makes it really easy to define new 
exception types in Clojure just by doing (defexception MyException). See 
the README for details.

https://github.com/redplanetlabs/defexception

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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/3baf78be-33a1-432e-82f0-d303bd8bd91c%40googlegroups.com.


[ANN] Red Planet Labs, a new well-funded Clojure startup

2019-04-03 Thread Nathan Marz
I'm really happy to announce my startup Red Planet Labs with $5M in 
funding. We have some incredible investors on board including Max Levchin, 
Naval Ravikant, and Alexis Ohanian. We're building a new kind of software 
development tool that will radically change the economics of software 
development.

Website: https://redplanetlabs.com/
Announcement blog 
post: 
https://medium.com/red-planet-labs/introducing-red-planet-labs-2a0304a67312

RPL is based on technology I spent over 5 years researching. The technology 
is entirely in Clojure, and it pushes the boundaries of what's possible 
with compilers, databases, and distributed systems. If you'd be interested 
in joining, please reach out!

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


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

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


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


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


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


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


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 meaningful utility, 
>>> especially in the context of graph-like datasets. This is especially true 
>>> when combined with some kind of algebra for unioning/intersecting/etc. I'm 
>>> also interested in this sort of thing for programmable user-interface use 
>>> cases: Think text editors with multiple-cursors.
>>>
>>> I think experimentation is in order

>>>
>>> Agreed. Here's some starting points for pre-hammock reading/viewing 
>>> materials:
>>>
>>> *Tree 

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.


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


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.


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.


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.


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.


[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: 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 <natha...@gmail.com 
> > 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.


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.


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.


[ANN] Specter 0.10.0 released

2016-04-26 Thread Nathan Marz
Happy to announce the release of Specter 0.10.0. If you're unfamiliar with 
Specter, it's a library that supercharges your ability to query and 
manipulate data structures and has performance rivaling hand-optimized 
code. The README and my talk at Clojure/west are the best introductions to 
the project.

Thanks to @StephenRudolph, @thomasathorne, @bfrabry, @aengelberg, and 
@mfikes for their contributions to this release. Their work constituted the 
bulk of the new functionality.


Highlights of the release:

- No longer uses reducers in cljs version (uses transducers instead). All 
the issues people were having using ALL should now be resolved.
- Zippers are integrated into Specter in the com.rpl.specter.zipper 
namespace.
- subselect, parser, and submap navigators
- Now compatible with bootstrap cljs


Here's a couple of interesting transformations using the new navigators:


(transform (subselect ALL :a even?)
  reverse
  [{:a 2 :b 2} {:a 3} {:a 4} {:a 6} {:a 8}])
;; [{:a 8 :b 2} {:a 3} {:a 6} {:a 4} {:a 2}]

(def STRING<->LONG (parser #(Long/parseLong %) str))
(transform [ALL LAST STRING<->LONG]
  inc
  {:a "1" :b "2"}
  )
;; {:a "2" :b "3"}

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


Re: How do threads work in command-line REPL?

2016-02-09 Thread Nathan Marz
I should clarify that the thread id doesn't change instantly, it seems to
change when I've left it idle for a bit. Also on lein 2.5.2.

On Tue, Feb 9, 2016 at 1:45 PM, Mimmo Cosenza <mimmo.cose...@gmail.com>
wrote:

> I just tried with boot real:
>
> boot.user=> (.getId (Thread/currentThread))
> 34
> boot.user=> (.getId (Thread/currentThread))
> 34
> boot.user=> (.getId (Thread/currentThread))
> 34
> boot.user=> (.getId (Thread/currentThread))
> 34
> boot.user=> (.getId (Thread/currentThread))
> 34
> boot.user=> (.getId (Thread/currentThread))
> 34
>
>
> mimmo
>
> On 09 Feb 2016, at 19:38, Alex Miller <a...@puredanger.com> wrote:
>
> That seems pretty weird. I can't reproduce it. I'm using lein 2.5.2.
>
> On Tuesday, February 9, 2016 at 12:19:09 PM UTC-6, Nathan Marz wrote:
>>
>> I was doing some work that involved the use of thread locals, and I
>> noticed that within a REPL session (launched via 'lein repl') my thread
>> locals would reset themselves to their initial value. I did some digging
>> and found that the thread id keeps changing within a single REPL session,
>> e.g.:
>>
>> user=> (.getId (Thread/currentThread))
>> 65
>> user=> (.getId (Thread/currentThread))
>> 74
>> user=> (.getId (Thread/currentThread))
>> 78
>> user=> (.getId (Thread/currentThread))
>> 78
>> user=> (.getId (Thread/currentThread))
>> 78
>> user=> (.getId (Thread/currentThread))
>> 82
>>
>> I'm hoping someone who knows the internals of the REPL could shed some
>> light onto why this is the behavior and why it was designed this way.
>>
>> Thanks,
>> 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.
>
>
>


-- 
Twitter: @nathanmarz
http://nathanmarz.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.


How do threads work in command-line REPL?

2016-02-09 Thread Nathan Marz
I was doing some work that involved the use of thread locals, and I noticed
that within a REPL session (launched via 'lein repl') my thread locals
would reset themselves to their initial value. I did some digging and found
that the thread id keeps changing within a single REPL session, e.g.:

user=> (.getId (Thread/currentThread))
65
user=> (.getId (Thread/currentThread))
74
user=> (.getId (Thread/currentThread))
78
user=> (.getId (Thread/currentThread))
78
user=> (.getId (Thread/currentThread))
78
user=> (.getId (Thread/currentThread))
82

I'm hoping someone who knows the internals of the REPL could shed some
light onto why this is the behavior and why it was designed this way.

Thanks,
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: How do threads work in command-line REPL?

2016-02-09 Thread Nathan Marz
Yea, that code seems to explain the behavior we're seeing. I opened an
issue for this: http://dev.clojure.org/jira/browse/NREPL-80

On Tue, Feb 9, 2016 at 7:38 PM, Jony Hudson <jonyepsi...@gmail.com> wrote:

> Ahem.
>
> "method" -> "message"
>
>
> Jony
>
>
> On Wednesday, 10 February 2016 00:35:16 UTC, Jony Hudson wrote:
>>
>> I'm pretty fuzzy on how nREPL works, so I might be getting it wrong here
>> ... but I think it processes each method through a `future`. See:
>>
>>
>> https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/server.clj#L28
>>
>> All of the nREPL operations are async, AFAIK, and I think the future is
>> also relied upon to implement interruptible evaluation. See:
>>
>>
>> https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/interruptible_eval.clj#L243
>>
>> But I can't say I really understand that much of the eval code, so like I
>> say, I could be totally wrong here!
>>
>>
>> Jony
>>
>>
>> On Tuesday, 9 February 2016 18:19:09 UTC, Nathan Marz wrote:
>>>
>>> I was doing some work that involved the use of thread locals, and I
>>> noticed that within a REPL session (launched via 'lein repl') my thread
>>> locals would reset themselves to their initial value. I did some digging
>>> and found that the thread id keeps changing within a single REPL session,
>>> e.g.:
>>>
>>> user=> (.getId (Thread/currentThread))
>>> 65
>>> user=> (.getId (Thread/currentThread))
>>> 74
>>> user=> (.getId (Thread/currentThread))
>>> 78
>>> user=> (.getId (Thread/currentThread))
>>> 78
>>> user=> (.getId (Thread/currentThread))
>>> 78
>>> user=> (.getId (Thread/currentThread))
>>> 82
>>>
>>> I'm hoping someone who knows the internals of the REPL could shed some
>>> light onto why this is the behavior and why it was designed this way.
>>>
>>> Thanks,
>>> Nathan
>>>
>>>


-- 
Twitter: @nathanmarz
http://nathanmarz.com

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


Re: [ANN] Specter 0.9.2

2016-01-29 Thread Nathan Marz
It used to use cljc but needed to switch to cljx so that it could be
compatible with Clojure 1.6. It doesn't really affect users, it just adds
some inconvenience to working on Specter itself. Once it looks like most
people are on 1.7 or above, I'm all for switching it back to cljc.

On Fri, Jan 29, 2016 at 5:07 PM, Jason Lewis <ja...@decomplecting.org>
wrote:

> Wow, I hadn't seen this lib before, it really *is* the missing piece in a
> lot of ways.
>
> One question, are you considering migrating from cljx to cljc for
> cross-compiling? We've been trying to eliminate cljx dependencies in favor
> of cljc, and I'd be happy to help with the effort if it's on the roadmap.
>
> cheers,
> Jason
>
> On Tue, Jan 26, 2016 at 3:51 PM Nathan Marz <nathan.m...@gmail.com> wrote:
>
>> I just released Specter 0.9.2:
>>
>> https://github.com/nathanmarz/specter
>> https://clojars.org/com.rpl/specter/versions/0.9.2
>>
>> Specter solves a near-universal problem encountered when writing
>> Clojure/ClojureScript: the need to transform or query a data structure
>> that's more sophisticated than a basic map or list. It is a library that
>> captures the notion of "navigation" within a data structure and allows for
>> writing elegant queries and transformations. Its performance is close to
>> hand-optimized code so it can be used even in performance-critical code.
>> Additionally, Specter is extensible to any data structure as it is based on
>> a simple protocol.
>>
>> There have been over 15 releases since I last posted about Specter on the
>> group (almost a year ago), and there's been a ton of improvements since
>> then:
>>
>> - Precompilation feature enabling performance rivaling hand-optimized code
>> - Facilities for creating recursive navigators, including pre-walk and
>> post-walk traversals (declarepath/providepath, stay-then-continue,
>> continue-then-stay)
>> - ClojureScript support
>> - Conditional navigation (if-path, cond-path)
>> - Protocol paths: navigate based on the type of data encountered
>> - "Batteries included" set of navigators that captures majority of use
>> cases dealing with combinations of maps, lists, vectors, and sets
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/XePZ-WSviso/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.
>



-- 
Twitter: @nathanmarz
http://nathanmarz.com

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


Re: [ANN] Specter 0.9.2

2016-01-29 Thread Nathan Marz
I updated the example with a larger replacement sequence to hopefully
prevent that confusion in the future.

You can also use srange to eliminate subsequences, e.g.:

(setval (srange 4 7) nil [:a :b :c :d :e :f :g :h :i])
=> [:a :b :c :d :h :i]

And the navigator to prepend to a sequence is just selecting the empty
subsequence at the beginning:

(def BEGINNING (srange 0 0))
(setval BEGINNING [:a :b] '(1 2 3))
=> (:a :b 1 2 3)


On Fri, Jan 29, 2016 at 10:27 AM, Alan Thompson <clooj...@gmail.com> wrote:

> Oh!  I never even suspected that!  So you are replacing a length-2
> subsequence with a length-3 subsequence.  Very flexible.
>
> It might be useful to point out that feature in the docs.   :)
>
> Alan
>
>
> On Thu, Jan 28, 2016 at 10:49 PM, Nathan Marz <nat...@nathanmarz.com>
> wrote:
>
>> Both of those examples use half-open intervals :) The first selects the
>> subsequence with indices 1,2,3, and the second selects the subsequence with
>> indices 2,3. You can see in the second example that [2 3] in the overall
>> sequence is replaced by [-1 -1 -1].
>>
>> On Thu, Jan 28, 2016 at 9:10 PM, Alan Thompson <clooj...@gmail.com>
>> wrote:
>>
>>> Looks great, Nathan.  I also highly enjoyed your recent interview on the
>>> Cognitect podcast  <http://blog.cognitect.com/cognicast/095>.
>>>
>>> One quick question:  In the first example below from the README
>>> (verified at the repl), it seems that the (srange ...) function
>>> sometimes behaves as a half-open interval [1,4) like the (range ...)
>>> function in Clojure).  However, in the 2nd example it seems to behave
>>> as a closed interval [2,4].  Is there an easy way of knowing which behavior
>>> applies in different situations?
>>>
>>> Thanks,
>>> Alan
>>>
>>>
>>> Here's how to increment all the odd numbers between indexes 1
>>> (inclusive) and 4 (exclusive):
>>>
>>> user> (transform [(srange 1 4) ALL odd?] inc [0 1 2 3 4 5 6 7])
>>>
>>> [0 2 2 4 4 5 6 7]
>>>
>>> Here's how to replace the subsequence from index 2 to 4 with [-1 -1 -1]:
>>>
>>> user> (setval (srange 2 4) [-1 -1 -1] [0 1 2 3 4 5 6 7 8 9])
>>>
>>> [0 1 -1 -1 -1 4 5 6 7 8 9]
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Thu, Jan 28, 2016 at 4:11 PM, Jean Baro <jfb...@gmail.com> wrote:
>>>
>>>>
>>>> Congratulations for the spectacular work and thanks for sharing this
>>>> with the world.
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clojure@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from 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 a topic in the
>>> Google Groups "Clojure" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/clojure/XePZ-WSviso/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.
>>>
>>
>>
>>
>> --
>> Twitter: @nathanmarz
>> http://nathanmarz.com
>>
>> --
>&g

Re: [ANN] Specter 0.9.2

2016-01-28 Thread Nathan Marz
Both of those examples use half-open intervals :) The first selects the
subsequence with indices 1,2,3, and the second selects the subsequence with
indices 2,3. You can see in the second example that [2 3] in the overall
sequence is replaced by [-1 -1 -1].

On Thu, Jan 28, 2016 at 9:10 PM, Alan Thompson  wrote:

> Looks great, Nathan.  I also highly enjoyed your recent interview on the
> Cognitect podcast  .
>
> One quick question:  In the first example below from the README (verified
> at the repl), it seems that the (srange ...) function sometimes behaves
> as a half-open interval [1,4) like the (range ...) function in Clojure).
> However, in the 2nd example it seems to behave as a closed interval [2,4].
> Is there an easy way of knowing which behavior applies in different
> situations?
>
> Thanks,
> Alan
>
>
> Here's how to increment all the odd numbers between indexes 1 (inclusive)
> and 4 (exclusive):
>
> user> (transform [(srange 1 4) ALL odd?] inc [0 1 2 3 4 5 6 7])
>
> [0 2 2 4 4 5 6 7]
>
> Here's how to replace the subsequence from index 2 to 4 with [-1 -1 -1]:
>
> user> (setval (srange 2 4) [-1 -1 -1] [0 1 2 3 4 5 6 7 8 9])
>
> [0 1 -1 -1 -1 4 5 6 7 8 9]
>
>
>
>
>
>
> On Thu, Jan 28, 2016 at 4:11 PM, Jean Baro  wrote:
>
>>
>> Congratulations for the spectacular work and thanks for sharing this with
>> the world.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/XePZ-WSviso/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.
>



-- 
Twitter: @nathanmarz
http://nathanmarz.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.


[ANN] Specter 0.9.2

2016-01-26 Thread Nathan Marz
I just released Specter 0.9.2:

https://github.com/nathanmarz/specter
https://clojars.org/com.rpl/specter/versions/0.9.2

Specter solves a near-universal problem encountered when writing 
Clojure/ClojureScript: the need to transform or query a data structure 
that's more sophisticated than a basic map or list. It is a library that 
captures the notion of "navigation" within a data structure and allows for 
writing elegant queries and transformations. Its performance is close to 
hand-optimized code so it can be used even in performance-critical code. 
Additionally, Specter is extensible to any data structure as it is based on 
a simple protocol.

There have been over 15 releases since I last posted about Specter on the 
group (almost a year ago), and there's been a ton of improvements since 
then:

- Precompilation feature enabling performance rivaling hand-optimized code
- Facilities for creating recursive navigators, including pre-walk and 
post-walk traversals (declarepath/providepath, stay-then-continue, 
continue-then-stay)
- ClojureScript support
- Conditional navigation (if-path, cond-path)
- Protocol paths: navigate based on the type of data encountered
- "Batteries included" set of navigators that captures majority of use 
cases dealing with combinations of maps, lists, vectors, and sets

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


Using type hints to optimize protocol invocation

2015-09-08 Thread Nathan Marz
My understanding is that invocation of protocol methods incurs about 30%
overhead due to the need to look up the appropriate function for the type.
I also learned recently that Clojure does not use static type information
to do the lookup at compile-time and avoid the overhead. Given that Clojure
already does do some type analysis (to optimize Java method invocations),
why not do it for protocol invocation as well? Just trying to further my
understanding of the Clojure compiler.

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


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.


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