Skip to content

Commit 070847c

Browse files
committed
Re-wrote documentation for options and optionutils
1 parent d65b67f commit 070847c

File tree

2 files changed

+97
-63
lines changed

2 files changed

+97
-63
lines changed

lib/pure/options.nim

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,6 @@
3939
## return none(int) # This line is actually optional,
4040
## # because the default is empty
4141
##
42-
## .. code-block:: nim
43-
## require "abc".find('c'):
44-
## some x: assert(x == 2)
45-
## none: assert false # This will not be reached, because the string
46-
## # contains 'c'
47-
##
48-
## This pattern assures that you only access the value of on option in a safe
49-
## way. If you want to use a more familiar exception pattern you can use:
50-
##
51-
## .. code-block:: nim
52-
##
5342
## try:
5443
## assert("abc".find('c').get() == 2) # Immediately extract the value
5544
## except UnpackError: # If there is no value
@@ -59,58 +48,11 @@
5948
## raises ``UnpackError`` if there is no value. There is another option for
6049
## obtaining the value: ``unsafeGet``, but you must only use it when you are
6150
## absolutely sure the value is present (e.g. after checking ``isSome``). If
62-
## you do not care about the tiny overhead that ``get`` and ``require`` causes,
63-
## you should simply never use ``unsafeGet``.
64-
##
65-
## By far the safest and simplest way to use an option value is the ``require``
66-
## procedure. It can take either a single statement as seen above, or multiple.
67-
## Note that in the same way as the other operators work ``require`` will not
68-
## evaluate all statements if an earlier one doesn't return a value:
69-
##
70-
## .. code-block:: nim
71-
## let msg = require([some(-100), some(200)]):
72-
## some [x, _]: "First value is " & $x
73-
## none: "No value"
74-
## echo msg # This will echo "First value is -100"
75-
##
76-
## As seen above you can ignore the value of the option with an underscore as
77-
## the identifier. But if you want to assign it to a locally available symbol
78-
## simply add it in the same position in the list. The underscore can be used to
79-
## ignore one value, the entire list of values, or only some of the values.
80-
##
81-
## This module also implements common mapping functionality to use a procedure
82-
## on an optional value, carrying over the absence state if there is no value:
83-
##
84-
## .. code-block:: nim
85-
##
86-
## let
87-
## x = some(10)
88-
## y = none(int)
89-
## assert(map(x, proc(x: int): int = x + 10) == some(20))
90-
## assert(map(y, proc(x: int): int = x + 10).isNone)
91-
##
92-
## Options can also be used for conditional chaining. Let's use the ``find``
93-
## procedure we defined above:
94-
##
95-
## .. code-block:: nim
96-
## var position = "hello world".find('w')
97-
## echo position # echoes out Some(6) is expected
98-
## position = "hello world".find('w').?min(4)
99-
## echo position # echoes out Some(4), we take the minimum of 6 and 4
100-
## position = "hello world".find('q').?min(4)
101-
## echo position # echoes out None[int], min is never run since find returns
102-
## # a none option.
103-
## position = "hello world".find('w').?min(4).max(0)
104-
## echo position # echoes out Some(4) both min and max are run
105-
## position = "hello world".find('q').?min(4).max(0)
106-
## echo position # echoes out None[int], min and max is never run
107-
##
108-
## Since options use their has-ity as their boolean value this chaining can
109-
## also be used in if statements:
110-
##
111-
## .. code-block:: nim
112-
## if ("hello world".find('w').?min(4)).isSome:
113-
## echo "Never run"
51+
## you do not care about the tiny overhead that ``get`` causes,
52+
## you should simply never use ``unsafeGet``. Also have a look at ``optionutils``
53+
## for more ways of safely interacting with optional values. Prior to 0.19.0 many
54+
## of the features found in that module was part of this module. This module now
55+
## only contains the basic concept of options.
11456
import typetraits
11557

11658
type

lib/pure/optionutils.nim

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,95 @@
1+
#
2+
#
3+
# Nim's Runtime Library
4+
# (c) Copyright 2015 Nim Contributors
5+
#
6+
# See the file "copying.txt", included in this
7+
# distribution, for details about the copyright.
8+
#
9+
10+
## Abstract
11+
## ========
12+
##
13+
## This module expands the usability of options with several practical patters
14+
## and procedures. The goal is to make it safer and more ergonomic to use options
15+
## and to handle optional values.
16+
##
17+
## Tutorial
18+
## ========
19+
##
20+
## Let's start with the same example as in the options module: a procedure that
21+
## finds the index of a character in a string.
22+
##
23+
## .. code-block:: nim
24+
##
25+
## import options
26+
##
27+
## proc find(haystack: string, needle: char): Option[int] =
28+
## for i, c in haystack:
29+
## if c == needle:
30+
## return some(i)
31+
## return none(int) # This line is actually optional,
32+
## # because the default is empty
33+
##
34+
## allSome "abc".find('c'):
35+
## some x: assert(x == 2)
36+
## none: assert false # This will not be reached, because the string
37+
## # contains 'c'
38+
##
39+
## This pattern assures that you only access the value of on option in a safe
40+
## way. This is by far the safest and simplest way to use an option value. It
41+
## can take either a single statement as seen above, or multiple. Note that
42+
## ``allSome`` will not evaluate all statements if an earlier one doesn't return
43+
## a value:
44+
##
45+
## .. code-block:: nim
46+
## let msg = allSome([none(int), some(200)]):
47+
## some [x, _]: "First value is " & $x
48+
## none: "No value"
49+
## echo msg # This will echo "No value"
50+
##
51+
## In this block the call to ``some(200)`` is never executed, so it's safe to
52+
## put a list of expensive operations in a block like this.
53+
##
54+
## As seen above you can also ignore the value of an option by using an
55+
## underscore as the identifier. But if you want to assign it to a locally
56+
## available symbol simply add it in the same position in the list. The
57+
## underscore can be used to ignore one value, the entire list of values, or
58+
## only some of the values.
59+
##
60+
## This module also implements common mapping functionality to use a procedure
61+
## on an optional value, carrying over the absence state if there is no value:
62+
##
63+
## .. code-block:: nim
64+
##
65+
## let
66+
## x = some(10)
67+
## y = none(int)
68+
## assert(map(x, proc(x: int): int = x + 10) == some(20))
69+
## assert(map(y, proc(x: int): int = x + 10).isNone)
70+
##
71+
## Options can also be used for conditional chaining with the `.?` operator.
72+
## Let's use the ``find`` procedure we defined above:
73+
##
74+
## .. code-block:: nim
75+
## var position = "hello world".find('w')
76+
## echo position # echoes out Some(6) as expected
77+
## position = "hello world".find('w').?min(4)
78+
## echo position # echoes out Some(4), we take the minimum of 6 and 4
79+
## position = "hello world".find('q').?min(4)
80+
## echo position # echoes out None[int], min is never run since find returns
81+
## # a none option.
82+
## position = "hello world".find('w').?min(4).max(0)
83+
## echo position # echoes out Some(4) both min and max are run
84+
## position = "hello world".find('q').?min(4).max(0)
85+
## echo position # echoes out None[int], min and max is never run
86+
##
87+
## Since options use their has-ity as their boolean value this chaining can
88+
## also be used in if statements:
89+
##
90+
## .. code-block:: nim
91+
## if ("hello world".find('w').?min(4)).isSome:
92+
## echo "Never run"
193
import options
294
import macros
395

0 commit comments

Comments
 (0)