<< Back to previous view

[CLJS-89] Simplify the dot access special form. Created: 14/Oct/11  Updated: 27/Jul/13  Resolved: 01/Feb/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Critical
Reporter: Fogus Assignee: Fogus
Resolution: Completed Votes: 2
Labels: None


 Description   

Currently ClojureScript provides the following dot access syntaxes:

(.p o)           ;=> a property access

(.m o <args>)    ;=> a method call

(. o p)          ;=> a property access

(. o p <args>)   ;=> a method call

(. o (m))        ;=> a method call

(. o (m <args>)) ;=> a method call

This is potentially confusing. Especially considering that Clojure looks as follows:

(.p o)           ;=> a property access if p is a property

(.p o)           ;=> a method call if p is a method

(.m o <args>)    ;=> a method call

(. o p)          ;=> a property access if p is a property

(. o p)          ;=> a method call if p is a method

(. o p <args>)   ;=> a method call

(. o (m))        ;=> a method call

(. o (m <args>)) ;=> a method call

The divergence between the Clojure and ClojureScript way is due to first-class functions. That is, in JavaScript a property can be a field or a function or a method. There is currently no way to distinguish between the desire to call a method and retrieve a function as a property except through syntax. This ticket would shorten the gap between Clojure and ClojureScript in the following way (ClojureScript proposal below):

(.m o)           ;=> a method call

(.m o <args>)    ;=> a method call

(. o m)          ;=> a method call

(. o m <args>)   ;=> a method call

(. o (m))        ;=> a method call

(. o (m <args>)) ;=> a method call

(.-p o)          ;=> a property access

(. o -p)         ;=> a property access

This would be a breaking change, but would shorten the divergence between Clojure and ClojureScript.



 Comments   
Comment by Fogus [ 16/Nov/11 9:09 AM ]

The implementation on the prop-lookup branch is functional and has associated tests. Ready for inclusion.

Comment by Benjamin Conlan [ 02/Dec/11 12:02 AM ]

I've just given this a quick spin and it works beautifully (at least regarding the property value vs property function syntax).

But after looking at my code I can't help but think that for the non-function case (ie json data) just using the maps symbol operator might be more desirable instead of (.-p o))

so json such as:

var jsonData = {
  "person": {
    "title" : "mr",
    "name" : {
      "firstname" : "Harry",
      "surname" : "Jones"
    }
  }
}

could be accessed like:

(:firstname (:name (:person jsonData)))

But in saying this I haven't put any thought into this statement (and of course the suggested code doesn't work anyway in the master/prop-access branches).

In coming full circle, I'm just appreciative of your work on the prop-access branch.

Comment by Stuart Sierra [ 03/Jan/12 5:05 PM ]

Back in the dark ages before Clojure 1.0, you always had to write this;

(. o (m))  ; method call
(. o f)    ; field access

Later, but before the introduction of (.m o) syntax, this was shortened to (. o x) for both methods and fields. What if we went back to the original dot operator syntax, but assume that (.m o) always means a method call:

(. o f)     ; always field access
(. o (m))   ; always method call
(.m o)      ; always method call

Raw field access is rare in Java, perhaps less so in JavaScript. But this doesn't require adding any new syntax and is consistent with what Clojure programmers are used to.

The common case for field access in ClojureScript is, I believe, interop which uses JavaScript objects as map-like data structures. My preferred solution for that case would be better conversion between JS objects and real ClojureScript maps.

Comment by Thomas Scheiblauer [ 01/Feb/12 12:37 PM ]

I would also prefer Stuart's solution due to the reasons he mentioned and because the currently implemented concatenation of sugar characters (.-somefield obj) didn't really make the matter taste more sweet it feels rather clumsy to me.
By the way, I would also propose to implement 'memfn' for staying consistent with Clojure (if it hasn't already been done so).

Comment by David Nolen [ 01/Feb/12 4:09 PM ]

At this point it's probably water under the bridge. If you're interested in memfn, please submit a patch

Comment by David Nolen [ 01/Feb/12 4:53 PM ]

Done

Generated at Sun Nov 23 01:25:57 CST 2014 using JIRA 4.4#649-r158309.