Skip to content

Consider extending Hy's . form to accept calls #1108

@gilch

Description

@gilch

Clojure's .. can have method calls. This is especially useful when chaining accessors, for example:

 (.. System (getProperties) (get "os.name"))

expands to ., which can also have calls:

(. (. System (getProperties)) (get "os.name"))

This doesn't appear to work in Hy:

=> (import os)
=> (. os (getcwd))
  File "<input>", line 1, column 7

  (. os (getcwd))
        ^------^
HyTypeError: b'The attribute access DSL only accepts HySymbols and one-item lists, got HyExpression instead'

The error message seems to indicate that this should work, is this a bug? And why restrict it to one item? Clojure doesn't.

This makes chaining of accessors awkward (--spy):

=> (. ((. ((. os getcwd)) isalpha)) __class__ __name__)
os.getcwd().isalpha().__class__.__name__
'bool'

Although the -> macro helps.

=> (-> os (.getcwd) (.isalpha) (. __class__) (. __name__))
os.getcwd().isalpha().__class__.__name__
'bool'

But Hy's . can chain when not using calls

=> (. "" __class__ __name__)
''.__class__.__name__
'str'

This makes it more like Clojure's .., than Clojure's ., which can only take two arguments.

The proposed extended form would look like this:

=> (. os (getcwd) (isalpha) __class__ __name__ [0])
os.getcwd().isalpha().__class__.__name__[0]
'b'

The calls could also accept arguments, as Clojure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions