Merge pull request #2789 from ozra/devel

Change wording in some parts. Fix some typos.
This commit is contained in:
Andreas Rumpf 2015-05-26 19:53:08 +02:00
commit 11bd7ef5e8
11 changed files with 94 additions and 65 deletions

View file

@ -1,15 +1,15 @@
About this document About this document
=================== ===================
**Note**: This document is a draft! Several of Nim's features need more **Note**: This document is a draft! Several of Nim's features may need more
precise wording. This manual will evolve into a proper specification some precise wording. This manual is constantly evolving until the 1.0 release and is
day. not to be considered as the final proper specification.
This document describes the lexis, the syntax, and the semantics of Nim. This document describes the lexis, the syntax, and the semantics of Nim.
The language constructs are explained using an extended BNF, in The language constructs are explained using an extended BNF, in which ``(a)*``
which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and ``(a)?`` means an
``(a)?`` means an optional *a*. Parentheses may be used to group elements. optional *a*. Parentheses may be used to group elements.
``&`` is the lookahead operator; ``&a`` means that an ``a`` is expected but ``&`` is the lookahead operator; ``&a`` means that an ``a`` is expected but
not consumed. It will be consumed in the following rule. not consumed. It will be consumed in the following rule.
@ -33,5 +33,5 @@ and ``a ^* b`` is short for ``(a (b a)*)?``. Example::
arrayConstructor = '[' expr ^* ',' ']' arrayConstructor = '[' expr ^* ',' ']'
Other parts of Nim - like scoping rules or runtime semantics are only Other parts of Nim - like scoping rules or runtime semantics are only
described in an informal manner for now. described in the, more easily comprehensible, informal manner for now.

View file

@ -30,7 +30,7 @@ exceptions* or *dying with a fatal error*. However, the implementation
provides a means to disable these runtime checks. See the section pragmas_ provides a means to disable these runtime checks. See the section pragmas_
for details. for details.
Wether a checked runtime error results in an exception or in a fatal error at Whether a checked runtime error results in an exception or in a fatal error at
runtime is implementation specific. Thus the following program is always runtime is implementation specific. Thus the following program is always
invalid: invalid:

View file

