Re: Navigators and lenses

2017-03-09 Thread Brandon Bloom

>
> But I don't agree at all with the claim that Specter is some sort of 
> offbeat, ill-researched version of lenses.
>

Since you're responding to me specifically, I'd like to be clear that I 
never made that claim. I only said we need more experimentation. This is a 
sufficiently big enough area of ideas to warrant exploration of competing 
approaches.

Specter's navigators can do more than lenses.


I can't speak for anybody else, but when I say "lenses", I'm referring to 
the full range of constructs offered by Edward Kmett's lenses package for 
Haskell. See the stunningly confusing diagram in the docs: 
https://hackage.haskell.org/package/lens - This includes "traversals" and 
"folds" which allow richer transformations than a one-to-one "lens" 
mapping, like the navigators concept in specter.

Specter wouldn't have such richness of functionality and pragmatic 
> performance considerations
>

As I've said on Twitter, Nathan has done an absolutely wonderful job with 
both static (compilation) and dynamic (caching) optimization techniques in 
Specter. The Haskell lenses library gets a lot of the former from existing 
GHC wizardry, but the I'm not sure about the latter, since I'm not 
sophisticated enough with Haskell to tell.

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

RDF's query language SPARQL: https://www.w3.org/TR/rdf-sparql-query/

On Wednesday, March 8, 2017 at 5:35:42 PM UTC-8, 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 Traversal *
>
>- XPath: https://www.w3.org/TR/xpath/
>- CSS: https://www.w3.org/TR/css3-selectors/
>
> *Richer Tree Querying*
>
>- XQuery: https://www.w3.org/TR/xquery/
>- jQuery: https://api.jquery.com
>
> *Second-Class "Generalized References" (nee "L-values")*
>
>- Common Lisp: 
>http://www.lispworks.com/documentation/lw50/CLHS/Body/05_a.htm
>- C/C++: 
>
> http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c
>
> *Lenses in Other Languages*
>
>- Haskell: 
>
> https://skillsmatter.com/skillscasts/4251-lenses-compositional-data-access-and-manipulation
>  
>(great overview of key concepts!)
>- Racket: https://docs.racket-lang.org/lens/index.html
>
> *Graph Querying*
>
>- Neo4j Cypher: https://neo4j.com/developer/cypher-query-language/
>- TinkerPop Gremlin: https://tinkerpop.apache.org/gremlin.html
>
>

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

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

   - XPath: https://www.w3.org/TR/xpath/
   - CSS: https://www.w3.org/TR/css3-selectors/

*Richer Tree Querying*

   - XQuery: https://www.w3.org/TR/xquery/
   - jQuery: https://api.jquery.com

*Second-Class "Generalized References" (nee "L-values")*

   - Common Lisp: 
   http://www.lispworks.com/documentation/lw50/CLHS/Body/05_a.htm
   - C/C++: 
   
http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c

*Lenses in Other Languages*

   - Haskell: 
   
https://skillsmatter.com/skillscasts/4251-lenses-compositional-data-access-and-manipulation
 
   (great overview of key concepts!)
   - Racket: https://docs.racket-lang.org/lens/index.html

*Graph Querying*

   - Neo4j Cypher: https://neo4j.com/developer/cypher-query-language/
   - TinkerPop Gremlin: https://tinkerpop.apache.org/gremlin.html

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

2016-12-06 Thread Brandon Bloom
I was just very surprised to discover my :ret specs were not being checked 
via instrument. I've read the rationale above, but I'm not yet convinced. 
While of course I can (and will) use spec/assert from a post condition, I 
lose the nice selective instrumentation features.

I'd also like to make a counter-point to this reasoning:
 

> Running return-value instrument-style checking on whatever few 
> hand-written tests you might have isn’t going to give you better coverage 
> than a simple (even hardwired) generator that captures similar ranges.


In my case, I was already testing the root-level return value, but this 
function is deeply recursive. A small non-conforming value deep in the 
evaluation stack was yielding non-conformance at a path deep in the root 
return value. I was confused by why the :ret check wasn't finding it 
earlier. By relying on the top-level check rather than inline checks 
per-call (as per instrument or :pre/:post) I lost access to the call stack. 
Adding the post condition pin-pointed the problem instantly.

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


Re: clojure.spec & protocol fn

2016-06-06 Thread Brandon Bloom
Just guessing from past experience in the Clojure internals:

Instrumenting protocol methods it likely possible, but unlikely to be worth 
the effort.

There are already a bunch of places where protocol functions are different. 
The accepted convention is to always wrap a protocol method with a normal 
function to recover the benefits. The pattern usually looks like:

(defprotocol P
  (-foo [x y z]))

(defn foo [x y z]
  (-foo x y z))

Put your spec on foo, not -foo.

This tends to be good practice anyway because you have a place to wrap 
global behavior around -foo.

On Monday, June 6, 2016 at 12:53:55 PM UTC-7, Vjeran Marcinko wrote:
>
> On Sunday, June 5, 2016 at 8:23:10 PM UTC+2, red...@gmail.com wrote:
>>
>> http://dev.clojure.org/jira/browse/CLJ-1941 has some discussion about 
>> places where instrumenting won't work. 
>>
>>
> Does this mean that this is a bug or something crucial related to protocol 
> design is preventing this ever being implemented?
>
> -Vjeran
>

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


Re: Is there an apply-able new?

2016-05-27 Thread Brandon Bloom
The new operation intentionally demands a statically knowable type to 
construct. While this is true of Java as well, it's not true of JavaScript. 
However, it is true of the Google Closure compiler's "type system" for 
advanced compilation. That said, if the library you're using isn't going to 
be optimized with advanced, you can do any typical dynamic metaprogramming 
you'd want to do in JavaScript and call in to that.

mynamespace.make = function(cls) {
  return new (Function.prototype.bind.apply(cls, arguments));
};

Then from ClojureScript:

(apply mynamespace/make qx.ui.mobile.form.Button ["Go!"])



On Friday, May 27, 2016 at 10:24:12 AM UTC-7, hiskennyness wrote:
>
> qooxdoo lets us supply oft-used widget parameters to the constructor. For 
> example, a button can specify its label and icon at new time. And this 
> works fine from cljs:
>
>(new qx.ui.mobile.form.Button "Go!") ;; label is the first arg
>
> But I am wrapping qooxdoo in something more concise and want to be able to 
> code:
>
>(qxia/make (::Button "Go!")
>   ..other init params to be "set"
>
> Unfortunately I cannot even
>
>(new (qx-class qia-type)) ;; computed class
>
> Let alone
>
>(apply new (qx-class qxia-type) make-inits)
>
> Not that I thought I would get away with it. :) I grok new is special.
>
> I can fall back on the qooxdoo API and use setLabel and setIcon, but I 
> like learning so I thought I would ask if there were some way to:
>
>1. compute a class (preferably by first constructing a name) and/or
>2. do the moral equivalent of applying new to parameters
>
> -hk
>
>

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

2015-05-10 Thread Brandon Bloom
Just cut a 0.6.1 release with a few small fixes on the Clojure side and now 
moderately-less experimental ClojureScript support.

I know that, as of the this past week, you now have ∞×2 more options for 
ClojureScript pretty printing. Coincidence? or Thank you .cljc? You 
decide. Anyway, while clojure.pprint and its cljs.pprint port are both 
supremely useful and excellent software, Fipp has a lot to offer too!

Please give it a try, you may become addicted to how snappy it prints; or 
you may discover you have something other than EDN which you wish to pretty 
print. Fipp is the fastest game in town, and its simple/easy generic engine 
is available for your use and abuse.

Cheers,
Brandon

On Sunday, May 3, 2015 at 11:01:19 AM UTC-7, Brandon Bloom wrote:

 Fipp is a better pretty printer for Clojure (and now/soon ClojureScript!)

 https://github.com/brandonbloom/fipp

 Please give it a try and let me know how it goes.

 Version 0.6.0 includes...
 - Several nice performance improvements via Transducers
 - A totally rewritten Edn printer with tagged literal support
 - Experimental ClojureScript support

 Known CLJS Issues
 - No tagged literal support yet
 - The cljs.jar repl does something funky to newlines when printing
 - Lots of CLJS types with pr extensions are not yet specially handled
 - A bunch more stuff, to be fixed soon!

 Keep an eye out for related upgrades to the Pudget and Whidbey companion 
 projects when I get some more free time.

 Cheers,
 Brandon




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

2015-05-10 Thread Brandon Bloom


 If you have a public project on Github that is using transducers, would 
 you please point me to it? I would like to see what you did. 


Fipp's Clojure 1.7 tuned-up engine uses transducers to emulate 
mapcat(-with-state), while minimizing intermediate object allocations. 
Reducers was used previously, but mapcat still required intermediate 
allocations. Transducers avoid that, but take on a more effectful feel.

Code 
here: 
https://github.com/brandonbloom/fipp/blob/648d928d94f0b247af9a0c4f95e7ec7024b5b001/src/fipp/engine.cljc

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

2015-05-03 Thread Brandon Bloom
Short version: Old version of the lib was on the classpath.

Longer version: `lein with-profiles -user whatevertask` to disable the user 
profile apparently doesn't work.

I was using:
export CLASSPATH=$(lein with-profiles -user classpath) java clojure.main

Figured I had ruled out my tools, since I was explicitly using the builtin 
tools, but... When I hand crafted the class path, it all worked. Mumbled 
dammit lein to myself, and then tracked it down to a rogue shadow version 
of my namespace in one of the jars on the path. *grumble grumble*.

It's also worth mentioning that this problem wasn't being caught because 
the newer version was earlier on the class path. Once you split a file up 
in to foo.clj and foo.cljc files, you run in to a risk of finding the two 
halves of foo.clj* out of two different jars!

Thanks for the push to dig deeper, Alex!

Cheers,
Brandon

On Saturday, May 2, 2015 at 8:13:57 PM UTC-7, Alex Miller wrote:

 There should be no ill effect from simply renaming from clj to cljc. What 
 error are you seeing? 

 Please also consider whether something in your tool chain is at fault. For 
 example, if the cljc files are not getting properly packaged or included in 
 the classpath then there may need to be changed in the tools. While I've 
 tried several things successfully, there could easily be more to do.

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

2015-05-03 Thread Brandon Bloom
Fipp is a better pretty printer for Clojure (and now/soon ClojureScript!)

https://github.com/brandonbloom/fipp

Please give it a try and let me know how it goes.

Version 0.6.0 includes...
- Several nice performance improvements via Transducers
- A totally rewritten Edn printer with tagged literal support
- Experimental ClojureScript support

Known CLJS Issues
- No tagged literal support yet
- The cljs.jar repl does something funky to newlines when printing
- Lots of CLJS types with pr extensions are not yet specially handled
- A bunch more stuff, to be fixed soon!

Keep an eye out for related upgrades to the Pudget and Whidbey companion 
projects when I get some more free time.

Cheers,
Brandon


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


Re: [ANN] Clojure 1.7.0-beta2

2015-05-02 Thread Brandon Bloom
Upgrading a couple of projects to 1.7 seems to have gone quite smoothly. 
Thanks!

However, I've encountered some problems with new features, like .cljc files.
Please see https://groups.google.com/forum/#!topic/clojure/TrYkq1lUuZw 

Cheers,
Brandon

On Friday, April 24, 2015 at 11:27:34 AM UTC-7, Alex Miller wrote:

 Clojure 1.7.0-beta2 is now available.

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

 Regression fixes since 1.7.0-beta1:

 1) CLJ-1711 - structmap iterator broken
 2) CLJ-1709 - range wrong for step != 1
 3) CLJ-1713 - range chunks are not serializable
 4) CLJ-1698 - fix reader conditional bugs

 Additional enhancements to new features since 1.7.0-beta1:

 1) CLJ-1703 - Pretty print #error and new public function Throwable-map
 2) CLJ-1700 - Reader conditionals now allowed in the REPL
 3) CLJ-1699 - Allow data_readers.cljc as well as data_readers.clj
   
 For a full list of changes since 1.6.0, see:
 https://github.com/clojure/clojure/blob/master/changes.md

 Please give it a try and let us know if things are working (or not)!

 - Alex



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


Different behavior for .cljc file?

2015-05-02 Thread Brandon Bloom
Hi Clojure 1.7 folks,

I'm trying to port Fipp to ClojureScript with .cljc files and feature 
expressions. My first step was to rename files from .clj to .cljc, but 
doing that broke my code. I'm not exactly sure what's wrong, but before I 
dig any further

Is simply renaming .clj to .cljc files expected to preserve the code's 
behavior?

If yes, I've hit a bug that I don't yet understand. Let me know, so I can 
help track it down.

 

If no, I don't understand the .cljc file approach. Please help me 
understand!


This is the (rename-only) commit that breaks my tests:

https://github.com/brandonbloom/fipp/commit/019e8b527bd8146554f2fb98eb2c13c1d33229ec


Cheers,
Brandon

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

2015-01-04 Thread Brandon Bloom
Awesome!

Seems like there is an opportunity for a cljs command line tool and some 
packaging gurus out there to package it up for brew, apt, etc. Would be super 
nice to have a quick repl by running `cljs` or scripts with `#!/usr/bin/env 
cljs` up top.

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

2014-11-28 Thread Brandon Bloom
For reference, here's the 
ticket: http://dev.clojure.org/jira/browse/CLJ-1185

And the 
commit: 
https://github.com/clojure/clojure/commit/b45b067f56c78b8128f57913e662d9638ee480c5

On Friday, November 28, 2014 11:19:41 AM UTC-5, Nicola Mometto wrote:


 This has already been fixed, and reductions will support reduced in 
 1.7.0. 
 In the meantime you can use 1.7.0-alpha4. 

 Nicola 

 myguidingstar writes: 

  
  
  (reduce (fn [acc x] 
(if ( acc 10) 
  (reduced acc) 
  (+ acc x))) 
  0 
  (range 100)) 
  ;; = 15 
  (reductions (fn [acc x] 
(if ( acc 10) 
  (reduced acc) 
  (+ acc x))) 
  0 
  (range 100)) 
  ;; thows ClassCastException clojure.lang.Reduced cannot be cast to 
 java.lang.Number  clojure.lang.Numbers.gt (Numbers.java:227) 
  Is it a bug or intended behavior? 

 -- 


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

2014-10-20 Thread Brandon Bloom


 Well, the question is, where does this additional complexity come from. 
 In Java, it results in enormous quantities of boilerplate get/set 
 methods. In Scala, these are autocoded away. 


Boilerplate isn't complexity: It's inefficiency.

I'll grant that it creates complexity-potential-energy via many increased 
space for complexity to hide. However, it's far more complex to eliminate 
boilerplate via dynamic mechanisms, such as interface dispatch or, heaven 
forbid, Ruby-style abuses such as method_missing. Simpler is to eliminate 
boilerplate by developing terser encodings in terms of values, and bringing 
computation to bear to interpret (or translate) those values.

But I'll argue that avoiding the UAP isn't about complexity. It's about an 
intentional modeling of non-uniform access. Clojure data is built, 
constructively, out of lists, maps, sets, vectors, symbols, keywords, 
numbers, strings, etc. Any inductive data types, by the very nature of 
computation, are implemented in terms of co-inductive operations on codata 
types. You can't observe something in your computer without executing code 
to interpret some representation which models some abstraction. Any 
representation is built concretely out of the abstractions below it. By 
committing to :keyword style access, you're making a proclamation that 
you're operating on a concrete representation. If that concrete 
representation happens to be implemented abstractly (as it must be), you 
can override it (again with ILookup, etc). However, if you're going to 
override it, you damn well better provide value-like semantics.

UAP grants you flexibility in changing an abstraction. However, it grants 
*too much* flexibility. It lets you change from a convincing emulation of a 
true mathematical value to a full-blown computation object. Making 
operations on data source-incompatible with operations on codata is a 
feature, not a bug.

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


Re: Modelling in Clojure

