mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-21 00:11:26 +00:00
recursive tuple types are now invalid (breaking change)
This commit is contained in:
@@ -1209,7 +1209,9 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
|
||||
a = ptrSize
|
||||
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray,
|
||||
tyBigNum:
|
||||
if typ.lastSon == typ: result = szIllegalRecursion
|
||||
let base = typ.lastSon
|
||||
if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion):
|
||||
result = szIllegalRecursion
|
||||
else: result = ptrSize
|
||||
a = result
|
||||
of tyArray, tyArrayConstr:
|
||||
|
||||
@@ -194,9 +194,10 @@ The IEEE standard defines five types of floating-point exceptions:
|
||||
precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input.
|
||||
|
||||
The IEEE exceptions are either ignored at runtime or mapped to the
|
||||
Nim exceptions: `EFloatInvalidOp`:idx:, `EFloatDivByZero`:idx:,
|
||||
`EFloatOverflow`:idx:, `EFloatUnderflow`:idx:, and `EFloatInexact`:idx:.
|
||||
These exceptions inherit from the `EFloatingPoint`:idx: base class.
|
||||
Nim exceptions: `FloatInvalidOpError`:idx:, `FloatDivByZeroError`:idx:,
|
||||
`FloatOverflowError`:idx:, `FloatUnderflowError`:idx:,
|
||||
and `FloatInexactError`:idx:.
|
||||
These exceptions inherit from the `FloatingPointError`:idx: base class.
|
||||
|
||||
Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control
|
||||
whether the IEEE exceptions are ignored or trap a Nim exception:
|
||||
@@ -205,11 +206,12 @@ whether the IEEE exceptions are ignored or trap a Nim exception:
|
||||
{.NanChecks: on, InfChecks: on.}
|
||||
var a = 1.0
|
||||
var b = 0.0
|
||||
echo b / b # raises EFloatInvalidOp
|
||||
echo a / b # raises EFloatOverflow
|
||||
echo b / b # raises FloatInvalidOpError
|
||||
echo a / b # raises FloatOverflowError
|
||||
|
||||
In the current implementation ``EFloatDivByZero`` and ``EFloatInexact`` are
|
||||
never raised. ``EFloatOverflow`` is raised instead of ``EFloatDivByZero``.
|
||||
In the current implementation ``FloatDivByZeroError`` and ``FloatInexactError``
|
||||
are never raised. ``FloatOverflowError`` is raised instead of
|
||||
``FloatDivByZeroError``.
|
||||
There is also a `floatChecks`:idx: pragma that is a short-cut for the
|
||||
combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
|
||||
turned off as default.
|
||||
@@ -269,7 +271,7 @@ specified. The values are ordered. Example:
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
TDirection = enum
|
||||
Direction = enum
|
||||
north, east, south, west
|
||||
|
||||
|
||||
@@ -292,7 +294,7 @@ An explicit ordered enum can have *holes*:
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TTokenType = enum
|
||||
TokenType = enum
|
||||
a = 2, b = 4, c = 89 # holes are valid
|
||||
|
||||
However, it is then not an ordinal anymore, so it is not possible to use these
|
||||
@@ -307,7 +309,7 @@ values to use:
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
TMyEnum = enum
|
||||
MyEnum = enum
|
||||
valueA = (0, "my value A"),
|
||||
valueB = "value B",
|
||||
valueC = 2,
|
||||
@@ -319,16 +321,16 @@ possible to only specify one of them.
|
||||
|
||||
An enum can be marked with the ``pure`` pragma so that it's fields are not
|
||||
added to the current scope, so they always need to be accessed
|
||||
via ``TMyEnum.value``:
|
||||
via ``MyEnum.value``:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
TMyEnum {.pure.} = enum
|
||||
MyEnum {.pure.} = enum
|
||||
valueA, valueB, valueC, valueD
|
||||
|
||||
echo valueA # error: Unknown identifier
|
||||
echo TMyEnum.valueA # works
|
||||
echo MyEnum.valueA # works
|
||||
|
||||
|
||||
String type
|
||||
@@ -358,7 +360,7 @@ i-th *unichar*. The iterator ``runes`` from the `unicode module
|
||||
<unicode.html>`_ can be used for iteration over all Unicode characters.
|
||||
|
||||
|
||||
CString type
|
||||
cstring type
|
||||
------------
|
||||
The ``cstring`` type represents a pointer to a zero-terminated char array
|
||||
compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
|
||||
@@ -422,11 +424,11 @@ Example:
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
TIntArray = array[0..5, int] # an array that is indexed with 0..5
|
||||
TIntSeq = seq[int] # a sequence of integers
|
||||
IntArray = array[0..5, int] # an array that is indexed with 0..5
|
||||
IntSeq = seq[int] # a sequence of integers
|
||||
var
|
||||
x: TIntArray
|
||||
y: TIntSeq
|
||||
x: IntArray
|
||||
y: IntSeq
|
||||
x = [1, 2, 3, 4, 5, 6] # [] is the array constructor
|
||||
y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
|
||||
|
||||
@@ -469,7 +471,7 @@ allows to pass a variable number of arguments to a procedure. The compiler
|
||||
converts the list of arguments to an array implicitly:
|
||||
|
||||
.. code-block:: nim
|
||||
proc myWriteln(f: TFile, a: varargs[string]) =
|
||||
proc myWriteln(f: File, a: varargs[string]) =
|
||||
for s in items(a):
|
||||
write(f, s)
|
||||
write(f, "\n")
|
||||
@@ -483,7 +485,7 @@ last parameter in the procedure header. It is also possible to perform
|
||||
type conversions in this context:
|
||||
|
||||
.. code-block:: nim
|
||||
proc myWriteln(f: TFile, a: varargs[string, `$`]) =
|
||||
proc myWriteln(f: File, a: varargs[string, `$`]) =
|
||||
for s in items(a):
|
||||
write(f, s)
|
||||
write(f, "\n")
|
||||
@@ -518,11 +520,11 @@ in future versions of the compiler.
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
TPerson = tuple[name: string, age: int] # type representing a person:
|
||||
# a person consists of a name
|
||||
# and an age
|
||||
Person = tuple[name: string, age: int] # type representing a person:
|
||||
# a person consists of a name
|
||||
# and an age
|
||||
var
|
||||
person: TPerson
|
||||
person: Person
|
||||
person = (name: "Peter", age: 30)
|
||||
# the same, but less readable:
|
||||
person = ("Peter", 30)
|
||||
@@ -535,9 +537,9 @@ can also be defined with indentation instead of ``[]``:
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TPerson = tuple # type representing a person
|
||||
name: string # a person consists of a name
|
||||
age: natural # and an age
|
||||
Person = tuple # type representing a person
|
||||
name: string # a person consists of a name
|
||||
age: natural # and an age
|
||||
|
||||
Objects provide many features that tuples do not. Object provide inheritance
|
||||
and information hiding. Objects have access to their type at runtime, so that
|
||||
@@ -545,23 +547,23 @@ the ``of`` operator can be used to determine the object's type.
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TPerson {.inheritable.} = object
|
||||
Person {.inheritable.} = object
|
||||
name*: string # the * means that `name` is accessible from other modules
|
||||
age: int # no * means that the field is hidden
|
||||
|
||||
TStudent = object of TPerson # a student is a person
|
||||
id: int # with an id field
|
||||
Student = object of Person # a student is a person
|
||||
id: int # with an id field
|
||||
|
||||
var
|
||||
student: TStudent
|
||||
person: TPerson
|
||||
assert(student of TStudent) # is true
|
||||
student: Student
|
||||
person: Person
|
||||
assert(student of Student) # is true
|
||||
|
||||
Object fields that should be visible from outside the defining module, have to
|
||||
be marked by ``*``. In contrast to tuples, different object types are
|
||||
never *equivalent*. Objects that have no ancestor are implicitly ``final``
|
||||
and thus have no hidden type field. One can use the ``inheritable`` pragma to
|
||||
introduce new object roots apart from ``system.TObject``.
|
||||
introduce new object roots apart from ``system.RootObj``.
|
||||
|
||||
|
||||
Object construction
|
||||
@@ -572,7 +574,7 @@ has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is
|
||||
an ``object`` type or a ``ref object`` type:
|
||||
|
||||
.. code-block:: nim
|
||||
var student = TStudent(name: "Anton", age: 5, id: 3)
|
||||
var student = Student(name: "Anton", age: 5, id: 3)
|
||||
|
||||
For a ``ref object`` type ``system.new`` is invoked implicitly.
|
||||
|
||||
@@ -680,6 +682,14 @@ dereferencing operations for reference types:
|
||||
n.data = 9
|
||||
# no need to write n[].data; in fact n[].data is highly discouraged!
|
||||
|
||||
In order to simplify structural type checking, recursive tuples are not valid:
|
||||
|
||||
.. code-block:: nim
|
||||
# invalid recursion
|
||||
type MyTuple = tuple[a: ref MyTuple]
|
||||
|
||||
Likewise ``T = ref T`` is an invalid type.
|
||||
|
||||
As a syntactical extension ``object`` types can be anonymous if
|
||||
declared in a type section via the ``ref object`` or ``ptr object`` notations.
|
||||
This feature is useful if an object should only gain reference semantics:
|
||||
|
||||
@@ -61,6 +61,8 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] =
|
||||
result = @[]
|
||||
for itm in items(seq1):
|
||||
if not result.contains(itm): result.add(itm)
|
||||
|
||||
{.deprecated: [distnct: deduplicate].}
|
||||
|
||||
proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] =
|
||||
## Returns a new sequence with a combination of the two input sequences.
|
||||
|
||||
5
todo.txt
5
todo.txt
@@ -3,9 +3,6 @@ version 0.10
|
||||
|
||||
- Test nimfix on various babel packages
|
||||
|
||||
- bug: 'type T = ref T' not recognized as illegal recursion
|
||||
- deprecate recursive tuples; tuple needs laxer type checking
|
||||
|
||||
- VM: Pegs do not work at compile-time
|
||||
- VM: ptr/ref T cannot work in general
|
||||
|
||||
@@ -37,8 +34,6 @@ Misc
|
||||
- make tuple unpacking work in a non-var/let context
|
||||
- special rule for ``[]=``, items, pairs
|
||||
- built-in 'getImpl'
|
||||
- type API for macros; make 'spawn' a macro
|
||||
- markAndSweepGC should expose an API for fibers
|
||||
- prevent 'alloc(TypeWithGCedMemory)'
|
||||
- some table related tests are wrong (memory usage checks)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ News
|
||||
be used instead.
|
||||
- String case (or any non-ordinal case) statements
|
||||
without 'else' are deprecated.
|
||||
- Recursive tuple types are deprecated. Use ``object`` instead.
|
||||
- Recursive tuple types are not allowed anymore. Use ``object`` instead.
|
||||
|
||||
|
||||
Language Additions
|
||||
|
||||
Reference in New Issue
Block a user