options

This module implements types which encapsulate an optional value.

A value of type Option[T] either contains a value x (represented as some(x)) or is empty (none(T)).

This can be useful when you have a value that can be present or not. The absence of a value is often represented by nil, but it is not always available, nor is it always a good solution.

Basic usage

Let's start with an example: a procedure that finds the index of a character in a string.

import options

proc find(haystack: string, needle: char): Option[int] =
  for i, c in haystack:
    if c == needle:
      return some(i)
  return none(int)  # This line is actually optional,
                    # because the default is empty
let found = "abc".find('c')
assert found.isSome and found.get() == 2

The get operation demonstrated above returns the underlying value, or raises UnpackDefect if there is no value. Note that UnpackDefect inherits from system.Defect, and should therefore never be caught. Instead, rely on checking if the option contains a value with isSome and isNone procs.

How to deal with an absence of a value:

let result = "team".find('i')

# Nothing was found, so the result is `none`.
assert(result == none(int))
# It has no value:
assert(result.isNone)

Types

Option[T] = object
  when T is SomePointer:
    val
  else:
      val
      has

  
An optional type that stores its value and state separately in a boolean.   Source Edit
UnpackDefect = object of Defect
  Source Edit
UnpackError {...}{.deprecated: "See corresponding Defect".} = UnpackDefect
  Source Edit

Procs

proc option[T](val: T): Option[T] {...}{.inline.}

Can be used to convert a pointer type (ptr or ref or proc) to an option type. It converts nil to None.

See also:

Example:

type
  Foo = ref object
    a: int
    b: string
var c: Foo
assert c.isNil
var d = option(c)
assert d.isNone
  Source Edit
proc some[T](val: T): Option[T] {...}{.inline.}

Returns an Option that has the value val.

See also:

Example:

var
  a = some("abc")
  b = some(42)
assert $type(a) == "Option[system.string]"
assert b.isSome
assert a.get == "abc"
assert $b == "Some(42)"
  Source Edit
proc none(T: typedesc): Option[T] {...}{.inline.}

Returns an Option for this type that has no value.

See also:

Example:

var a = none(int)
assert a.isNone
assert $type(a) == "Option[system.int]"
  Source Edit
proc none[T](): Option[T] {...}{.inline.}
Alias for none(T) proc.   Source Edit
proc isSome[T](self: Option[T]): bool {...}{.inline.}
Checks if an Option contains a value.

Example:

var
  a = some(42)
  b = none(string)
assert a.isSome
assert not b.isSome
  Source Edit
proc isNone[T](self: Option[T]): bool {...}{.inline.}
Checks if an Option is empty.

Example:

var
  a = some(42)
  b = none(string)
assert not a.isNone
assert b.isNone
  Source Edit
proc get[T](self: Option[T]): lent T {...}{.inline.}

Returns contents of an Option. If it is None, then an exception is thrown.

See also:

Example:

let
  a = some(42)
  b = none(string)
assert a.get == 42
doAssertRaises(UnpackDefect):
  echo b.get
  Source Edit
proc get[T](self: Option[T]; otherwise: T): T {...}{.inline.}
Returns the contents of the Option or an otherwise value if the Option is None.

Example:

var
  a = some(42)
  b = none(int)
assert a.get(9999) == 42
assert b.get(9999) == 9999
  Source Edit
proc get[T](self: var Option[T]): var T {...}{.inline.}
Returns contents of the var Option. If it is None, then an exception is thrown.

Example:

let
  a = some(42)
  b = none(string)
assert a.get == 42
doAssertRaises(UnpackDefect):
  echo b.get
  Source Edit
proc map[T](self: Option[T]; callback: proc (input: T)) {...}{.inline.}

Applies a callback function to the value of the Option, if it has one.

See also:

Example:

var d = 0
proc saveDouble(x: int) =
  d = 2*x

let
  a = some(42)
  b = none(int)

b.map(saveDouble)
assert d == 0
a.map(saveDouble)
assert d == 84
  Source Edit
proc map[T, R](self: Option[T]; callback: proc (input: T): R): Option[R] {...}{.
    inline.}

Applies a callback function to the value of the Option and returns an Option containing the new value.

If the Option is None, None of the return type of the callback will be returned.

See also:

Example:

var
  a = some(42)
  b = none(int)

proc isEven(x: int): bool =
  x mod 2 == 0

assert $(a.map(isEven)) == "Some(true)"
assert $(b.map(isEven)) == "None[bool]"
  Source Edit
proc flatten[A](self: Option[Option[A]]): Option[A] {...}{.inline.}
Remove one level of structure in a nested Option.

Example:

let a = some(some(42))
assert $flatten(a) == "Some(42)"
  Source Edit
proc flatMap[A, B](self: Option[A]; callback: proc (input: A): Option[B]): Option[
    B] {...}{.inline.}

Applies a callback function to the value of the Option and returns an Option containing the new value.

If the Option is None, None of the return type of the callback will be returned.

Similar to map, with the difference that the callback returns an Option, not a raw value. This allows multiple procs with a signature of A -> Option[B] to be chained together.

See also:

Example:

proc doublePositives(x: int): Option[int] =
  if x > 0:
    return some(2*x)
  else:
    return none(int)
let
  a = some(42)
  b = none(int)
  c = some(-11)
assert a.flatMap(doublePositives) == some(84)
assert b.flatMap(doublePositives) == none(int)
assert c.flatMap(doublePositives) == none(int)
  Source Edit
proc filter[T](self: Option[T]; callback: proc (input: T): bool): Option[T] {...}{.
    inline.}

Applies a callback to the value of the Option.

If the callback returns true, the option is returned as Some. If it returns false, it is returned as None.

See also:

Example:

proc isEven(x: int): bool =
  x mod 2 == 0
let
  a = some(42)
  b = none(int)
  c = some(-11)
assert a.filter(isEven) == some(42)
assert b.filter(isEven) == none(int)
assert c.filter(isEven) == none(int)
  Source Edit
proc `==`(a, b: Option): bool {...}{.inline.}
Returns true if both Options are None, or if they are both Some and have equal values.

Example:

let
  a = some(42)
  b = none(int)
  c = some(42)
  d = none(int)

assert a == c
assert b == d
assert not (a == b)
  Source Edit
proc `$`[T](self: Option[T]): string

Get the string representation of the Option.

If the Option has a value, the result will be Some(x) where x is the string representation of the contained value. If the Option does not have a value, the result will be None[T] where T is the name of the type contained in the Option.

  Source Edit
proc unsafeGet[T](self: Option[T]): lent T {...}{.inline.}

Returns the value of a some. Behavior is undefined for none.

Note: Use it only when you are absolutely sure the value is present (e.g. after checking isSome). Generally, using get proc is preferred.

  Source Edit