2014-10-18 Thread Brandon Bloom


 I don't know who is the outlier. The point is that Scala, for instance, 
 has explicit support to hide the distinction between accessing a value 
 and computing a value. The point is to support the uniform access 
 principle. 

 http://en.wikipedia.org/wiki/Uniform_access_principle 


In one sense, accessing data and calling functions uniform: keyword lookups 
are just function calls themselves. In another sense, lookup by keyword 
requires implementing ILookup etc rather than changing a simple function.

If you take the stance that the data is your API (and you should), then it 
makes sense that switching from a keyword lookup to a function call is a 
breaking change! It shouldn't be easy to rip the data-rug out from under 
your callers. At least it *is* possible, depending on how far you're 
willing to go down the Clojure interfaces rabbit hole. Of course, this 
equation changes even more in favor of Clojure's keywords approach if your 
client lives across the network.

That said, if you're not sure if you want to make the data your API, you 
can reserve the right to change your mind later quite easily. Let's say you 
have (ns user) and want to create a username function:

(def username :username) ; tada!

Yes, this requires some foresight. Back in my C# days, the guidance was 
always make everything a property. That was especially important if you 
cared about binary compatibility, since changing from a readonly field to a 
getter was a breaking ABI change. But you know what, over quite a few major 
and minor releases of our widely used APIs, I don't recall ever once 
changing from a trivial `return foo` getter to more complex getter logic. 
The expectation that a getter is a simple data read was always a core part 
of the public interface.

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

2014-09-28 Thread Brandon Bloom
Forgive me if this is unwelcome self-promotion, but I figured I'd take this 
opportunity to point out some similar projects:

My re-usable pretty-printing engine with a simple EDN printer:
https://github.com/brandonbloom/fipp

A colorizing EDN printer built on Fipp:
https://github.com/greglook/puget/

nREPL integration for Puget:
https://github.com/greglook/whidbey

On Thursday, September 4, 2014 5:50:10 PM UTC-4, Vladimir Bokov wrote:

 Hi folks, I got just tired to gazing into big amount of data and scroll 
 3-4 screens of my 13' laptop to grasp the structure,
 so I used pprint's pretty printer, but add colors and changed indentation 
 *by default*
 (actually pprint has tuning parameters, too, but anyway it's breaking maps 
 by single entry by line...)

 Now the screen area gets used more effectively and looks more friendly imo 
 :)
 See it: https://github.com/razum2um/aprint

 Looking forward yours opinion if I should make a nrepl middleware to use 
 it *right away*, without doing (ap)
 every time ;)


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


Re: Is Korma still a good current choice for DB backend?

2014-07-24 Thread Brandon Bloom

 I think you mean (not date-range) and (not qualifier)? Otherwise you'll
 have (true OR ...) if the params are present... But that's a very neat
 trick!


Ah, yes, that's of course what I meant. Was wasting mental cycles on
parameter ordering... Use named parameters people!


 I ran it past our DBA and he verified that the execution plan definitely
 short-circuits the booleans with true / false (which was my initial concern
 after being somewhat gunshy of 'OR' in queries due to performance problems
 that has caused in complex queries).


You should also verify the `date  LEAST(NULL, MAX(date))` approach too. I
suspect that the query planner will summarily eliminate the aggregate.

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


Re: Is Korma still a good current choice for DB backend?

2014-07-23 Thread Brandon Bloom
You could just add tests for extra params in OR clauses.

For example, instead of:

(str SELECT ... main query stuff WHERE basic conditions
 (when date-range (str  AND dateUpdated = ? AND dateUpdated  ?))
 (when qualifier  AND someColumn = ?))


You do this:

SELECT ... main query stuff WHERE basic conditions
AND (? OR dateUpdated = ? AND dateUpdated  ?
AND (? OR someColumn = ?)

Then instead of delegating to a bunch of different parameters, you just 
supply all the parameters all the time, using dummies where appropriate.

(if date-range
 (if qualifier
 (query-with-date-range-and-qualifier db basic params (first date-range) 
 (second date-range) qualifier)
 (query-with-date-range db basic params (first date-range) (second 
 date-range)))
 (if qualifier
 (query-with-qualifier db basic params qualifier)
 (query-basic db basic params)))


Example:

(query db basic params (boolean date-range) (or date-range (now)) (or 
date-range (now)) (boolean qualifier) (or qualifier ))

You can actually do better than this too, but it will be database specific. 
For the date range example, Postgres has functions that can handle null and 
will optimize your query quite intelligently:

SELECT ... FROM orders WHERE date  GREATEST(MIN(date), ?) AND date  
LEAST(MAX(date), ?)

That's even better because the query can now specify min and max dates 
separately without a combinatoric explosion of queries.

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


Re: unexpected behavior of clojure.core/empty

2014-07-19 Thread Brandon Bloom
I've been bitten by all three of these things in the past:

1) A MapEntry looks like a vector, but isn't.
2) Two element vectors can't be used as map entries.
3) Applying empty to a MapEntry returns nil.

On Saturday, July 19, 2014 4:04:13 PM UTC-4, Jozef Wagner wrote:

 While the c.l.MapEntry is a persistent vector, there is no such thing as 
 an empty MapEntry persistent vector. Returning empty HAMT persistent vector 
 instead is not a good solution, as 2 elements HAMT vector does not 
 implement IMapEntry interface.

 One approach on how to solve this is in Zach's clj-tuple [1] where every 
 2-tuple automatically implements IMapEntry interface.

 [1] https://github.com/ztellman/clj-tuple

 Jozef

 On Saturday, July 19, 2014 9:49:21 PM UTC+2, puzzler wrote:

 As Mike points out, it does seem that MapEntry is considered a collection 
 and is designed to emulate a vector so that you don't really have to worry 
 about whether you have a MapEntry or a two-element vector (and as he points 
 out, in ClojureScript there really is no distinction between a MapEntry and 
 a vector).

 With that in mind, I would agree that MapEntry's lack of implementation 
 for empty is most likely an oversight, and ideally should behave as if it 
 were a vector.




 On Sat, Jul 19, 2014 at 11:46 AM, Mike Fikes mike...@me.com wrote:

 MapEntry is a collection:

 (coll? (clojure.lang.MapEntry. a 1))

 ;= true


 (ancestors (class (clojure.lang.MapEntry. a 1)))

 ;= (a set that includes clojure.lang.IPersistentCollection)


 The docstring for empty implies it would return an empty MapEntry. But 
 perhaps since MapEntry is a special collection type that must have a size 
 exactly equal to 2, empty must return nil.


 Perhaps ClojureScript will one day introduce a MapEntry type and behave 
 the same way as Clojure (ClojureScript currently returns a 
 PersistentVector).
  
 -- 
 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: unexpected behavior of clojure.core/empty

2014-07-19 Thread Brandon Bloom
I understand that, but the issue that bothers me is that MapEntry prints 
like a vector and satisfies the clojure.core/vector? predicate. If you call 
first or seq or something like that on a map, your REPL will lie to you. 
Worse, you might even be 100% aware that you have a MapEntry instead of a 
vector only to have a distant part of your program blow up on you at a much 
later date for some seemingly innocuous change. You've then got to trace 
your program backwards and wrap some expression in (vec ...).

On Saturday, July 19, 2014 9:35:55 PM UTC-4, Alex Baranosky wrote:

 You cannot have an empty MapEntry though, because map entries always have 
 just one size, a key and a value. I can definitely see how it can be 
 confusing though.


 On Sat, Jul 19, 2014 at 4:42 PM, Brandon Bloom brandon...@gmail.com 
 javascript: wrote:

 I've been bitten by all three of these things in the past:

 1) A MapEntry looks like a vector, but isn't.
 2) Two element vectors can't be used as map entries.
 3) Applying empty to a MapEntry returns nil.

 On Saturday, July 19, 2014 4:04:13 PM UTC-4, Jozef Wagner wrote:

 While the c.l.MapEntry is a persistent vector, there is no such thing as 
 an empty MapEntry persistent vector. Returning empty HAMT persistent vector 
 instead is not a good solution, as 2 elements HAMT vector does not 
 implement IMapEntry interface.

 One approach on how to solve this is in Zach's clj-tuple [1] where every 
 2-tuple automatically implements IMapEntry interface.

 [1] https://github.com/ztellman/clj-tuple

 Jozef

 On Saturday, July 19, 2014 9:49:21 PM UTC+2, puzzler wrote:

 As Mike points out, it does seem that MapEntry is considered a 
 collection and is designed to emulate a vector so that you don't really 
 have to worry about whether you have a MapEntry or a two-element vector 
 (and as he points out, in ClojureScript there really is no distinction 
 between a MapEntry and a vector).

 With that in mind, I would agree that MapEntry's lack of implementation 
 for empty is most likely an oversight, and ideally should behave as if it 
 were a vector.




 On Sat, Jul 19, 2014 at 11:46 AM, Mike Fikes mike...@me.com wrote:

 MapEntry is a collection:

 (coll? (clojure.lang.MapEntry. a 1))

 ;= true


 (ancestors (class (clojure.lang.MapEntry. a 1)))

 ;= (a set that includes clojure.lang.IPersistentCollection)


 The docstring for empty implies it would return an empty MapEntry. But 
 perhaps since MapEntry is a special collection type that must have a size 
 exactly equal to 2, empty must return nil.


 Perhaps ClojureScript will one day introduce a MapEntry type and 
 behave the same way as Clojure (ClojureScript currently returns a 
 PersistentVector).
  
 -- 
 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 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




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


Re: unexpected behavior of clojure.core/empty

2014-07-19 Thread Brandon Bloom
It's worth mentioning that ClojureScript does not have a MapEntry type.

Vectors implement IMapEntry using nth:

https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L3601-L3605

And empty returns an empty vector:

ClojureScript:cljs.user (empty (first {:a 1}))
[]


On Saturday, July 19, 2014 10:44:12 PM UTC-4, Mike Fikes wrote:

 I did a little “code archaeology” in an attempt to elucidate what Rich may 
 had been thinking:

 In mid 2007, some of the persistent collection implementations had an 
 EMPTY value defined. [1, 2]. (But, of course, no such EMPTY value was 
 defined for MapEntrys.)

 Around a year later, MapEntrys were revised to participate in the vector 
 abstraction [3].

 A couple of months *after* this, “empty” was added to the collection 
 abstraction [4], and usually implemented in terms of the EMPTY value, and 
 MapEntry was made to return null.

 My analysis is inconclusive: Making MapEntry return null is logical, given 
 that there is no EMPTY value to return. But, the MapEntry / vector business 
 happening prior to this blurs the argument.

 Perhaps the real problem is that not all collections can be emptied, and 
 thus thus empty shouldn't have been added to the collection abstraction. 
 (ClojureScript separates out the idea, introducing IEmptyableCollection.)

 [1] 
 https://github.com/clojure/clojure/commit/12457e7bf29747232bbfda2a0de3b72fbb14f3a9
 [2] 
 https://github.com/clojure/clojure/commit/4232de83a53e12741252d31aef9cecee5b8981da
 [3] 
 https://github.com/clojure/clojure/commit/978af02b0a7e2b430c917b32b58215edcae2ad2d
 [4] 
 https://github.com/clojure/clojure/commit/697b69fe9c8f5e2e8d40382e70d4ddd490c4a9ee


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

2014-06-16 Thread Brandon Bloom
Since my ears are ringing, I'll chime in.

There's a few things to separate out here:

1) Symbolic math
2) Term rewriting
3) Staged computation

Mathematica can provide all three to varying degrees. Espresso targets 
symbolic mathematics. Kovas' work is about term rewriting as a 
computational paradigm. Clojure offers limited, but practically proven 
facilities for staged computation in the form of eval, macros, etc.

My guess is that you can accomplish whatever specific DSL task you're after 
with traditional functional approaches and get acceptable performance. 
Seeing as you're new to Clojure, I suggest you try to go down that road 
first. When you have a particular use case to discuss and some experience 
solving the problem with traditional techniques, we can discuss 
opportunities for more sophisticated approaches.

However, if you're really after #3, you're probably out of luck in the 
short term. Longer term, I indent to experiment with this stuff in the 
context of https://github.com/brandonbloom/eclj

Cheers,
Brandon

