Hello there,

I'm not quite sure whether is convenient for each method implementation to 
possibly shadow previous names, particularly those of clojure.core.

(defprotocol Example
    (get [this]))
    
The previous example redefines get in the current namespace. But is that we 
usually mean by "method"? That's more of what one would expect of a *
function* definition. Given a file in a mainstream OOP lang, one can define 
N "get" methods in N classes and no bad things will happen, as they are 
attached to the classes, not the namespace. In principle, with protocols 
and records, Clojure is trying to distil the best of OOP. But this detail, 
in my opinion, seriously hampers such a goal.

Maybe get could have clojure.core semantics when the first argument does 
not implement Example. I doubt it'd yield clear code though, as it 
overloads meaning.

There is actually a way to work around this:

(ns protocols)

(defprotocol Prot
  (first [this]))

(ns usage)

(defrecord Rec []
  protocols.Prot
  (first [this] "A value."))
  
(first (Rec.)) ; clojure.core/first gets called. This wouldn't happen in 
the previous namespace!
(.first (Rec.)) ; protocols.Prot.first gets called.

However, it feels like exploiting implementation details. In fact, *it 
won't work in ClojureScript*: one would be only left with the option of 
using :refer-clojure. Which in practice means "don't": library authors or 
even programmers in a team can't expect their API consumers to unqualify 
names from clojure.core.

In my opinion, the problem lies in that the (.method obj) syntax has too 
low-level semantics: it seems to mean just "interop call". Shouln't it be 
leveled-up to the more general "method call"? It maps well to both Java and 
JavaScript, and probably any language.

Thus, I believe that ideally, calls to Clojure *methods* should be 
dot-prefixed. It'd allow us to freely/fearlessly choose whatever name we 
can come up for a protocol method. Otherwise there would effectively exist 
about 500 reserved words (OTOH, one gets a convenient warning when 
shadowing an existing name).

Furthermore, this would blur the popular conception that dot-syntax is 
"ugly" in lisps. Rich has 
written<http://www.reddit.com/r/programming/comments/6jgnp/why_arc_is_bad_for_exploratory_programming/c040ptn>
:

In Clojure I can close a file like this:

(.close file)

That's a 'Java' call. Now, I could write a Clojure 'library' that let me 
say:

(close file)

but I really have better things to do, and so do the people that use 
Clojure.

(his point doesn't completely map to mine. But it can help changing your 
mind)

Finally, I believe that method calls should be visually obvious, as their 
output can potentially depend on the fields of the implementing 
record/type, however immutable:

(defprotocol Foo (method [this]))

(defrecord Bar [x y z]
    Foo
    (method [this] "A value."))
    
If we run (method a-bar-instance), x, y and z are, in a way, "implicit 
arguments" that method receives, since it has access to them. How do we 
tell function calls from method calls? Is it immediately obvious the 
presence of these "implicit arguments"?

Just as Rich warns us against *unlabeled* 
mutation<http://www.deftitlenil.com/2011/09/notes-strangeloop-programming-languages.html>,
 
I feel concerned with unlabeled method calls.

So my proposal would be:

   - Acknowledge the dot-calls as a feature of defrecord/deftype methods, 
   rather than a syntax that happens to work
   - Make dot-calls possible in ClojureScript. As a nice side-effect, this 
   would simplify calling ClojureScript from JavaScript  (someone other 
   than me has had this problem 
too<http://stackoverflow.com/questions/9018326/how-do-i-create-an-js-object-with-methods-and-constructor-in-clojurescript>
   ).
   
At least from the point of view of someone that isn't too familiar with the 
Clojure internals, I see no downsides - although I tried it! For instance, 
given that one can call (.first ()), I thought that then one could call (.first 
(ARecord.)), which would ruin my whole idea. But fortunately, that isn't 
the case.

My question is quite simply - do you agree? Are these semantics 
Clojure(Script) should look forward?

Thank you very much for your attention.

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