One small thing that feels inconsistent in the standard library (and which has confused me a bit since I started using nim) is that in addition to the new keyword different standard library classes have different new and/or init procedures. For example there is newSeq and newSeqWith, newTable, newTableWith, initTable, etc.

Perhaps there is a clear rule to choose which is which and when to use which (or create initXXX vs newXXX procedures on your own libraries), but (on the surface) it feels inconsistent and is confusing (at least it was for me).

I'd prefer that you could always use new (and define a constructor procedure if you need some custom initialization).

I also agree that it would be best for not nil to be the default, but I don't know if that is too much of a change this close to v1.0. It would probably break a lot of existing code (and perhaps find a few bugs in the process).

2018-04-26 07:40:12
@didlybom The names follow (a document that is not well known). initT is used for value-based types, newT for pointer-based types. newSeq and newString depart from it because they were created early on.
2018-04-26 09:34:47

Araq, {.experimental.}, that's an exceptionally (haha) pragmatic and likable plan! Even the exceptions are fine with an exception-free core because that makes a no-exceptions flag quite feasible in the future, when a better option emerges.

What about the crufty / obsolete / inconsistent stuff in the std lib, of which there is plenty, by most accounts in this thread?

Incidentally, pruning the std lib and putting it in nimbles instead also makes for a better upgrade path in a beautiful, experimental-free world, because it's easy to code up alternatives for the brave new world.

On practical ways forward, I also like the suggestion for levels-of-packaging that would let people eat the batteries-included cookie and have it.

2018-04-26 14:07:26
To keep the ball rolling with std lib pruning, here's my proposal (kind of a sketch, not to be taken too literally).

Level 1 - "Nim Kernel": System modules that every Nim compiler supports (embedded systems, virtual machines, etc).

algorithm base64 complex critbits deques hashes endians fenv intsets json lists (+sharedlist) locks logging macros marshal math nativesockets parseutils pegs random rationals ropes segfaults sequtils sets stats streams strformat strscans strtabs strutils subexes tables (+sharedtables) threadpool times unittest

Level 2 - "Nim Standard": Nim Standard library modules for currently popular mobile and desktop operating systems.

asyncdispatch asyncfile asynchttpserver asyncnet dynlib encodings httpclient md5 memfiles mimetypes net os osproc parsecfg parsecsv parseopt2 posix rdstdin selectors ssl terminal unicode uri winlean

Level 3 - "Nim Extra": Modules available as installable Nimble packages. All available out-of-the-box in a Nim Legacy Distro.

asyncftpclient asyncjs basic2d basic3d browsers cgi cookies coro db_sqlite db_mysql db_postgres distros dom events fsmonitor future highlite htmlparser httpserver iup jsffi lexbase matchers mersenne mysql nre odbcsql oids options parseopt parsesql parsexml pcre postgres re rst rstast rstgen scgi sexp sha1 smtp sqlite3 strmisc xmldom xmldomparser xmlparser xmltree

2018-04-27 10:55:53
@Allin: I really like your plan. We need to change it in its details though. Will write an RFC and post the link to it here. 2018-04-27 18:28:13
I like the idea to make seq and string default @[] and "", we can use {.noinit.} to make them nil if care about performance.
2018-04-29 14:36:42
@Allin I didn't find basic2d and basic3d, in the docs the links are dead. 2018-04-29 17:05:05
performant code when you want -> sane/safe/easy defaults
2018-04-29 18:46:31

@didlybom The names follow (a document that is not well known). initT is used for value-based types, newT for pointer-based types. newSeq and newString depart from it because they were created early on.

Thanks for the explanation @araq. The problem is that seqs and strings are likely to be the very first kind of thing that a new user is going to create. The fact that those two deviate from the general rule makes the rule hard to understand, IMHO. What good is a rule that is not applicable to the most common use case?

Wouldn't it make sense to define "initSeq" and "initString" procedures? It those were then used in the tutorials and the documentation it would help new users learn the rule you mentioned. Ideally the existing newSeq and newString could be marked as deprecated as well, but I do not know if that would be feasible given that it would basically make almost _all existing nim code deprecated.

2018-04-29 21:17:30


But strings and sequences ARE already treated a little differently than plain reference object types, aren't they? The most trivial example being: strings have their literals and sequences (and arrays) have openArray but neither string nor sequence has object constructor. So what now? Well, just treat them more or less like primitives. If neither string nor sequence have nil as a proper value then they will certainly not behave like reference types.

What is interesting: @[] and "" don't have to actually differ from nil, it could be an implementation detail. Pretty much like option[ref T not nil] can be implemented as ref T.

2018-05-01 10:00:31