On Monday, June 16, 2014 1:25:40 PM UTC-4, kovasb wrote:

 So I've thought about this quite a bit (as have some other people, 
 like Brandon Bloom), and started working on a library a while back 
 exploring some ideas https://github.com/kovasb/term 

 The main idea of term is to take any expression and turn unbound 
 symbols into datatypes that satisfy mathematica-like properties. 

 for instance 

 (head (term (a 1 2 3))) - a 
 (let [x (term a)] (head (x 1 2 3))) - a 
 (term (map a [1 2 3])) - ((a 1) (a 2) (a 3)) 


 This works pretty well, but to be truly useful you also need a 
 standard library of transformation rules that will for instance 
 implement + with combinations of symbols and concrete values, and of 
 course an evaluator. 

 Based on my experiments it is quite possible to create a term 
 rewriting evaluator that matches Mathematica's speed (see 
 https://github.com/kovasb/combinator) 

 The main question is how such a system deals with clojure 
 interoperability. Ultimately the transformation rules must bottom out 
 in clojure, and their results will eventually be consumed by clojure, 
 so getting that right will largely determine the usability of the 
 system. 











 On Mon, Jun 16, 2014 at 7:57 AM, Dilvan dil...@gmail.com javascript: 
 wrote: 
 Hi, 
  
 Thanks for both answers. I will try to find the relevant text in Joy 
 of 
  Clojure (I have access to the first edition). 
 I followed the expresso link, but I am not interested in mathematical 
  expressions. 
 Refining my question: I am more interested in the programming aspects 
 of 
  Mathematica (or to its descendant Wolfram Language). In the eval case, a 
  better example would be (a is unbound): 
  
   (def b 1) 
   (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b 
   -- '(+ 37 a) 
  
 Eval-partial would return a Lisp expression with unbound symbols. 
 The expression being evaluated could be quite complex. 
 With eval-partial, I would like to be able to have complex functions 
 that 
  depend on results that aren't ready yet. They would evaluate (partially) 
 to 
  expressions that could be re-evaluated later, to see if all the symbols 
 they 
  depend upon are ready (bound). I intend to use this technique to write 
 more 
  flexible DSLs. 
  
 BTW, if expresso can do some similar to this, I am willing to give it 
 a 
  second look. 
  
 Any ideas? 
  
 Cheers, 
  
  Dilvan. 
  
  
  On Friday, June 13, 2014 6:46:56 PM UTC-3, Dilvan wrote: 
  
 Hi all, 
  
 I'm a novice to Clojure (but not to programming). 
 I'm looking for an implementation of an eval function to eval 
  expression like Mathematica does. 
 For instance, in Mathematica the expression: 
  
 8 + a + 9 (2 + b) + 2 
  
 if a and b are not bound, translates to 
  
  Plus[10, a, Times[9, Plus[2, b]]] 
  
 if a and b become bounded later (let say to 1 and 2) and the 
 expression 
  is evaluated again, it returns 47. 
  
 I would like to be able to run: 
   (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b 
 and get, if a and b are unbound: 
   (fn [x y] (+ 10 x (* 9 (+ 2 y 
 or (better still) 
   ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y] 
 Notice that, whenever possible, the eval takes place and parts of 
 the 
  expression are evaluated (in the example above, the expression (+ 8 2) 
 is 
  evaluated to 10). 
  
 If you know of any implementation or have any ideas on the subject, 
  please let me know. 
  
 Cheers, 
  Dilvan. 
  
  
  -- 
  You received this message because you are subscribed to the Google 
  Groups Clojure group. 
  To post to this group, send email to clo...@googlegroups.com 
 javascript: 
  Note that posts from new members are moderated - please be patient with 
 your 
  first post. 
  To unsubscribe from this group, send email to 
  clojure+u...@googlegroups.com javascript: 
  For more options, visit

Re: recursive hierarchies and derive

2014-05-13 Thread Brandon Bloom
Leif is right, but isa?'s docstring doesn't mention this behavior. Here's 
the relevant 
code: 
https://github.com/clojure/clojure/blob/028af0e0b271aa558ea44780e5d951f4932c7842/src/clj/clojure/core.clj#L5120

On Tuesday, May 13, 2014 12:22:28 AM UTC-4, Leif wrote:

 Hi, Ranko.

 I *think* it's because vectors are handled specially during dispatch, to 
 easily handle both dispatching on multiple args and hierarchies:

 isa?http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa?works
  with vectors by calling 
 isa?http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa?on
  their corresponding elements:

 (isa? [::square ::rect] [::shape ::shape])

 --Leif

 On Monday, May 12, 2014 8:41:35 PM UTC-4, r wrote:

 Why is something like 

 (derive [::matrix ::ring-element] ::ring-element)

 prevented by the assertion in clojure.core/derive?
 Is there something that is an actual show-stopper 
 or is this an implementation detail?

 Cheers,
 ranko




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

2014-02-11 Thread Brandon Bloom


 The other question: is it possible to have two mutually refering deftype 
 definitions. 


Although recursive types makes sense on the JVM, it doesn't necessarily 
make sense on hosts without an explicit type system in which to resolve the 
mutual recursion; consider ClojureScript. You don't need recursive type 
definitions in order to have mutually recursive instances. You can simply 
indirect through mutation.

For you particular case...

 The closest I have got it: 
 (declare create-alice) 
 (declare create-brian) 

Yup, that's A-OK. You can also just write (declare create-alice 
create-brian).

The tricky bit comes in when you actually need to refer to the types by 
name directly. Say, if you wanted to create mutually recursive deftypes 
with type hints (maybe for host interop reasons). In that case, you can 
indirect through interfaces/protocols:

(defprotocol IFoo ...)
(defprotocol IBar ...)

(deftype Foo [^IBar bar] ...)
(deftype Bar [^IFoo foo] ...)

If you genuinely need mutually recursive types and can't indirect through 
protocols (or interfaces), then you probably have a particular JVM interop 
use case and should just write Java for that purpose.

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


Re: concat/forth in -, -

2014-01-19 Thread Brandon Bloom
It's worth noting that the - and - macros are just that: macros. They 
have lexical extent and are expanded at compile time.

Factjor is (essentially) interpreted, but can be used in interesting higher 
order ways. For example, you can write functions that return lazy sequences 
of Factjor instructions. The idea of sequences-as-concatenative-programs, 
called quotations, is best explored by downloading Factor and tinkering 
with the (excellent!) environment  live/interactive 
docs: http://factorcode.org/

When I presented Factjor at Clojure/West a while back, quite a few people 
mentioned to me that they were reminded of the threading macros. I never 
attempted to do this, but in theory it wouldn't be too hard to create a 
macro that does (naive) partial evaluation of concatenative code at 
expansion time!

If you attempt it, I'd love to see what you come up with :-)

On Saturday, January 18, 2014 7:01:52 PM UTC-5, Nicola Mometto wrote:

 I don't know if that's what you're asking for, but there's 
 https://github.com/brandonbloom/factjor 

 t x writes: 

  Hi, 
  
Despite the title and content of this email, this is a serious, non 
  joking (i.e. brainfuck) question. 
  
  After studying 
  https://github.com/rplevy/swiss-arrows/blob/master/src/swiss/arrows.cljfor 
  a bit, it hit me: 
  
  - and - are special cases of forth machines, where there is a stack, 
  which always has exactly one item. 
  
  Thus, when we have something like 
  (- init 
instr1 
instr2 
... instr k ... ) 
  
  what happens is that init is pushed onto the stack, then for each $i$, 
 we 
  pop the top item off the stack, pass it to (instr i), then push the 
 value 
  back on the stack. 
  
  
  Now, if take a few steps back and squint, we ask: why is it that we only 
  have one item on the stack? why not multiple items on the stack -- and 
 now, 
  suddenly, we are approaching forth. 
  
  Thus, in a completely serious question -- is there any clojure 
  threading-macro DSL basically provides a forth-like? 
  
  -- 


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


Re: obtain # of elements currently on a channel?

2014-01-11 Thread Brandon Bloom
Any API that lets you peek at the state of a channel is a surefire source 
of race conditions. So no, public API-wise, there isn't any way to do what 
you want. In theory, you can peek at the internals using reflection to get 
that information, but don't do that!

Instead, you can simply *count* yourself. Stick an extra go-loop on either 
end that swaps an atom with inc or dec.

On Saturday, January 11, 2014 12:19:51 PM UTC-5, t x wrote:

 Hi,

   I have a clojure.core.async.chan

   Is there a way to figure out the # of elements currently queued on the 
 channel? (preferably in O(1) time)

   I don't want to actually take any item off the channel, I just want a 
 progress bar, something like there are 20 transactions ahead of you in 
 life to be processed

 Thanks!


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


Re: [ANN] data.avl 0.0.10 -- fast sorted maps and sets with log-time rank queries

2014-01-05 Thread Brandon Bloom
Michał: This is awesome. Thanks for the continued awesome work on data 
structures!
 

   ;; if the key is not present in the collection, -1 is returned: 
   (avl/rank-of (avl/sorted-set 3 4 5) 0) 
   ;= -1 


Curious: Why not return nil instead of -1?

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


Re: (core.async/go nil) behavior?

2013-12-14 Thread Brandon Bloom
Sounds like a bug to me. A nil value in return position of a go block 
should probably close the channel.

On Saturday, December 14, 2013 2:18:07 PM UTC-5, Stephen Cagle wrote:

 core.async discourages you from placing nil in a channel, as nil is only 
 taken when the channel has been closed. However, if I create a go block 
 with a body that evaluates to nil, core.async will return a channel that 
 contains nil. This is a nil as a take! value, not a nil to indicate the 
 channels closed state. Is there any ruling/best practices/thoughts about 
 whether this is correct behavior? Is it a anti-pattern to actually take 
 from a go block itself? Perhaps I should only be taking from channels that 
 I pass into the go block in order to avoid the above issue?


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


Re: Type of let form

2013-10-04 Thread Brandon Bloom
I agree, it's clear that this is intentional. The promised public API is 
the let form; let* is an implementation detail. Clojure and 
ClojureScript already have subtly different internal special symbols. For 
example: try vs try*.

Unfortunately, this implementation detail leaks out in the macro  
namespace systems because the special forms have unique symbol resolution 
rules. Luckily, clojure.core/special-symbol? can differentiate symbols with 
those resolution rules.

On Friday, October 4, 2013 4:20:58 PM UTC-4, John Hume wrote:

 This seems intentional, not a case of docs lagging behind. If you look at 
 the source of let you can see that it has :special-form true in its 
 metadata so that it will remain documented as special even though it's just 
 a macro.

 I assume the thinking is that it's more useful to continue to document 
 let, loop, and maybe others as special forms than to tell you they're 
 macros that expand into uglier calls to special forms, and then go on to 
 document (and support the APIs of) clojure.core/destructure and the less 
 sugary, true special forms (let*, loop*, and maybe others). 

 It's probably safe to assume these are implementation details that won't 
 necessarily hold in other dialects of Clojure and that breaking changes in 
 that layer might be introduced in a future version of Clojure and would not 
 be considered a backwards-incompatible change by the maintainers.



 On Fri, Oct 4, 2013 at 2:47 PM, Amrut amrut...@gmail.com javascript:wrote:

 Thanks. I went through the checkins and looks like it was changed 
 here.https://github.com/clojure/clojure/commit/3129be6d80d315e3be2f77dadcf7e904fc6015f5
  This 
 was 6 years back. Maybe it's time to update the documentation for special 
 forms.


 On Friday, October 4, 2013 11:41:22 AM UTC-7, Gary Trakhman wrote:

 The definitive authority on what is a special form and what isn't is 
 Compiler.java:

 https://github.com/clojure/**clojure/blob/master/src/jvm/**
 clojure/lang/Compiler.java#L39https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L39


 On Fri, Oct 4, 2013 at 2:27 PM, Amrut amrut...@gmail.com wrote:

 Hello,

 According to this http://clojure.org/special_forms, let is a 
 special form. but the 
 sourcehttp://clojuredocs.org/clojure_core/clojure.core/let tells 
 me that it's a macro that uses let*. I could not find any info on let* 
 form.
 Can someone please explain what is happening here?

 TIA

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

 For more options, visit 
 https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out
 .


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




 -- 
 http://elhumidor.blogspot.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/groups/opt_out.


Re: Reading namespaced keywords

2013-09-17 Thread Brandon Bloom
 The double-colon is only shorthand for the current namespace:

Or other namespaces via an alias:

(alias 'clj 'clojure.core)
::clj/foo = :clojure.core/foo

Inside ns forms, the :as keyword creates aliases.

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


Re: ANN: ClojureScript 0.0-1877 (Breaking change)

2013-09-09 Thread Brandon Bloom
 a (very) temporary workaround is to use the old code 

Why not just switch (k coll) to (get coll k) ?

If you know that coll is non-nil, you can also just use (coll k). Both 
forms also accept an optional not-found value.

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


Re: [ANN] Type Coverage - core.typed 0.2.3, lein-typed 0.3.0

2013-09-04 Thread Brandon Bloom
 lein-typed https://github.com/frenchy64/lein-typed 0.3.0 is also 
released, and supports a new 
coveragehttps://github.com/frenchy64/lein-typed#type-coverage
 command.

Awesome!
 
 This is all part of Brandon Bloom's ideal vision of how types should be 
used in Clojure. Thanks for the great idea!

Heh, you're welcome! Thanks for doing this  the shout out.

Just wanted to elaborate a little bit on the views I shared with Ambrose 
and why I pushed him to do this lein plugin, and then to add the coverage 
command. In short, I view types as just one more tool in the verification 
and correctness toolbox. They have lots of other uses, such as for aiding 
optimization in compilers, but they can (and should!) be part of a varied 
suite of tests for robust applications.

However, just as approaching 100% unit test coverage has diminishing 
returns, so does approaching 100% type coverage. Type annotations can fit 
in right next to your unit and integration tests, outside of your src 
directory. Alternatively, you can include your type annotations inline, 
just like :pre and :post conditions, or validators. For modules that fit at 
the intersection of easily and precisely typed, core.typed can save you a 
lot of manual verification work!

As for the lein plugin, I think that low barriers to use will encourage 
more people to try core.typed as a verification tool. My dream is to be 
able to run a single command that infers all the types in my program, with 
separate annotations on the public interface from the private ones. Then I 
can then validate and check-in the public annotations and discard the 
private annotations. Whenever I change the public interface or experience 
cascading type inference failures in private code, I'd get a test error 
with lein. In this world, I can get 80% of the benefits of types with only 
20% of the cost.

Cheers,
Brandon

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


Re: ClojureScript: Keyword Breaking Change Around the Corner

2013-08-28 Thread Brandon Bloom
 Will identical? correctly handle keywords under advanced compilation, 
with keywords constants emited?

The missing part of your question is: What about dynamically constructed 
keywords?

When the constant table provided by this patch is enabled, all keywords 
statically present in source code will test identical? to other keywords 
that come from elsewhere in the source. At compile time, all keywords will 
be replaced with namespace.dotted.field.lookups.

The real question is what happens when you construct keywords using the 
cljs.core/keyword function?

Well there are two subcategories:

1) Keywords that already exist in the constant table

2) Never before seen keywords

For #1, we *can* look them up in the constant table and return those 
instances, which will produce keywords that test identical? against 
source-level or other dynamically-created, but elsewhere-in-source 
keywords. I'm not sure if this branch does that (or if it should).

For #2, we can't intern the keywords like Clojure does on the JVM because 
JavaScript does not provide weak references. If we interned dynamically 
created keywords, then we'd have an exploitable memory leak.

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


Re: core.async - handling nils

2013-08-27 Thread Brandon Bloom
 In every use of channels I've had thus far, nil is better expressed as an
empty collection, false, 0, :tick, or some other ground value.

I agree completely. But I'll note that you mention false being useful...

If you're writing completely general operators, like map, which are
*sometimes* quite useful, then you have no choice but to do something like
if-recv or explicitly test against nil.

 It's these Rx style programming methods that make people think they need
this feature.

I built my little Rx with channels library (asyncx) without intention to
use it directly, but because I wanted to learn how to work with channels. I
rapidly learned that the techniques are a lot more different than they
look. In particular, it's more difficult to write channel  process
combinators precisely because they are more powerful. However, in practice,
each new reusable channel/process combinator yields more complexity than it
tends to save. I'd rather intentionally choose strictly less powerful
primitives where appropriate and enforce that with encapsulation.

With that in mind, if I ever revisit asyncx, I'll probably define push
sequences or streams in terms of protocols and deftypes. I'd use
core.async to implement them, but only for the lowest level primitives. I'd
provide ways to get in to or out of the stream subsystem for interop with
channels, but the public interface would take IStream objects.


On Tue, Aug 27, 2013 at 10:58 AM, Timothy Baldridge tbaldri...@gmail.comwrote:

 All your arguments come down to this:

 I have an arbitrary seq of things I want to send down a channel. It's
 exactly that concept I that I push against. Everything you've mentioned
 thus far is a data structure. Channels are not data structures they are
 concurrency management primitives, treat them as such and I doubt you'll
 ever have a need for nils in a channel.

 If we treat channels as ways of co-ordinating concurrent processes, then
 nil doesn't have a use case. In every use of channels I've had thus far,
 nil is better expressed as an empty collection, false, 0, :tick, or some
 other ground value.

 It's these Rx style programming methods that make people think they need
 this feature.

 Timothy




 On Tue, Aug 27, 2013 at 8:51 AM, Mike Anderson 
 mike.r.anderson...@gmail.com wrote:

 On 27 August 2013 20:45, Timothy Baldridge tbaldri...@gmail.com wrote:

 The reason for not allowing nils isn't a complex one, and basically
 boils down to the following:

 a) to avoid race conditions, we need a single value to signal the
 channel is closed. As mentioned, nil is the obvious choice for this as it
 matches lazy seqs and fits well with the rest of clojure:


 Agreed that you want a single sentinel value.

 It doesn't match lazy-seqs at all though: lazy seqs can contain nils just
 fine. There's a big difference between (next some-lazy-seq) [which could be
 nil, indicating an empty sequence] and the actual values in the seq [which
 could also be nil but don't indicate the end of the seq].


 (when-let [v (! c)]
   (process v))

 If we chose a different value, this becomes much more ugly:

 (let [v (! c)]
   (when-not (= v :async/closed)
 (process v)))


 This can be solved easily by providing a macro or some other predicate
 that knows how to check for the sentinel value correctly. e.g.

 (when-more [v (! c)]
   (process v))


 b) I question if there are any valid uses for putting nil in a channel.
 With all due respect to all who have written here, thus far, every
 complaint about nils and channels boils down to a conversion from seqs to
 channels. This is the wrong way to look at the problem. Channels are
 co-ordination primitives not data structures. Simply because a lazy seq
 looks like a channel, doesn't mean that they should be treated as such.


 In all the core.async code I've written I've never had to put a nil in a
 channel, so I'm left with the uncomfortable conclusion that most complaints
 on this subject are contrived. I could be wrong, but I just haven't seen a
 valid use case yet.


 To me it's all about consistency with other Clojure constructs. You can
 safely put nils in sequences, vectors, lists, sets etc.. nil is a valid
 value just like anything else. So why can't you put them in a channel?

 Two use cases I have encountered that motivate this:

 a) what if you want to send a sequence through a channel? Since nil as a
 value represents the empty sequence, you have to put in some extra special
 case handling with the current core.async model.

 b) what if you want to write generic code to send all the values in an
 arbitrary collection through a channel? you would have to wrap/unwrap nils
 at either end to make this work currently.

 Both of these, I think, are reasonable and common enough use cases that
 it's worth supporting them elegantly rather than forcing users to implement
 their own nil-wrapping functionality.


 This all being said, there really isn't a technical reason to not allow
 nils, it just 

