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.