This thread is supposed to become a progress report for Nimony. Tonight the following program worked for the first time:
import std / syncio
echo "hi", "abc"
This might not look impressive but it is (IMO): Nimony is a new Nim compiler which does not use much of the old codebase. A good dozen subsystems have been reimplemented from scratch:
Of course, this is still not ready for anybody. But once ARC has received more bugfixes we have a minimal Nim that offers seqs+objects and modularity.
For more information about its architecture, read: https://github.com/nim-lang/nimony/blob/master/doc/design.md
For more information about its planned design, read: https://github.com/nim-lang/nimony/discussions/529
The next milestone is get our seq implementation to work. I hope to get there within the next 2 weeks, but that might be overly optimistic as the interaction between generics and ARC hooks is hard.
Once seq works, our table implementation needs to compile. Once that is done, parseopt and then you can write super simple CLI programs with it while we implement ref...
What's the tooling situation like in the new Nimony implementation? I understand the new incremental compilation will boost nimsuggest's performance and help solve some quirks, but are there other benefits?
Also, what about debugging—will the GDB debugging experince improve? Better support for the rr debugger could be a killer feature.
Nimony sounds really exciting, congrats to the team!
Well there is no tooling yet, but since everything is based on NIF we have effectively implemented a "compiler database": A tool can just process the NIF files in nimcache/, you can write your own tools and NIF has a short spec.
As for the debugging, all the transformations and tools keep column-precise line information and name mangling information, a debugger can be written to make good use of that. However, I expect in practice we'll just use NIFC-to-LLVM instead of NIFC-to-C and get the typical debugging experience of all the other compiled languages.
I am curious about the replacement of macros through compiler plugins.
The way macros currently work in Nim is not without weaknesses, but I like that the only thing stopping one from writing a macro is pretty much import macros and they can go seamlessly in a Nim source file with related things. As they run in VM it is also possible to get very rapid iteration going on with nim check.
How far would the workflow of compiler plugins differ from this? To exaggerate a bit, will we be going back to having a separate a script outputting C code which needs to be added to the Makefile?
Slightly related how does this coincide with previous plans of removing untyped?
It's just
template foobar(x, y: int): int {.plugin: "foobar.nim".}
And then in foobar.nim you have a program that receives two command line parameters, two filenames <input.nif> and <output.nif> and you use the NIF APIs (or APIs on top of that that emulate macros.nim) for the transformation logic.
The stdlib uses too many Nim specific hacks. The stdlib uses too many of Nim's features that Nimony does not support yet.
I hope that with concepts baked in from the beginning, the Nimony standard library will develop along slightly different lines.
About concepts, would abstract generic operations still work? Example
proc mean[T](vs: seq[T]): float =
for x in vs:
result += x
result / vs.len.float
echo @[1.0, 2.0].mean
About concepts, would abstract generics still work?
When you mark your generic as .untyped, yes.
We’re extending Nim’s ref T to support three modes:
- Unchecked (current behavior)
- Nilable (may be nil; dereferences must be statically guarded)
- Non-nil (guaranteed non-nil; compiler enforces no-null)
Current (operator-heavy) syntax:
type Obj = ref object of RootRef Obj2 = ref object of Obj proc testNil() = var x: nil ref RootObj = nil var y: nil RootRef var nn: RootRef not nil var nn2: ref RootRef not nil
Goal: Propose a purely keyword-based alternative (no symbols like ? or !) that:
- Clearly distinguishes all three modes
- Feels idiomatic in Nim
- Is concise and easy to type
What keyword-only syntax would you suggest for “nilable ref” and “non-nil ref”? Give examples.
The models I used included:
Most of them converged on terms like:
However, Sonnet also suggested a different approach that I think is worth considering. These suggestions avoid reusing the same keywords (nil / not nil), which often carry distinct semantic meanings. Here's what Sonnet proposed:
# Option 1: opt/req (optional/required)
var x: opt ref RootObj # Nilable
var y: req ref RootObj # Non-nil
# Option 2: maybe/safe
var x: maybe ref RootObj # Nilable
var y: safe ref RootObj # Non-nil