Re: Some feedback on coding style

2013-05-27 Thread John D. Hume
Oops. That is what I meant, but I don't know why I thought pre- and
post-conditions get stored in metadata. It would be handy for :pre. Thanks,
Ambrose.

To the OP, I would still recommend using metadata to store the
applicability test and also making it a precondition of the fn in a partial
function implementation, but that will require more effort than I thought.
On May 27, 2013 8:12 AM, "Ambrose Bonnaire-Sergeant" <
abonnaireserge...@gmail.com> wrote:

> Hi John,
>
> By :pre, do you mean function preconditions? eg. (fn [] {:pre [..]}) ?
>
> How is :pre related to metadata and dispatch? AFAICT it's purely for
> macroexpansion and
> there is no metadata available on the precondition post-macroexpansion.
>
> Thanks,
> Ambrose
>
> On Mon, May 27, 2013 at 9:00 PM, John D. Hume wrote:
>
>> On May 26, 2013 8:53 PM, "Mark Engelberg" 
>> wrote:
>> >
>> > Another possible design choice is to store a domain-testing predicate
>> in the function's metadata.
>>
>> Using metadata would be a much more idiomatic choice than using arity.
>> Multiple arities are idiomatically used (like method overloading) to
>> default arguments.
>>
>> An interesting detail James thought of but didn't call out is putting the
>> domain check in the :pre metadata of the fn. This is an infrequently used
>> Clojure feature, but it's a perfect fit for partial functions. Calling a fn
>> with an argument that fails the :pre check will throw an exception, so the
>> body can be written to assume it's got good input. Anyone can grab the :pre
>> metadata to test for applicability, and anyone who knows clojure will have
>> at least passing familiarity with the concept.
>>
>> Your macro can still pull apart the pattern matching forms to build the
>> :pre fn, and it's still easy to do orElse-style composition.
>>
>> Unrelated: If you haven't already, you may want to read and follow up on
>> the May 16 thread "core.match" before going very far with 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.
>>
>>
>>
>
>  --
> --
> 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.




Re: Some feedback on coding style

2013-05-27 Thread Ambrose Bonnaire-Sergeant
Hi John,

By :pre, do you mean function preconditions? eg. (fn [] {:pre [..]}) ?

How is :pre related to metadata and dispatch? AFAICT it's purely for
macroexpansion and
there is no metadata available on the precondition post-macroexpansion.

Thanks,
Ambrose

On Mon, May 27, 2013 at 9:00 PM, John D. Hume wrote:

> On May 26, 2013 8:53 PM, "Mark Engelberg" 
> wrote:
> >
> > Another possible design choice is to store a domain-testing predicate in
> the function's metadata.
>
> Using metadata would be a much more idiomatic choice than using arity.
> Multiple arities are idiomatically used (like method overloading) to
> default arguments.
>
> An interesting detail James thought of but didn't call out is putting the
> domain check in the :pre metadata of the fn. This is an infrequently used
> Clojure feature, but it's a perfect fit for partial functions. Calling a fn
> with an argument that fails the :pre check will throw an exception, so the
> body can be written to assume it's got good input. Anyone can grab the :pre
> metadata to test for applicability, and anyone who knows clojure will have
> at least passing familiarity with the concept.
>
> Your macro can still pull apart the pattern matching forms to build the
> :pre fn, and it's still easy to do orElse-style composition.
>
> Unrelated: If you haven't already, you may want to read and follow up on
> the May 16 thread "core.match" before going very far with 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.
>
>
>

-- 
-- 
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: Some feedback on coding style

2013-05-27 Thread John D. Hume
On May 26, 2013 8:53 PM, "Mark Engelberg"  wrote:
>
> Another possible design choice is to store a domain-testing predicate in
the function's metadata.

Using metadata would be a much more idiomatic choice than using arity.
Multiple arities are idiomatically used (like method overloading) to
default arguments.

