Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
extending protocols one method at a time...
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  8 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Andrew Gwozdziewycz  
View profile  
 More options Feb 7 2011, 1:03 pm
From: Andrew Gwozdziewycz <apg...@gmail.com>
Date: Mon, 7 Feb 2011 13:03:42 -0500
Local: Mon, Feb 7 2011 1:03 pm
Subject: extending protocols one method at a time...
Hey all,

So, for a random project, I found myself using a single protocol
extended to a bunch of record types. I did this using the support
in `defrecord` itself, but what I dislike about it is that the
definitions for each method of the protocol are spread out amongst
multiple sections of code.

What I'd really like to do would be to define an implementation for
many types within a single definition. Conceptually, this is the
same thing you might do in OCaml or other staticly typed languages:

let bar x = match x with
   | String y -> ...
   | Character y -> ...

So, I came up with this (below), only it doesn't work. I haven't dug deep
yet to figure out why exactly, or if this could even technically be done
without manipulating something in core. (I'm going to assume for now
that I missed something simple, and it could be fixed trivially.)

(defprotocol Foo
  (bar [_] "do bar")
  (baz [_] "do baz"))

(defmacro defp [proto name arglist & bodies]
  (let [pairs (partition 2 bodies)
        protocol (resolve proto)
        namekw (keyword name)
        impls (reduce (fn [accum [t body]]
                        (let [tm (assoc
                                     (get accum t {})
                                   namekw `(fn ~arglist ~body))]
                          (assoc accum t tm)))
                      (get :impls protocol {})
                      pairs)]
    `(def ~proto (assoc (var-get ~protocol) :impls ~impls))))

(defp Foo bar [x]
  String (concat x x)
  Character (list x x))

(defp Foo baz [x]
  String (rest (seq x))
  Character nil)

So, is there a technical reason why this is a bad idea, other than
"the interface might change in the future"? And, If people are actually
into this idea, what adjustments should be made to the syntax?

Thanks in advance,

Andrew

--
http://www.apgwoz.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ken Wesson  
View profile  
 More options Feb 7 2011, 2:16 pm
From: Ken Wesson <kwess...@gmail.com>
Date: Mon, 7 Feb 2011 14:16:16 -0500
Local: Mon, Feb 7 2011 2:16 pm
Subject: Re: extending protocols one method at a time...
Can't you just use extend-protocol to group your protocol
implementations for each record type in one place?

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Gwozdziewycz  
View profile  
 More options Feb 7 2011, 2:49 pm
From: Andrew Gwozdziewycz <apg...@gmail.com>
Date: Mon, 7 Feb 2011 14:49:48 -0500
Local: Mon, Feb 7 2011 2:49 pm
Subject: Re: extending protocols one method at a time...

On Mon, Feb 7, 2011 at 2:16 PM, Ken Wesson <kwess...@gmail.com> wrote:
> Can't you just use extend-protocol to group your protocol
> implementations for each record type in one place?

That certainly works, but it's really not much different than:

(defrecord Bar [x y]
   Foo
     (bar [_] ...)
     (baz [_] ...)

which is what I'm trying to avoid.

It seems to me that the only reason that specifying the entire
implementation together is to avoid situations where the
implementation is not completely defined.

See, I'm less concerned about implementing the Protocol than I am
about creating "functions" that are dispatched by type, and since they
have to have the same argument list, I see no reason why that
boilerplate can't be eliminated.

Perhaps one solution for me is to write a macro that constructs a
protocol (and extends it to types) out of the definitions provided..
sort of a hybrid of extend-protocol and defp from before.

(defwhatever Foo
   (bar [_]
     String (body)
     Character (body))
   (baz [_]
     String (body)
     Character (body)))

Which gets me to where I ultimately want to be (methods defined
together per type extended too), but not quite what I'm really looking
for.

> 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+unsubscribe@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

--
http://www.apgwoz.com

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ken Wesson  
View profile  
 More options Feb 7 2011, 3:30 pm
From: Ken Wesson <kwess...@gmail.com>
Date: Mon, 7 Feb 2011 15:30:08 -0500
Local: Mon, Feb 7 2011 3:30 pm
Subject: Re: extending protocols one method at a time...

Now it sounds like you might want a plain old multimethod.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Gwozdziewycz  
View profile  
 More options Feb 7 2011, 5:21 pm
From: Andrew Gwozdziewycz <apg...@gmail.com>
Date: Mon, 7 Feb 2011 17:21:31 -0500
Local: Mon, Feb 7 2011 5:21 pm
Subject: Re: extending protocols one method at a time...

It'd be more easily done with multimethods, sure, but since they all
implement both methods, there's no reason to not use protocols. See
the dilemma?

> --
> 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+unsubscribe@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

--
http://www.apgwoz.com

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Gwozdziewycz  
View profile  
 More options Feb 7 2011, 5:53 pm
From: Andrew Gwozdziewycz <apg...@gmail.com>
Date: Mon, 7 Feb 2011 17:53:39 -0500
Local: Mon, Feb 7 2011 5:53 pm
Subject: Re: extending protocols one method at a time...
Playing around a bit more:

(defprotocol Foo
  (bar [_] "do bar")
  (baz [_] "do baz"))

(defmacro defp [name arglist proto & bodies]
  (let [pairs (partition 2 bodies)
        protocol (resolve proto)
        namekw (keyword name)
        impls (reduce (fn [accum [t body]]
                        (let [tm (assoc
                                     (get accum t {})
                                   namekw `(fn ~arglist ~body))]
                          (assoc accum t tm)))
                      (get :impls protocol {})
                      pairs)]
    `(clojure.core/-reset-methods (alter-var-root ~protocol assoc
:impls ~impls))))

(defp bar [x] Foo
   String (concat x x)
   Character (list x x))

(defp baz [x] Foo
  String (rest (seq x))
  Character nil)

(and changing up the interface to it a bit) this seems to work.

Though, it doesn't return (satisfies? Foo String) correctly, but, I'll
either figure that out later, or ultimately not care.

--
http://www.apgwoz.com

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Meikel Brandmeyer  
View profile  
 More options Feb 7 2011, 6:56 pm
From: Meikel Brandmeyer <m...@kotka.de>
Date: Tue, 8 Feb 2011 00:56:21 +0100
Local: Mon, Feb 7 2011 6:56 pm
Subject: Re: extending protocols one method at a time...
Hi,

Am 07.02.2011 um 23:53 schrieb Andrew Gwozdziewycz:

> Though, it doesn't return (satisfies? Foo String) correctly, but, I'll
> either figure that out later, or ultimately not care.

satisfies? is about instances.

Sincerely
Meikel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Gwozdziewycz  
View profile  
 More options Feb 7 2011, 11:10 pm
From: Andrew Gwozdziewycz <apg...@gmail.com>
Date: Mon, 7 Feb 2011 23:10:55 -0500
Local: Mon, Feb 7 2011 11:10 pm
Subject: Re: extending protocols one method at a time...

Ooh! Good point. Thanks!

On Feb 7, 2011 6:56 PM, "Meikel Brandmeyer" <m...@kotka.de> wrote:

Hi,

Am 07.02.2011 um 23:53 schrieb Andrew Gwozdziewycz:

> Though, it doesn't return (satisfies? Foo String) correctly, but, I'll
> either figure that out l...

satisfies? is about instances.

Sincerely
Meikel

--

You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post t...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »