Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2015-04-24 Thread Joel Holdbrooks
On Saturday, April 11, 2015 at 8:40:07 AM UTC-7, kovas boguta wrote:
 On Sat, Apr 11, 2015 at 10:46 AM, Malcolm Sparks mal...@juxt.pro 
 
 So, in summary, I think it would be useful to have a single 'default' routing 
 library in Clojure that supported isomorphism and was built on protocols, as 
 a minimum. Now that Clojure is attracting so many new users, it would be 
 great to discuss the outstanding differences between all the routing 
 libraries and try to drive some consensus as to what a combined library would 
 include.
 
 
 I'm on board with most of this post (and the Bidi approach in particular), 
 I'm not sure consensus is necessary but I'll throw in my 2 cents. 
 
 
 - Please, no more defroute etc macros 
 - Routing should be composable. I want to take some routes and just plug them 
 in at some level of my existing hierarchy. 
 - Middleware should be decoupled from the routes as much as possible. The 
 process for associating middleware to the request should be 
 parallel/complementary to resolving the resource. Maybe middleware is not 
 the best concept to begin with. 
  

I'm definitely in agreement that the approach Bidi and Silk have taken is much 
better than what exists on master in Secretary. Most of the undesirable aspects 
pointed out about Secretary have largely been resolved on the 2.0.0 branch for 
Secretary. The other desirable qualities found in Silk (unsure about Bidi) have 
been in existence in Secretary for sometime but the library was not oriented 
properly to make those features idiomatic.

I do not agree that defroute etc macros should be eliminated from the 
picture. There is nothing inherently wrong with authoring and/or encouraging 
their use. It is only an issue when those macros are the only way to use a 
library effectively. People enjoy using DSL's (until they hit a wall with them) 
and for small to medium scale projects they are completely appropriate and just 
as effective as the it's just data style of routing for getting shit done.

I will also say the same about middleware. Although I do not like the 
middleware pattern I do not believe it is worth throwing out the window just 
because it is not the best concept. It is a familiar pattern and sometimes 
that familiarity is worth avoiding the friction of learning a something else 
for some individuals and teams.

tl;dr retaining features that people enjoy using and are familiar with is fine 
so long as there is a composable API underneath it that can be used 
alternatively.

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

2015-04-11 Thread Malcolm Sparks
Author of bidi here. 

In his blog article, REST Litmus Test for Web Frameworks - 
https://www.innoq.com/blog/st/2010/07/rest-litmus-test-for-web-frameworks/ 
- Stefan Tilkov asks of REST libraries: 

Is there an easy way to produce links that point back resources 
identified by whatever means the framework exposes (such as some form of 
routing)?

The idea of bidi came out of a discussion I had with Philipp Meier about 
Liberator's support for hyperlinks, to meet Stefan's litmus test. Philipp 
argued that while he felt Liberator should remain independent of the URI 
routing layer, any routing layer that was part of a proper REST API should 
make it easy, and reliable, to produce hyperlinks. Now that REST APIs are a 
mission-critical part of many websites, I believe that producing reliable 
working hyperlinks is too important to be left to *ad-hoc* string 
concatenation, however disciplined. If the community are to standardise on 
a routing library, I feel it should be one that support isomorphism (as 
Pedestal, bidi and Silk do)

The design of bidi was heavily influenced by my experiences with Pedestal 
routing, which demonstrated the value of a data structure over macros. 
Unfortunately, I felt that Pedestal's integration of routing with its 
interceptor definitions meant that you couldn't extract an independent 
routing library from it. I also didn't really like the terse versus 
expanded format, and wanted bidi to have a single format, one that would 
strike the balance between being easy to write by hand and easy to 
generate. I'm still a fan of Pedestal but wish it had been offered from the 
beginning as a set of independent libraries which worked well together. 
'All or nothing' is never a great choice.

Silk was heavily influenced by bidi, as Dom has described earlier in this 
thread, and if you compare their source code they are very similar. Now 
that bidi supports ClojureScript, the key difference is in syntax and the 
fact that bidi routing is hierarchical, whereas Silk allows you to dispatch 
at a number of levels, as far as I can tell. The syntax differences are 
such that you could probably create some records and record constructors, 
satisfying the bidi protocols, that allowed you to layer Silk's syntax over 
bidi, a sort of 'silk-flavored-bidi' if you will. 

The hierarchical design of bidi was driven by the desire to support 
modularity- when you have multiple people or teams working on different 
parts of a website, it helps to be able to 'remount' one of the parts 
without anything breaking. Also, bidi excludes support for dispatching on 
differences in query parameters, as I believe that query parameters 
shouldn't, by definition, determine which resource is identified by the 
URI. Opinionated? Maybe!

Until recently, the way that you did isomorphism in bidi was to use a 
handler as an argument to path-for, which would return the route. That 
required URI-forming code (like views) to have access to all the handlers 
in the system - not great. I played around with using keywords, with some 
funky record injection in the route structure to convert them to handlers 
during dispatch, but then I looked at Secretary's 'named routes' and 
slapped myself very hard on the forehead (doh!). Since then, bidi has a 
'tag' function that you use to tag a handler with a keyword, from then on 
you can use that keyword when forming routes instead of the handler itself.

bidi will undergo some rework when the new reader conditionals of Clojure 
1.7 arrive out of beta, which I expect will replace its use of cljx. 
Otherwise, bidi itself is going to remain fairly stable. It is relied on by 
many production websites, such as https://www.onthemarket.com/, so can't 
change radically. However, building on protocols opens up numerous ways of 
extending bidi. For example, we're working on a new REST library 
(http://yada.juxt.pro) which combines bidi routing structures with resource 
maps to generate published Swagger definitions. This is achieved by adding 
a couple of new small records which satisfy bidi's protocols, demonstrating 
the endless flexibility of Clojure's protocols feature. So I'd hope that a 
'standard' routing library would be built on protocols too.

So, in summary, I think it would be useful to have a single 'default' 
routing library in Clojure that supported isomorphism and was built on 
protocols, as a minimum. Now that Clojure is attracting so many new users, 
it would be great to discuss the outstanding differences between all the 
routing libraries and try to drive some consensus as to what a combined 
library would include.









On Saturday, April 11, 2015 at 1:08:30 AM UTC+1, Daniel Jomphe wrote:

 This thread over Silk, Bidi and Secretary has been very interesting. I 
 looked at the three projects to see how they evolved after this thread 
 started. Any cross-pollination or progress worth sharing now that I've 
 missed? 

 From what I could gather: 

 * Secretary is evolving 

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2015-04-11 Thread kovas boguta
On Sat, Apr 11, 2015 at 10:46 AM, Malcolm Sparks malc...@juxt.pro

 So, in summary, I think it would be useful to have a single 'default'
 routing library in Clojure that supported isomorphism and was built on
 protocols, as a minimum. Now that Clojure is attracting so many new users,
 it would be great to discuss the outstanding differences between all the
 routing libraries and try to drive some consensus as to what a combined
 library would include.


I'm on board with most of this post (and the Bidi approach in particular),
I'm not sure consensus is necessary but I'll throw in my 2 cents.

- Please, no more defroute etc macros
- Routing should be composable. I want to take some routes and just plug
them in at some level of my existing hierarchy.
- Middleware should be decoupled from the routes as much as possible. The
process for associating middleware to the request should be
parallel/complementary to resolving the resource. Maybe middleware is not
the best concept to begin with.

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

2015-04-10 Thread Daniel Jomphe
This thread over Silk, Bidi and Secretary has been very interesting. I looked 
at the three projects to see how they evolved after this thread started. Any 
cross-pollination or progress worth sharing now that I've missed?

From what I could gather:

* Secretary is evolving towards a conservative 2.0 and won't, after all, be 
re-implemented on top of Silk. This may be a good thing: not bringing more 
transitive dependencies in all projects using Secretary. Thus, Secretary would 
remain the first stop for Compojure-like easy routing in ClojureScript apps.
* Bidi was already quite mature and comparable to Silk and remains as 
attractive as it was, especially with regard to its established production 
usage and corporate backing.
* Silk's development slowed for some time and this may make for a good occasion 
to reflect on its state and the value of its ambitions (which seemed quite 
interesting to me).
* I would add, from distant memory, that Pedestal's isomorphic routing is 
planned to be extracted into a self-contained library. Judging from the advent 
of Clojure 1.7's reader conditionals and Om's model 2 for which I'm expecting 
an announcement in a few weeks, I suppose Cognitect may start providing again 
their leadership on the front-end. Either they start recommending something 
like Bidi or Silk, or they (more probably) reader-cond-port their routing lib 
to ClojureScript.

I'm watching this space and thanks for any comments.

On Sunday, October 12, 2014 at 11:28:13 PM UTC-4, Dom Kiva-Meyer wrote:
 Thanks for the experience reports, Dylan!
 
 
 Colin, Silk is Ring-compatible and meant to be used as a single replacement 
 for both Compojure and Secretary (or any other server/browser routing 
 combination with incompatible syntax and semantics). But, as Dylan said, it's 
 totally fine to use it in conjunction with Compojure instead of replacement. 
 Silk should also work fine with all Ring middleware.
 In the next version, Silk will have a more familiar and mostly 
 Compojure-compatible syntax for defining routes. My hope is that this will 
 make it easier to translate Compojure examples/code to Silk.

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

2014-10-14 Thread Colin Yates
Thanks both.

On 13 October 2014 04:27, Dom Kiva-Meyer li...@domkm.com wrote:

 Thanks for the experience reports, Dylan!

 Colin, Silk is Ring-compatible and meant to be used as a single
 replacement for both Compojure and Secretary (or any other server/browser
 routing combination with incompatible syntax and semantics). But, as Dylan
 said, it's totally fine to use it in conjunction with Compojure instead of
 replacement. Silk should also work fine with all Ring middleware.
 In the next version, Silk will have a more familiar and mostly
 Compojure-compatible syntax for defining routes. My hope is that this will
 make it easier to translate Compojure examples/code to Silk.


 On Fri, Oct 10, 2014 at 9:25 AM, Dylan Butman dbut...@gmail.com wrote:

 I’ve been using silk in conduction with compojure. Most middleware aren’t
 compojure specific, but I’ve just found it easier to stick with base level
 compojure routes and then pass uris to silk for pattern matching. This is
 mostly because there is such a wealth of documentation and examples to draw
 from with compojure. For example, session management, login flows with
 friends, etc have already been solved and there is plenty of code to strip.
 Silk wouldn’t complicated them (in some cases it might simplify), but when
 the wheel rolls, push it.


 I’ve been approaching silk solely as a library for pattern matching
 within the specific domain of urls, which it does very cleanly. More
 importantly, it’s currently the only one that does it in both clojure and
 clojurescript, which makes it possible to have the same routing code used
 on client and server, which is necessary if you want to do server
 rendering, or more complicated websocket updates.

 --
 Note that posts from new members are moderated - please be patient with
 your first post.
 ---
 You received this message because you are subscribed to the Google Groups
 ClojureScript group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescr...@googlegroups.com.
 Visit this group at http://groups.google.com/group/clojurescript.


  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 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/D95anPmhNhU/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to
 clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


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


Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-10-12 Thread Dom Kiva-Meyer
Thanks for the experience reports, Dylan!

Colin, Silk is Ring-compatible and meant to be used as a single replacement
for both Compojure and Secretary (or any other server/browser routing
combination with incompatible syntax and semantics). But, as Dylan said,
it's totally fine to use it in conjunction with Compojure instead of
replacement. Silk should also work fine with all Ring middleware.
In the next version, Silk will have a more familiar and mostly
Compojure-compatible syntax for defining routes. My hope is that this will
make it easier to translate Compojure examples/code to Silk.


On Fri, Oct 10, 2014 at 9:25 AM, Dylan Butman dbut...@gmail.com wrote:

 I’ve been using silk in conduction with compojure. Most middleware aren’t
 compojure specific, but I’ve just found it easier to stick with base level
 compojure routes and then pass uris to silk for pattern matching. This is
 mostly because there is such a wealth of documentation and examples to draw
 from with compojure. For example, session management, login flows with
 friends, etc have already been solved and there is plenty of code to strip.
 Silk wouldn’t complicated them (in some cases it might simplify), but when
 the wheel rolls, push it.


 I’ve been approaching silk solely as a library for pattern matching within
 the specific domain of urls, which it does very cleanly. More importantly,
 it’s currently the only one that does it in both clojure and clojurescript,
 which makes it possible to have the same routing code used on client and
 server, which is necessary if you want to do server rendering, or more
 complicated websocket updates.

 --
 Note that posts from new members are moderated - please be patient with
 your first post.
 ---
 You received this message because you are subscribed to the Google Groups
 ClojureScript group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescr...@googlegroups.com.
 Visit this group at http://groups.google.com/group/clojurescript.


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

2014-10-08 Thread Dom Kiva-Meyer
Thanks for putting that together, Dylan. Looking forward to seeing what
you're building. :)

Olli, please feel free to reach out to me (email, Twitter, GitHub issue,
whatever) if you have any questions. Thanks for trying it out!

On Tue, Oct 7, 2014 at 12:05 PM, Dylan Butman dbut...@gmail.com wrote:

 Sorry i don't have time to really explain any of this...

 but here's some code I pulled out of a recent project. maybe it'll be
 helpful to you. unfortunately I can't share the whole project.

 https://gist.github.com/pleasetrythisathome/7adbdc9c8b7ab689df45

 --
 Note that posts from new members are moderated - please be patient with
 your first post.
 ---
 You received this message because you are subscribed to the Google Groups
 ClojureScript group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescr...@googlegroups.com.
 Visit this group at http://groups.google.com/group/clojurescript.


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

2014-08-10 Thread Dom Kiva-Meyer
Good stuff, Marc! Thanks for the feedback.

That behavior in `composite` is a bug. Thanks for reporting.

Sorting the query map seems reasonable. Good suggestion!

Thanks again, Marc.



On Sat, Aug 9, 2014 at 8:05 PM, marc marc.bosc...@gmail.com wrote:

 I've been playing and like Silk a lot!

 However the following I find curious as I'm wondering what the intended
 behaviour should be:
 user= (silk/match (silk/composite [user- (silk/integer :id) -fred (
 silk/option :this that) s]) user-42-fredjs)
 {:id 42, :this j}

 user= (silk/match (silk/composite [user- (silk/integer :id) -fred (
 silk/option :this that) s]) user-42-freds)
 nil


 I would have thought the last one would have produced:
 user= (silk/match (silk/composite [user- (silk/integer :id) -fred (
 silk/option :this that) s]) user-42-freds)
 {:id 42, :this that}



 My only other suggestion, not worthy of a pull request, is the following:

 (defn domkm.silk/encode-query
  Takes a query map.
  Returns a string of query pairs encoded and joined.
  [query]
  (- query
(apply into sorted-map) ; ensure consistent ordering to improve
 cache-ability of URLs...
(map (fn [[k v]] (str (encode k) = (encode v
(str/join )))


 Regards,

 Marc


 On Sunday, 10 August 2014 05:00:50 UTC+10, DomKM wrote:

 Hi Allen,

 Thanks for the feedback!

 1) This, and precompiling regexes where possible, is my intention with
 Silk.

 2) I'm not convinced that requiring fully-qualified routes would be a
 feature. Let's say we have route A which should match /foo/bar and
 route B which should match /foo/*. If these routes are unordered, route B
 would have to additionally be constrained with `(not= * bar)`. It
 seems like this could make route definition very painful when working in
 a large application with many routes that match on multiple parts of the
 URL.


 On Sat, Aug 9, 2014 at 10:06 AM, Allen Rohner aro...@gmail.com wrote:

 I'd like to thank everyone in the community for both Silk, and
 Secretary.

 I'll throw out some (uninvited) feature requests I'd love to see in a
 future route-matching library.

 1) Make trie-based route dispatching possible. A feature pedestal
 has/will soon have, is to compile the routing table into trie, rather than
 the compojure-style wrapped functions. This can have a nice speedup on busy
 applications. I'm not asking anyone to write this code, just consider the
 design such that it's possible to add this behavior in the future.

 2) I'll claim that making route definition order is a misfeature. Routes
 should always be fully qualified, such that re-arranging them doesn't
 affect routing behavior (and therefore, the route table should be an
 unordered collection, like a map or set, not a vector). One nice
 readability reason for this is that if your route order does matter, than
 at least one route definition is lying about which routes it actually
 dispatches on.

 Just things to consider :-)

 Thanks,
 Allen


 On Thursday, August 7, 2014 9:31:56 PM UTC-5, DomKM wrote:

 Thanks for your feedback, Dylan!

 If you define routes with :path and :query, will the route
 match/unmatch with undefined query keys? If so, how are they handled? If
 not, I'd suggest making query matching optional, where nils are 
 substituted.


 I'm not entirely sure what you mean, but I'll give it a shot. Please
 provide some example code if I answered the wrong question.

 `nil` is a pattern that matches anything. If your URL pattern query is
 `nil` then the URL query will not be checked.
 A map is a pattern that matches its values against the values of
 another map. Therefore, `nil` and `{}` are equivalent when used as a query
 pattern.
 You can make a query value pattern optional by wrapped it with
 `silk/option`.

 It's a little unclear how your matching functions relate to route. It
 looks like Silk always breaks at / in path and matches, is that correct?


 Yes. There is a URL type in Silk and matching is done against instances
 of it. The path is represented as a vector of segments.

 The readme is currently very deficient and I apologize for that.

 There are some really good things in secretary. What do you think about
 them?
 Splat, regex, format matchers.


 In terms of regex matching, Silk used to have a built-in regex pattern
 but I removed it when I made a big architectural change. I forget why I
 removed it, but I'll re-add it since it does seem like a very common
 requirement.

 Currently, part of Secretary's splat exists as a built-in Silk pattern.
 For example, `(silk/composite [foo :* bar])` would match
 fooanythingbar and return `{:* anything}`. The `:*` isn't special; it's
 just a keyword. Format is just a specific case of composite:
 `(silk/composite [:* . :format])`. Unlike Secretary, Silk does not have a
 built-in special syntax for string patterns. This is because special syntax
 strings are not composable and, since Silk matches against unencoded
 strings, who am I to say you can't have : or * in your URL paths? ;)

 

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-08-09 Thread Allen Rohner
I'd like to thank everyone in the community for both Silk, and Secretary. 

I'll throw out some (uninvited) feature requests I'd love to see in a 
future route-matching library. 

1) Make trie-based route dispatching possible. A feature pedestal has/will 
soon have, is to compile the routing table into trie, rather than the 
compojure-style wrapped functions. This can have a nice speedup on busy 
applications. I'm not asking anyone to write this code, just consider the 
design such that it's possible to add this behavior in the future. 

2) I'll claim that making route definition order is a misfeature. Routes 
should always be fully qualified, such that re-arranging them doesn't 
affect routing behavior (and therefore, the route table should be an 
unordered collection, like a map or set, not a vector). One nice 
readability reason for this is that if your route order does matter, than 
at least one route definition is lying about which routes it actually 
dispatches on. 

Just things to consider :-)

Thanks,
Allen

On Thursday, August 7, 2014 9:31:56 PM UTC-5, DomKM wrote:

 Thanks for your feedback, Dylan!

 If you define routes with :path and :query, will the route match/unmatch 
 with undefined query keys? If so, how are they handled? If not, I'd suggest 
 making query matching optional, where nils are substituted.


 I'm not entirely sure what you mean, but I'll give it a shot. Please 
 provide some example code if I answered the wrong question.

 `nil` is a pattern that matches anything. If your URL pattern query is 
 `nil` then the URL query will not be checked.
 A map is a pattern that matches its values against the values of another 
 map. Therefore, `nil` and `{}` are equivalent when used as a query pattern.
 You can make a query value pattern optional by wrapped it with 
 `silk/option`. 

 It's a little unclear how your matching functions relate to route. It 
 looks like Silk always breaks at / in path and matches, is that correct?

  
 Yes. There is a URL type in Silk and matching is done against instances of 
 it. The path is represented as a vector of segments.

 The readme is currently very deficient and I apologize for that.

 There are some really good things in secretary. What do you think about 
 them?
 Splat, regex, format matchers.


 In terms of regex matching, Silk used to have a built-in regex pattern but 
 I removed it when I made a big architectural change. I forget why I removed 
 it, but I'll re-add it since it does seem like a very common requirement.

 Currently, part of Secretary's splat exists as a built-in Silk pattern. 
 For example, `(silk/composite [foo :* bar])` would match 
 fooanythingbar and return `{:* anything}`. The `:*` isn't special; it's 
 just a keyword. Format is just a specific case of composite: 
 `(silk/composite [:* . :format])`. Unlike Secretary, Silk does not have a 
 built-in special syntax for string patterns. This is because special syntax 
 strings are not composable and, since Silk matches against unencoded 
 strings, who am I to say you can't have : or * in your URL paths? ;)

 Looking at the Secretary readme, there appear to be two ways to use splat 
 that Silk currently does not have built-in support for. In Secretary, 
 /foo/* would match /foo/bar/baz and return `{:* bar/baz}`. Also, 
 /*/* would match /a/b and return `{:* [a b]}`. I keep saying 
 built-in because, while multi-segment path patterns and binding the same 
 parameter key to multiple path segments does not currently exist in Silk, 
 it is very easy to extend Silk with that functionality. You could easily 
 create a pattern that did exactly what Secretary and Clout do by default 
 and use it to match a path instead of a vector. However, I do question the 
 utility of these two features. Are either of these common requirements and, 
 if so, could I see some examples of why they are necessary or helpful? This 
 isn't rhetorical; please let me know if Silk is missing something that is 
 within its scope and is useful to most consumers.

 protocol based render function for multiple arity unmatching. this is 
 really great.


 I don't think I fully understand the use cases for this protocol. Do you 
 want to be able to look routes up by types? If so, since route names in 
 Silk can be anything, you could use a type as a name. Anyway, I put 
 together this little gist 
 https://gist.github.com/DomKM/26658b53a50e48f0be70 of ways in which 
 Silk could be used similarly to how I *think* someone might use Secretary's 
 IRenderRoute. Do these cover the use cases for that protocol?


 I also agree with everything in Joel's response and look forward to 
 working with him on improving the routing story. :)


 On Thu, Aug 7, 2014 at 2:52 PM, Joel Holdbrooks cjhold...@gmail.com 
 javascript: wrote:

 I'm in agreement that Silk is a step in the right direction. I've reached 
 out to Dom and I think we can learn a lot from each other and work together 
 to improve the routing story in Clojure 

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-08-09 Thread Dom Kiva-Meyer
Hi Allen,

Thanks for the feedback!

1) This, and precompiling regexes where possible, is my intention with Silk.

2) I'm not convinced that requiring fully-qualified routes would be a
feature. Let's say we have route A which should match /foo/bar and route
B which should match /foo/*. If these routes are unordered, route B would
have to additionally be constrained with `(not= * bar)`. It seems like
this could make route definition very painful when working in a large
application with many routes that match on multiple parts of the URL.


On Sat, Aug 9, 2014 at 10:06 AM, Allen Rohner aroh...@gmail.com wrote:

 I'd like to thank everyone in the community for both Silk, and Secretary.

 I'll throw out some (uninvited) feature requests I'd love to see in a
 future route-matching library.

 1) Make trie-based route dispatching possible. A feature pedestal has/will
 soon have, is to compile the routing table into trie, rather than the
 compojure-style wrapped functions. This can have a nice speedup on busy
 applications. I'm not asking anyone to write this code, just consider the
 design such that it's possible to add this behavior in the future.

 2) I'll claim that making route definition order is a misfeature. Routes
 should always be fully qualified, such that re-arranging them doesn't
 affect routing behavior (and therefore, the route table should be an
 unordered collection, like a map or set, not a vector). One nice
 readability reason for this is that if your route order does matter, than
 at least one route definition is lying about which routes it actually
 dispatches on.

 Just things to consider :-)

 Thanks,
 Allen


 On Thursday, August 7, 2014 9:31:56 PM UTC-5, DomKM wrote:

 Thanks for your feedback, Dylan!

 If you define routes with :path and :query, will the route match/unmatch
 with undefined query keys? If so, how are they handled? If not, I'd suggest
 making query matching optional, where nils are substituted.


 I'm not entirely sure what you mean, but I'll give it a shot. Please
 provide some example code if I answered the wrong question.

 `nil` is a pattern that matches anything. If your URL pattern query is
 `nil` then the URL query will not be checked.
 A map is a pattern that matches its values against the values of another
 map. Therefore, `nil` and `{}` are equivalent when used as a query pattern.
 You can make a query value pattern optional by wrapped it with
 `silk/option`.

 It's a little unclear how your matching functions relate to route. It
 looks like Silk always breaks at / in path and matches, is that correct?


 Yes. There is a URL type in Silk and matching is done against instances
 of it. The path is represented as a vector of segments.

 The readme is currently very deficient and I apologize for that.

 There are some really good things in secretary. What do you think about
 them?
 Splat, regex, format matchers.


 In terms of regex matching, Silk used to have a built-in regex pattern
 but I removed it when I made a big architectural change. I forget why I
 removed it, but I'll re-add it since it does seem like a very common
 requirement.

 Currently, part of Secretary's splat exists as a built-in Silk pattern.
 For example, `(silk/composite [foo :* bar])` would match
 fooanythingbar and return `{:* anything}`. The `:*` isn't special; it's
 just a keyword. Format is just a specific case of composite:
 `(silk/composite [:* . :format])`. Unlike Secretary, Silk does not have a
 built-in special syntax for string patterns. This is because special syntax
 strings are not composable and, since Silk matches against unencoded
 strings, who am I to say you can't have : or * in your URL paths? ;)

 Looking at the Secretary readme, there appear to be two ways to use splat
 that Silk currently does not have built-in support for. In Secretary,
 /foo/* would match /foo/bar/baz and return `{:* bar/baz}`. Also,
 /*/* would match /a/b and return `{:* [a b]}`. I keep saying
 built-in because, while multi-segment path patterns and binding the same
 parameter key to multiple path segments does not currently exist in Silk,
 it is very easy to extend Silk with that functionality. You could easily
 create a pattern that did exactly what Secretary and Clout do by default
 and use it to match a path instead of a vector. However, I do question the
 utility of these two features. Are either of these common requirements and,
 if so, could I see some examples of why they are necessary or helpful? This
 isn't rhetorical; please let me know if Silk is missing something that is
 within its scope and is useful to most consumers.

 protocol based render function for multiple arity unmatching. this is
 really great.


 I don't think I fully understand the use cases for this protocol. Do you
 want to be able to look routes up by types? If so, since route names in
 Silk can be anything, you could use a type as a name. Anyway, I put
 together this little gist
 

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-08-09 Thread marc
I've been playing and like Silk a lot!

