KEMBAR78
Inconsistencies in `prototype` shorthand (::) and `this` shorthand (@) · Issue #1601 · jashkenas/coffeescript · GitHub
Skip to content

Inconsistencies in prototype shorthand (::) and this shorthand (@) #1601

@geraldalewis

Description

@geraldalewis

The :: .prototype(.) shorthand should behave consistently with the @ this(.) shorthand.

Adding symmetry in how each shorthand is implemented will give developers a better mental model of their behavior and reduce issues.

@ currently compiles to a literal this, access this. or invocation this( depending on context.
:: currently compiles to a literal .prototype or access .prototype. depending on context.
It does not compile to an invocation.

@ will not behave as :: in every context. Below is a breakdown of where they behave consistently and where they behave inconsistently.


Consistent

# JavaScript output indicated in comments
# code wrapped in -> as :: can indicate a line continuation

as value (unless :: standalone)

-> @              # this
-> C::            # C.prototype

member access (unless :: standalone)

-> @member        # this.member
-> C::member      # C.prototype.member

index

-> @['member']    # this['member']
-> C::['member']  # C.prototype['member']

applying ::

-> @::   # this.prototype
-> C:::: # C.prototype.prototype

Inconsistent

invocation

class C; C:: = (a) -> console.log a

-> @ 'invoke'     # this('invoke');
-> C:: invoke     # C.prototype.invoke; // (acts as member access)
# -> C:: 'invoke' # error (unexpected 'STRING')

list comprehensions (from #1477 by @dbrans)

for k of @ when k isnt constructor then   # for (k in this) { if (k !== constructor) {} }
for k of A:: when k isnt constructor then # for (k in A.prototype.when(k !== constructor)) {}

instanceof

@ instanceof C   # this instanceof C;
C:: instanceof B  # C.prototype["instanceof"](B);

standalone

-> @              # this
# -> ::           # error; any use-case?

standalone member access

-> @member        # this.member
# -> ::member     # error; any use-case?

Proposal

:: should:

  • still raise an error if used standalone
  • behave like @ in all other ways:
    • not indicate a line continuation
    • work in list comprehensions
    • be callable Edit: See @jashkenas comment
      (it technically is, but it looks like this line prevents implicit calls)

or

  • :: should always compile to .prototype.
  • @ should always compile to this.
  • @ should continue lines

Personally, I'm in favor of #1


Related issues: #1477, #1554 (fixed), #1234 (fixed)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions