Alexey Cherkaev <alexey.cherk...@gmail.com> writes:

Hi Alexey,

> If you have a protocol
>
> (defprotocol Foo (foo [x] [x y]))
>
> and implement it for the record
>
> (defrecord Bar [p q r]
>   Foo
>   (foo [x] x)
>   (foo [x y] [x y]))
>
> you write each method separately.  The same is true for extend-type.
> Yet, if you use extend-protocol syntax is more like usual Clojure
> multi-arity function definition:
>
> (extend-protocol Foo
>   Bar
>   (foo
>      ([x] x)
>      ([x y] [x y])))
>
> The first question is why there is a difference?

I think, the difference is that deftype/defrecord create an interface
(and an implementation class) under the hoods, and there, the different
arities of foo are actually different methods.

extend/extend-type/extend-protocol dynamically extend a protocol to some
type.  Basically, the protocol's underlying dynamic dispatch table gets
a new [type impl-function] entry where impl-function is a real Clojure
function, thus you must specify all arities you want to support the
normal Clojure way.

> Secondly, if you mess up which syntax is where, the error you will get
> is quite obscure, nothing guards you against essentially a *wrong
> syntax*: both extend-type and extend-protocol are macros, so it
> shouldn’t be too difficult to add a quick check on correctness.

Yeah, for extend-protocol/extend-type the standard multi-arity syntax is
the only correct one.

> But lastly, wouldn’t it be better to have a uniform syntax?

The problem is that defrecord and deftype also allow for implementing
interfaces.  If Foo above was an interface, foo with 1 argument and foo
with 2 arguments are completely separate methods (ok, they overload),
thus it makes sense to define them separately.  However, if Foo was a
protocol, it would also make sense to notate it as multi-arity function.
But then you have an inconsistent syntax inside defrecord/deftype.
Well, although one could argue that this was a good thing because it
would allow to see immediately if Foo was a protocol or an interface.

Bye,
Tassilo

-- 
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/d/optout.

Reply via email to