However the following I find curious as I'm wondering what the intended 
behaviour should be:
user= (silk/match (silk/composite [user- (silk/integer :id) -fred (silk
/option :this that) s]) user-42-fredjs)
{:id 42, :this j}

user= (silk/match (silk/composite [user- (silk/integer :id) -fred (silk
/option :this that) s]) user-42-freds)
nil


I would have thought the last one would have produced:
user= (silk/match (silk/composite [user- (silk/integer :id) -fred (silk
/option :this that) s]) user-42-freds)
{:id 42, :this that}



My only other suggestion, not worthy of a pull request, is the following:

(defn domkm.silk/encode-query
 Takes a query map.
 Returns a string of query pairs encoded and joined.
 [query]
 (- query
   (apply into sorted-map) ; ensure consistent ordering to improve 
cache-ability of URLs...
   (map (fn [[k v]] (str (encode k) = (encode v
   (str/join )))


Regards,

Marc

On Sunday, 10 August 2014 05:00:50 UTC+10, DomKM wrote:

 Hi Allen,

 Thanks for the feedback!

 1) This, and precompiling regexes where possible, is my intention with 
 Silk.

 2) I'm not convinced that requiring fully-qualified routes would be a 
 feature. Let's say we have route A which should match /foo/bar and 
 route B which should match /foo/*. If these routes are unordered, route B 
 would have to additionally be constrained with `(not= * bar)`. It seems 
 like this could make route definition very painful when working in a 
 large application with many routes that match on multiple parts of the URL. 


 On Sat, Aug 9, 2014 at 10:06 AM, Allen Rohner aro...@gmail.com 
 javascript: wrote:

 I'd like to thank everyone in the community for both Silk, and Secretary. 

 I'll throw out some (uninvited) feature requests I'd love to see in a 
 future route-matching library. 

 1) Make trie-based route dispatching possible. A feature pedestal 
 has/will soon have, is to compile the routing table into trie, rather than 
 the compojure-style wrapped functions. This can have a nice speedup on busy 
 applications. I'm not asking anyone to write this code, just consider the 
 design such that it's possible to add this behavior in the future. 

 2) I'll claim that making route definition order is a misfeature. Routes 
 should always be fully qualified, such that re-arranging them doesn't 
 affect routing behavior (and therefore, the route table should be an 
 unordered collection, like a map or set, not a vector). One nice 
 readability reason for this is that if your route order does matter, than 
 at least one route definition is lying about which routes it actually 
 dispatches on. 

 Just things to consider :-)

 Thanks,
 Allen


 On Thursday, August 7, 2014 9:31:56 PM UTC-5, DomKM wrote:

 Thanks for your feedback, Dylan!

 If you define routes with :path and :query, will the route match/unmatch 
 with undefined query keys? If so, how are they handled? If not, I'd 
 suggest 
 making query matching optional, where nils are substituted.


 I'm not entirely sure what you mean, but I'll give it a shot. Please 
 provide some example code if I answered the wrong question.

 `nil` is a pattern that matches anything. If your URL pattern query is 
 `nil` then the URL query will not be checked.
 A map is a pattern that matches its values against the values of another 
 map. Therefore, `nil` and `{}` are equivalent when used as a query pattern.
 You can make a query value pattern optional by wrapped it with 
 `silk/option`. 

 It's a little unclear how your matching functions relate to route. It 
 looks like Silk always breaks at / in path and matches, is that correct?

  
 Yes. There is a URL type in Silk and matching is done against instances 
 of it. The path is represented as a vector of segments.

 The readme is currently very deficient and I apologize for that.

 There are some really good things in secretary. What do you think about 
 them?
 Splat, regex, format matchers.


 In terms of regex matching, Silk used to have a built-in regex pattern 
 but I removed it when I made a big architectural change. I forget why I 
 removed it, but I'll re-add it since it does seem like a very common 
 requirement.

 Currently, part of Secretary's splat exists as a built-in Silk pattern. 
 For example, `(silk/composite [foo :* bar])` would match 
 fooanythingbar and return `{:* anything}`. The `:*` isn't special; it's 
 just a keyword. Format is just a specific case of composite: 
 `(silk/composite [:* . :format])`. Unlike Secretary, Silk does not have a 
 built-in special syntax for string patterns. This is because special syntax 
 strings are not composable and, since Silk matches against unencoded 
 strings, who am I to say you can't have : or * in your URL paths? ;)

 Looking at the Secretary readme, there appear to be two ways to use 
 splat that Silk currently does not have built-in support for. In Secretary, 
 /foo/* would match /foo/bar/baz and return `{:* bar/baz}`. Also, 
 /*/* would 

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-08-07 Thread Dom Kiva-Meyer
Thanks for your feedback, Dylan!

If you define routes with :path and :query, will the route match/unmatch
 with undefined query keys? If so, how are they handled? If not, I'd suggest
 making query matching optional, where nils are substituted.


I'm not entirely sure what you mean, but I'll give it a shot. Please
provide some example code if I answered the wrong question.

`nil` is a pattern that matches anything. If your URL pattern query is
`nil` then the URL query will not be checked.
A map is a pattern that matches its values against the values of another
map. Therefore, `nil` and `{}` are equivalent when used as a query pattern.
You can make a query value pattern optional by wrapped it with
`silk/option`.

It's a little unclear how your matching functions relate to route. It looks
 like Silk always breaks at / in path and matches, is that correct?


Yes. There is a URL type in Silk and matching is done against instances of
it. The path is represented as a vector of segments.

The readme is currently very deficient and I apologize for that.

There are some really good things in secretary. What do you think about
 them?
 Splat, regex, format matchers.


In terms of regex matching, Silk used to have a built-in regex pattern but
I removed it when I made a big architectural change. I forget why I removed
it, but I'll re-add it since it does seem like a very common requirement.

Currently, part of Secretary's splat exists as a built-in Silk pattern. For
example, `(silk/composite [foo :* bar])` would match fooanythingbar
and return `{:* anything}`. The `:*` isn't special; it's just a keyword.
Format is just a specific case of composite: `(silk/composite [:* .
:format])`. Unlike Secretary, Silk does not have a built-in special syntax
for string patterns. This is because special syntax strings are not
composable and, since Silk matches against unencoded strings, who am I to
say you can't have : or * in your URL paths? ;)

Looking at the Secretary readme, there appear to be two ways to use splat
that Silk currently does not have built-in support for. In Secretary,
/foo/* would match /foo/bar/baz and return `{:* bar/baz}`. Also,
/*/* would match /a/b and return `{:* [a b]}`. I keep saying
built-in because, while multi-segment path patterns and binding the same
parameter key to multiple path segments does not currently exist in Silk,
it is very easy to extend Silk with that functionality. You could easily
create a pattern that did exactly what Secretary and Clout do by default
and use it to match a path instead of a vector. However, I do question the
utility of these two features. Are either of these common requirements and,
if so, could I see some examples of why they are necessary or helpful? This
isn't rhetorical; please let me know if Silk is missing something that is
within its scope and is useful to most consumers.

protocol based render function for multiple arity unmatching. this is
 really great.


I don't think I fully understand the use cases for this protocol. Do you
want to be able to look routes up by types? If so, since route names in
Silk can be anything, you could use a type as a name. Anyway, I put
together this little gist
https://gist.github.com/DomKM/26658b53a50e48f0be70 of ways in which Silk
could be used similarly to how I *think* someone might use Secretary's
IRenderRoute. Do these cover the use cases for that protocol?


I also agree with everything in Joel's response and look forward to working
with him on improving the routing story. :)


On Thu, Aug 7, 2014 at 2:52 PM, Joel Holdbrooks cjholdbro...@gmail.com
wrote:

 I'm in agreement that Silk is a step in the right direction. I've reached
 out to Dom and I think we can learn a lot from each other and work together
 to improve the routing story in Clojure overall.

  There are some really good things in secretary. What do you think about
 them?
  Splat, regex, format matchers.
  protocol based render function for multiple arity unmatching. this is
 really great.

 These are definitely nice things and I'm willing to bet Silk would be
 capable of supporting some of them.

 It's obvious to me to that if we can iron out the details with Silk,
 Secretary could built on top of it as a higher level interface while at the
 same time taking advantage of what Silk has to offer. It might mean some
 breaking changes in Secretary but those were already slated anyway.

 --
 Note that posts from new members are moderated - please be patient with
 your first post.
 ---
 You received this message because you are subscribed to the Google Groups
 ClojureScript group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescr...@googlegroups.com.
 Visit this group at http://groups.google.com/group/clojurescript.


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

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-08-06 Thread Dom Kiva-Meyer
Hi Joel,

Thanks for your feedback. Off topic, but Garden is awesome and Ankha has
been indispensable when developing Om applications! Thanks for those.

I didn't complain or suggest a patch because, aside from Bidi, I didn't
find a Clojure or ClojureScript routing library that I could conceive of
fitting *my criteria* without fundamental, completely breaking alterations
-- alterations that warrant a new library, not a new version number. I care
about compatibility, extensibility, bidirectionally, purity, transparency,
and decoupling -- which is why I wrote Silk.

Since you brought up Secretary as a routing library that could potentially
be made isomorphic, I'll compare it to Silk as I did with Bidi. I am not as
familiar with Secretary as I am with Bidi, and it looks to have changed
since I last used it, so please do correct me if I say anything incorrect
or misleading.

In terms of commonalities with Silk, Secretary obviously works in
ClojureScript and has named routes. It is also somewhat extensible via
protocols.

In terms of differences, Secretary is obviously incompatible with Clojure,
couples route definition with route handling, uses a complex macro to
define routes instead of using data structures, can only match URL paths,
and is impure. While I value all of these features that Secretary lacks, I
think that last one, impurity, is the most significant.

I love Clojure's pragmatic philosophy; it is mostly pure but very
practical. Mutation is always possible, but uncontrolled mutation is
frowned upon and intentionally difficult. Where we draw the line between
functional purity and impurity is unclear and very open to interpretation,
but it is my strong opinion that route creation and matching should sit
firmly on the pure side.

The public interface for defining routes in Secretary is `defroute`, a
macro which only sometimes defines something but *always* mutates a global
atom. When using Secretary, how does one know the order in which routes are
matched? I assume it is in dependency order as determined by the Google
Closure compiler, but it is unclear to me. What about if Secretary is
ported to Clojure and you hot reload namespaces as you develop with it? You
could potentially change the routing order from what it would be at
runtime. Component https://github.com/stuartsierra/component is extremely
useful for development and its popularity is well warranted, but
Secretary's design fundamentally precludes compatibility with Component or
anything that requires that mutation be limited and controllable.

Silk is also, in many ways, lower level than Secretary. Secretary could be
built on top of Silk without much additional effort since extending Silk to
match paths specified with Clout/Secretary syntax (/path/to/:param) would
be trivial. On the other hand, building Silk on top of Secretary would be
extremely difficult.

It is not my intention to lambast Secretary and I hope it doesn't come
across that way. Solving front-end routing problems is difficult and is a
different beast altogether from back-end routing because it lacks the
established Ring model (adapters, requests, etc.) and even lacks the HTTP
request/response model. Secretary did a good job at solving these difficult
problems.

We share a desire to bring an end to the saturation of routing libraries. I
just don't think that retrofitting a library designed for one paradigm will
work without causing significant pain to users.  At some point, it just
makes sense to start fresh. Silk is designed from the ground up to work on
both platforms, be extremely extensible, and include all of the best parts
of the various routing libraries that I have used and examined. These
strict flexibility requirements led to a design which, I think, is very
simple and fairly low-level while remaining reasonably convenient.

I appreciate your invitation to help you work toward the goal of making
Secretary isomorphic and would be happy to talk to you about it. However, I
don't think that Secretary or any other routing library can easily replace
Silk. Therefore, I also invite you to help improve any deficiencies you see
in Silk. I would greatly appreciate constructive criticism. I'll take you
up on your offer to email you privately. :)

