fleabitdev / glsp

The GameLisp scripting language
https://gamelisp.rs/
Apache License 2.0
394 stars 13 forks source link

Feature request: object destructuring #24

Closed tyomitch closed 3 years ago

tyomitch commented 3 years ago
(defstruct Point row col)

(defn foo (point)
    (let #((row row) (col col)) point)
    ; error: literal pattern mismatch: expected #((row row) (col col)), received #<obj:Point>
)

Even better if (let #(row col) point) could be supported as shorthand for the above.

fleabitdev commented 3 years ago

You want an indexing pattern :)

(defstruct Point row col)
(let point (Point (row 1) (col 2))
(let [row col] point)
(prn row col) ; prints 1 2

Sorry for the confusion - the pattern-matching chapter in the reference manual could do with a rewrite, if I'm being honest!

tyomitch commented 3 years ago

May I argue that this syntax is out of line with most other patterns?

After (let (x (y z) "any literal" ..rest) foo), the value (x (y z) "any literal" ..rest) equals foo, but after (let [row col] point), the value [row col] is nothing like foo. This is why using #((row row) (col col)) for the pattern felt intuitive.

fleabitdev commented 3 years ago

You're quite right - there are two metaphors that could have been used here. I chose "indexing patterns" over "table-destructuring patterns" for a few reasons:

(let [x : int?, y : int?] pt)

I agree that the lack of symmetry is frustrating.