nim-lang / RFCs

A repository for your Nim proposals.
135 stars 26 forks source link

Nim Roadmap 2023 #503

Closed Araq closed 6 months ago

Araq commented 1 year ago

See, I am sending an angel ahead of you to guard you along the way and to bring you to the place I have prepared. -- Exodus 23:20

Version 2.0

Version 2.2

Incremental compilation (IC) / nimsuggest / IDE tooling

This is a single point as for me it's a single thing. If we had a compiler that only recompiles the module that was touched the "nimsuggest" tool can be a simple command line tool that answers a single question like "where is symbol X used?".

We have this tool already, it's nim check --navigate, but the implementation of IC needs to be finished. In order to implement this feature in a disciplined manner that avoids complexity and hard to track down subtle bugs the following strategy will be followed:

With --ic:stress IC is enabled for every single module and the compiler always uses the same non-conditional logic:

The Nim compiler compiles a single a.nim module at a time. It is compiled to C(++). Let b.nim be a dependency of a.nim. If b.nim has been compiled to b.rod already and b.nim did not change since then, import b.rod and proceed.

Otherwise, compile b.nim via spawning another Nim compiler process that compiles b.nim to b.rod. Then proceed by importing b.rod. This rather simple setup ensures that by construction we stress test the mechanism completely, all the time. The downside is that all the required IO slows down the compiler a lot, so that development and testing will be slow.

Stretch goals

Allow recursive module dependencies

  1. "Package level objects"
  2. "code reordering"

see also https://github.com/nim-lang/Nim/pull/18818 https://github.com/nim-lang/Nim/pull/18822

Language

Library

JSON

The JSON module is in a poor shape, the API exposes public fields, sometimes is not intuitive (the %* operator) and has poor performance. It could be split up into: jsonbuilder, jsonparser, jsonlexer, jsontree, jsonmapper.

Async

The higher level async modules should be moved into their own Nimble package. The required building blocks like selectors.nim remain in the standard library, they served Nim well.

Less concrete goals

  1. Find a better design for "Term rewriting macros". Once done, deprecate the old feature.
  2. Find a better design for "Special Operators". Once done, deprecate the old feature.
  3. Implement "Aliasing restrictions in parameter passing". The compiler can always produce warnings first.
  4. Concepts: Find a way of how to infer static values and stabilize the feature.
  5. Find a way of allowing a syntax like of Value(let x, var y) and embrace an official pattern matching solution that makes use of this syntax.

Atlas tool

How can you help?

The standard library cleanups should be rather easy to do. Atlas is also still a very simple tool, only about 600 lines of Nim code.

Varriount commented 1 year ago

Regarding incremental compilation:

The downside is that all the required IO slows down the compiler a lot, so that development and testing will be slow. I don't know the specifics of how one would do this on Linux, but on Windows one could use something like a RAM disk to reduce IO latency.

For the JSON module(s), would it be possible to go with json/lexer, json/parser, etc.?

For term-rewriting macros (and I might write up an RFC for this), I feel that a better mechanism would be a way for a Nim module to implement AST rewriting. This could be something like plugins for the compiler, or an interface exposed by a module. This way the community can experiment with various forms of AST rewriting, and an "ideal" solution can emerge.

Araq commented 1 year ago

I don't know the specifics of how one would do this on Linux, but on Windows one could use something like a RAM disk to reduce IO latency.

Interesting, thanks!

For the JSON module(s), would it be possible to go with json/lexer, json/parser, etc.?

No. We don't have directories in Nim code (except in import, of course), only module names.

For term-rewriting macros (and I might write up an RFC for this), I feel that a better mechanism would be a way for a Nim module to implement AST rewriting.

AST rewriting via compiler plugins sounds interesting.

c-blake commented 1 year ago

I could not see where the snippet @Varriount quoted came from, but on Linux, you can just use --nimcache:/dev/shm/.... to use a RAM disk -- no license required. (By default 50% of system RAM is available there, but this is adjustable.) Or have $HOME/.cache/nim be a symbolic link into /dev/shm/nim-$LOGNAME. (I've been doing this since I began using Nim, actually..just to economize on writes to my NVMe drives.)

EDIT: and it seems like this is also pretty easy on OSX -- https://www.techjunkie.com/how-to-create-a-4gbs-ram-disk-in-mac-os-x/ but it is not "just there by default".

arnetheduck commented 1 year ago

Speaking of caches, LLVM supports caching during lto, something I'll probably enable in nlvm "soon": https://clang.llvm.org/docs/ThinLTO.html#id11 - I imagine nim could enable it too when used with clang

PMunch commented 1 year ago

For the JSON module(s), would it be possible to go with json/lexer, json/parser, etc.?

No. We don't have directories in Nim code (except in import, of course), only module names.

I'm pretty sure they meant the module names. So that you could do something like import std/json/[parser, lexer] for example. IMO this seems like a nice clean design.

Araq commented 1 year ago

Yeah but what if he does import std / json / parser; import std / xml / parser? Then he has to disambiguate via import as and nothing of the nice clean design remains.

PMunch commented 1 year ago

True, but I feel like it's less often that you'll need to import low-level parsers for two separate languages. I hope we'll still get a import std/json which exposes a similar API to what we have today. And if you indeed had to implement some weird dual parsing library then import std/json/parser as jsonparser doesn't seem like too bad a tradeof.

metagn commented 1 year ago

Sorry to be vague, but I think json/parser should only happen when you aren't meant to import json/parser normally. As in, it should be like a component/submodule of the json module, instead of a module of the json subpackage of the standard library. If it's an independent library, then it can be jsonparser, but otherwise it may pollute the std namespace

Clonkk commented 11 months ago

@ringabout @Araq

Are there (rough) estimates or update regarding this roadmap ?

Araq commented 11 months ago

I just updated it and @ringabout is now working on "Patch the full compiler to use "definite assignment analysis" itself."

ringabout commented 10 months ago

Update: with https://github.com/nim-lang/Nim/pull/22365 merged, the compiler now enables strictdefs in itself.

blackmius commented 10 months ago

what does "IDE tooling" in "Incremental compilation (IC) / nimsuggest / IDE tooling" means?

Araq commented 6 months ago

Continued here: https://github.com/nim-lang/RFCs/issues/543