Cheers,
Dom



On Tue, Aug 5, 2014 at 7:35 PM, Joel Holdbrooks cjholdbro...@gmail.com
wrote:

 Awesome work. It's fantastic to see a library that's interested in
 targeting both the front-end and the back-end. This is the type of attitude
 I would love to see more often in the Clojure community.

 OTOH, it would have been awesome to have heard your thoughts WRT the
 concept of isomorphic routing on the Secretary issue tracker.

 You said you couldn't find something suitable, why didn't you complain or
 suggest a patch? We would have been happy to have supported your endeavor
 in making that possible and your ideas. In fact, we would have been willing
 to make breaking changes for them!

 Many of us want this!

 Originally, several 

Re: [ClojureScript] Re: [ANN] Silk, an isomorphic routing library for Clojure and ClojureScript

2014-08-06 Thread Joel Holdbrooks
Dom,

We’re actually well aware of many of the flaws you have pointed out with 
Secretary. In fact, we even have open issues for some of them.

 While I value all of these features that Secretary lacks, I think that last 
 one, impurity, is the most significant... Mutation is always possible, but 
 uncontrolled mutation is frowned upon and intentionally difficult

It is not as if we don’t understand the benefits of immutability or know 
Clojure idioms. There’s no need to school anyone. We're not n00bs here. :-) 
When I became a committer to the library I did what I could to improve what was 
already there.

Personally, I do not like the overly complex macro that we have nor do I like 
the global state. These are just implementation details and it wouldn’t require 
too much effort to switch to something that’s immutable with a minimum amount 
of breaking change. We already have several vanilla functions for 
adding/removing routes that could easily be made stateless. The three of us 
(myself, Gianni, and Joel) have been busy and just haven’t had the chance to 
fix it.

Anyway, you’ve done a great job enumerating your reasons for writing Silk and 
flaws about Secretary; some of it is accurate, some of it is misguided. I’m not 
going to return fire by addressing them because I don’t think it will make much 
of a difference. Really, what we need to do is work together.

We can continue this discussion elsewhere.

Joel

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