Skip to content

outplace and chaining -- version 2 #193

@Araq

Description

@Araq

There have been a couple of competing designs in order to add outplace and chaining to Nim. Here is a new one that tries to be convenient to use, simple to implement and without gotchas. Names have been chosen instead of operators for two reasons:

  • How they interact with the "dot notation" is obvious.
  • Many people prefer words over Perl-like custom operators.

outplace / dup

The current outplace should be renamed to dup focussing on the "works on a duplicate/copy" aspect. dup looks like the following:

macro dup*[T](x: T; calls: varargs[untyped]): T = discard "..."

# examples
var a = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
doAssert a.dup(sort) == sorted(a)

var aCopy = a
aCopy.insert(10)

doAssert a.dup(insert(10), sort()) == sorted(aCopy)
doAssert a.dup(insert(_, 10), sort()) == sorted(aCopy)

As can be seen in the examples, the 2nd argument to dup is a list of "call expressions". The call expression can contain _, if so the _ is replaced by the copy that dup introduces. Otherwise the copy is passed as the first argument to the call. If the expression is missing the (), it is turned into a call.

chain / operateOn / with

The operateOn macro should be renamed to with. It looks like this:

macro with*[T](x: T; calls: varargs[untyped]): void = discard "..."

var w: Window
with(w, setColor(green), setPosition(10, 20), setVisible(true))

The same rules apply as for dup, the 2nd argument is a list of call expressions with optional _ markers. Notice that dup returns an expression of type T and that with returns an expression of type void.

Block syntax

Both operations also work with a "block syntax", the 2nd argument then is a block of statements that is transformed.

with w:
  setColor(green)
  setPosition(1, 2)
  setVisible(true)

@[1, 2, 3, 4, 5].dup:
  insert 10
  sort()
  filterByIt it != 4

The block syntax does not support control flow, if etc are not allowed, only a flat list of call expressions and for every call the first argument is injected. The macros are deliberately not smart.

dup is a very important feature for Nim as it allows us to deprecate sorted and friends, hence dup will be added to sugar.nim. with is rarely useful, as either Nim's named parameters or varargs can be used instead. with will be in its own module std / with.

See #192 for a disussion that led to this particular design.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions