Re: extend-type and extend-protocol: different syntax for multi-arity methods

2015-05-14 Thread Alexey Cherkaev
Hi Tassilo,

Thanks for the reply.

The thing is, although the implementations for extending protocols directly
in records and with extend-type might be different, there is no reason why
the syntax should be different: from Clojure-programmer perspective it’s
all the same. It is a leaked abstraction if we have to thing about those
details. The same applies for interface implementation: overloaded methods
there and multi-arity functions in Clojure shouldn’t look differently to a
Clojure programmer (unless there is some more profound difference).
​


Best regards,
Alexey

On 13 May 2015 at 14:46, Tassilo Horn  wrote:

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


extend-type and extend-protocol: different syntax for multi-arity methods

2015-05-13 Thread Alexey Cherkaev
Hi all,

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?

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.

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

Regards,
Alexey
​

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


Re: Strange behaviour of a callable record

2015-04-24 Thread Alexey Cherkaev
Thanks, Nicola! It solved it. When I looked at docs, I couldn't figure out 
the role of `applyTo`. Well, now I know.

On Thursday, April 23, 2015 at 1:47:11 PM UTC+2, Nicola Mometto wrote:
>
>
> You're not implementing IFn.applyTo, you should. 
>
> Why applyTo is used in the second example while invoke is used in the 
> other cases has to do with implementation details of how def expressions 
> are compiled/evaluated. 
>
> Alexey Cherkaev writes: 
>
> > Hi, 
> > 
> > I have encountered the problem with Clojure 1.6.0, when I create the 
> record 
> > that implements IFn. 
> > 
> > For example, 
> > 
> > (defrecord Foo [x] 
> > clojure.lang.IFn 
> > (invoke [_ f] (f x))) 
> > 
> > Than create an instance of this record: 
> > 
> > (def f (->Foo 10)) 
> > 
> > And we can call it without a problem: 
> > 
> > user=> (f inc) 
> > 11 
> > 
> > Yet, if you try to define a value to keep the result, compiler throws an 
> > error: 
> > 
> > user=> (def z (f inc)) 
> > 
> > CompilerException java.lang.AbstractMethodError, 
> > compiling:(form-init4774307052978984831.clj:1:8) 
> > 
> > There is workaround: create local binding first and then assign the 
> value 
> > to a global variable: 
> > 
> > user=> (def z (let [temp (f inc)] temp)) 
> > #'user/z 
> > user=> z 
> > 11 
> > 
> > Is this a bug or I don't fully understand why you can't do that? 
> > 
> > Cheers, Alexey 
>
> -- 
>

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


Strange behaviour of a callable record

2015-04-23 Thread Alexey Cherkaev
Hi,

I have encountered the problem with Clojure 1.6.0, when I create the record 
that implements IFn.

For example,

(defrecord Foo [x]
clojure.lang.IFn
(invoke [_ f] (f x)))

Than create an instance of this record:

(def f (->Foo 10))

And we can call it without a problem:

user=> (f inc)
11

Yet, if you try to define a value to keep the result, compiler throws an 
error:

user=> (def z (f inc))

CompilerException java.lang.AbstractMethodError, 
compiling:(form-init4774307052978984831.clj:1:8)

There is workaround: create local binding first and then assign the value 
to a global variable:

user=> (def z (let [temp (f inc)] temp))
#'user/z
user=> z
11

Is this a bug or I don't fully understand why you can't do that?

Cheers, Alexey

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