chain
Nim's function chaining and method cascading
Summary
| Latest Version | Unknown |
|---|---|
| License | MIT |
| CI Status | Failing |
| Downloads | 0 |
| Last Indexed | 2026-07-21 05:24 |
Tags
Installation
nimble install chain
choosenim install chain
git clone https://github.com/khchen/chain
OS Compatibility
| Platform | Linux | macOS | Windows | FreeBSD | OpenBSD | NetBSD | Android | iOS | WASM | Embedded |
|---|---|---|---|---|---|---|---|---|---|---|
| chain | ✓ | ✓ | ✓ | - | - | - | - | - | - | - |
Source
| Repository | https://github.com/khchen/chain |
|---|---|
| Homepage | https://github.com/khchen/chain |
| Registry Source | nimble_official |
README
Chain
For object oriented programming, function chaining and method cascading syntax is really convenient. We already have std/with and cascade. However, when I use them to write real GUI program (for example, wNim), both of them have a lot of limit. So I write this chain macro, which is designed to be drop-in replacement for these two module, and more powerful.
Features:
* Parameters syntax or block syntax (like std/with).
* as syntax to create named variable that can be used in block.
* Expressions will be evaluated only one time (by create anonymous variable).
* Nested fields, nested calls, and nested chain.
* Underscore can be used anywhere to represent this object.
* Works in control flow statements, including block, try/except/finally, defer, if, when, for, while, case, etc.
Notice: using chain wisely can improve readability, but overuse may lead opposite effect.
Basic Usage
Replace std/with:
var x = "yay"
chain x:
add "abc"
add "efg"
doAssert x == "yayabcefg"
Replace cascade:
chain Button() as btn: # btn can be used inside and outside the block
text = "ok"
width = 30
color = "#13a89e"
enable()
or
var btn = chained Button(): # btn cannot be used inside the block
text = "ok"
width = 30
color = "#13a89e"
enable()
I recommend chain ... as instead of chained because it is more convenient. However, the choice is yours.
Features in detail
-
Parameters syntax. ```nim var a = 44 chain(a, +=4, -=5) doAssert a == 43
type Point = object x, y: int
proc setX(pt: var Point, x: int) = pt.x = x proc setY(pt: var Point, y: int) = pt.y = y
chain(Point() as pt, setX(1), setY(2)) doAssert pt == Point(x: 1, y: 2) ```
-
Block syntax. ```nim chain 44 as a: +=4 -=5 doAssert a == 43
chain Point() as pt: setX(1) setY(2) doAssert pt == Point(x: 1, y: 2) ```
-
chaincan accept both variable or expression. For expression, unlikestd/with, it will be evaluate only one time. ```nim var count1, count2: int template next1(): int = count1.inc; count1 template next2(): int = count2.inc; count2 proc nop(x: int) = discardwith next1: # std/with will call next1() three times nop; nop; nop
chain next2: # chain will call next2() only one time nop; nop; nop
doAssert count1 == 3 doAssert count2 == 1 ```
-
Nested fields, nested calls, and nested chain. In summary,
chainadd_.to every calls and assignments, exceptchain,chained, and_(underscore).nim # pseudocode chain a: b.c.d = e f.g.h() chain i: j.k.l = m n.o.p()To add a expression without_., use parentheses to enclose it.nim chain Point() as pt: x = 1 _.x = 1 (pt.x = 1) # all the same -
Underscore can be used anywhere to represent
thisobject. ```nim chain "abc": (doAssert _ == "abc") chain "def": (doAssert _ == "def")chain "abc": chain _ & "def": &= "ghi" .add _ [0] = 'z' (doAssert _ == "zbcdefghiabcdefghi") ```
-
Works in control flow statements, including block, try/except/finally, defer, if, when, for, while, case, etc. ```nim chain 1: block: +=1 defer: +=1 try: +=1 finally: +=1 if true: +=1 when true: +=1 for i in 1..1: +=1 while true: +=1 break
(doAssert _ == 9) ```
-
GUI example. ```nim import wNim/[wApp, wFrame, wMenuBar, wMenu] import chain
chain App(): chain Frame(): title = "wNim" size = (640, 480)
wIdExit do (): _.close() chain MenuBar(_): chain Menu(_, "&File"): append(wIdOpen, "&Open") appendSeparator() append(wIdExit, "E&xit") show() center()mainLoop()
```
License
Read license.txt for more details.
Copyright (c) 2021 Kai-Hung Chen, Ward. All rights reserved.