On Dec 7, 9:07 am, Laurent PETIT <laurent.pe...@gmail.com> wrote:
> 2009/12/7 Hugo Duncan <hugodun...@users.sourceforge.net>
>
> > On Mon, 07 Dec 2009 06:53:38 -0500, Rich Hickey <richhic...@gmail.com>
> > wrote:
>
> > > Yes, methods are not really functions. Thinking about them as closures
> > > over the object is a good way to go - you can see that analogy in play
> > > when you consider recur, which works with these methods, but could not
> > > rebind 'this'. The recur case sealed the deal in the decision not to
> > > include 'this' in the argument lists.
>
> > I had a quick play with protocols, and the biggest problem I had getting
> > started was realising that the signature of a method definition in
> > defprotocol was different to the signature required to implement the same
> > method in deftype.  FWIW, I found it very non-intuitive.
>
> Hello,
>
> And now that you've got it, do you still feel this  non-intuitive.
> Because I had the same feeling first: I thought I would never rembember how
> things work and why put 'this-like args there, and not there ...
> But now that everything "clicked in place", I feel the last status of what
> Rich achieved to do the most natural and intuitive.
>
> Basically, what helped me was along the lines of what Konrad said :
>  * defprotocol and extend are "purely functional" : so you have to specify
> every argument, including the object the functions acts upon.
>  * deftype with embedded protocol definition for the type, or reify, in the
> contrary, do not define pure functions. They define methods. You cannot get
> them as values and pass them around like higher-order functions, for
> example. And you must know this fact, it cannot be an implementation detail.
> So, since you know this fact, you remember that you're in a method
> definition (in the general sense of object oriented languages : method of a
> class) and, as you do with e.g. java, C#, ... , when definining methods, you
> do not add the target of the method as an implicit argument.
>
> The big advantage I see to this is that once you get it, you don't have
> anymore to remember where 'this is explicit and where it's implicit: it's
> intuitive.
> The other big advantage is that the use of recur inside these
> functions/methods bodies continue to match exactly the signature of the
> function/method (otherwise you would have had to remember that, e.g. in
> methods defined via deftype, you must place an explicit "this" argument in
> the method arg list, but not place it in the recur calls ... :-( )
>
> HTH,
>
> --
> laurent

That was my experience as well.  It started off as a gotcha (since I
was copy/pasting the protocol definitions over to the deftype), but
then after playing for a bit it wasn't a big deal.  In all my usages
so far I haven't needed to reference 'this'.

The one area I am running into issues is with being able to provide a
default implementation, or extending types such that I can override a
method.

For example, I have:

(defprotocol http-resource
  (GET     [res req resp])
  (POST    [res req resp])
  (PUT     [res req resp])
  (DELETE  [res req resp])
  (HEAD    [res req resp])
  (OPTIONS [res req resp])
  (TRACE   [res req resp]))

But I considering the usage, most of those need not be implemented per-
type, and could all be defaulted to something like:

(deftype resource [] http-resource
  (GET [req resp] (send-status! resp 405))
  (POST [req resp] (send-status! resp 405))
  (PUT [req resp] (send-status! resp 405))
  (DELETE [req resp] (send-status! resp 405))
  (HEAD [req resp] (send-status! resp 405))
  (OPTIONS [req resp] (send-status! resp 405))
  (TRACE [req resp] (send-status! resp 405)))

Alas I can't simply extend-type since that modifies the type, instead
of creating a new, modified type.  And even then, methods in the
extension map don't get called if the method exists directly on the
type, i.e., no overriding.

I'm sure my problem is simply vestigial OO thinking, but I'm not sure
how to achieve the simplicity I want.  The one route I tried that sort-
of works is making a macro to create the types, rather than extending
some extant implementation.  The downside is I have to see which
methods I'm being given and only provide "defaults" for the method
names/arities that aren't.

It might be sufficient if there was some facility for cloning another
type and overriding certain methods, though I can foresee problems
dealing with managing the field definitions between the original and
the altered clone.

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

Reply via email to