Re: core.async - handling nils

2013-08-27 Thread Brandon Bloom
As long as we don't go full Haskell mode:

data Message a = Value a | Done


On Tue, Aug 27, 2013 at 11:20 AM, Timothy Baldridge tbaldri...@gmail.comwrote:

 Right, the use of false is a special case. I'm thinking of a mouse event
 stream, may have a button channel that sends true or false based on the
 state of the mouse button. Even saying that though, I would probably opt
 for :clicked and :unclicked or somethig of that nature.

 Timothy


 On Tue, Aug 27, 2013 at 9:15 AM, Brandon Bloom 
 brandon.d.bl...@gmail.comwrote:

  In every use of channels I've had thus far, nil is better expressed as
 an empty collection, false, 0, :tick, or some other ground value.

 I agree completely. But I'll note that you mention false being useful...

 If you're writing completely general operators, like map, which are
 *sometimes* quite useful, then you have no choice but to do something like
 if-recv or explicitly test against nil.

  It's these Rx style programming methods that make people think they
 need this feature.

 I built my little Rx with channels library (asyncx) without intention to
 use it directly, but because I wanted to learn how to work with channels. I
 rapidly learned that the techniques are a lot more different than they
 look. In particular, it's more difficult to write channel  process
 combinators precisely because they are more powerful. However, in
 practice, each new reusable channel/process combinator yields more
 complexity than it tends to save. I'd rather intentionally choose strictly
 less powerful primitives where appropriate and enforce that with
 encapsulation.

 With that in mind, if I ever revisit asyncx, I'll probably define push
 sequences or streams in terms of protocols and deftypes. I'd use
 core.async to implement them, but only for the lowest level primitives. I'd
 provide ways to get in to or out of the stream subsystem for interop with
 channels, but the public interface would take IStream objects.


 On Tue, Aug 27, 2013 at 10:58 AM, Timothy Baldridge tbaldri...@gmail.com
  wrote:

 All your arguments come down to this:

 I have an arbitrary seq of things I want to send down a channel. It's
 exactly that concept I that I push against. Everything you've mentioned
 thus far is a data structure. Channels are not data structures they are
 concurrency management primitives, treat them as such and I doubt you'll
 ever have a need for nils in a channel.

 If we treat channels as ways of co-ordinating concurrent processes, then
 nil doesn't have a use case. In every use of channels I've had thus far,
 nil is better expressed as an empty collection, false, 0, :tick, or some
 other ground value.

 It's these Rx style programming methods that make people think they need
 this feature.

 Timothy




 On Tue, Aug 27, 2013 at 8:51 AM, Mike Anderson 
 mike.r.anderson...@gmail.com wrote:

 On 27 August 2013 20:45, Timothy Baldridge tbaldri...@gmail.comwrote:

 The reason for not allowing nils isn't a complex one, and basically
 boils down to the following:

 a) to avoid race conditions, we need a single value to signal the
 channel is closed. As mentioned, nil is the obvious choice for this as it
 matches lazy seqs and fits well with the rest of clojure:


 Agreed that you want a single sentinel value.

 It doesn't match lazy-seqs at all though: lazy seqs can contain nils
 just fine. There's a big difference between (next some-lazy-seq) [which
 could be nil, indicating an empty sequence] and the actual values in the
 seq [which could also be nil but don't indicate the end of the seq].


 (when-let [v (! c)]
   (process v))

 If we chose a different value, this becomes much more ugly:

 (let [v (! c)]
   (when-not (= v :async/closed)
 (process v)))


 This can be solved easily by providing a macro or some other predicate
 that knows how to check for the sentinel value correctly. e.g.

 (when-more [v (! c)]
   (process v))


 b) I question if there are any valid uses for putting nil in a
 channel. With all due respect to all who have written here, thus far, 
 every
 complaint about nils and channels boils down to a conversion from seqs to
 channels. This is the wrong way to look at the problem. Channels are
 co-ordination primitives not data structures. Simply because a lazy seq
 looks like a channel, doesn't mean that they should be treated as such.


 In all the core.async code I've written I've never had to put a nil in
 a channel, so I'm left with the uncomfortable conclusion that most
 complaints on this subject are contrived. I could be wrong, but I just
 haven't seen a valid use case yet.


 To me it's all about consistency with other Clojure constructs. You can
 safely put nils in sequences, vectors, lists, sets etc.. nil is a valid
 value just like anything else. So why can't you put them in a channel?

 Two use cases I have encountered that motivate this:

 a) what if you want to send a sequence through a channel? Since nil as
 a value represents the empty sequence, you have

Re: core.async - handling nils

2013-08-17 Thread Brandon Bloom
That's precisely the design followed by Magpie, described here:
http://journal.stuffwithstuff.com/2013/04/17/well-done/

Parts 1  2 of that series are worth reading too.


