Thanks!
On Sun, May 26, 2013 at 6:27 PM, Ambrose Bonnaire-Sergeant < abonnaireserge...@gmail.com> wrote: > Hi David, > > Clojure can generate auto-syms with a trailing #. > > user=> `(fn [x#] x#) > (clojure.core/fn [x__349__auto__] x__349__auto__) > > Thanks, > Ambrose > > > On Mon, May 27, 2013 at 9:08 AM, David Pollak < > feeder.of.the.be...@gmail.com> wrote: > >> Mark and James, >> >> Thank you for your input. >> >> There are two reasons why I don't want to simply test for nil as the >> result of running the pattern match: >> >> - The right side of the pattern can be side-effecting. For example, if >> you are servicing a web request, there may be database calls, etc. >> Therefore, I need a test that does not have side effects. >> - There may be a choice of multiple partial functions where the best >> choice is chosen (e.g., 3 different partial functions can serve a web >> request, but given the response type weighting, we may want to choose the >> JSON response, but we don't know which response type to choose until we've >> checked what the possibilities are) >> >> Anyway, using the joys of arity, I've solved the problem. >> >> (pf 33) ;; apply the partial function to 33 >> >> (pf :defined? 33) ;; is the function defined at 33 >> >> I blogged about the design choices at >> http://blog.goodstuff.im/first_clojure_macro >> >> Thanks! >> >> David >> >> >> >> On Sat, May 25, 2013 at 11:26 AM, James Reeves <ja...@booleanknot.com>wrote: >> >>> In Scala, PartialFunction is a trait, which in Clojure I'd represent >>> using a protocol: >>> >>> (defprotocol Partial >>> (defined-at? [x])) >>> >>> (defn partial-fn [guard f] >>> (reify >>> Partial >>> (defined-at? [x] (guard x)) >>> clojure.lang.IFn >>> (invoke [f x] >>> {:pre [(guard x)]} >>> (f x)))) >>> >>> And then, when I have a mechanism to create a partial function, I'd then >>> work on a macro to transform: >>> >>> (pfn [x :guard even?] (/ x 2)) >>> >>> Into: >>> >>> (partial-fn even? (fn [x] (/ x 2))) >>> >>> I'm not sure how much benefit you'd get out of partial functions that >>> are not part of the core language. You'd need to write a fair bit of >>> infrastructure around them, but it might be worth it. >>> >>> In Clojure, it seems quite common to use functions that return nil to >>> achieve the same effect as partial functions, and there are several >>> functions and macros, like some-> and keep, that support that idiom. >>> >>> - James >>> >>> >>> >>> On 25 May 2013 17:14, David Pollak <feeder.of.the.be...@gmail.com>wrote: >>> >>>> Hello, >>>> >>>> This is my first post to this group. If my post or the tone of my post >>>> is not up to this communities standards, please give me feedback so that I >>>> can integrate with the community. >>>> >>>> I'm coming from Scala-land. >>>> >>>> In Scala, there's a PartialFunction: >>>> http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.PartialFunction >>>> >>>> The key take-away for PartialFunctions is "... is a unary function >>>> where the domain does not necessarily include all values of type A." >>>> >>>> The ability to test a PartialFunction to see if the domain includes a >>>> particular value is very helpful. pf.isDefinedAt(x) allows testing to see >>>> if the function is defined at a given value of x. >>>> >>>> But a PartialFunction is a subclass of Function, so PartialFunctions >>>> can be applied: >>>> >>>> pf(x) >>>> >>>> The Scala compiler will take a pattern and turn it into a >>>> PartialFunction: >>>> >>>> def pf: PartialFunction[String, Number] = >>>> { >>>> case "" => 0 // special case blank to zero >>>> case x if isInt(x) => x.toInt >>>> case x if isDouble(x) => x.toDouble >>>> case x if isBigInt(x) => asBigInt(x) >>>> } >>>> >>>> Another property of PartialFunction is they can be composed: >>>> >>>> pf = pf1 orElse pf2 orElse pf3 // pf isDefinedAt any place any of the >>>> partial functions are defined >>>> >>>> We use PartialFunctions extensively in Lift to allow choosing if a >>>> particular URL should be served by Lift, if it should be served by a >>>> particular REST handler, etc. For example, defining a REST route in Lift: >>>> >>>> serve { >>>> case "api" :: "user" :: AsLong(userId) :: _ GetJson _ => >>>> User.find(userId).map(_.toJson) >>>> } >>>> >>>> As I've been learning Clojure in preparation for a presentation at >>>> Strange Loop and as part of a new project I've been working on ( >>>> http://blog.goodstuff.im/plugh), I am looking to bring the best things >>>> in Lift into the Clojure code I write. >>>> >>>> Clojure's pattern matching stuff is pretty nifty. I especially like how >>>> you can extract values out of a Map (this is *so* much more powerful that >>>> Scala's pattern matching, even with unapply... but I digress). >>>> >>>> So, I wrote a macro (it's my first, so feedback on the style for the >>>> macro itself): >>>> >>>> (defmacro match-func [& body] `(fn [~'x] (match [~'x] ~@body))) >>>> >>>> This creates a function that is the application of the match to a >>>> parameter, so: >>>> >>>> ((match-func [q :guard even?] (+ 1 q) [z] (* 7 z)) 33) >>>> ;; 231 >>>> >>>> I am struggling with the right style for how to create something that's >>>> both a function: >>>> >>>> (def my-test (match-func [q :guard even?] (+ 1 q) [z] (* 7 z))) >>>> >>>> (my-test 33) >>>> >>>> And also something that can be tested for definition at a given value. >>>> >>>> Put another way, if Clojure had something that's both a function and a >>>> thing that could be asked if it's defined for a given input, how would one >>>> in Clojure apply that thing and also ask that thing if it was defined? >>>> >>>> Thanks for reading my long question and I look forward to feedback. >>>> >>>> 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. >>>> >>>> >>>> >>> >>> -- >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to 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. >>> >>> >>> >> >> >> >> -- >> 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. >> >> >> > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to 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. > > > -- 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.