An interesting detail James thought of but didn't call out is putting the
domain check in the :pre metadata of the fn. This is an infrequently used
Clojure feature, but it's a perfect fit for partial functions. Calling a fn
with an argument that fails the :pre check will throw an exception, so the
body can be written to assume it's got good input. Anyone can grab the :pre
metadata to test for applicability, and anyone who knows clojure will have
at least passing familiarity with the concept.

Your macro can still pull apart the pattern matching forms to build the
:pre fn, and it's still easy to do orElse-style composition.

Unrelated: If you haven't already, you may want to read and follow up on
the May 16 thread "core.match" before going very far with 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: Some feedback on coding style

2013-05-26 Thread Mark Engelberg
Another possible design choice is to store a domain-testing predicate in
the function's metadata.

(with-meta (fn [x] ...) {:domain integer?})

(defn is-defined? [f x]
  (-> f meta :domain x))

-- 
-- 
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: Some feedback on coding style

2013-05-26 Thread David Pollak
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 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 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 applicatio

Re: Some feedback on coding style

2013-05-26 Thread Ambrose Bonnaire-Sergeant
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  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 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  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)))
>>>
>>> (

Re: Some feedback on coding style

2013-05-26 Thread David Pollak
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 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  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 forw

Re: Some feedback on coding style

2013-05-26 Thread James Reeves
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  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 post

Re: Some feedback on coding style

2013-05-25 Thread Mark Engelberg
The most common way to do this in Clojure is to define your function such
that if the input is not in the domain, the function returns nil.

Since nil and false are the only "falsey" values in Clojure, you can use
ordinary tests to determine if the function returned a result.  The idiom
that lets you apply a function and guarantee that there is a result is:

(when-let [result (pf x)]
  ...)

which is shorthand for:

(let [result (pf x)]
   (when result
   ...))

If the when test fails, then the expression returns nil, which means that
you naturally get another partial function restricted to the appropriate
domain.

There is a threading form, some->, which provides for certain kinds of
partial function composition (a chain of calls, but as soon as you hit a
nil result, the whole thing becomes nil).  I can't think of anything
exactly like orElse, but it's easy enough to write, since or returns the
first non-falsey value:
(defn orElse [pf1 pf2] (fn [x] (or (pf1 x) (pf2 x

Extending this to a variable number of arguments is left as an exercise.

As you can see, Clojure's punning of nil as both "no result" and a false
value, along with the way that all other values are treated as true and the
when idiom, allows for some compact code.

However, it's not all roses.  If you want your function to be able to
return nil as an actual meaningful result, this strategy won't work.  If
your function sometimes returns false, then the when idiom fails.  It works
well enough in local contexts where you really understand the kind of data
you're working with and know that nil and false won't be an issue, but if
you're building a larger library, this approach is fragile.  I've found
that this lack of precision surrounding nil and false is one of the biggest
source of bugs.  You'll have code that works on all tests and "reasonable"
input, but when someone uses your code on something that has nil or false
in a collection and boom, things get squirrely.  Since you're coming from
Scala which carefully protects you from this kind of confusion, you'll
probably find this to be a real annoyance.  Nevertheless, most Clojurians
just create partial functions in this way where a nil result means the
function is undefined for that input, and muddle through okay.

If partial functions play a central role in your library, then to be truly
robust, you'll have to work harder than the typical, sloppy approach.  Use
maps as a role model, since maps are essentially partial functions.  (get
{:a 1, :b 2} :c) returns nil.  But for special purposes, people can do (get
{:a 1, :b 2} :c ::undefined), choosing a distinctive value to represent
undefined.

Try modeling your partial functions as functions that typically return nil
if undefined, but an optional return value can be provided for undefined
inputs.

In general, the Clojure philosophy is that no guarantees are made if you
pass an invalid input to a function: you might get garbage out, you might
get nil, or you might get an error.  It's not really consistent and
different functions and libraries work in different ways.  The
nil-returning ones are the most easily composable, though, which is why
that tends to be the most common way.

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