On Sat, Aug 17, 2013 at 8:48 PM, Mikera mike.r.anderson...@gmail.comwrote:

 My overall sense is that the convenience of using if-let directly in a few
 use cases doesn't justify making channels fall short of being able to send
 arbitrary values (nil specifically, and clearly boolean false can cause
 some problems too).

 I think it would be a much better design to have a sentinel value and a
 couple of specialised functions or macros that can detect  / interact with
 it appropriately. With a sentinel value the key part of your if-recv code
 could just be something like:

 `(let [~name (! ~port)]
   (if (end-of-stream? ~name)
 ~else
 ~then


 I can see that wrappers for nil values could also work, but that seems to
 be a more complex solution (and also potentially with more overhead) than a
 sentinel value


 On Saturday, 17 August 2013 07:50:06 UTC+8, Brandon Bloom wrote:

 I ran into the other half of this problem: If you expect nils to signify
 closed channels, then you can't leverage the logically false nature of nil
 without excluding explicit boolean false values. Given the pleasant syntax
 of if-let / ! pairs, I reworked my early experiments to use if-recv
 which is defined as follows:

 (defmacro if-recv
   Reads from port, binding to name. Evaluates the then block if the
   read was successful. Evaluates the else block if the port was closed.
   ([[name port :as binding] then]
`(if-recv ~binding ~then nil))
   ([[name port] then else]
`(let [~name (! ~port)]
   (if (nil? ~name)
 ~else
 ~then


 I've considered some alternative core.async designs, such as an
 additional done sentinel value, or a pair of quote/unquote operators (see
 reduced), but nothing seems as simple as just avoiding booleans and nils,
 as annoying as that is. I'd be curious to here what Rich  team
 considered and how they're thinking about it. However, my expectation is
 that the nil approach won't change, since it's pretty much good enough.

 On Thursday, August 15, 2013 10:44:48 PM UTC-4, Mikera wrote:

 Hi all,

 I'm experimenting with core.async. Most of it is exceptionally good, but
 bit I'm finding it *very* inconvenient that nil can't be sent over
 channels. In particular, you can't pipe arbitrary Clojure sequences through
 channels (since sequences can contain nils).

 I see this as a pretty big design flaw given the ubiquity of sequences
 in Clojure code - it appears to imply that you can't easily compose
 channels with generic sequence-handling code without some pretty ugly
 special-case handling.

 Am I missing something? Is this a real problem for others too?

 If it is a design flaw, can it be fixed before the API gets locked down?

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


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


Re: core.async - handling nils

2013-08-16 Thread Brandon Bloom
I ran into the other half of this problem: If you expect nils to signify 
closed channels, then you can't leverage the logically false nature of nil 
without excluding explicit boolean false values. Given the pleasant syntax 
of if-let / ! pairs, I reworked my early experiments to use if-recv which 
is defined as follows:

(defmacro if-recv
  Reads from port, binding to name. Evaluates the then block if the
  read was successful. Evaluates the else block if the port was closed.
  ([[name port :as binding] then]
   `(if-recv ~binding ~then nil))
  ([[name port] then else]
   `(let [~name (! ~port)]
  (if (nil? ~name)
~else
~then


I've considered some alternative core.async designs, such as an additional 
done sentinel value, or a pair of quote/unquote operators (see 
reduced), but nothing seems as simple as just avoiding booleans and nils, 
as annoying as that is. I'd be curious to here what Rich  team considered 
and how they're thinking about it. However, my expectation is that the nil 
approach won't change, since it's pretty much good enough.

On Thursday, August 15, 2013 10:44:48 PM UTC-4, Mikera wrote:

 Hi all,

 I'm experimenting with core.async. Most of it is exceptionally good, but 
 bit I'm finding it *very* inconvenient that nil can't be sent over 
 channels. In particular, you can't pipe arbitrary Clojure sequences through 
 channels (since sequences can contain nils). 

 I see this as a pretty big design flaw given the ubiquity of sequences in 
 Clojure code - it appears to imply that you can't easily compose channels 
 with generic sequence-handling code without some pretty ugly special-case 
 handling.

 Am I missing something? Is this a real problem for others too? 

 If it is a design flaw, can it be fixed before the API gets locked down?


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


Re: core.async - handling nils

2013-08-16 Thread Brandon Bloom
 have every other value come wrapped in a Just or Some-like constructor

That's what I meant by a pair of quote/unquote operators

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


Re: core.async channel GUID

2013-08-07 Thread Brandon Bloom
You can emulate this relatively easily with a pair of serialize/deserialize 
functions which read/write to a global atom containing a map.

On Wednesday, August 7, 2013 7:15:55 PM UTC-4, David Pollak wrote:

 Howdy,

 I'm working on bridging between core.async channels in the browser and on 
 the server. It would be very useful to have a GUID associated with the 
 channel so that when I serialize a message that contains a channel, I can 
 send the GUID instead and on the other side, create a proxy channel so that 
 the client or server and send a reply message to the channel and it will be 
 sent over the wire.

 Would it be possible to add a GUID to the channel?

 Thanks,

 David

 -- 
 Telegram, Simply Beautiful CMS https://telegr.am
 Lift, the simply functional web framework http://liftweb.net
 Follow me: http://twitter.com/dpp
 Blog: http://goodstuff.im

  

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




Re: subseq, garbage collection, and finalize

2013-07-29 Thread Brandon Bloom
Thanks Cedric  Patrick for the WeakReference and ReferenceQueue tips. Will
try that next time.

 There is an initial instance without metadata

Oh! That makes a lot of sense. Thanks much for figuring that out and
explaining it. We could probably optimize that second allocation away
relatively easily.

I'm much more confident in my assertion that subseq won't retain extra
memory. Also judging from the implementation, it seems like it would be
possible to implement submap and subset functions produce sorted maps
and sets with a range of keys without linear subseq traversal. Would be
cool to see that!

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




subseq, garbage collection, and finalize

2013-07-28 Thread Brandon Bloom
Hi all,

I'm trying to understand the object retention behavior when subseq is 
applied to sorted collections.

A quick glance at the source of 
APersistentTreeMap.javahttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentTreeMap.java
 suggests 
that the reified subseq only contains pointers to nodes to the left or 
right of the initial value node. Assuming I'm reading correctly, that means 
subseq should never retain unaccessible nodes in the original sorted map or 
set.

Here's an experiment that seems to back that up:
https://gist.github.com/brandonbloom/6101597

This produces a few questions:

   1. Is my experiment good? 
   2. What is the cause of the double finalizations? It seems like every 
   object has an initial speculative finalize fail on it... Why?
   3. Am I correct in saying that subseq will never retain extra objects 
   from the original tree?

Thanks,
Brandon

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




Re: direction of an arrow in core.async

2013-07-14 Thread Brandon Bloom
 When I read code like (- 1 2), I tranform it into (1 - 2) in my head

I used to do this when I was first learning a lisp, but now I read + as 
sum instead of plus and - as subtract instead of minus. 
Similarly, if you see ( x y), you can say x less than y, but what about 
(= x y z)? Instead, I read that as ascending. With =, it would be 
strictly ascending. Choosing prefix-friendly pronunciations for 
non-alphanumeric functions helps you get out of the operator mind set and 
into the applicative mindset.

In the absence of a mental infix transform, (! c) reads like redirecting 
from a file in your shell.

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




Re: [ANN]: Introducing lein-try

2013-07-13 Thread Brandon Bloom
This is awesome! I've totally wanted this.

Unfortunately, I can't get it to work...

~ $ lein try '[clj-time 0.5.1]'
nREPL server started on port 61689
REPL-y 0.1.10
Clojure 1.5.1
Exit: Control+D or (exit) or (quit)
Commands: (user/help)
Docs: (doc function-name-here)
  (find-doc part-of-name-here)
  Source: (source function-name-here)
  (user/sourcery function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org: [clojuredocs or cdoc]
  (user/clojuredocs name-here)
  (user/clojuredocs ns-here name-here)
user= (use 'clj-time.core)
FileNotFoundException Could not locate clj_time/core__init.class or 
clj_time/core.clj on classpath:   clojure.lang.RT.load (RT.java:443)

What gives?

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




Re: [ANN]: Introducing lein-try

2013-07-13 Thread Brandon Bloom
Odd. I just assumed that the arguments were being joined by spaces, then
clojure.core/read, rather than parsed as individual arguments.

Not all of us use Bash... square brackets are used for special patterns in
Zsh.

Without quotes, the arguments are being interpreted in this way:

lein try '[clj-time' '0.5.1]'

That seems to work, but it a bit awkward to use.


On Sat, Jul 13, 2013 at 12:44 PM, Steven Degutis sbdegu...@gmail.comwrote:

 It looks like you're not supposed to quote the arguments you pass it.


 On Sat, Jul 13, 2013 at 11:27 AM, Brandon Bloom brandon.d.bl...@gmail.com
  wrote:

 This is awesome! I've totally wanted this.

 Unfortunately, I can't get it to work...

 ~ $ lein try '[clj-time 0.5.1]'
 nREPL server started on port 61689
 REPL-y 0.1.10
 Clojure 1.5.1
 Exit: Control+D or (exit) or (quit)
 Commands: (user/help)
 Docs: (doc function-name-here)
   (find-doc part-of-name-here)
   Source: (source function-name-here)
   (user/sourcery function-name-here)
  Javadoc: (javadoc java-object-or-class-here)
 Examples from clojuredocs.org: [clojuredocs or cdoc]
   (user/clojuredocs name-here)
   (user/clojuredocs ns-here name-here)
 user= (use 'clj-time.core)
 FileNotFoundException Could not locate clj_time/core__init.class or
 clj_time/core.clj on classpath:   clojure.lang.RT.load (RT.java:443)

 What gives?

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

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




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




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




Re: core.async: communicating termination

2013-07-12 Thread Brandon Bloom
 However, if what one is trying is to *stop* putting values on the 
channel, I see no possible race conditions.

Querying the state of a channel at worst leads to race conditions and at 
best leads to bad design.

You're only supposed to close a channel from the producer side. So if 
you're the only writer, then you know if you've closed the channel or not. 
If there are multiple writers, then need to be coordinated in some way. 
Typically, they would alt! against reading from a control channel and 
writing to the output channel. When you get a shutdown signal from the 
control channel, you stop writing.

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




Re: core.async: communicating termination

2013-07-12 Thread Brandon Bloom
 You're only supposed to close a channel from the producer side.
 Why?

First, an appeal to authority: http://golang.org/pkg/builtin/#close
Notice the type of the argument: chan-
That's a write-only port. Go's type system allows automatic coercion from
read/write ports to constrained read or write only ports. However, you
can't coerce a constrained port back to an unconstrained one.

See also the discussion here:
https://groups.google.com/d/topic/golang-nuts/pZwdYRGxCIk/discussion

There are a few points discussed there, but in summary: It is a programming
error to write a message to a closed channel. close is not a resource
cleanup operation, it is a control signal. It flows in the same direction
as the messages sent on the channel itself. If the receiver were allowed to
close the channel, then the sender would have no way of avoiding a
closed/write race condition.

This brings up another issue: Currently writing to a closed channel is a
no-op, but it probably should throw an exception. Similarly, closing a
closed channel is a no-op, but also probably should throw an exception.
Both are things that a well behaved sender should never do, since they know
when they close, so they know not to keep putting stuff in there. Or, they
are warned of the impending close by some coordination process  the same
rules apply.

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




Re: core.async: communicating termination

2013-07-11 Thread Brandon Bloom
Wouldn't closed and drained predicates introduce race conditions?

(Sorry for brevity, on my phone)

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




Re: Microsoft Rx -style operations with core.async

2013-07-02 Thread Brandon Bloom
When I first wrote this code, I intentionally avoided any custom 
syntactical sugar and worked as closely with the primitives as I could.

After a few days away, I've used fresh eyes to abstract and revamp. The new 
code is *dramatically* cleaner and I only needed to introduce a few simple 
and predictable macros.

With regards to my prior feedback:
 
 1) The (let [c chan] (go ...) c) pattern is *extremely-common*. Might be 
nice to have something like (go-as c ...) that expands to that pattern.

I've implemented go-as without buffer parameterization. This was a huge 
cleanup.

 2) It's somewhat annoying to always have to consider boolean false all 
the time.

I've introduced two macros: if-recv and when-recv. (if-recv [x p] ...) is 
equivalent to (let [x (! p)] (if-not (nil? x) ...)) and when-recv does 
what you'd expect.

Currently, these macros only operate on a single port to read from. I need 
to give this a bit more thought before I attempt a multiplexing version of 
this macro.

 3) Not mentioned in my prior feedback: Looping receives over a channel is 
pretty common too.

For that, I've got the (dorecv [x port] ...) macro, which is analogous to 
doseq, but reads from port via !

Similarly, a multiplexing variant of dorecv needs more thought before I 
attempt that.

I think you'll agree that the new code is much nicer 
looking: 
https://github.com/brandonbloom/asyncx/blob/89fe35eae8be9a3350855bf841fc11c46ea04b0f/src/asyncx/core.clj
(doc strings available for these new macros too)

Each one of these primitives is about an order of magnitude more useful 
than any of the original Rx operators... So I guess that means I can 
consider this a successful learning experience! In fact, I think these 4 
macros might even be useful enough for the core.async namespace after some 
more field testing. Please let me know if these are helpful to you. I'd 
also love to know if there are any little patterns or macros like these 
that you've discovered.

Cheers,
Brandon

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




Re: core.async - question about close!

2013-07-01 Thread Brandon Bloom
close! is a control signal from producer to consumers. It's how you say 
Nothing else follows. It is not necessary for garbage collection. 

On Monday, July 1, 2013 2:43:02 AM UTC-4, puzzler wrote:

 Is close! merely a convenience function to ensure that future puts to a 
 channel will not be permitted, or is it essential to close! a channel so 
 that it will be garbage collected?


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




Microsoft Rx -style operations with core.async

2013-06-30 Thread Brandon Bloom
Hi all,

Today, primarily for my own edification, I've been implementing as many 
Microsoft Reactive Extensions operators as I can using core.async. The 
results have been *spectacular*. core.async is an absolute pleasure to work 
with. I'm so happy with how they have turned out, that I really want to 
share.

You can find my work-in-progress here:
https://github.com/brandonbloom/asyncx

The primary file of interest is:
https://github.com/brandonbloom/asyncx/blob/master/src/asyncx/core.clj

At the time of this message, I've implemented the bulk of the relevant 
operators described here:
http://msdn.microsoft.com/en-us/library/hh242961(v=vs.103).aspx

All of my implementations utilize parking operations, so this library 
should be fully portable to ClojureScript.

My notes describe any difference from Rx, notable omissions, and known 
issues:
https://github.com/brandonbloom/asyncx/blob/master/notes
I'll probably work more on this tonight and will update my notes as I go.

Rich  team: I understand that you guys will probably take a run at 
implementing this sort of library in the not too distant future. Please let 
me know if and how I can contribute to that effort.

Cheers,
Brandon

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




Re: Microsoft Rx -style operations with core.async

2013-06-30 Thread Brandon Bloom
 I don't know the semantics of the MS functions so maybe this mirrors them

This code is not an attempt to replicate the semantics of Rx, just provide
a comparable set of operators.

 the implementations of take-while and drop-while remove an extra
element from the argument channel, right?

Yes. All of these operations inherently consume values from channels. Your
c variable is no longer usable once you've given it out to a consumer that
expects exclusive access.

Channels and Push Sequences are different in many ways. In particular,
callback-based push sequences can have multiple subscribers. That's why
there are no fan-out operations listed on that Msft reference page: All
subscription can implicitly fan out.

I've only thought briefly about this, but there are potentially many
different strategies for fan out (eg
buffering/blocking/dropping/sliding).It's not yet obvious to me what the
various higher level operators should look like (or be called). I'm open to
suggestions. I also haven't studied the design space from the Golang
perspective yet either. Maybe that community has some good ideas...

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




Re: Microsoft Rx -style operations with core.async

2013-06-30 Thread Brandon Bloom
Two bits of core.async feedback:

1) The (let [c chan] (go ...) c) pattern is *extremely-common*. Might be
nice to have something like (go-as c ...) that expands to that pattern.

2) It's somewhat annoying to always have to consider boolean false all the
time. Since nil signifies a closed channel, if, when, if-let, and when-let
are extremely convenient. Unfortunately, they are subtly bugged! You need
nil? checks everywhere, cluttering up relatively nice code.


On Sun, Jun 30, 2013 at 5:27 PM, Brandon Bloom brandon.d.bl...@gmail.comwrote:

 Hi all,

 Today, primarily for my own edification, I've been implementing as many
 Microsoft Reactive Extensions operators as I can using core.async. The
 results have been *spectacular*. core.async is an absolute pleasure to work
 with. I'm so happy with how they have turned out, that I really want to
 share.

 You can find my work-in-progress here:
 https://github.com/brandonbloom/asyncx

 The primary file of interest is:
 https://github.com/brandonbloom/asyncx/blob/master/src/asyncx/core.clj

 At the time of this message, I've implemented the bulk of the relevant
 operators described here:
 http://msdn.microsoft.com/en-us/library/hh242961(v=vs.103).aspx

 All of my implementations utilize parking operations, so this library
 should be fully portable to ClojureScript.

 My notes describe any difference from Rx, notable omissions, and known
 issues:
 https://github.com/brandonbloom/asyncx/blob/master/notes
 I'll probably work more on this tonight and will update my notes as I go.

 Rich  team: I understand that you guys will probably take a run at
 implementing this sort of library in the not too distant future. Please let
 me know if and how I can contribute to that effort.

 Cheers,
 Brandon

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




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




Re: Microsoft Rx -style operations with core.async

2013-06-30 Thread Brandon Bloom
 My understanding with some member of the core.async team is that most
channel based APIs fns should *take* a channel and only construct one as a
default.

Could you elaborate on and motivate that?

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




Re: Microsoft Rx -style operations with core.async

2013-06-30 Thread Brandon Bloom
Then maybe we need (go-as [c arg] ...)

On Sunday, June 30, 2013 8:15:45 PM UTC-4, David Nolen wrote:

 Because of blocking on read/write on unbuffered channels - users might 
 need more flexibility.


 On Sun, Jun 30, 2013 at 8:13 PM, Brandon Bloom 
 brandon...@gmail.comjavascript:
  wrote:

  My understanding with some member of the core.async team is that most 
 channel based APIs fns should *take* a channel and only construct one as a 
 default.

 Could you elaborate on and motivate that?

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




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




Re: core.async

2013-06-29 Thread Brandon Bloom
I don't think it's published to a maven repository yet. You can check it
out, install it with `lein install`, then depend on it via [core.async
0.1.0-SNAPSHOT]


On Sat, Jun 29, 2013 at 2:50 PM, David Pollak dpollak...@gmail.com wrote:

 What's the entry in project.clj to use the core.async stuff?

 Thanks!


 On Sat, Jun 29, 2013 at 9:44 AM, Joseph Smith j...@uwcreations.com wrote:

 It seems to me that the Clojure space suffers from an unusual malady:
 it's busy sitting here quietly advancing half of applied computer science,
 and no one seems to notice the full extent of its import.

 And it makes me sound like a broken record with my colleagues: Oh!
 Clojure has...



---
 Joseph Smith
 @solussd






 On Jun 29, 2013, at 6:07 AM, Peter Taoussanis ptaoussa...@gmail.com
 wrote:

 Oh man, how is everyone _not_ running around screaming about this right
 now?

 It seems to me that the Clojure space suffers from an unusual malady:
 it's busy sitting here quietly advancing half of applied computer science,
 and no one seems to notice the full extent of its import.

 Man, I'm sometimes forced to just stop for a moment and sit in awe at how
 lucky I've been to see this stuff develop and to get to use it.

 Clojure was huge. And before we're close to digesting its potential,
 there's protocols. And Clojurescript. Then Datomic. Reducers. Now this.

 And it's not about everything being necessarily _novel_, though there is
 often novelty. For me it's largely about the cohesiveness of the design and
 the consistency of the overarching vision. Everything _fits_. I feel like
 I'm using tools and ideas that weren't just developed with care, or
 cleverness, or experience, but all of those things in a kind of harmony
 that's vanishingly rare to find in any field.

 I honestly feel like I'm witnessing history being made.

 Thank you Rich Hickey, and everyone else in this community for making my
 work every day so enjoyable.

 - Peter Taoussanis

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




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




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




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




Re: Is there a better way to update a map atom?

2013-06-29 Thread Brandon Bloom
 Can anyone explain the relationship between swap! and reset! ?

swap! is for CAS

See: http://en.wikipedia.org/wiki/Compare-and-swap

In the examples here, you're fully replacing a value, so reset! is fine... 
assuming that the replacement value was not derived from the existing 
value. If the atom was deref-ed (via deref or the @ reader macro), that 
value is a perception of a potentially old state. Making a decision outside 
of an atomic swap operation would potentially be invalidated by another 
thread performing a conflicting mutation.

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




Re: Is there a better way to update a map atom?

2013-06-29 Thread Brandon Bloom
Could we please curb the pedantry?

On Sat, Jun 29, 2013 at 9:21 PM, Ben Wolfson wolf...@gmail.com wrote:

 On Sat, Jun 29, 2013 at 6:06 PM, Cedric Greevey cgree...@gmail.comwrote:

 Who said swap *was* CAS, rather than was implemented *in terms of* CAS?
 In any event, your claim that no comparison is done unless it's done in
 the supplied function is just plain wrong. Comparison *is* done, outside
 that function, to make sure the atom wasn't changed by another thread while
 the function was executing.


 swap! is for CAS

 The claim here is clearly not that swap! is implemented in terms of CAS
 (which would be very unenlightening, since the question was about the
 distinction between swap! and reset!, which can *also* be implemented in
 terms of CAS). I admit it would have been more careful of me to say that
 the semantics of swap! are such that whether or not any comparison is done
 is an implementation detail; those semantics (which are that swap!
 [a]tomically swaps the value of atom to be: (apply f current-value-of-atom
 args) don't specify a comparison, which is not the case with CAS. (reset!
 *isn't* implemented in terms of swap! or CAS, but it *could* be, as far as
 the semantics are concerned; if it were, I think it would still be right to
 say that reset! conceptually doesn't do a comparison against anything, even
 though, again, as an implementation detail, it could.)

 Or just look at the source for clojure.lang.Atom.swap():


 IOW, the first 100 lines of Atom.java contain all the answers?



 --
 Ben Wolfson
 Human kind has used its intelligence to vary the flavour of drinks, which
 may be sweet, aromatic, fermented or spirit-based. ... Family and social
 life also offer numerous other occasions to consume drinks for pleasure.
 [Larousse, Drink entry]

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




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




Re: core.async

2013-06-28 Thread Brandon Bloom
 Are people in love with names like `!` and `!!`, or is there room for 
rethinking the naming?

These operators are important and common enough to justify being *syntax* 
in Go, which is pretty minimal on syntax overall.

Personally, I think the names are pretty good.

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




Re: core.async

2013-06-28 Thread Brandon Bloom
 CSP proper is amenable to certain kinds of automated correctness analysis.
 No work has been done on that front for core.async as yet.

Although a far cry from Go's race 
detectorhttp://blog.golang.org/race-detector, 
Go did ship with one feature that is helpful for preventing a certain class 
of bugs: explicit restriction to a send-only or receive-only channel via 
constraining conversion or assignment. 
See http://golang.org/ref/spec#Channel_types

Although Go utilizes the type system to accomplish this at compile time, 
core.async could achieve the same effect at runtime. Essentially, there 
could be two conversion functions for wrapping a channel in a read-only or 
write-only proxy object.

I'm not sure if this is actually useful, but I'm curious: Has this been 
considered?

On Friday, June 28, 2013 3:06:47 PM UTC-4, Rich Hickey wrote:

 I've blogged a bit about the new core.async library:

 http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html

 Please try it out.

 Thanks,

 Rich



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




Re: ANN: ClojureScript release 0.0-1798

2013-06-25 Thread Brandon Bloom
Even if it's horribly broken, maybe we should default it to on for advanced 
builds anyway? It's not like anything can be harder to debug than raw 
advanced compilation output. Besides, we might get some more interest and 
contributions if it *feels* like it's close!

On Tuesday, June 25, 2013 7:37:28 PM UTC-4, David Nolen wrote:

 Wow, really? I didn't really consider it usable yet as we don't emit quite 
 enough information for mapping symbols.


 On Tue, Jun 25, 2013 at 7:14 PM, gerrit.h...@gmail.com javascript:wrote:

 Thanks a lot for the source map support. Made it possible for me to find 
 the cause of my broken advanced compiled cljs. Without the source map I was 
 totally lost...

 In case anybody wonders how to enable it:

 Just add a :source-map path/to/js/folder/source-map-name.js.map key 
 value pair to the :compiler map of your :cljsbuild map.

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





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




Re: representing clojure source code as data?

2013-06-23 Thread Brandon Bloom
 By raw data structures, you mean the concrete implementing classes, a
la clojure.lang.PersistentVector?

Yes.

 (quote 1) -
 {:head :list :body [quote 1]}


You're not going far enough with this. Here's how my code is representing
that:

{:composite :list, :items [{:value quote} {:value 1}]}

That approach encodes non-composite types into the concrete class of the
:value field. However, you can encode that too. Here's an alternative:

{:type :list, :items [{:type :symbol :value quote} {:type :long :value 1}]}

 All syntax is turned into first class representations. Reader macros and
 datastructure literals are indexed by special keywords; primitives stand
 for themselves without extra wrapping.


The key benefit of going all the way with the maps is that all of your
nodes always have space for :extra/keys
Take a look at :op :constant in CLJS for an example of how useful this is
for analysis. At minimum, you want to be able to store :line and :column
and the like, but Keywords and numbers and such don't implement IMeta.


 Clojure code is EDN data + a set of non-EDN constructs; doing with with
 100% EDN is the problem I'm trying to solve.


Right. At this point, the Clojure reader is a superset of the EDN reader,
but all of the Clojure-specific forms can be (and often are) encoded as
both EDN forms and in-memory types objects. The notable exception being the
lack of an in memory representation of tagged literals.

Right now, the Clojure reader does some inline evaluation of Clojure-forms
like unquote and unquote-splicing. In theory, the reader could return a
'(clojure.core/unquote ...) list in memory, of a {:composite ...} AST node
shape. I think that https://github.com/clojure/tools.reader could probably
be made pluggable for returning the desired shapes.

 Random java objects and whatnot.

Random java objects and whatnot can only enter into your forms as the
result of tagged literal or macro functions. In both cases, there really
needs to be a separation between the reading of the value and the
construction of the value. CLJS is currently bugged for #inst literals with
respect to quoting, since the reader is returning code instead of Date
objects. If the literal's result is read by a macro, then you need a java
date, but if it's read by runtime code you need a js date, so it's a tricky
issue.

Every program that computes from the source code can just add its results
 as new attributes. This includes both the traditional compiler passes, as
 well as additional testing  analysis, or even the results of running the
 code.


I've been thinking about this issue a bit. Datomic's model is absolutely
great for the normalized core data of things, but I'm not convinced that
it's ideal for the results of observations. I rather not get into this in
this thread. I think that there's enough work at the reader level before we
can even discuss the analysis level.

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




Re: generating core.logic queries

2013-06-21 Thread Brandon Bloom
 Perhaps not, but apparently the developers of core.logic are.

That's kinda a funny remark to make to David Nolen, who is *the* developer 
of core.logic.

In this case, he's talking about this wiki page: 
https://github.com/clojure/core.logic/wiki/Extending-core.logic-(Datomic-example)

That's not a recommendation to use Datomic, that's just one particularly 
interesting example of how to extend core.logic

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




Re: representing clojure source code as data?

2013-06-21 Thread Brandon Bloom
 I think there are 2 representations that could be useful:

I think there are really two axis: 1) Shape of the data and 2) Language 
being described

You've outlined 2 out of the 3 interesting (to me) shapes: 1) raw data 
structures and 2) datoms. I think that the 3rd interesting one is a 
map/vector tree, like the CLJS analyzer output.

The two languages to describe are EDN and Clojure. You can further break 
Clojure down by host platform, and even potentially further (for example: 
pre and post macro expansion variants of the language).

 1. as pure EDN data that encodes the various reader macros within the 
strict EDN subset, as a kind of minimal AST

I made a related design page here: 
http://dev.clojure.org/display/design/Representing+EDN

The contents of that design page right now are focused on the raw data 
structures shape of EDN, hence the proposal for a TaggedLiteral type.

Here's some code for parsing raw data with a TaggedLiteral record into a 
vector/map tree of sorts:
https://github.com/brandonbloom/ascribe/blob/04384d21bd9e74e29d84cf2ec1c55dd5034195e0/test/ascribe/cljs/parse.clj

As for the Code variant, the tools.analyzer library and CLJS compilers have 
an internal AST representation that should eventually be standardized. The 
important thing there for me is that we differentiate fundamental 
properties of AST nodes and synthesized/derived attributes that are 
attached to each node.



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




Re: [pre-ANN] test2, the last Clojure testing framework

2013-06-11 Thread Brandon Bloom
 Maybe it makes sense to separate out the 'common testing interop' effort
 from the 'another test framework' effort, so it can can get off the ground?

I agree with this. It's easier to solve fewer problems at once. Maybe
you should reduce the scope to just the common result reporting
schema? At least for the first try at this.

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




Re: [pre-ANN] test2, the last Clojure testing framework

2013-06-10 Thread Brandon Bloom
There are currently 4 roles defined: Definer, Asserter, Runner, and 
Reporter.

It looks like the Runner does finding, filtering, and execution. I think 
you could further break the Runner down into Discoverer and Executor. I 
might want to just ask What tests do I have? without actually running 
anyway. I may also want a different Executor, like a distributed/parallel 
executor, while preserving the discovery logic.

On Saturday, June 8, 2013 11:14:42 AM UTC-4, Steven Degutis wrote:

 Test2 is a new testing lib for Clojure, where the power is its simplicity, 
 extensibility, and a 
 SPEChttps://github.com/evanescence/test2/blob/master/SPEC.md much 
 like Ring's.

 Github: https://github.com/evanescence/test2

 Some background: It came out of 
 discussionshttps://github.com/evanescence/test2/wiki/Communal-Brainstorming 
 with 
 the smart folks in #clojure, who were frustrated with the inflexibility of 
 existing libs, and intended this to be the spiritual successor to 
 clojure.test. We wanted something that was still simple like clojure.test, 
 but could be extended externally much more easily in case you wanted 
 features found in clojure.test, Midje, Speclj, or Expectations, or whatever 
 else.

 This is a pre-ANN because it's more of a call for extensions. I've written 
 one last night, 
 test2-autorunnerhttps://github.com/evanescence/test2-autorunner, 
 which took about an hour. This should give some idea of how easy it is and 
 how well-designed the SPEC was by the smart folks of #clojure. There are 
 some ideas at the bottom of the wiki, but of course any extensions are 
 encouraged.

 -Steven


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




Re: Why the CLR languages fail?

2013-06-06 Thread Brandon Bloom
Alexandru's analysis is spot on.

Here's the pithy IRC version I've used in the past: C# has a better type 
system and compiler, so it doesn't need as good of a JIT. That's a problem 
for languages that aren't C#, especially dynamic ones.

There are lots of caveats, but that more or less covers it.

On Thursday, June 6, 2013 6:53:05 AM UTC-4, Alexandru Nedelcu wrote:

 On Thu, Jun 6, 2013 at 12:47 PM, Colin Fleming 
 colin.ma...@gmail.comjavascript:
  wrote:

 I'm not sure this is true, Don Syme has written several times about how 
 difficult it would be to implement F# on the JVM - I believe tail recursion 
 and not being able to define new intrinsic types (i.e. new primitives) are 
 the sticking points. 


 Yes, both of these have been issues people had to confront on the JVM. 
 However, for example tail-recursion in CLR not being used by C# meant that 
 it went unoptimized and even broken on the 64bits CLR for years. 

 Also, tail-recursion is not such a big issue, because self-tail recursion 
 is easy to optimize by generating a simple loop (Scala does it, Clojure 
 does it) and more complicated cases require indeed usage of trampolines. 
 Not to underestimate their importance, being a useful feature to model 
 state-machines, however you can still work by means of trampolines (Clojure 
 elegantly solves it with syntactic sugar and it's workable in Scala because 
 of it's good type-system [1])

 On the other hand, the lack of support for new primitives has been hurting 
 language implementations, like JRuby. Note that both features have 
 experimental implementations as part of OpenJDK and it's possible we'll see 
 them in the JVM. Plus, why stop at tail-calls? There are many languages 
 that can hardly be implemented on top of both .NET and the JVM - not having 
 continuations support, useful for Scheme or Smalltalk is a PITA. Haskell 
 wouldn't be possible in either, because of it's laziness by default. You 
 also mentioned primitive types, but for example the CLR lacks a Union data 
 type, so implementing lazy integers for example comes with a lot of 
 overhead.
  

 I think a lot of people believe that from a functionality point of view 
 the CLR is better than the JVM - as far as I know it's not missing any 
 functionality from the JVM and it has significant advantages (reified 
 generics as well as the functionality mentioned above).


 That's not true. It does have a couple of advantages (like the ones you 
 mentioned), but that list is shrinking and the advantages that the JVM has 
 are huge and the list gets bigger with each new release. 

 Reified generics are actually a PITA for new languages. Scala's generics 
 are much more flexible, with a much better design than the ones in Java - 
 you cannot implement Scala's type system on top of .NET's generics without 
 cutting down on their features. Erasure is not bad per se and for the 
 utility of reified generics, it really depends on what language you're 
 talking about. Erasure has only been bad for Java, because Java's type 
 system is too weak and because in Java the wildcards are used on the 
 methods themselves, rather than at the class level, which has been a big 
 mistake. Also, Scala's type system is much stronger, much more static and 
 much more expressive. I never felt the need for reification in Scala. It 
 even has the option of doing specialization for primitives, to avoid 
 boxing/unboxing, as an optimization option. Haskell also implements 
 generics by erasure.

 Reified generics are bad for other languages if you need to workaround 
 them. For dynamic languages it's somewhat a disaster. On the JVM the 
 bytecode is pretty dynamic, except for when you need to work with 
 primitives (for invoking operations optimized for primitives) or when you 
 call a method, you need to know the interface it belongs to (something 
 which changed in OpenJDK 7 with invokeDynamic). Otherwise you don't have 
 static types in the actual bytecode (e.g. casting an object to something is 
 just an assertion in the actual bytecode that you don't need). But with 
 reified generics, suddenly you have more static typing you need to take 
 care of and avoid.

 When generating bytecode it's easier on the JVM. The final packages (Jars) 
 are just Zip files containing .class files, with a text-based manifest. The 
 .class files themselves contain the debugging symbols and those debugging 
 symbols are part of the standard spec, whereas the format for the CLR was 
 never a part of the ECMA standard, was private and for a long time Mono has 
 been using their own format for those debugging symbols, as they had to 
 slowly reverse-engineer whatever Microsoft was doing. Because Java 
 libraries tend to use a lot of bytecode-generating routines, the tools 
 available for that are amazing (like ASM), whereas on top of .NET things 
 like System.Reflection.Emit takes care of only a subset, so the Mono people 
 had to come up with their own alternatives (like 

Re: I don't feel the absence of a debugger, because I've learnt enough that I don't ever need a debugger.

2013-05-27 Thread Brandon Bloom
Coming from Visual Studio all those years ago, I deeply missed my debugger.

These days, I miss my debugger extremely rarely. And when I do use a 
debugger, I much prefer a non-visual one: Either something like dgb, or 
something like a hypothetical open-repl-here function, where I can ask 
specific questions and get specific answers... logged to my terminal! I 
find that trace points (aka print statements) are more useful than break 
points because I can look at cross sections of execution (read: logs) 
rather than specific instruction pointer locations. And when you get a log 
in your terminal, you spend less time re-asking and re-evaluating by 
hovering your mouse around, which is quick to confuse you. Logs are 
particularly useful with pretty printed Clojure data, since you know the 
values have remained immutable since you have printed them!

Most of the time, stepping through code is just much slower than thinking, 
inserting a precise print statement, and then re-executing the broken code.

However, this means that you need to design your code for determinism, 
repeatability, and visibility. So not having a debugger means also 
has pleasant affects on your design!

On Monday, May 27, 2013 2:34:23 PM UTC-4, Oskar Kvist wrote:

 Stuart Halloway said in his video Clojure in the Field (
 http://www.infoq.com/presentations/Clojure-tips) from March 1, 2013 (I 
 think): I don't feel the absence of a debugger because I've learnt enough 
 that I don't ever need a debugger. I am very intrigued by that statement. 
 What does he (or you, if you are reading, Stuart) mean? For me, debugging 
 is the biggest thing that I don't know how to do well currently in Clojure 
 (I use Vim, and have not programmed in Clojure for a while), so I am really 
 interested in what he meant.

 And by the way: As I said, I have not been using Clojure for a few months, 
 but: What's the state of the art of debugging for Vim users? I've been 
 meaning to try out vim-fireplace and ritz and see if they work together 
 well, but have not gotten around to it yet. I would very much appreciate a 
 nudge in the right direction.


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




Re: defmethod/require race condition

2013-05-09 Thread Brandon Bloom
This is an unfortunate ugly side effect of def and def-like forms being, 
um, side effectual.

In the particular case of defmethod, I think that the general 
recommendation would be to structure your namespaces such that methods are 
defined along side the code that could produce dispatch values which would 
trigger those methods. For example, if you were to dispatch by :some-key, 
then the functions that produce maps with {:some-key :foo} should be in the 
same namespace as (defmethod f :foo ...)

On Thursday, May 9, 2013 5:19:40 PM UTC-4, sdegutis wrote:

 In my app, sometimes a file containing a defmethod hasn't been 
 required yet by the time some other function calls the multi-method. 
 So naturally it throws an exception. 

 But later, as the app continues to run, the file containing the proper 
 defmethod eventually gets required by another file. Then everything 
 works fine. 

 The ugly solution is to require all possible implementations of a 
 multi-method in the file that calls it. But that feels like it defeats 
 the goal of polymorphism, to not have to know about concrete 
 implementors of an interface. 

 Is there a better solution to this kind of race condition? 

 -Steven 


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




Re: invokedynamic instructions in Clojure

2013-04-16 Thread Brandon Bloom
Do you have any measurements, results, or conclusions to report?

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

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

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

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

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

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

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

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


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




Re: [ANN] Instaparse 1.0.0

2013-04-14 Thread Brandon Bloom
Thanks for the details. You definitely made the right pragmatic decision. What 
you've said pretty much matches what I expected to hear, although I'm 
hopeful that the approach can be refined, since it's quite eloquent. Beyond 
eloquence, the derivatives approach is also interesting for schema 
validation. See: http://www.thaiopensource.com/relaxng/derivative.html

Regarding memory pressure, I think the primary pain point originates from 
the same underlying cause: Those Racket-isms that you found difficult to 
port to Clojure. Cyclic data structures, in particular, preclude the 
structural sharing that occurs with incremental changes to persistent data 
structures. Additionally, memoization is thwarted because cycles complicate 
equality. Cycles are better off encoded as named references in a spanning 
tree (and, like an AST, would need nominal equality) and Laziness can be 
achieved indirectly via fixed-point rewriting (rather than explicit thunks) 
which is already necessary for the algorithm.

I asked Matt Might about all 
thishttps://twitter.com/BrandonBloom/status/322877682138349568, 
but Twitter isn't really the best forum for that conversation.

Cheers,
Brandon

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




Re: [ANN] Instaparse 1.0.0

2013-04-12 Thread Brandon Bloom
Super cool! Nice work.

Your readme says I had difficulty getting his Parsing with Derivatives 
technique to work in a performant way.  I was wondering if you could 
please elaborate.

What kind of performance did you achieve?
How does that compare to the GLL parser you implemented?
Did you implement memoization/compaction/fixed-point/etc from the latest 
research? 
How do the implementations compare in terms of code size and readability?

Thanks,
Brandon

On Tuesday, April 9, 2013 1:18:39 AM UTC-4, puzzler wrote:

 Instaparse is an easy-to-use, feature-rich parser generator for Clojure.  
 The two stand-out features:

 1. Converts standard EBNF notation for context-free grammars into an 
 executable parser.  Makes the task of building parsers as lightweight and 
 simple as working with regular expressions.

 2. Works with *any* context-free grammar.  This means you don't have to 
 learn the esoteric subtleties of LR, LL, LALR or any other specialized 
 subset.  Left-recursion, right-recursion, ambiguous grammars -- instaparse 
 handles it all.

 Example:

 (def as-and-bs
   (parser
 S = AB*
  AB = A B
  A = 'a'+
  B = 'b'+))

 = (as-and-bs abbbbb)
 [:S
  [:AB [:A a a a a a] [:B b b b]]
  [:AB [:A a a a a] [:B b b]]]

 https://github.com/Engelberg/instaparse for full feature list and 
 extensive tutorial.


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




Re: What's the point of - ?

2013-03-12 Thread Brandon Bloom
One other thing to consider is partial application. The collection 
functions tend to put the most-likely-to-be-curried arguments first. For 
example:

(def sum (partial reduce + 0))

Compare to coll-reduce, which dispatches on the type of the first argument:

(require '[clojure.core.protocols :refer (coll-reduce)])
(def sum #(coll-reduce % + 0))

On Tuesday, March 12, 2013 1:29:31 PM UTC-4, Sean Corfield wrote:

 On Tue, Mar 12, 2013 at 10:21 AM, Neale Swinnerton 
 ne...@isismanor.comjavascript: 
 wrote: 
  if designing from scratch should we favour being threadable with - or 
 - ? 

 My understanding is that the two threading macros are there to support 
 two existing standard idioms in Clojure: 
 * functions operating on collections tend to have the collection in 
 the last argument slot (so you use -) 
 * other functions - where the first argument is usually the cascade 
 point so you use - 

 (I remember reading a better articulated explanation than that but 
 can't find the link easily - hopefully you get the idea) 
 -- 
 Sean A Corfield -- (904) 302-SEAN 
 An Architect's View -- http://corfield.org/ 
 World Singles, LLC. -- http://worldsingles.com/ 

 Perfection is the enemy of the good. 
 -- Gustave Flaubert, French realist novelist (1821-1880) 


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




Re: features expression

2013-03-06 Thread Brandon Bloom
 I believe protocols can entirely alleviate the need for feature expressions.

How do you figure that?

One major incompatibility between Clojure and ClojureScript currently is that 
the protocols don't match up. If you want a deftype form that is 90% the same, 
but has a conditional switch for a clojure.lang interface or a cljs.core 
protocol, then you need to have a conditional selection of forms *before* macro 
expansion time, where the deftype form is looking for symbols representing type 
names.

There are plenty of cleaner solutions, like using extend-type, but those come 
at a performance cost and there is a unique solution for each type of 
compatibility problem you run into.

The only generalized solution that makes sense to me (would love to hear 
others) is a preprocessing step. Here's my suggestion: 
http://dev.clojure.org/display/design/Feature+Expressions?focusedCommentId=6390066#comment-6390066

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




Re: [ClojureScript] features expression

2013-03-05 Thread Brandon Bloom
 I personally think the CL feature expression approach is satisfactory.

The more I think about it, the less I think that the CL Feature Expression 
approach is satisfactory as is.

I'm now reasonably convinced that, horror of horrors, we should look to the C 
preprocessor for inspiration.

CL's approach only provides flags, not key/value pairs. Also, the CL approach 
does not provide a structured form for if/else or cond expressions and has only 
limited and/or/not predicate combinators. Experience in writing portable C code 
has proven that == and = are important for checking version numbers and 
feature levels.

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




Re: help make a macro that takes an input and will evaluate only the unquoted parts

2013-02-19 Thread Brandon Bloom
Shameless self-promotion: https://github.com/brandonbloom/backtick

On Tuesday, February 19, 2013 1:35:28 PM UTC-5, AtKaaZ wrote:

 I am trying (but failing) to find a way to have a macro like:
 = *(xmacro* {:a (+ 1 2) :b ~(+ 1 3)})
 {:a (clojure.core/+ 1 2), :b 4}
 ;*without specifying the backquote ` on the input*

 I need it to behave like this:
 = (*eval '`*{:a (+ 1 2) :b ~(+ 1 3)})
 {:a (clojure.core/+ 1 2), :b 4}

 But I don't get how I could do that, yet I feel I'm missing something 
 pretty basic.

 I've also made a gist for this: https://gist.github.com/AtKaaZ/4988320

 But this is the best that I can do without errors:

 = (defmacro x [a] `~a )
  
 = (*x `*{:a (+ 1 2) :b ~(+ 1 3)})
 {:a (clojure.core/+ 1 2), :b 4}

 But I don't want to have to specify the backquote ` in the 
 input to the macro, I need the macro to automatically add 
 that.

 Thank you for your help.


 -- 
 Please correct me if I'm wrong or incomplete,
 even if you think I'll subconsciously hate it.

  

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




Re: IF?

2013-02-12 Thread Brandon Bloom
Clojure, like most Lisps, has a top-to-bottom, inside-out, left-to-right, 
eager evaluation strategy. All Clojure forms are expressions, and thus must 
return a value. Given these two design requirements, (if test then else) is 
the natural branching primitive. It implies serialize execution 
(top-to-bottom) with arguments being evaluated first (inside-out; test is 
evaluated before the parent of the 'if and it's successor siblings, but 
after it's predecessor siblings). It also enforces that no matter the value 
of 'test, the 'if will yield a value (ignoring exceptions).

There are other approaches out there. Haskell, for example, uses fully lazy 
evaluation with provably pure functions. That means Haskell can utilize 
pattern matching as it's primitive branching construct and get something 
akin to short circuiting for free. Consider this boolean and function 
(note: not a macro):

-- | Boolean \and\
():: Bool - Bool - Bool
True   x  =  x
False  _  =  False

Back to the Lisp world, there are plenty of other schemes for primitives, 
branching, macros, etc. These include the classic cond, the fancy 
Macro-like http://en.wikipedia.org/wiki/Fexpr and a whole lot more.

Clojure, however, is a language specifically designed to be hosted. The 
simple serialized evaluation strategy is one that is designed to play nice 
with the likes of the JVM, CLR, and JavaScript runtimes. The set of 
primitive primitives is extremely small (fewer than 10), but there are a 
couple of host/interop primitives as well (dot, new, etc) as some things 
that are primitives for convenience or performance.

Given the broadly understood design constraints of Clojure, you're unlikely 
to find discussion of the nuances of the fundamental branching operators. 
However, the Lisp, functional programming, and theoretical computer science 
communities have studied this problem in quite some depth. Maybe some folks 
can provide some suggested readings.

Cheers,
Brandon

On Tuesday, February 12, 2013 9:40:45 AM UTC-5, Dies_Felices wrote:

 Hi there, 

 Before I go on, I'll apologize as this might get long and vague in 
 parts.  That will just be my showing where I'm even more confused than 
 I generally am.  I have only recently started trying to learn Clojure 
 and by inference Lisp. 

 Last night, I watched this video - 
 http://blip.tv/clojure/clojure-for-java-programmers-1-of-2-989128. 
 Admittedly though there were more than a few parts which flew right 
 over my head, I took those as a prompt for further reading.  This 
 morning though the question of the IF primitive struck me. 

 Basically, in this video Rich Hickey tells us that if is one of only a 
 few primitive statements and it can not be a function because it is 
 composed of two functional blocks of which only one is used at a 
 time.  This made sense and is reminiscent of what I've read about lisp 
 elsewhere. 

 This part doesn't make much sense but I'm including it to build the 
 context of the actual question when I get to that, this will I hope 
 make it more straight forwards. 
 This morning I was thinking what if all your operands and data were 
 predicated and the compiler were able to see some sort of 
 environmental variable then you could build an IF like function or 
 macro.  Armed with this different perspective I realised I'd seen it 
 before but also by itself it doesn't make much sense in a high level 
 language. 

 First of all, operands and data by themselves don't need to be 
 predicated and it would cause everyone a lot of work.  Then also the 
 compiler doesn't need to be aware of any special environmental 
 variables either for the same reason as before. 

 However, I think there is scope for consideration of a predicated code 
 block which returns a data structure or object or function or more or 
 less what ever would be the appropriate thing for Clojure to return. 
 Using this predicated code block structure IF, AND, OR, NOT, 
 Select Case would all be able to be macros constructed using this 
 primitive. 

 As I imagine it there would be two possible syntax variations that 
 might implement this. 

 The first like the LET would be in the form (Logical-Predicate- 
 Primitive Test-Expression (Scope-A) (Scope-B) (Scope-C)).  In 
 the case of Test-Expression = TRUE then Scope is returned 
 otherwise NIL.  You can have as many Scope-s as you like. 

 The second is much more dramatic.  At the moment in Lisps a list of 
 symbols (A B C) is read in and then A is evaluated looking for a 
 function.  If A is not a function then (I think) an error is thrown 
 but either way it's not proper lisp expression by itself.  Even if at 
 some point previously there had been a (def A 5), the value 5 isn't a 
 function either so nothing good happens. 
 The second case would work something like this ((Test-Expression) 
 (Scope-A) (Scope-B) (Scope-C)) which as above would allow you to 
 have as many Scope-s as you like.  In this case 

Re: Call for volunteers to help moderate a ClojureScript Google group

2013-01-23 Thread Brandon Bloom
/me steps forward

On Wednesday, January 23, 2013 10:53:34 AM UTC-8, Andy Fingerhut wrote:

 An interest was expressed by a few in having a separate ClojureScript 
 mailing list. 

 If it is a Google group, that requires moderating messages sent to the 
 group, via manual approval.  I suspect early on there will be many people 
 posting to the group for the first time that have long worked with 
 ClojureScript, and you'll know them, and you can approve that and all 
 future messages from them, but every time a new sender sends their first 
 few messages to the group, a person needs to receive an email, click a 
 link, read the message to verify it is on topic, and click a couple of 
 buttons to approve it or reject it. 

 Anyone interested in helping out with that?  It is easier if the load can 
 be spread across multiple people.  If someone else approves a message, you 
 still might get an email about a message needing approval, but the last 
 couple of steps above are then unnecessary. 

 Andy 



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




Re: Is contributing to clojurescript is intentionally made hard ?

2013-01-20 Thread Brandon Bloom
There are 176 forks on GitHub. Even assuming that all 51 contributors have 
a public fork (most probably do), that's 125 potential contributors 
unaccounted for. Only 29% of those forks account for an accepted 
contribution. What portion of the remainder might have been contributors?

I was curious if 29% was good in comparison to other projects on GitHub. 
I also have never written a Ring/Compojure app, so I took 2ish hours and 
threw a little toy together and seeded it with some interesting 
repositories from GitHub's explore feature.

Code: https://github.com/brandonbloom/cvf
Running: http://boiling-inlet-6842.herokuapp.com/

Feel free to add some repositories to it, but please try not to break it. 
It's not exactly robust :-)

In short, 29% seems pretty reasonable for the number of forks ClojureScript 
has. Obviously that percentage goes down as the number of forks goes up, so 
some normalization would need to occur.

Of note, technomancy/leiningen scores 49% for 331 forks. That's pretty 
*awesome*. Good job guys!

On Saturday, January 19, 2013 10:00:22 PM UTC-8, David Nolen wrote:

 I have nothing to add to this thread beyond pointing out that 
 ClojureScript has had _51_ contributors in the short year and a half of its 
 existence: http://github.com/clojure/clojurescript/graphs/contributors.

 Via JIRA.

 David


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

Re: Is contributing to clojurescript is intentionally made hard ?

2013-01-20 Thread Brandon Bloom
I think the inflammatory thread subject didn't help...

Java and cross-browser CI both sound great. I don't know if Clojure/core 
already has CI or what, but maybe you should take these ideas over to 
another thread? Possibly on the Dev mailing list. Because of the 
intentionally slow pace of Clojure development, I'd suggest one thread per 
topic (CLJ CI is a different topic than CLJS CI) and one thread at a time.

On Sunday, January 20, 2013 12:43:19 PM UTC-8, Irakli Gozalishvili wrote:

  I just wanted to mention that pull request was one of the several notes 
 I've made, but looks like it's being irritating enough people that 
 it completely took over this thread. The problem itself is not a JIRA or 
 that sending patches is too hard (even though I think it's too much 
 incidental complexity :) problem is that in order to fix a bug I've 
 encountered, I have to go through a lot of hoops and that's too much for 
 the first sip. Maybe less for people doing Java based programs as I still 
 have dark memories from amount of configuring I have to do to actually get 
 things running, but it definitely is for people that or from 
 other communities and if clojure is not ready to accept people from 
 different backgrounds what is the point of speaking at jsconf
 http://blip.tv/jsconf/jsconf2012-david-nolen-6141386 ?

 Now I think a lot of points have being completely missed here, pull 
 requests is just a tip of the iceberg, world has moved on from
 sending patches to building great tooling like 
 https://travis-ci.org/integration testing that verifies code quality of an 
 each checking and 
 even those pull requests submitted, which saves a lot of time for both 
 submitter and maintainer that otherwise would have to
 download patch, apply and run tests. Of course if you're Rich Hickey you 
 may find bugs in patches without doing all that, but if me 
 sloppy contributor can detect issues before patch reaches Rich would save 
 his time of looking at it. Not to say that I'm sure that even Rich could 
 miss something and having tooling that makes sure nothing breaks is useful. 
 It's 
 actually very surprising to me that project of this size does not has 
 integration testing in place. 

 Now it's not clear which browsers clojurescript is going to work but 
 regardless of claims it would be great to have facts. So my next step was 
 to setup integration tests with http://ci.testling.com/ that is like 
 travis.ci but runs your tests in all possible browsers  believe there 
 are tons of bugs when it comes to cross-browser compatibility.

 So it's not just that some people keep insisting on using pull requests 
 it's a lot more and maybe it's time for this community to revisit some 
 decisions. It's just natural process of grows.

 Regards
 --
 Irakli Gozalishvili
 Web: http://www.jeditoolkit.com/

 On Sunday, 2013-01-20 at 09:58 , Anthony Grimes wrote:



 On Sunday, January 20, 2013 11:33:56 AM UTC-6, Fogus wrote:

  

 To make matters worse, Clojure/core consistently avoids discussing these 
 issues in public


 I would guess because their position hasn't changed since the last time. 
  This is only speculation.  A page like what Anthony proposes could help, 
 but it wouldn't satisfy everyone.  Stuart Sierra wrote up something 
 related, but it doesn't cover everything discussed here 
 http://clojure.com/blog/2012/02/17/clojure-governance.html


 Well, no, if the answer remains the same it probably won't satisfy 
 everyone, but at least they'll have an easy way to learn why.

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

  
  

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

Re: Is contributing to clojurescript is intentionally made hard ?

2013-01-19 Thread Brandon Bloom
For what it's worth, I've submitted 20+ patches to ClojureScript and one or 
two to Clojure proper. I still find the process to be extremely unpleasant. 
I consistently avoid interacting with JIRA until the last possible minute: 
That software is actively user-hostile. Without naming names, I've spoken 
with a half dozen other active contributors who feel the same way. If I 
wasn't between jobs at the time, I'd never have made it over the hump 
towards being a contributor.

On Friday, January 18, 2013 1:01:52 PM UTC-8, Irakli Gozalishvili wrote:

 I have being trying to engage community and to contribute to clojurescript 
 for a while already, 
 but so far it's being mostly frustrating and difficult. I hope to start 
 discussion here and maybe
 get some constructive outcome.

 ## Rationale

 I'm primarily interested in clojurescript and not at all in clojure, 
 because of specific reasons (that
 I'll skip since their irrelevant for this discussion) dependency on JVM is 
 a problem. Removing
 that's dependency is also my primary motivation to contribute. 

 ## Problems

 - I do understand that most of the clojurescript audience is probably 
 also interested in clojure,
   but please don't enforce that. Have a separate mailing list so 
 that people interested in
   clojurescript and not clojure could follow relevant discussions without 
 manually filtering out
   threads.

 - What is the point of being on github if you don't accept pull requests 
 and require I do understand
   that there maybe specific reasons why jira flow was chosen, but 
 seriously that's another ball
   thrown at potential contributor to joggle. Not to mention that there are 
 several options how
   jira and github could be integrated.

 - My latest attempt was to configure travis.ci for integration tests
   https://github.com/clojure/clojurescript/pull/21
   
Integration tests are great specially because they run on every pull 
 request and post details back
into pull requests. This also means that lot of local test run time can 
 be saved. Not to mention that
for clojurescript tests you need JVM, v8, spidermonkey and more…

 If these things are intentionally made hard to stop new people with more 
 clojurescipt interests then please
 make it more clear, cause otherwise it just a motivation killer. 

 Thanks
 --
 Irakli Gozalishvili
 Web: http://www.jeditoolkit.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

Re: Is contributing to clojurescript is intentionally made hard ?

2013-01-19 Thread Brandon Bloom
 contributions to clojure are definitely less easy to make than to projects
 that willy-nilly accept any pull request.

False dichotomy. Accepting pull requests does not mean you need to be 
willy-nilly about it.

You know how people carefully optimize their signup forms and checkout 
flows? They do this because there's a (very large) category of people who 
simply give up when things aren't immediately obvious. Granted, this 
category is much smaller among the class of folks skilled enough to create 
a desirable Clojure patch. However, the fact that this topic keeps coming 
up suggests that maybe that group is large enough to pay attention too.

As the Clojure implementations evolve, fewer and fewer people will discover 
issues large enough to justify diving into the code base to fix them. Most 
people just work around the issues. If somebody takes the initiative to 
properly fix an issue, we shouldn't add yet another hurdle discouraging 
them from contributing.

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

Re: Is contributing to clojurescript is intentionally made hard ?

2013-01-19 Thread Brandon Bloom
Aaron, please forgive my failure at formalities: Allow me to add that I 
agree with the rest of your post.

The Linux kernel and Guava guys are absolutely right about patches 
defaulting to the rejected state. I'm a big believer in the minus 100 
points philosophy.

It's just that I just really hate JIRA.

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

Re: Better ways of documenting functions with type information?

2013-01-13 Thread Brandon Bloom
You could use type hints and pre/post conditions:

(defn foo
  Gets adjusted pixels or whatever
  [^BufferedImage screen ^Number x ^Number y]
  {:post [(foo-map? %)]}
  ...)

(defn foo-map?
  True if x is a map of maps with pixel colors ...
  [x]
  ...)

That said, it would be nice if clojure.repl/doc printed type hints and 
prepost conditions. You can however use clojure.repl/source to see 
prepost conditions.


On Sunday, January 13, 2013 10:03:35 AM UTC-8, Marcel Möhring wrote:

 Hello, 

 is there a better way to document a function if I want to include type 
 information 
 and parameters for in/out? 

 Currently I am using this approach but it feels rather clumsy: 

 Takes a screen and a pixel coordinate and returns 
 a map of maps with pixel colors 
 and adjusted pixel coordinates around the pixel. 
 Directions are degree numbers from 0 to 315. 
 in: screen (BufferedImage), x (Number), y (Number) 
 out: map of maps ({direction (Number) {:color (Number) :x (Number) 
 :y (Number)}}) 

 Are there any better ways? 

 Thanks, 
 Marcel 



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

Re: ANN: fipp - Fast Idiomatic Pretty-Printer

2013-01-12 Thread Brandon Bloom
Done: 
https://github.com/brandonbloom/fipp/commit/e7ae2cce42b9f0baf0f8e242b669fc19aad57ed3

Thanks!

On Saturday, January 12, 2013 4:23:41 AM UTC-8, Michael Klishin wrote:

 Brandon,

 Please provide dependency information in the README, otherwise Clojure 
 beginners won't be able to use your project.

 If you need an example:
 https://github.com/michaelklishin/welle#maven-artifacts

 -- 
 MK

 http://github.com/michaelklishin
 http://twitter.com/michaelklishin
  

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

ANN: fipp - Fast Idiomatic Pretty-Printer

2013-01-11 Thread Brandon Bloom
Hi all,

I decided to create a new pretty printer in the spirit of Data All The 
Things! And it's fast too!

Fipp, the Fast Idiomatic Pretty-Printer for Clojure, is a pretty printer 
with linear runtime and bounded space requirements. Unlike clojure.pprint's 
side-effectual API, Fipp is configured by pretty print documents that are 
similar to Hiccup HTML templates. It's based on some fancy pants research 
pretty printers from the Haskell world.

You can see my implementation and lots more notes 
at https://github.com/brandonbloom/fipp

Let me know what you guys think.

Cheers,
Brandon

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

Re: symbolic protocols

2013-01-08 Thread Brandon Bloom


 The defmulti would be closer to 

  (defmulti mm first) 

 because we need to dig into the list to get the first symbol. 


I don't think that there is anything stopping you from creating such a code 
walker now. Maybe you should built a proof of concept to demonstrate some 
use cases concretely? 
 

 But there need to be a way to recurse as well, if you want to 
 interprete the whole expression. That part is hard to capture in the 
 multimethod. 


Look for a paper titled Expansion-Passing Style: A General Macro 
Mechanism for ideas on how to handle recursion and expansion dispatch.

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

Re: What's the current status of Clojure-in-Clojure?

2013-01-08 Thread Brandon Bloom
ClojureScript has the best chance of forming a base of Clojure-in-Clojure. 
I believe David Nolen would consider any patches that help decouple us from 
JavaScript.

On Tuesday, January 8, 2013 3:44:16 PM UTC-8, Thor wrote:

 I think this would be a fun project to contribute to, but a few searches 
 haven't led me to where the development is taking place. Is it just part of 
 the main Clojure github project?

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

Re: core.matrix proposal

2013-01-08 Thread Brandon Bloom
There's a bunch of useful operations that games  animation systems perform 
frequently that are less common in other uses of linear algebra. For 
example: linear and spline interpolations.

The DirectXMath library is worth 
studying: 
http://msdn.microsoft.com/en-us/library/windows/desktop/hh437833(v=vs.85).aspx
Similarly, the XNA math 
libraries: 
http://msdn.microsoft.com/en-us/library/bb196942(v=xnagamestudio.35).aspx

On Sunday, January 6, 2013 11:13:04 PM UTC-8, Mikera wrote:

 Yep, the idea is to be flexible enough to support many different 
 implementations.

 The pure Clojure version should be very easy to use and flexible since it 
 uses regular Clojure persistent vectors. The trade-off is of less 
 performance compared to the Java/native implementations.

 As an added bonus, writing a pure Clojure version is useful for testing / 
 validating the design of the API before we extend it to more complex 
 implementations.

 On Sunday, 6 January 2013 12:54:08 UTC+8, Rob Lachlan wrote:

 I really like this idea -- I think there's a need for a dedicated matrix 
 computation library in clojure.  I really like the idea of having matrix 
 operations implemented in clojure (I think that you have this in 
 persistent_vector.clj) but also being able to call on java libraries.


 On Saturday, January 5, 2013 2:00:23 AM UTC-8, Mikera wrote:

 Hello all,

 I've been experimenting with a common API / abstraction for matrix and 
 vector maths in Clojure:

   https://github.com/mikera/matrix-api

 The idea is:
  - Provide a clear, consistent API for matrix and vector operations
  - Support multiple different underlying implementations (e.g. native 
 code via JBLAS vs pure Java like vectorz-clj)
  - Provide a base which other libraries that need to consume matrices 
 can build upon (e.g. Incanter)
  - Offer good performance while still presenting a reasonably flexible 
 high level API

 I think this could be very useful for the Clojure community, especially 
 given the interest in big data, simulations, machine learning, 3D graphics 
 etc. If it goes well and there is enough interest, I guess that this could 
 form the basis for a future core.matrix library.

 Comments / ideas / patches welcome.

   Mike.



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

Re: Clojure 1.5.0 RC 1

2013-01-01 Thread Brandon Bloom
 Please test it.

I just tried it out and was really bummed to discover 
that http://dev.clojure.org/jira/browse/CLJ-873 was not merged. That's the 
clojure.core// division symbol issue.

It's a pretty straightforward patch that fixes a real problem for 
ClojureScript and a few other random libraries that I work with. The 
discussion seems all positive, so I'm not sure why it didn't make the cut 
for 1.5

Other than that, it seems to be working smoothly for my projects.

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

Re: What would you use a #[] data literal for?

2012-12-31 Thread Brandon Bloom
 Significant performance gain is achieved when destructuring by skipping 
nth and directly calling type fields instead.

Have you also patched the destructuring mechanism?

 Concrete vector implementation is not known when destructuring, so I'm 
left with a custom reader literal.

How does the reader literal affect the site of destructuring? Are you also 
using the #[] literal for the destructure target? ie:

(let [#[x y] #[1 2]] ...)

If so, then wouldn't to make more sense to rely on type hints?

(let [[x y] ^Tuple2 (tuple 1 2)] ...)

I guess, potentially, you could rely on the explicit vector type for small 
literals:

(let [[x y] ^Vec2 [1 2]] ...)

But that seems like a bad idea

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

Re: What would you use a #[] data literal for?

2012-12-30 Thread Brandon Bloom
Wouldn't it be better to implement this as an automatic optimization, just 
like PersistentArrayMap vs PersistentHashMap ?

fwiw, I'm cautiously in favor of #[] being used for queues.

On Sunday, December 30, 2012 3:45:24 AM UTC-8, Jozef Wagner wrote:

 I use it in Clojurescript for a custom tuple type. 

 For small number of items, deftypes are way faster to create and access 
 than PersistentVectors. I use tuple type e.g. for returning multiple values 
 from a function. Implementing #[] allowed me to have a compact syntax for 
 creating and destructuring such tuples.

 (defn foo [a b] 
   #[(+ a b) (- a b) (* a b)])

 (defn foo []
   (let [#[plus minus times] (foo 1 2)]
 (str bla bla plus blaah minus)))

 JW

 On Friday, December 28, 2012 11:15:52 PM UTC+1, vemv wrote:

 I was just wondering - given that we have the #() and #{} literals, why 
 not a #[] as well? Queues look like a good fit.



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

Re: I'm curious if the development of native Clojurescript macros is in progress

2012-12-28 Thread Brandon Bloom
 So I'm curious if the adoption of native macros into Clojurescript is in 
progress by contributors.

The only visibile progress I know of here is Kanaka's self hosting fork: 
https://github.com/kanaka/clojurescript

If not, is it on the plan at least? Or is it rejected after some discussion?


The goal is to get the official ClojureScript compiler self-hosting is 
2013, but there are a lot of stickly little issues and the few active 
contributors are busy people. Help is welcome!

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

Re: ANN: clj-schema, Schemas For Clojure Maps

2012-12-09 Thread Brandon Bloom
I wanted something like this to create an AST validator for ClojureScript! 
Will have to find some time to study your approach.

On Sunday, November 25, 2012 3:22:04 PM UTC-8, Alex Baranosky wrote:

 Clj-schema is a library for defining and validating schemas for maps, as 
 well as for using those schemas to create valid test data.  We've been 
 using this in production for at least a few months now, at Runa.

 https://github.com/runa-dev/clj-schema

 The main benefits I've found from using this library are:
 * validating the inputs to the application: validating Ring request params 
 and config files
 * validating before storing maps into the DB
 * using the clj-schema.fixtures library to create valid test data that 
 stays valid.  So as the standard form of a map changes over time the tests 
 will stay in sync with those changes automatically.
 * there are some code-readability benefits as well - any developer can 
 pretty quickly see what certain kinds of maps tend to look like.

 There's more info in the README:
 https://github.com/runa-dev/clj-schema/blob/master/README.md

 Future possibilities:
 * auto-generating test data from clj-schema fixtures
 * being able to create schemas for sets and sequences (currently a schema 
 is always for a map)

 Contributors welcome.

 Alex


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

Re: Clojure raytracing scene description language

2012-12-09 Thread Brandon Bloom
Are you only interested in static scenes? Or are you interested in 
simulations too?

On Sunday, December 9, 2012 4:03:36 PM UTC-8, Mikera wrote:

 Hi all,

 I'm working on a hobby project to implement a Clojure raytracer, something 
 along the lines of POV-Ray:
 https://github.com/mikera/enlight

 It's a a fairly preliminary stage right now, but I'm interested in ideas 
 on how to create the scene description language. Roughly the objectives are:
 - Allow an intuitive, declarative definition of a 3D scene
 - Allow parts of the scene to be generated programatically (e.g. randomly 
 duplicating objects!)
 - Allow mathematical functions and textures to be expressed (probably 
 using clisk - https://github.com/mikera/clisk)
 - Enable the scene to be compiled down to an optimised scene graph for 
 rendering
 - Be reasonably concise as a DSL

 I'm thinking of something like:

 [
 [:camera :position [0 0 -10] :look-at [0 0 0]]   ;; a camera for the 
 scene
 [:sphere :radius 1 :translate [0 2 0] :colour red]  ;;  a translated red 
 shere
 [:box [0 0 0] [1 1 1] :colour (function [1 x y])]   ;; a box with a 
 procedural colour function
 (for [i [2 3 4]] [:box [i 1 1] [(inc i) 2 2]])  ;; generate multiple boxes 
 with a parameterised position
 ]

 Any thoughts / ideas / feedback?


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

Re: Can anyone point me to that library that supports quasiquoting without full namespace expansion?

2012-12-02 Thread Brandon Bloom
I just published a new 0.2.0-SNAPSHOT that includes a fix parallel to Rich 
Hickey's change to handling of records in Clojure 1.5.

On Sunday, December 2, 2012 10:27:46 AM UTC-8, Conrad wrote:

 Never mind, I just found it on clojars. It is: 
 https://github.com/brandonbloom/backtick

 On Sunday, December 2, 2012 12:24:29 PM UTC-6, Conrad wrote:

 I remember seeing it somewhere recently but I can't find it now...

 As you probably know, if you quasiquote in clojure it automatically adds 
 namespaces:

  `[foo ~1]
 [mylibrary.core/foo 1]

 The library I am looking for lets you write:

  (template [foo ~1])
 [foo 1]

 Thanks for your help!



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

Re: Can CLJS functions have metadata?

2012-11-21 Thread Brandon Bloom
Fixed: http://dev.clojure.org/jira/browse/CLJS-359

On Saturday, August 25, 2012 12:49:47 AM UTC-7, Shantanu Kumar wrote:

 Hi,

 I noticed that `with-meta` is not working on function objects in CLJS. 
 Compilation fails with the following error:

 Error: No protocol method IWithMeta.-with-meta defined for type function: 
 function (maps, x) {
   return x;
 }

 I tried it out on the REPL and found the following:

 -- BEGIN: repl-rhino --
 ClojureScript:cljs.user (with-meta #(do :foo) {:foo :bar})
 Error evaluating: (with-meta (fn* [] (do :foo)) {:foo :bar}) :as 
 cljs.core.with_meta.call(null,(function (){\nreturn 
 \\\uFDD0'foo\;\n}),cljs.core.ObjMap.fromObject([\\\uFDD0'foo\],{\\\uFDD0'foo\:\\\uFDD0'bar\}));\n
 org.mozilla.javascript.JavaScriptException: Error: No protocol method 
 IWithMeta.-with-meta defined for type function: 
 function () {
 return \ufdd0'foo;
 }
  (cljs/core.cljs#222)
 at cljs/core.cljs:222 (anonymous)
 at cljs/core.cljs:214 (_with_meta)
 at cljs/core.cljs:806 (with_meta)
 at cljs repl:2 (anonymous)
 at cljs repl:2

 nil
 -- END: repl-rhino --

 Is this supposed to be a bug? I can file an issue on JIRA if so.

 Shantanu


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

core.logic and other types of solvers

2012-10-26 Thread Brandon Bloom
There was a mention of linear programming in this 
threadhttps://groups.google.com/d/topic/clojure/oFCk5rOQUUo/discussionabout 
core.logic.

I wonder: Is it possible to compose the techniques?

I've only just started digging into core.logic (ie today), but I've messed 
with less-general constraint systems in the past. My prior experience is 
primarily with physics engines in games, but also some linear solvers. In 
particular, I'm thinking about future efforts in GUI applications.

Consider for Adobe's Adam and 
Evehttp://stlab.adobe.com/group__asl__overview.html#asl_overview_adam_and_eve_architecture,
 
which are a property model and layout engine respectively. Adam uses a 
specialized solver for resolving multi-way dataflow; Eve uses a linear 
solver for constraining the geometry of UI widgets.

I'd suspect the specialized solvers provide performance 
and predictability tuned to their particular use cases. It's worth noting 
is that both components must provide interactive performance. I wonder if 
there is some way to leverage the infrastructure of core.logic backed by 
different types of solvers.


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

Re: thinking in data, polymorphism, etc.

2012-10-25 Thread Brandon Bloom
 I have a fairly common scenario where I have a set of operations that 
need to work on two types of data (not data types in the clojure sense) 
that have different internal structure (i.e. maps with different keys).

Could you please be a little more concrete? If you provide a specific 
example, we can provide some specific solutions accompanied by some 
rationale to help you solve similar problems in the future.

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

Re: thinking in data, polymorphism, etc.

2012-10-25 Thread Brandon Bloom


 (fn [_ _]  ;dispatch-function checks for OS - ignores args
 (let [os (System/getProperty os.name)]
   (if (.startsWith os Mac OS) :Linux  (keyword os)


This seems like a very poor use of multi-methods. Multi-methods exist to 
provide both dynamic and open dispatch. In this case, the dispatch function 
is completely static.

If you don't need dynamism or openness, then you're better off with a 
simple case form at the top level:

(case platform
  :linux (def halt [root-pwd minutes-after] ...)
  :windows ...
  ...
  (def halt [ args] (throw ...)))

If you prefer the appearance of top-level forms, or need the openness, you 
could pretty easily implement a static version of defmulti  defmethod 
which ensure you only pay the dispatch cost once at startup, rather than on 
every invocation.

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

  1   2   >