Closed al6x closed 3 years ago
The syntax is ambiguous regarding the let scope. This is better
type
Unit = object
race: string
hp: int
name: string
with(Unit):
race = "Protoss"
hp = 100
echo Unit(race, hp, name: "Zeratul")
echo Unit(race, hp, name: "Artanis")
echo Unit(:race, :hp, name: "Zeratul") # Alternative way
So that the default value are scoped.
Alternatively we can expand using
which currently supports
using
c: Context
n: Node
counter: int
proc foo(c, n) = ...
proc bar(c, n, counter) = ...
proc baz(c, n) = ...
proc mixedMode(c, n; x, y: int) =
# 'c' is inferred to be of the type 'Context'
# 'n' is inferred to be of the type 'Node'
# But 'x' and 'y' are of type 'int'.
Hmm, with
and using
feels too complicated, the whole point of this shortcut is to be trivial and be used on the fly.
The need to know about and use special keywords like with
or using
kinda defeat the whole point of having such shortcut. In the end code will be even more complicated than without using this shortcut at all.
I think the only thing needed is to have object constructor not require the field names just like a proc call.
i.e. today we have to do MyConstructor(a: x, b: y, c: z)
and we should allow MyConstructor(x, y, z)
I think the only thing needed is to have object constructor not require the field names just like a proc call.
Wouldn't that imply that changing the order of the fields in the type definition is a breaking change?
Rust also has this shorthand that the field name can be omitted if and only if the local variable has the same name, which in my opinion is a nice tradeoff in terms of conciseness and safe semantics.
I think the only thing needed is to have object constructor not require the field names just like a proc call.
Wouldn't that imply that changing the order of the fields in the type definition is a breaking change?
Yes but I think this pattern is common
type Foo = object
a: int
b: float
c: string
proc initFoo(a: int, b: float, c: string): Foo =
result.a = a
result.b = b
result.c = c
let
a = 1
b = 2.0
c = "three"
let x = initFoo(a, b, c)
or
type Foo = object
a: int
b: float
c: string
let
a = 1
b = 2.0
c = "three"
let x = Foo(a: a, b: b, c: c)
and both would be replaced by
type Foo = object
a: int
b: float
c: string
let
a = 1
b = 2.0
c = "three"
let x = Foo(a, b, c)
Now, do people often change the field order for public objects, I don't know. The Rust-like suggestion is interesting.
This can and should be done via a macro instead of compiler patch.
echo Unit.init(race, hp, name: "Zeratul")
closing, see https://github.com/nim-lang/RFCs/pull/225; please re-open as an issue, not a PR
A shorter way to pass parameters during object initalization, read rendered markdown
Short example:
CC @dom96