Loading...
Skip to end of metadata
Go to start of metadata

Problem

There is currently no unified field access syntax between Clojure and ClojureScript.

(covered by ticket CLJS-89)

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.

Potential Solution

A way to shorten the gap between Clojure and ClojureScript is to use the following syntax for ClojureScript:

(.p o)           ;=> a method call

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

(. o p)          ;=> a method call

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

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

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

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

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

Thus reserving the single hyphenated symbol form for property access.  This functionality should also be created in Clojure.  This would require a breaking change in ClojureScript and only an enhancement to Clojure.

Labels:
  1. Oct 15, 2011

    I see in Rich's original notes on ClojureScript that the following option was also proposed.

    (: o p)

    This avoids the overloading of keywords. This does have the downside that it requires an addition to Clojure in order to unify the interop forms. The following

    (. o :p)

    works in Clojure today.

  2. Oct 15, 2011

    Given that we have (set! ...) (aget ...) and (aset ...), it doesn't seem out of order to have some "get" macro for properties.

  3. Oct 16, 2011

    '.' as a uniform gateway to interop has tremendous value. Even if we normally use the sugar (.bar foo) etc, after macro expansion they all become dot forms and things like code walkers etc can have an easier time of them. I'd avoid another gateway (which -get would be) strenuously, as in - no way.

    Perhaps (. foo -bar) ?

    This has the virtue of not involving keywords (which have downsides if we want sugar). The sugar:

    (.-bar foo) also seems aesthetically more appealing for some reason.

    As far as (. foo :bar) working already, it is an undocumented feature and could be changed to (. foo -bar) should we decide.

    1. Oct 18, 2011

      Which are the downsides of keywords for sugar? .:bar is currently read as a symbol.

      1. Oct 18, 2011

        When desugared, a keyword will have to be created for (. foo :bar) (vs a symbol beginning with ':' ) Thus the transformation is not uniform.

  4. Oct 16, 2011

    I like the sugared (.-bar foo)

    1. Oct 16, 2011

      I buy the unified theory of . interop. Out of curiosity, if we move to some other platform that supports it, would a property "-bar" be accessed by

      (.–bar foo)?

       

      hmm.. meant for that to be a global reply.

      1. Oct 16, 2011

        Same for any prefix, if we use : and host supports leading :, then ::

    2. Oct 19, 2011

      Hasn't minus a connotation of privacy? I find a strecth to mean field access.

      Bad idea of the day: repeating dot: (. foo .bar), sugared (..bar foo) which of course looks a lots like (.. bar foo) but in this age of -> who still uses .. ? Wink

      1. Oct 19, 2011

        I'm not sure that connotation is wholly wrong here. In any case, further overloading dot seems like more complexity vs having something else. Other prefixes characters are possible.

  5. Oct 25, 2011

    Going down the (. -foo bar) / (. bar -foo) path in implementation.

    1. Oct 25, 2011

      What's the idea behind supporting (. -foo bar) ?

      The property never appears in this position in Clojure.

    2. Oct 29, 2011

      Please remember and retain that (.whatever x) -> (. x whatever) transformation is a (special) macro expansion (and will happen during macroexpand-1). The evaluator only needs to handle (. x whatever)