@ -48,7 +48,7 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph:
However if the call is of the form ``f(...)`` where ``f`` is a parameter However if the call is of the form ``f(...)`` where ``f`` is a parameter
of the currently analysed routine it is ignored. The call is optimistically of the currently analysed routine it is ignored. The call is optimistically
assumed to have no effect. Rule 2 compensates for this case. assumed to have no effect. Rule 2 compensates for this case.
2. Every expression of some proc type wihtin a call that is not a call 2. Every expression of some proc type within a call that is not a call
itself (and not nil) is assumed to be called indirectly somehow and thus itself (and not nil) is assumed to be called indirectly somehow and thus
its raises list is added to ``p``'s raises list. its raises list is added to ``p``'s raises list.
3. Every call to a proc ``q`` which has an unknown body (due to a forward 3. Every call to a proc ``q`` which has an unknown body (due to a forward

View file

@ -80,7 +80,7 @@ underscores ``__`` are not allowed::
digit ::= '0'..'9' digit ::= '0'..'9'
IDENTIFIER ::= letter ( ['_'] (letter | digit) )* IDENTIFIER ::= letter ( ['_'] (letter | digit) )*
Currently any unicode character with an ordinal value > 127 (non ASCII) is Currently any Unicode character with an ordinal value > 127 (non ASCII) is
classified as a ``letter`` and may thus be part of an identifier but later classified as a ``letter`` and may thus be part of an identifier but later
versions of the language may assign some Unicode characters to belong to the versions of the language may assign some Unicode characters to belong to the
operator characters instead. operator characters instead.

View file

@ -178,8 +178,7 @@ Module scope
~~~~~~~~~~~~ ~~~~~~~~~~~~
All identifiers of a module are valid from the point of declaration until All identifiers of a module are valid from the point of declaration until
the end of the module. Identifiers from indirectly dependent modules are *not* the end of the module. Identifiers from indirectly dependent modules are *not*
available. The `system`:idx: module is automatically imported in every other available. The `system`:idx: module is automatically imported in every module.
module.
If a module imports an identifier by two different modules, each occurrence of If a module imports an identifier by two different modules, each occurrence of
the identifier has to be qualified, unless it is an overloaded procedure or the identifier has to be qualified, unless it is an overloaded procedure or

View file

@ -18,9 +18,7 @@ The deprecated pragma is used to mark a symbol as deprecated:
proc p() {.deprecated.} proc p() {.deprecated.}
var x {.deprecated.}: char var x {.deprecated.}: char
It can also be used as a statement. Then it takes a list of *renamings*. The It can also be used as a statement, in that case it takes a list of *renamings*.
upcoming ``nimfix`` tool can automatically update the code and perform these
renamings:
.. code-block:: nim .. code-block:: nim
type type
@ -28,6 +26,9 @@ renamings:
Stream = ref object Stream = ref object
{.deprecated: [TFile: File, PStream: Stream].} {.deprecated: [TFile: File, PStream: Stream].}
The ``nimfix`` tool can be used to, without effort, automatically update your
code and refactor it by performing these renamings.
noSideEffect pragma noSideEffect pragma
------------------- -------------------
@ -54,9 +55,7 @@ destructor pragma
----------------- -----------------
The ``destructor`` pragma is used to mark a proc to act as a type destructor. The ``destructor`` pragma is used to mark a proc to act as a type destructor.
Its usage is deprecated, use the ``override`` pragma instead. Its usage is deprecated, See `type bound operations`_ instead.
See `type bound operations`_.
override pragma override pragma
--------------- ---------------
@ -371,7 +370,7 @@ The ``register`` pragma is for variables only. It declares the variable as
in a hardware register for faster access. C compilers usually ignore this in a hardware register for faster access. C compilers usually ignore this
though and for good reasons: Often they do a better job without it anyway. though and for good reasons: Often they do a better job without it anyway.
In highly specific cases (a dispatch loop of an bytecode interpreter for In highly specific cases (a dispatch loop of a bytecode interpreter for
example) it may provide benefits, though. example) it may provide benefits, though.
@ -429,13 +428,13 @@ Example:
2. When a top level call is encountered (usually at the very end of the module), 2. When a top level call is encountered (usually at the very end of the module),
the compiler will try to determine the actual types of all of the symbols in the the compiler will try to determine the actual types of all of the symbols in the
matching overload set. This is a potentially recursive process as the signatures matching overload set. This is a potentially recursive process as the signatures
of the symbols may include other call expressions, whoose types will be resolved of the symbols may include other call expressions, whose types will be resolved
at this point too. at this point too.
3. Finally, after the best overload is picked, the compiler will start compiling 3. Finally, after the best overload is picked, the compiler will start
the body of the respective symbol. This in turn will lead the compiler to discover compiling the body of the respective symbol. This in turn will lead the
more call expresions that need to be resolved and steps 2 and 3 will be repeated compiler to discover more call expressions that need to be resolved and steps
as necessary. 2 and 3 will be repeated as necessary.
Please note that if a callable symbol is never used in this scenario, its body Please note that if a callable symbol is never used in this scenario, its body
will never be compiled. This is the default behavior leading to best compilation will never be compiled. This is the default behavior leading to best compilation

View file

@ -2,17 +2,46 @@ Procedures
========== ==========
What most programming languages call `methods`:idx: or `functions`:idx: are What most programming languages call `methods`:idx: or `functions`:idx: are
called `procedures`:idx: in Nim (which is the correct terminology). A called `procedures`:idx: in Nim (which is the correct terminology). A procedure
procedure declaration defines an identifier and associates it with a block declaration consists of an identifier, zero or more formal parameters, a return
of code. value type and a block of code. Formal parameters are declared as a list of
A procedure may call itself recursively. A parameter may be given a default identifiers separated by either comma or semicolon. A parameter is given a type
value that is used if the caller does not provide a value for this parameter. by ``: typename``. The type applies to all parameters immediately before it,
until either the beginning of the parameter list, a semicolon separator or an
already typed parameter, is reached. The semicolon can be used to make
separation of types and subsequent identifiers more distinct.
If the proc declaration has no body, it is a `forward`:idx: declaration. If .. code-block:: nim
the proc returns a value, the procedure body can access an implicitly declared # Using only commas
proc foo(a, b: int, c, d: bool): int
# Using semicolon for visual distinction
proc foo(a, b: int; c, d: bool): int
# Will fail: a is untyped since ';' stops type propagation.
proc foo(a; b: int; c, d: bool): int
A parameter may be declared with a default value which is used if the caller
does not provide a value for the argument.
.. code-block:: nim
# b is optional with 47 as its default value
proc foo(a: int, b: int = 47): int
Parameters can be declared mutable and so allow the proc to modify those
arguments, by using the type modifier `var`.
.. code-block:: nim
# "returning" a value to the caller through the 2nd argument
# Notice that the function uses no actual return value at all (ie void)
proc foo(inp: int, outp: var int) =
outp = inp + 47
If the proc declaration has no body, it is a `forward`:idx: declaration. If the
proc returns a value, the procedure body can access an implicitly declared
variable named `result`:idx: that represents the return value. Procs can be variable named `result`:idx: that represents the return value. Procs can be
overloaded. The overloading resolution algorithm tries to find the proc that is overloaded. The overloading resolution algorithm determines which proc is the
the best match for the arguments. Example: best match for the arguments. Example:
.. code-block:: nim .. code-block:: nim
@ -41,9 +70,8 @@ Calling a procedure can be done in many different ways:
# call as a command statement: no () needed: # call as a command statement: no () needed:
callme 0, 1, "abc", '\t' callme 0, 1, "abc", '\t'
A procedure may call itself recursively.
A procedure cannot modify its parameters (unless the parameters have the type
`var`).
`Operators`:idx: are procedures with a special operator symbol as identifier: `Operators`:idx: are procedures with a special operator symbol as identifier:
@ -475,7 +503,7 @@ If the for loop has exactly 2 variables, a ``pairs`` iterator is implicitly
invoked. invoked.
Symbol lookup of the identifiers ``items``/``pairs`` is performed after Symbol lookup of the identifiers ``items``/``pairs`` is performed after
the rewriting step, so that all overloadings of ``items``/``pairs`` are taken the rewriting step, so that all overloads of ``items``/``pairs`` are taken
into account. into account.
@ -511,11 +539,12 @@ Closure iterators have other restrictions than inline iterators:
1. ``yield`` in a closure iterator can not occur in a ``try`` statement. 1. ``yield`` in a closure iterator can not occur in a ``try`` statement.
2. For now, a closure iterator cannot be evaluated at compile time. 2. For now, a closure iterator cannot be evaluated at compile time.
3. ``return`` is allowed in a closure iterator (but rarely useful). 3. ``return`` is allowed in a closure iterator (but rarely useful) and ends
4. Both inline and closure iterators cannot be recursive. iteration.
4. Neither inline nor closure iterators can be recursive.
Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
default to being inline, but that this may change in future versions of the default to being inline, but this may change in future versions of the
implementation. implementation.
The ``iterator`` type is always of the calling convention ``closure`` The ``iterator`` type is always of the calling convention ``closure``
@ -612,8 +641,8 @@ parameters of an outer factory proc:
Implicit return type Implicit return type
-------------------- --------------------
Since inline interators must always produce values that will be consumed in Since inline iterators must always produce values that will be consumed in
a for loop, the compiler will implicity use the ``auto`` return type if no a for loop, the compiler will implicitly use the ``auto`` return type if no
type is given by the user. In contrast, since closure iterators can be used type is given by the user. In contrast, since closure iterators can be used
as a collaborative tasking system, ``void`` is a valid return type for them. as a collaborative tasking system, ``void`` is a valid return type for them.

View file

@ -10,7 +10,7 @@ Statements are separated into `simple statements`:idx: and
Simple statements are statements that cannot contain other statements like Simple statements are statements that cannot contain other statements like
assignments, calls or the ``return`` statement; complex statements can assignments, calls or the ``return`` statement; complex statements can
contain other statements. To avoid the `dangling else problem`:idx:, complex contain other statements. To avoid the `dangling else problem`:idx:, complex
statements always have to be intended. The details can be found in the grammar. statements always have to be indented. The details can be found in the grammar.
Statement list expression Statement list expression
@ -229,22 +229,18 @@ the expression after the ``elif`` is evaluated (if there is an
``elif`` branch), if it is true the corresponding statements after ``elif`` branch), if it is true the corresponding statements after
the ``:`` are executed. This goes on until the last ``elif``. If all the ``:`` are executed. This goes on until the last ``elif``. If all
conditions fail, the ``else`` part is executed. If there is no ``else`` conditions fail, the ``else`` part is executed. If there is no ``else``
part, execution continues with the statement after the ``if`` statement. part, execution continues with the next statement.
The scoping for an ``if`` statement is slightly subtle to support an important In ``if`` statements new scopes begin immediately after the ``if``/``elif``/``else`` keywords and ends after the corresponding *then* block.
use case. A new scope starts for the ``if``/``elif`` condition and ends after For visualization purposes the scopes have been enclosed in ``{| |}`` in the following example:
the corresponding *then* block:
.. code-block:: nim .. code-block:: nim
if {| (let m = input =~ re"(\w+)=\w+"; m.isMatch): if {| (let m = input =~ re"(\w+)=\w+"; m.isMatch):
echo "key ", m[0], " value ", m[1] |} echo "key ", m[0], " value ", m[1] |}
elif {| (let m = input =~ re""; m.isMatch): elif {| (let m = input =~ re""; m.isMatch):
echo "new m in this scope" |} echo "new m in this scope" |}
else: else: {|
# 'm' not declared here echo "m not declared here" |}
In the example the scopes have been enclosed in ``{| |}``.
Case statement Case statement
-------------- --------------
@ -601,7 +597,7 @@ A table constructor is syntactic sugar for an array constructor:
The empty table can be written ``{:}`` (in contrast to the empty set The empty table can be written ``{:}`` (in contrast to the empty set
which is ``{}``) which is thus another way to write as the empty array which is ``{}``) which is thus another way to write as the empty array
constructor ``[]``. This slightly unusal way of supporting tables constructor ``[]``. This slightly unusual way of supporting tables
has lots of advantages: has lots of advantages:
* The order of the (key,value)-pairs is preserved, thus it is easy to * The order of the (key,value)-pairs is preserved, thus it is easy to

View file

@ -43,6 +43,10 @@ Fortunately Nim supports side effect analysis:
echo f() * 2 # not optimized ;-) echo f() * 2 # not optimized ;-)
You can make one overload matching with a constraint and one without, and the
one with a constraint will have precedence, and so you can handle both cases
differently.
So what about ``2 * a``? We should tell the compiler ``*`` is commutative. We So what about ``2 * a``? We should tell the compiler ``*`` is commutative. We
cannot really do that however as the following code only swaps arguments cannot really do that however as the following code only swaps arguments
blindly: blindly:
@ -105,8 +109,10 @@ Predicate Meaning
with the marked parameter. with the marked parameter.
=================== ===================================================== =================== =====================================================
Predicates that share their name with a keyword have to be escaped with
backticks: `` `const` ``.
The ``alias`` and ``noalias`` predicates refer not only to the matching AST, The ``alias`` and ``noalias`` predicates refer not only to the matching AST,
but also to every other bound parameter; syntactially they need to occur after but also to every other bound parameter; syntactically they need to occur after
the ordinary AST predicates: the ordinary AST predicates:
.. code-block:: nim .. code-block:: nim
@ -144,7 +150,7 @@ constant folding, so the following does not work:
The reason is that the compiler already transformed the 1 into "1" for The reason is that the compiler already transformed the 1 into "1" for
the ``echo`` statement. However, a term rewriting macro should not change the the ``echo`` statement. However, a term rewriting macro should not change the
semantics anyway. In fact they can be deactived with the ``--patterns:off`` semantics anyway. In fact they can be deactivated with the ``--patterns:off``
command line option or temporarily with the ``patterns`` pragma. command line option or temporarily with the ``patterns`` pragma.
@ -345,15 +351,15 @@ optimization for types that have copying semantics:
## puts a (key, value)-pair into `t`. The semantics of string require ## puts a (key, value)-pair into `t`. The semantics of string require
## a copy here: ## a copy here:
let idx = findInsertionPosition(key) let idx = findInsertionPosition(key)
t[idx] = key t[idx].key = key
t[idx] = val t[idx].val = val
proc `[]=`*(t: var Table, key: string{call}, val: string{call}) = proc `[]=`*(t: var Table, key: string{call}, val: string{call}) =
## puts a (key, value)-pair into `t`. Optimized version that knows that ## puts a (key, value)-pair into `t`. Optimized version that knows that
## the strings are unique and thus don't need to be copied: ## the strings are unique and thus don't need to be copied:
let idx = findInsertionPosition(key) let idx = findInsertionPosition(key)
shallowCopy t[idx], key shallowCopy t[idx].key, key
shallowCopy t[idx], val shallowCopy t[idx].val, val
var t: Table var t: Table
# overloading resolution ensures that the optimized []= is called here: # overloading resolution ensures that the optimized []= is called here:

View file

@ -9,11 +9,11 @@ Type equality
------------- -------------
Nim uses structural type equivalence for most types. Only for objects, Nim uses structural type equivalence for most types. Only for objects,
enumerations and distinct types name equivalence is used. The following enumerations and distinct types name equivalence is used. The following
algorithm (in pseudo-code) determines type equality: algorithm, *in pseudo-code*, determines type equality:
.. code-block:: nim .. code-block:: nim
proc typeEqualsAux(a, b: PType, proc typeEqualsAux(a, b: PType,
s: var set[PType * PType]): bool = s: var HashSet[(PType, PType)]): bool =
if (a,b) in s: return true if (a,b) in s: return true
incl(s, (a,b)) incl(s, (a,b))
if a.kind == b.kind: if a.kind == b.kind:
@ -43,7 +43,7 @@ algorithm (in pseudo-code) determines type equality:
a.callingConvention == b.callingConvention a.callingConvention == b.callingConvention
proc typeEquals(a, b: PType): bool = proc typeEquals(a, b: PType): bool =
var s: set[PType * PType] = {} var s: HashSet[(PType, PType)] = {}
result = typeEqualsAux(a, b, s) result = typeEqualsAux(a, b, s)
Since types are graphs which can have cycles, the above algorithm needs an Since types are graphs which can have cycles, the above algorithm needs an

View file

@ -803,7 +803,7 @@ exclude ``nil`` as a valid value with the ``not nil`` annotation:
p(x) p(x)
The compiler ensures that every code path initializes variables which contain The compiler ensures that every code path initializes variables which contain
not nilable pointers. The details of this analysis are still to be specified non nilable pointers. The details of this analysis are still to be specified
here. here.
@ -1132,7 +1132,7 @@ that don't. Distinct types provide a means to introduce a new string type
It is an essential property of abstract types that they **do not** imply a It is an essential property of abstract types that they **do not** imply a
subtype relation between the abtract type and its base type. Explict type subtype relation between the abstract type and its base type. Explicit type
conversions from ``string`` to ``SQL`` are allowed: conversions from ``string`` to ``SQL`` are allowed:
.. code-block:: nim .. code-block:: nim