summary refs log tree commit diff stats
path: root/doc/manual.rst
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2021-05-31 13:14:50 -0700
committerGitHub <noreply@github.com>2021-05-31 22:14:50 +0200
commit60cbdbf37ac66624f78edd5b3d575c80c6603679 (patch)
tree5970e920c9d838cd366fd32e8af009e515295cef /doc/manual.rst
parenta36efb59b5a74db6c5bbe6c0997c0221d0f55491 (diff)
downloadNim-60cbdbf37ac66624f78edd5b3d575c80c6603679.tar.gz
close #18092 document elif in case statements (#18105)
* close #18092 [skip ci] document elif in case statements

* fixup

* clarify spec; mention special rule for string in case statements

* address comments
Diffstat (limited to 'doc/manual.rst')
-rw-r--r--doc/manual.rst30
1 files changed, 18 insertions, 12 deletions
diff --git a/doc/manual.rst b/doc/manual.rst
index 6a0dec120..ff34b62ca 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -2981,11 +2981,13 @@ Example:
 
 .. code-block:: nim
 
-  case readline(stdin)
+  let line = readline(stdin)
+  case line
   of "delete-everything", "restart-computer":
     echo "permission denied"
   of "go-for-a-walk":     echo "please yourself"
-  else:                   echo "unknown command"
+  elif line.len == 0:     echo "empty" # optional, must come after `of` branches
+  else:                   echo "unknown command" # ditto
 
   # indentation of the branches is also allowed; and so is an optional colon
   # after the selecting expression:
@@ -2996,19 +2998,23 @@ Example:
     else:                   echo "unknown command"
 
 
-The `case` statement is similar to the if statement, but it represents
+The `case` statement is similar to the `if` statement, but it represents
 a multi-branch selection. The expression after the keyword `case` is
 evaluated and if its value is in a *slicelist* the corresponding statements
 (after the `of` keyword) are executed. If the value is not in any
-given *slicelist* the `else` part is executed. If there is no `else`
-part and not all possible values that `expr` can hold occur in a
-*slicelist*, a static error occurs. This holds only for expressions of
-ordinal types. "All possible values" of `expr` are determined by `expr`'s
-type. To suppress the static error an `else` part with an
-empty `discard` statement should be used.
+given *slicelist*, trailing `elif` and `else` parts are executed using same
+semantics as for `if` statement, and `elif` is handled just like `else: if`.
+If there are no `else` or `elif` parts and not
+all possible values that `expr` can hold occur in a *slicelist*, a static error occurs.
+This holds only for expressions of ordinal types.
+"All possible values" of `expr` are determined by `expr`'s type.
+To suppress the static error an `else: discard` should be used.
 
 For non-ordinal types, it is not possible to list every possible value and so
 these always require an `else` part.
+An exception to this rule is for the `string` type, which currently doesn't
+require a trailing `else` or `elif` branch; it's unspecified whether this will
+keep working in future versions.
 
 Because case statements are checked for exhaustiveness during semantic analysis,
 the value in every `of` branch must be a constant expression.
@@ -3054,15 +3060,15 @@ won't work:
   var foo = Foo(x: @[])
   foo.get_x().add("asd")
 
-This can be fixed by explicitly using `return`:
+This can be fixed by explicitly using `result` or `return`:
 
 .. code-block:: nim
   proc get_x(x: Foo): var seq[string] =
     case true
     of true:
-      return x.x
+      result = x.x
     else:
-      return x.x
+      result = x.x
 
 
 When statement