39 KiB
v1.6.0 - 2021-10-14
Major new features
With so many new features, pinpointing the most salient ones is a subjective exercise, but here are a select few:
iterable[T]
The iterable[T] type class was added to match called iterators,
which solves a number of long-standing issues related to iterators.
Example:
iterator iota(n: int): int =
for i in 0..<n: yield i
# previously, you'd need `untyped`, which caused other problems such as lack
# of type inference, overloading issues, and MCS.
template sumOld(a: untyped): untyped = # no type inference possible
var result: typeof(block:(for ai in a: ai))
for ai in a: result += ai
result
assert sumOld(iota(3)) == 0 + 1 + 2
# now, you can write:
template sum[T](a: iterable[T]): T =
# `template sum(a: iterable): auto =` would also be possible
var result: T
for ai in a: result += ai
result
assert sum(iota(3)) == 0 + 1 + 2 # or `iota(3).sum`
In particular iterable arguments can now be used with the method call syntax. For example:
import std/[sequtils, os]
echo walkFiles("*").toSeq # now works
See PR #17196 for additional details.
Strict effects
The effect system was refined and there is a new .effectsOf annotation that does
explicitly what was previously done implicitly. See the
manual
for more details.
To write code that is portable with older Nim versions, use this idiom:
when defined(nimHasEffectsOf):
{.experimental: "strictEffects".}
else:
{.pragma: effectsOf.}
proc mysort(s: seq; cmp: proc(a, b: T): int) {.effectsOf: cmp.}
To enable the new effect system, compile with --experimental:strictEffects.
See also #18777 and RFC
#408.
Private imports and private field access
A new import syntax import foo {.all.} now allows importing all symbols
(public or private) from foo.
This can be useful for testing purposes or for more flexibility in project organization.
Example:
from system {.all.} as system2 import nil
echo system2.ThisIsSystem # ThisIsSystem is private in `system`
import os {.all.} # weirdTarget is private in `os`
echo weirdTarget # or `os.weirdTarget`
Added a new module std/importutils, and an API privateAccess, which allows access
to private fields for an object type in the current scope.
Example:
import times
from std/importutils import privateAccess
block:
let t = now()
# echo t.monthdayZero # Error: undeclared field: 'monthdayZero' for type times.DateTime
privateAccess(typeof(t)) # enables private access in this scope
echo t.monthdayZero # ok
See PR #17706 for additional details.
nim --eval:cmd
Added nim --eval:cmd to evaluate a command directly, e.g.: nim --eval:"echo 1".
It defaults to e (nimscript) but can also work with other commands, e.g.:
find . | nim r --eval:'import strutils; for a in stdin.lines: echo a.toUpper'
# use as a calculator:
nim --eval:'echo 3.1 / (1.2+7)'
# explore a module's APIs, including private symbols:
nim --eval:'import os {.all.}; echo weirdTarget'
# use a custom backend:
nim r -b:js --eval:"import std/jsbigints; echo 2'big ** 64'big"
See PR #15687 for more details.
Round-trip float to string
system.addFloat and system.$ now can produce string representations of
floating point numbers that are minimal in size and possess round-trip and correct
rounding guarantees (via the
Dragonbox algorithm).
This currently has to be enabled via -d:nimPreviewFloatRoundtrip.
It is expected that this behavior becomes the new default in upcoming versions,
as with other nimPreviewX define flags.
Example:
from math import round
let a = round(9.779999999999999, 2)
assert a == 9.78
echo a # with `-d:nimPreviewFloatRoundtrip`: 9.78, like in python3 (instead of 9.779999999999999)
New std/jsbigints module
Provides arbitrary precision integers for the JS target. See PR #16409. Example:
import std/jsbigints
assert 2'big ** 65'big == 36893488147419103232'big
echo 0xdeadbeef'big shl 4'big # 59774856944n
New std/sysrand module
Cryptographically secure pseudorandom number generator, allows generating random numbers from a secure source provided by the operating system. Example:
import std/sysrand
assert urandom(1234) != urandom(1234) # unlikely to fail in practice
See PR #16459.
New module: std/tempfiles
Allows creating temporary files and directories, see PR #17361 and followups.
import std/tempfiles
let tmpPath = genTempPath("prefix", "suffix.log", "/tmp/")
# tmpPath looks like: /tmp/prefixpmW1P2KLsuffix.log
let dir = createTempDir("tmpprefix_", "_end")
# created dir looks like: getTempDir() / "tmpprefix_YEl9VuVj_end"
let (cfile, path) = createTempFile("tmpprefix_", "_end.tmp")
# path looks like: getTempDir() / "tmpprefix_FDCIRZA0_end.tmp"
cfile.write "foo"
cfile.setFilePos 0
assert readAll(cfile) == "foo"
close cfile
assert readFile(path) == "foo"
User-defined literals
Custom numeric literals (e.g. -128'bignum) are now supported.
Additionally, the unary minus in -1 is now part of the integer literal, i.e.
it is now parsed as a single token.
This implies that edge cases like -128'i8 finally work correctly.
Example:
func `'big`*(num: cstring): JsBigInt {.importjs: "BigInt(#)".}
assert 0xffffffffffffffff'big == (1'big shl 64'big) - 1'big
Dot-like operators
With -d:nimPreviewDotLikeOps, dot-like operators (operators starting with .,
but not with ..) now have the same precedence as ., so that a.?b.c is now
parsed as (a.?b).c instead of a.?(b.c).
A warning is generated when a dot-like operator is used without -d:nimPreviewDotLikeOps.
An important use case is to enable dynamic fields without affecting the
built-in . operator, e.g. for std/jsffi, std/json, pkg/nimpy. Example:
import std/json
template `.?`(a: JsonNode, b: untyped{ident}): JsonNode =
a[astToStr(b)]
let j = %*{"a1": {"a2": 10}}
assert j.?a1.?a2.getInt == 10
Block arguments now support optional parameters
This solves a major pain point for routines accepting block parameters, see PR #18631 for details:
template fn(a = 1, b = 2, body) = discard
fn(1, 2): # already works
bar
fn(a = 1): # now works
bar
Likewise with multiple block arguments via do:
template fn(a = 1, b = 2, body1, body2) = discard
fn(a = 1): # now works
bar1
do:
bar2
Other new features
New and deprecated modules
The following modules were added (they are discussed in the rest of the text):
-
std/enumutils -
std/genasts -
std/importutils -
std/jsbigints -
std/jsfetch -
std/jsformdata -
std/jsheaders -
std/packedsets -
std/setutils -
std/socketstreams -
std/strbasics -
std/sysrand -
std/tasks -
std/tempfiles -
std/vmutils -
Deprecated
std/mersenne. -
Removed deprecated
std/iupmodule from stdlib; it has already moved to nimble.
New std/jsfetch module
Provides a wrapper for JS Fetch API. Example:
# requires -d:nimExperimentalAsyncjsThen
import std/[jsfetch, asyncjs, jsconsole, jsffi, sugar]
proc fn {.async.} =
await fetch("https://api.github.com/users/torvalds".cstring)
.then((response: Response) => response.json())
.then((json: JsObject) => console.log(json))
.catch((err: Error) => console.log("Request Failed", err))
discard fn()
New std/tasks module
Provides basic primitives for creating parallel programs. Example:
import std/tasks
var num = 0
proc hello(a: int) = num+=a
let b = toTask hello(13) # arguments must be isolated, see `std/isolation`
b.invoke()
assert num == 13
b.invoke() # can be called again
assert num == 26
New module: std/genasts
Provides an API genAst that avoids the problems inherent with quote do and can
be used as a replacement.
Example showing how this could be used for writing a simplified version of unittest.check:
import std/[genasts, macros, strutils]
macro check2(cond: bool): untyped =
assert cond.kind == nnkInfix, "$# not implemented" % $cond.kind
result = genAst(cond, s = repr(cond), lhs = cond[1], rhs = cond[2]):
# each local symbol we access must be explicitly captured
if not cond:
doAssert false, "'$#'' failed: lhs: '$#', rhs: '$#'" % [s, $lhs, $rhs]
let a = 3
check2 a*2 == a+3
if false: check2 a*2 < a+1 # would error with: 'a * 2 < a + 1'' failed: lhs: '6', rhs: '4'
See PR #17426 for details.
New module: std/setutils
- Added
setutils.toSetthat can take any iterable and convert it to a built-inset, if the iterable yields a built-in settable type. - Added
setutils.fullSetwhich returns a full built-insetfor a valid type. - Added
setutils.complementwhich returns the complement of a built-inset. - Added
setutils.[]=.
New module: std/enumutils
- Added
genEnumCaseStmtmacro that generates case statement to parse string to enum. - Added
itemsfor enums with holes. - Added
symbolNameto return theenumsymbol name ignoring the human-readable name. - Added
symbolRankto return the index in which anenummember is listed in an enum.
system
- Added
system.prepareMutationfor better support of low levelmoveMem,copyMemoperations forgc:orc's copy-on-write string implementation. system.addEscapedCharnow renders\ras\rinstead of\c, to be compatible with most other languages.- Added
cmpMemtosystem. doAssertRaisesnow correctly handles foreign exceptions.addIntnow supports unsigned integers.
Compatibility notes:
system.deletehad surprising behavior when the index passed to it was out of bounds (it would delete the last entry then). Compile with-d:nimStrictDeleteso that an index error is produced instead. Be aware however that your code might depend on this quirky behavior so a review process is required on your part before you can use-d:nimStrictDelete. To make this review easier, use the-d:nimAuditDeleteswitch, which pretends thatsystem.deleteis deprecated so that it is easier to see where it was used in your code.-d:nimStrictDeletewill become the default in upcoming versions.cucharis now deprecated as it aliasedcharwhere arguably it should have aliaseduint8. Please usecharoruint8instead.reprnow doesn't insert trailing newlines; the previous behavior was very inconsistent, see #16034. Use-d:nimLegacyReprWithNewlinefor the previous behavior.reprnow also renders ASTs correctly for user defined literals, setters,do, etc.- Deprecated
any. See RFC #281. - The unary slice
..bwas deprecated, use0..binstead.
std/math
- Added
almostEqualfor comparing two float values using a machine epsilon. - Added
clampwhich allows using aSliceto clamp to a value. - Added
ceilDivfor integer division that rounds up. - Added
isNaN. - Added
copySign. - Added
euclDivandeuclMod. - Added
signbit. - Added
frexpoverload procs. Deprecatedc_frexp, usefrexpinstead.
Compatibility notes:
math.roundnow rounds "away from zero" in the JS backend, which is consistent with other backends. See #9125. Use-d:nimLegacyJsRoundfor the previous behavior.
Random number generators: std/random, std/sysrand, std/oids
- Added
std/sysrandmodule (see details above). - Added
randStatetemplate that exposes the default random number generator. Useful for library authors. - Added
initRand()overload with no argument which uses the current time as a seed. initRand(seed)now allowsseed == 0.- Fixed overflow bugs.
- Fix
initRandto avoid random number sequences overlapping, refs #18744. std/oidsnow usesstd/random.
Compatibility notes:
- Deprecated
std/mersenne. random.initRand(seed)now produces non-skewed values for the first call torand()after initialization with a small (< 30000) seed. Use-d:nimLegacyRandomInitRandto restore previous behavior for a transition time, see PR #17467.
std/json, std/jsonutils
- With
-d:nimPreviewJsonutilsHoleyEnum,jsonutilsnow can serialize/deserialize holey enums as regular enums (viaord) instead of as strings. It is expected that this behavior becomes the new default in upcoming versions.toJsonnow serializesJsonNodeas is via reference (without a deep copy) instead of treatingJsonNodeas a regular ref object, this can be customized viajsonNodeMode. std/jsonandstd/jsonutilsnow serializeNaN,Inf,-Infas strings, so that%[NaN, -Inf]is the string["nan","-inf"]instead of[nan,-inf]which was invalid JSON.std/jsoncan now handle integer literals and floating point literals of arbitrary length and precision. Numbers that do not fit the underlyingBiggestIntorBiggestFloatfields are kept as string literals and one can use external BigNum libraries to handle these. TheparseFloatfamily of functions also has now optionalrawIntegersandrawFloatsparameters that can be used to enforce that all integer or float literals remain in the "raw" string form so that client code can easily treat small and large numbers uniformly.- Added
BackwardsIndexoverload forJsonNode. json.%,json.to,jsonutils.fromJson,jsonutils.toJsonnow work withuint|uint64instead of raising (as in 1.4) or giving wrong results (as in 1.2).std/jsonutilsnow handlescstring(including as Table key), andset.- Added
jsonutils.jsonTooverload withopt = Joptions()param. jsonutils.toJsonnow supports customization viaToJsonOptions.std/json,std/jsonutilsnow support round-trip serialization when-d:nimPreviewFloatRoundtripis used.
std/typetraits, std/compilesettings
distinctBasenow is identity instead of error for non distinct types.distinctBasenow allows controlling whether to be recursive or not.- Added
enumLento return the number of elements in an enum. - Added
HoleyEnumfor enums with holes,OrdinalEnumfor enums without holes. - Added
hasClosure. - Added
pointerBaseto returnTforref T | ptr T. - Added
compilesettings.SingleValueSetting.libPath.
networking: std/net, std/asyncnet, std/htmlgen, std/httpclient, std/asyncdispatch, std/asynchttpserver, std/httpcore
- Fixed buffer overflow bugs in
std/net. - Exported
sslHandlefromstd/netandstd/asyncnet. - Added
hasDataBufferedtostd/asyncnet. - Various functions in
std/httpclientnow accepturlof typeUri. Moreover, therequestfunction'shttpMethodargument of typestringwas deprecated in favor ofHttpMethodenumtype; see #15919. - Added
asyncdispatch.activeDescriptorsthat returns the number of currently active async event handles/file descriptors. - Added
getPorttostd/asynchttpserverto resolve OS-assignedPort(0); this is usually recommended instead of hardcoding ports which can lead to "Address already in use" errors. - Fixed premature garbage collection in
std/asyncdispatch, when a stacktrace override is in place. - Added
httpcore.is1xxand missing HTTP codes. - Added
htmlgen.portalfor making "SPA style" pages using HTML only.
Compatibility notes:
- On Windows, the SSL library now checks for valid certificates.
For this purpose it uses the
cacert.pemfile, which was extracted fromhttps://curl.se/ca/cacert.pem. Besides the OpenSSL DLLs (e.g.libssl-1_1-x64.dll,libcrypto-1_1-x64.dll) you now also need to shipcacert.pemwith your.exefile.
std/hashes
hashes.hashcan now supportobjectandref(can be overloaded in user code), if-d:nimPreviewHashRefis used. It is expected that this behavior becomes the new default in upcoming versions.hashes.hash(proc|ptr|ref|pointer)now callshash(int)and honors-d:nimIntHash1.hashes.hash(closure)has also been improved.
OS: std/os, std/io, std/socketstream, std/linenoise, std/tempfiles
os.FileInfo(returned bygetFileInfo) now containsblockSize, determining preferred I/O block size for this file object.- Added
os.getCacheDir()to return platform specific cache directory. - Improved
os.getTempDir(), see PR #16914. - Added
os.isAdminto tell whether the caller's process is a member of the Administrators local group (on Windows) or a root (on POSIX). - Added optional
optionsargument tocopyFile,copyFileToDir, andcopyFileWithPermissions. By default, on non-Windows OSes, symlinks are followed (copy files symlinks point to); on Windows,optionsargument is ignored and symlinks are skipped. - On non-Windows OSes,
copyDirandcopyDirWithPermissionscopy symlinks as symlinks (instead of skipping them as it was before); on Windows symlinks are skipped. - On non-Windows OSes,
moveFileandmoveDirmove symlinks as symlinks (instead of skipping them sometimes as it was before). - Added optional
followSymlinksargument tosetFilePermissions. - Added a simpler to use
io.readCharsoverload. - Added
socketstreammodule that wraps sockets in the stream interface. - Added experimental
linenoise.readLineStatusto get line and status (e.g. ctrl-D or ctrl-C).
Environment variable handling
- Empty environment variable values are now supported across OS's and backends.
- Environment variable APIs now work in multithreaded scenarios, by delegating to direct OS calls instead of trying to keep track of the environment.
putEnv,delEnvnow work at compile time.- NodeJS backend now supports osenv:
getEnv,putEnv,envPairs,delEnv,existsEnv.
Compatibility notes:
std/os:putEnvnow raises if the first argument contains a=.
POSIX
- On POSIX systems, the default signal handlers used for Nim programs (it's used for printing the stacktrace on fatal signals) will now re-raise the signal for the OS default handlers to handle. This lets the OS perform its default actions, which might include core dumping (on select signals) and notifying the parent process about the cause of termination.
- On POSIX systems, we now ignore
SIGPIPEsignals, use-d:nimLegacySigpipeHandlerfor previous behavior. - Added
posix_utils.osReleaseFileto get system identification fromos-releasefile on Linux and the BSDs. (link) - Removed undefined behavior for
posix.open.
std/prelude
std/strformatis now part ofinclude std/prelude.- Added
std/sequtilsimport tostd/prelude. std/preludenow works with the JS target.std/preludecan now be used viainclude std/prelude, butinclude preludestill works.
String manipulation: std/strformat, std/strbasics
- Added support for parenthesized expressions.
- Added support for const strings instead of just string literals.
- Added
std/strbasicsfor high-performance string operations. - Added
strip,setSlice,add(a: var string, b: openArray[char]).
std/wrapnils
std/wrapnilsdoesn't useexperimental:dotOperatorsanymore, avoiding issues like bug #13063 (which affected error messages) for modules importingstd/wrapnils.- Added
??.macro which returns anOption. std/wrapnilscan now be used to protect againstFieldDefecterrors in case objects, generates optimal code (no overhead compared to manual if-else branches), and preserves lvalue semantics which allows modifying an expression.
Containers: std/algorithm, std/lists, std/sequtils, std/options, std/packedsets
- Removed the optional
longestMatchparameter of thecritbits._WithPrefixiterators (it never worked reliably). - Added
algorithm.merge. - In
std/lists: renamedappendtoaddand retainedappendas an alias; addedprependandprependMovedanalogously toaddandaddMoved; addedremoveforSinglyLinkedLists. - Added new operations for singly- and doubly linked lists:
lists.toSinglyLinkedListandlists.toDoublyLinkedListconvert fromopenArrays;lists.copyimplements shallow copying;lists.addconcatenates two lists - an O(1) variation that consumes its argument,addMoved, is also supplied. See PRs #16362, #16536. - New module:
std/packedsets. Generalizesstd/intsets, see PR #15564.
Compatibility notes:
- Deprecated
sequtils.deleteand added an overload taking aSlicethat raises a defect if the slice is out of bounds, likewise withstrutils.delete. - Deprecated
proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T]instd/algorithm. std/optionschanged$some(3)to"some(3)"instead of"Some(3)"and$none(int)to"none(int)"instead of"None[int]".
std/times
- Added
ZZZandZZZZpatterns totimes.nimDateTimeparsing, to match time zone offsets without colons, e.g.UTC+7 -> +0700. - Added
dateTimeand deprecatedinitDateTime.
std/macros and AST
- New module
std/genasts, see description above. - The required name of case statement macros for the experimental
caseStmtMacrosfeature has changed frommatchto`case`. - Tuple expressions are now parsed consistently as
nnkTupleConstrnode. Will affect macros expecting nodes to be ofnnkPar. - In
std/macros,treeRepr,lispRepr,astGenReprnow represent SymChoice nodes in a collapsed way. Use-d:nimLegacyMacrosCollapseSymChoiceto get the previous behavior. - Made custom op in
macros.quotework for all statements.
std/sugar
- Added
sugar.dumpToStringwhich improves onsugar.dump. - Added an overload for the
collectmacro that infers the container type based on the syntax of the last expression. Works with std seqs, tables and sets.
Compatibility notes:
- Removed support for named procs in
sugar.=>.
Parsing: std/parsecfg, std/strscans, std/uri
- Added
sectionsiterator inparsecfg. strscans.scanfnow supports parsing single characters.- Added
strscans.scanTuplewhich usesstrscans.scanfinternally, returning a tuple which can be unpacked for easier usage ofscanf. - Added
decodeQuerytostd/uri. parseopt.initOptParserhas been made available andparseopthas been added back tostd/preludefor all backends. PreviouslyinitOptParserwas unavailable if thestd/osmodule did not haveparamCountorparamStr, but the use of these ininitOptParserwere conditionally to the runtime arguments passed to it, soinitOptParserhas been changed to raiseValueErrorwhen the real command line is not available.parseoptwas previously excluded fromstd/preludefor JS, as it could not be imported.
Compatibility notes:
- Changed the behavior of
uri.decodeQuerywhen there are unencoded=characters in the decoded values. Prior versions would raise an error. This is no longer the case to comply with the HTML spec and other languages' implementations. Old behavior can be obtained with-d:nimLegacyParseQueryStrict.cgi.decodeDatawhich uses the same underlying code is also updated the same way.
JS stdlib changes
- Added
std/jsbigintsmodule, which provides arbitrary precision integers for the JS target. - Added
setCurrentExceptionfor the JS backend. writeStackTraceis available in the JS backend now.- Added
then,catchtostd/asyncjsfor promise pipelining, for now hidden behind-d:nimExperimentalAsyncjsThen. - Added
std/jsfetchmodule Fetch wrapper for the JS target. - Added
std/jsheadersmodule Headers wrapper for the JS target. - Added
std/jsformdatamodule FormData wrapper for the JS target. - Added
jscore.debuggerto call any available debugging functionality, such as breakpoints. - Added
jsconsole.dir,jsconsole.dirxml,jsconsole.timeStamp. - Added dollar
$andlenforjsre.RegExp. - Added
jsconsole.jsAssertfor the JS target. - Added
**tostd/jsffi. - Added
copyWithinforseqandarrayfor JS targets. - In
std/dom,Intervalis now aref object, same asTimeout. Definitions ofsetTimeout,clearTimeout,setInterval,clearIntervalwere updated. - Added
dom.scrollIntoViewproc with options. - Added
dom.setInterval,dom.clearIntervaloverloads. - Merged
std/dom_extensionsinto thestd/dommodule, as it was a module with a single line, see RFC #413. $now gives more correct results on the JS backend.
JS compiler changes
cstringdoesn't support the[]=operator anymore in the JS backend.- Array literals now use JS typed arrays when the corresponding JS typed array exists,
for example
[byte(1), 2, 3]generatesnew Uint8Array([1, 2, 3]).
VM and nimscript backend
- VM now supports
addr(mystring[ind])(index + index assignment). nimscriptnow handlesexcept Exception as e.nildereference is not allowed at compile time.cast[ptr int](nil)[]is rejected at compile time.static[T]now works better, refs #17590, #15853.distinct Tconversions now work in VM.items(cstring)now works in VM.- Fix
addr,len,highin VM (#16002, #16610). std/cstrutilsnow works in VM.
OS/platform-specific notes
- Support for Apple silicon/M1.
- Support for 32-bit RISC-V, refs #16231.
- Support for armv8l, refs #18901.
- Support for CROSSOS, refs #18889.
- The allocator for Nintendo Switch, which was nonfunctional because
of breaking changes in libnx, was removed, in favor of the new
-d:nimAllocPagesViaMallocoption. - Allow reading parameters when compiling for Nintendo Switch.
--nimcachenow correctly works in a cross-compilation setting.- Cross compilation targeting Windows was improved.
- This now works from macOS/Linux:
nim r -d:mingw main
Performance / memory optimizations
- The comment field in PNode AST was moved to a side channel, reducing overall memory usage during compilation by a factor 1.25x
std/jsonutilsdeserialization is now up to 20x faster.os.copyFileis now 2.5x faster on macOS, by usingcopyfilefromcopyfile.h; use-d:nimLegacyCopyFilefor macOS < 10.5.- Float to string conversion is now 10x faster thanks to the Dragonbox algorithm,
with
-d:nimPreviewFloatRoundtrip. newSeqWithis 3x faster.- CI now supports batching (making Windows CI 2.3X faster).
- Sets now uses the optimized
countSetBitsproc, see PR #17334.
Debugging
- You can now enable/disable VM tracing in user code via
vmutils.vmTrace. koch toolsnow buildsbin/nim_dbgwhich allows easy access to a debug version of Nim without recompiling.- Added new module
compiler/debugutilsto help with debugging Nim compiler. - Renamed
-d:nimCompilerStackraceHintsto-d:nimCompilerStacktraceHintsand used it in more contexts; this flag which works in tandem with--stackTraceMsgsto show user code context in compiler stacktraces.
Type system
typeof(voidStmt)now works and returnsvoid.enumvalues can now be overloaded. This needs to be enabled via{.experimental: "overloadableEnums".}. We hope that this feature allows for the development of more fluent (less ugly) APIs. See RFC #373 for more details.- A type conversion from one
enumtype to another now produces an[EnumConv]warning. You should useord(orcast, but the compiler won't help, if you misuse it) instead.type A = enum a1, a2 type B = enum b1, b2 echo a1.B # produces a warning echo a1.ord.B # produces no warning - A dangerous implicit conversion to
cstringnow triggers a[CStringConv]warning. This warning will become an error in future versions! Use an explicit conversion likecstring(x)in order to silence the warning. - There is a new warning for any type conversion to
enumthat can be enabled via.warning[AnyEnumConv]:onor--warning:AnyEnumConv:on. - Reusing a type name in a different scope now works, refs #17710.
- Fixed implicit and explicit generics in procedures, refs #18808.
New-style concepts
Example:
type
Comparable = concept # no T, an atom
proc cmp(a, b: Self): int
The new design does not rely on system.compiles and may compile faster.
See PR #15251
and RFC #168 for details.
Lexical / syntactic
- Nim now supports a small subset of Unicode operators as operator symbols.
The supported symbols are: "∙ ∘ × ★ ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ ± ⊕ ⊖ ⊞ ⊟ ∪ ∨ ⊔".
To enable this feature, use
--experimental:unicodeOperators. Note that due to parser limitations you cannot enable this feature via a pragma{.experimental: "unicodeOperators".}reliably, you need to enable it via the command line or in a configuration file. var a {.foo.} = exprnow works inside templates (except whenfoois overloaded).
Compiler messages, error messages, hints, warnings
- Significant improvement to error messages involving effect mismatches, see PRs #18384, #18418.
- Added
--declaredLocsto show symbol declaration location in error messages. - Added
--spellSuggestto show spelling suggestions on typos. - Added
--processing:dots|filenames|offwhich customizeshintProcessing;--processing:filenamesshows which include/import modules are being compiled as an import stack. FieldDefectmessages now shows discriminant value + lineinfo, in all backends (C, JS, VM)- Added
--hintAsErrorwith similar semantics as--warningAsError. - Added
--unitsep:on|offto control whether to add ASCII unit separator\31before a newline for every generated message (potentially multiline), so tooling can tell when messages start and end. - Added
--filenames:abs|canonical|legacyRelProjwhich replaces--listFullPaths:on|off --hint:all:on|offis now supported to select or deselect all hints; it differs from--hints:on|offwhich acts as a (reversible) gate. Likewise with--warning:all:on|off.- The style checking of the compiler now supports a
--styleCheck:usagesswitch. This switch enforces that every symbol is written as it was declared, not enforcing the official Nim style guide. To be enabled, this has to be combined either with--styleCheck:erroror--styleCheck:hint. - Type mismatch errors now show more context, use
-d:nimLegacyTypeMismatchfor previous behavior. typedesc[Foo]now renders as such instead oftype Fooin compiler messages.runnableExamplesnow show originating location in stacktraces on failure.SuccessXmessage now shows more useful information.- New
DuplicateModuleImportwarning; improvedUnusedImportandXDeclaredButNotUsedaccuracy.
Compatibility notes:
--hint:CCnow prints to stderr (like all other hints) instead of stdout.
Building and running Nim programs, configuration system
- JSON build instructions are now generated in
$nimcache/outFileBasename.jsoninstead of$nimcache/projectName.json. This allows avoiding recompiling a given project compiled with different options if the output file differs. --usenimcache(implied bynim r main) now generates an output file that includes a hash of some of the compilation options, which allows caching generated binaries:nim r main # recompiles nim r -d:foo main # recompiles nim r main # uses cached binary nim r main arg1 arg2 # likewise (runtime arguments are irrelevant)nim rnow supports cross compilation from unix to windows when specifying-d:mingwby using Wine, e.g.:nim r --eval:'import os; echo "a" / "b"'printsa\b.nimcan compile version 1.4.0 as follows:nim c --lib:lib --stylecheck:off -d:nimVersion140 compiler/nim.-d:nimVersion140is not needed for bootstrapping, only for building 1.4.0 from devel.nim enow accepts arbitrary file extensions for the nimscript file, although.nimsis still the preferred extension in general.- The configuration subsystem now allows for
-d:releaseand-d:dangerto work as expected. The downside is that these defines now have custom logic that doesn't apply for other defines.
Multithreading
- TLS: macOS now uses native TLS (
--tlsEmulation:off). TLS now works withimportcppnon-POD types; such types must use.cppNonPodand--tlsEmulation:offshould be used. - Added
unsafeIsolateandextracttostd/isolation. - Added
std/tasks, see description above.
Memory management
--gc:arcnow bootstraps (PR #17342).- Lots of improvements to
gc:arc,gc:orc, see PR #15697, #16849, #17993. --gc:orcis now 10% faster than previously for common workloads. If you have trouble with its changed behavior, compile with-d:nimOldOrc.- The
--gc:orcalgorithm was refined so that custom container types can participate in the cycle collection process. See the documentation of=tracefor more details. - On embedded devices
malloccan now be used instead ofmmapvia-d:nimAllocPagesViaMalloc. This is only supported for--gc:orcor--gc:arc.
Compatibility notes:
--newruntimeand--refchecksare deprecated, use--gc:arc,--gc:orc, or--gc:noneas appropriate instead.
Docgen
- docgen: RST files can now use single backticks instead of double backticks and
correctly render in both
nim rst2html(as before) as well as common tools rendering RST directly (e.g. GitHub). This is done by adding thedefault-role:: codedirective inside the RST file (which is now handled bynim rst2html). - Source+Edit links now appear on top of every docgen'd page when
nim doc --git.url:url ...is given. - Latex doc generation is revised: output
.texfiles should be compiled byxelatex(not bypdflatexas before). Now default Latex settings provide support for Unicode and better avoid margin overflows. The minimum required version is TeXLive 2018 (or an equivalent MikTeX version). - The RST parser now supports footnotes, citations, admonitions, and short style references with symbols.
- The RST parser now supports Markdown table syntax.
Known limitations:
- cell alignment is not supported, i.e. alignment annotations in a delimiter
row (
:---,:--:,---:) are ignored - every table row must start with
|, e.g.| cell 1 | cell 2 |.
- cell alignment is not supported, i.e. alignment annotations in a delimiter
row (
- Implemented
doc2texcompiler command which converts documentation in.nimfiles to Latex. - docgen now supports syntax highlighting for inline code.
- docgen now supports same-line doc comments:
func fn*(a: int): int = 42 ## Doc comment - docgen now renders
deprecatedand other pragmas. runnableExamplesnow works with templates and nested templates.runnableExamples: "-r:off"now works for examples that should compile but not run.runnableExamplesnow renders code verbatim, and produces correct code in all cases.- docgen now shows correct, canonical import paths in docs.
- docgen now shows all routines in sidebar, and the proc signature is now shown in sidebar.
Effects and checks
- Significant improvement to error messages involving effect mismatches
- There is a new
castsection{.cast(uncheckedAssign).}: bodythat disables some compiler checks regardingcase objects. This allows serialization libraries to avoid ugly, non-portable solutions. See RFC #407 for more details.
Compatibility notes:
- Fixed effect tracking for borrowed procs (see #18882).
One consequence is that, under some circumstances, Nim could previously permit a procedure with side effects to be written with
func- you may need to change some occurrences offunctoproc. To illustrate, Nim versions before 1.6.0 compile the below without errorbut Nim 1.6.0 produces the errorproc print(s: string) = echo s type MyString = distinct string proc print(s: MyString) {.borrow.} func foo(s: MyString) = print(s)similar to how we expect thatError: 'foo' can have side effectsproducesfunc print(s: string) = echo sError: 'print' can have side effects
Tools
- Major improvements to
nimgrep, see PR #15612 . fusionis now un-bundled from Nim,./koch fusionwill install it via Nimble at a fixed hash.testament: addednimoutFull: boolspec to compare full output of compiler instead of a subset; many bugfixes to testament.
Misc/cleanups
- Deprecated
TaintedStringand--taintmode. - Deprecated
--nilseqswhich is now a noop. - Added
-d:nimStrictModein CI in several places to ensure code doesn't have certain hints/warnings. - Removed
.travis.yml,appveyor.yml.disabled,.github/workflows/ci.yml.disabled. [skip ci]now works in azure and CI pipelines, see detail in PR #17561.