Nim: Destructuring objects by field names

Created on 17 Feb 2020  路  3Comments  路  Source: nim-lang/Nim

When person is an object,

let (name, age) = person

would be equivalent to

let name = person.name
let age = person.age

The shorter unpacking syntax is very frequently used in Javascript (ES6), so it seems useful. Since tuple unpacking is already implemented in Nim but it cannot be used with objects, this would complete the feature using the same syntax but with fields names inferred from variable names.

In contrast to positional destructuring (tuple unpack), this avoids the use of underscores to omit fields not needed, but most importantly avoids problems whenever fields are changed. Positional unpacking is error prone and has big maintenance burden if fields are ever changed.

Feature

Most helpful comment

Shouldn't this go in https://github.com/nim-lang/RFCs? Also an alternative could be

let (name: nameVar, age: ageVar) = person

which also works for named tuples

All 3 comments

If slightly different syntax is ok, this can be done via a macro quite easily:

import macros

type
  Person = object
    name: string
    age: int
    id: int
    amount: float

macro unpackLet(argsBody: untyped): untyped =
  expectKind argsBody[0], nnkAsgn
  let arg = argsBody[0][1]
  let par = argsBody[0][0]
  expectKind par, nnkPar
  var access = nnkPar.newTree
  result = nnkVarTuple.newTree
  for ch in par:
    # add fields to tuple on LHS
    result.add ch
    # build dot expressions to create RHS
    access.add nnkDotExpr.newTree(arg, ch)
  result.add newEmptyNode()
  result.add access
  # put everything into let section
  result = nnkLetSection.newTree(result)

var person = Person(name: "Foo",
                    age: 33,
                    id: 12,
                    amount: 1.234)

unpackLet:
  (name, age) = person

echo "Name ", name
echo "Age ", age

In contrast to positional destructuring (tuple unpack), this avoids the use of underscores to omit fields not needed, but most importantly avoids problems whenever fields are changed. Positional unpacking is error prone and has big maintenance burden if fields are ever changed.

This introduces a new, rather foreign concept into Nim, namely that inside let (name1, name2) = rhs the names have to conform to rhs. For every other construct you get to choose the names freely. -1 from me.

Shouldn't this go in https://github.com/nim-lang/RFCs? Also an alternative could be

let (name: nameVar, age: ageVar) = person

which also works for named tuples

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kobi2187 picture kobi2187  路  4Comments

awr1 picture awr1  路  3Comments

koki-koba picture koki-koba  路  3Comments

wizzardx picture wizzardx  路  4Comments

zaxebo1 picture zaxebo1  路  4Comments