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 t...@gnu.org wrote:

 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.


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.