elvis

The elvis package implements a 'truthy', 'ternary' and a 'coalesce' operator to Nim as syntactic sugar for working with conditional expressions


Keywords
operator, elvis, ternary, template, truthy, falsy, exception, none, null, nil, 0, NaN, coalesce, nim
License
MIT
Install
nimble install elvis

Documentation

Elvis

The Elvis package implements a truthy (?), ternary (?!), coalesce (?:) and a conditional assignment (?=) operator and an experimental conditional access operator (?.) as syntactic sugar for Nim to work with conditional expressions using more than just boolean types.

Truthy operator : ?

The ? operator will try to convert any expression to a boolean. In general a value is considered false if it has not yet been initialised or isNil, none or throws an excpetion.

These rules are currently implmented..

type false falsy example truthy example
int 0 assert(not(?0)) assert ?1
float 0.0 or NaN assert(not(?NaN)) assert ?1.1
char \0 assert(not(?'\0')) assert ?'0'
string "" assert(not(?"")) assert ?"0"
seq[T] @[] var s:seq[int]; assert(not(?s)) assert ?(@[0])
option[T] none assert(not(none(string))) assert ?some("")
Any exception assert(not(?{"one":1}.newTable["two"])) assert ?{"one":1}.newTable["one"]
nilable isNil() `` ``

Elvis Operator: ?:

The elvis operator will return the left operand if it is 'truthy' otherwise it will return the right operand.

See null coalescing operator ?:

Examples, Test and Implmentation ideas have been in part derived from the Coalesce module ('https://github.com/piedar/coalesce'). That module should be prefered by those looking for a stricter implmentation of a Null coalescing operator, but the implmentation here may be more usefull especially now that stings are not nilable (from Nim 0.19)

Examples:

assert ("" ?: "b") == "b"
assert (0 ?: 1) == 1
assert (none(int) ?: 1) == 1

Longer chains work too, and the expression short-circuits if possible.

eg.

let result = tryComputeFast(input) ?: tryComputeSlow(input) ?: myDefault

Ternary Operator : ? !

The Ternary operator will return the middle operand if the left operand evaluates as truthy otherwise it will return the right operand.

This implementation was taken from Araq's suggestion on from https://forum.nim-lang.org/t/3342

Note: Due to compiler limitations the '!' operation is implemented as a proc and is evaluated eagerly.

Examples:

assert (true ? "a" ! "b") == "a"
assert (false ? "a" ! "b") == "b"
assert ("c" ? "a" ! "b") == "a"
assert ("" ? "a" ! "b") == "b"

Conditional Assignment Operator : ?=

The Conditional assignment operator will assign the right operand to the left operand only when the left operand evaluates as Truthy

Examples:

var s:string
s ?= "a" 
assert (s == "a")
s ?= "b"
assert (s == "a")

Conditional Access Operator : ?.

The Conditional access operator will call the right operand with the left operand as thefirst argument when the left operand evaluates as truthy. Otherwise it will return a new unintiated instance (falsy) whatever type the right operand proc would have returned.

Example:

 let s = @["one"]
 assert((s[0]?.len) == 3)
 assert((s[1]?.len) == 0)