
Nimrod: C + Macros + GC - norswap
http://nimrod-code.org/index.html
======
mynegation
This is the closest to my ideal language I've ever seen. Elegant and
expressive syntax of Python, statically typed with automatic type inference,
compiled to native code, garbage collected, macros, AST manipulation, very
comprehensive "batteries included" standard library. Definitely worth a closer
look!

------
xaa
This reminds me a lot of D. It's low-level, GCed, essentially intended as a
nicer C/C++.

But I think it suffers from the same fatal flaw that D does: you have to semi-
manually translate C headers that you want to use. Like D, it provides an
automated tool to help, but the translated headers will inevitably lag their
original counterparts.

As another commenter below noted, the var and proc thing is also redundant and
annoying. However, the ability to compile to C (and, as a result, to easily
cross-compile) is really nice.

~~~
dom96
> But I think it suffers from the same fatal flaw that D does: you have to
> semi-manually translate C headers that you want to use. Like D, it provides
> an automated tool to help, but the translated headers will inevitably lag
> their original counterparts.

I can't think of a better alternative. Can you suggest one? The fact that
Nimrod compiles to C already is a huge plus, it makes wrapping C code very
easy.

~~~
stonemetal
If the language has "A real package system" why not allow for packages written
in other languages? If a C build system can look at a .h and a .lib and figure
out what symbols are exported and use them then I seen no reason why a
compiler for xyz could not also do that. If you reused OSS projects like Clang
it may not even be a monumental effort.

------
lobster_johnson
Nimrod looks a _lot_ like someone took Borland's ObjectPascal and removed the
begin/end block semantics in favour of whitespace indentation.

For example, they use the "var: type" syntax; the syntax for declaring classes
is nearly identical; "case [value] of" is right out of Pascal, as is the
"0..2" range syntax. They refer to "procedures" as opposed to functions. They
even use naming conventions from ObjectPascal: "T" as a prefix for types (eg.,
TChannel), "P" for the Nimrod equivalent to pointers (eg., PChannel is a "ref
TChannel"), "F" for class members.

I would not be surprised if the author was an old Turbo Pascal/Delphi hand.

~~~
smilekzs
On first sight it resembled Python, while a second look revealed lots of
Pascal legacy... Really what's the deal-maker?

------
dom96
What's really amazing about this language is that until only recently it has
been developed solely by one person in his spare time no less. It is competing
with the likes of Rust and Go which have pretty big companies behind them.

~~~
srean
There are quite a few very performant languages like that. I would like to
list two, ATS and Felix. I commented on Felix today at
[https://news.ycombinator.com/item?id=6274322](https://news.ycombinator.com/item?id=6274322)

A good HN day for language enthusiasts.

------
ics
> The Nimrod Compiler can also generate C++ or Objective C for easier
> interfacing.

This really is an inconvenient time for the weekend to be ending.

------
continuations
This looks good. However according to the web framework benchmark its
performance looks pretty underwhelming, below that of Python and Ruby:

[http://www.techempower.com/benchmarks/#section=data-r6&hw=i7...](http://www.techempower.com/benchmarks/#section=data-r6&hw=i7&test=json)

Has anyone used this in production?

~~~
dom96
Hey, guy behind Jester here (The web framework being benchmarked). Please
don't let these results deter you from Nimrod. Not only is Jester alpha-grade
software, but when I submitted these benchmarks I did not have much time to
properly utilize Nimrod's concurrency features (I was in the middle of exams).
My first submission was not parallel at all and I quickly corrected it so that
multiple processes were simply spawned (with no regard to the amount of CPU
cores) which is definitely not ideal and the results show this. So please
don't blame Nimrod for this, blame me instead.

For better evidence of Nimrod's power take a look at these benchmarks:
[http://togototo.wordpress.com/2013/08/23/benchmarks-round-
tw...](http://togototo.wordpress.com/2013/08/23/benchmarks-round-two-parallel-
go-rust-d-scala-and-nimrod/)

~~~
bhauer
Hi dom96. Thanks again for contributing the Jester tests! I hope you get some
time to continue your work on Jester. We'd like to have Nimrod represented
properly in the results.

Are there other Nimrod web frameworks (and importantly, domain experts with
those frameworks) that could be contributed for Round 7?

~~~
dom96
No problem! Thanks for accepting my contributions! I hope so too, but maybe
with Nimrod's recent surge in popularity someone can give me a hand :)

Sadly, I am not aware of any other web frameworks. Speaking of Round 7, do you
have an ETA for it?

~~~
bhauer
Not yet, we've been busy with other projects. But I want us to aim for mid-
September.

------
Symmetry
I actually discovered this yesterday and spent Saturday morning learning about
it. I really like most of the syntax, especially the "var/const/let"
distinction together with "if/when". I'm sort of wish that Rust and Go would
just copy that. The semantics seemed to be up to par with this generation of
potential C replacements, but not any better than the others.

~~~
dbaupp
Rust has let mut, let and static which seem to correspond fairly closely to
var, let and const.

------
stesch
I hate that this language looks so good. Fast benchmarks, good library,
readable code, documentation. I don't want to learn another language! Now I
have to …

------
buster
Just when i started reading tutorials about Rust this comes up... Looks nice,
but does it also have concurrency built in (Rust tasks, Erlangs processes,
message passing, etc.)?

~~~
lambda
From the second paragraph on the linked page:

> Beneath a nice infix/indentation based syntax with a powerful (AST based,
> hygienic) macro system lies a semantic model that supports a soft realtime
> GC on thread local heaps. Asynchronous message passing is used between
> threads, so no "stop the world" mechanism is necessary.

~~~
buster
Yes, so not. I've found the actor module, but it's based on threads so no
"lightweigth" and not as powerful as the networked, lightweight erlang
processes. I'd really love to see that in a new language, especially since
Rust and Nimrod are the first ones in a while i really like from the syntax
point of view..

~~~
marshray
Erlang seems to pay a small performance penalty for that ability though. The
VM is not allowed to run more than a few thousand instructions without
checking for a signal to task switch.

But if that kind of guaranteed cooperation isn't needed, I'd expect that
lightweight threads could be added to a language like this in a
straightforward way.

------
jaytaylor
I wonder what other wonderful languages I've never heard of. Really, please
share!

~~~
evincarofautumn
Kitten, a statically typed, globally type-inferred, GC-less functional stack
language, with opt-in layout-based syntax and an effect system to separate
pure and impure operations.

Disclaimer: I wrote this; it’s nowhere near complete, but not bad to play
around with. We’re working toward a release in a few weeks, to include some
missing language features and a new x86_64 runtime.

[https://github.com/evincarofautumn/kitten](https://github.com/evincarofautumn/kitten)

[http://kittenlang.org/](http://kittenlang.org/)

~~~
tomp
Can I ask you one thing: why did you decide to write a stack-based programming
language?

I'm really curious, as I personally see nothing good with them. The same kind
of non-mathematical syntax as LISP (`1 2 +` as opposed to `+ 1 2`), without
any of the goodness (code is data).

~~~
evincarofautumn
In Factor, code _is_ data. Remember, though, that there are many sources of
goodness in a language. As for your actual question, I decided to write a
stack-based language because:

• They can be implemented very efficiently on real hardware. The stack-based
VM is well established as an implementation technique for non–stack-based
languages.

• Like in Lisp, the simple structure makes them suitable for useful
visualisations beyond the program text. Static typing creates even more cool
possibilities for such analysis.

• There is fertile ground for new research, and applying existing theory to
these languages for the first time—particularly type and effect systems.

• It’s just a lot of fun. :)

~~~
tomp
I agree with all of those, to me is just seems like transformation into stack-
based language should be made as part of the compilation process, not written
down by the programmer. Maybe it's just me, I totally admit that I'm not used
to thinking in concatenative languages as I've never used one, but
mathematics, with named variables and control- and data-flow denoted by
functions or sequential lines of operations, seems the most natural notation
to read, write and think in.

~~~
evincarofautumn
I totally understand. In fact, Kitten has named variables for that reason. You
can write code that looks imperative, expressiony, or dataflowy, according to
taste. Here’s a silly example:

    
    
        // Implicitly thread state between functions.
        def promptInt:
          ": " cat prompt
          readInt
          fromSome
    
        // Write stacky code if you want.
        def squareDiff:
          - dup *
    
        // Use locals as much as you need to.
        "x0" promptInt ->x0
        "y0" promptInt ->y0
        "x" promptInt ->x
        "y" promptInt ->y
    
        x0 x squareDiff ->a
        y0 y squareDiff ->b
    
        a b + sayInt

------
pilif
Reading the tutorial is indeed very pleasant. I have to say however, that from
such a new language I would ask for more correct string handling as opposed to
the let-me-sidestep-encoding-issues-and-still-call-it-UTF8 that's going on.

Defining characters as 8 bit is not quite correct (you will get char variables
holding a fraction of a character), treating strings as arrays of characters
by conversion also isn't (now you have an array of partial characters) and
ignoring the encoding (just assuming UTF8) is a sure cause for annoying bugs -
something the rest of the language goes great lengths to avoid.

I've only read the tutorial so far. Maybe the library fixes some of the issues
- we'll see. The thing is just that if you start adding metadata to your sting
types (they do encode the length (in what? Characters? Partial characters?
Bytes?)), then why not also at least add an encoding (to help programmers not
to mix strings of different encodings)? Why do everything right and then
weasel out when you get to strings?

Sorry. I'm totally obsessive what string encodings is concerned :-)

~~~
deckiedan
Sounds like you'd be a great person to join the team as chief string theorist.
:-)

------
cju
As anyone tried it for embedded code on microcontrollers ?

It looks usable for soft realtime, almost keeping speed and control of C and
adding ease (and fun) of coding.

GC is tunable and there are compilation options for embedded systems
([http://nimrod-code.org/nimrodc.html#nimrod-for-embedded-
syst...](http://nimrod-code.org/nimrodc.html#nimrod-for-embedded-systems)).

~~~
mwcampbell
I haven't tried this, but I see that the Nimrod 0.9.0 release notes (from
about a year ago) include this item:

> The stdlib can now be avoided to a point where C code generation for 16bit
> micro controllers is feasible.

------
atrilumen
I've been tempted by this one several times. I may have to play around with it
and SDL2.

One thing that gets me, though, is the var keyword in a statically typed
language. Why say "var thing: string" instead of "string thing"?

I think that consistent, explicit declaration of types is much cleaner and
easier to read than this recurring mixture of type inference and annotation.

~~~
twotwotwo
One point in favor of inference is that it gives you less to read, and what
the compiler can infer, the reader usually can, too. On the other side, you
could say you shouldn't _have_ to infer while you read and having types in
front of you reduces cognitive load.

I bet the folks building these languages with inference probably and wouldn't
mind having fewer annotations (and being more consistent, in a sense) if they
could. It's just that to get rid of some of these annotations you have to make
deep changes to the language, like OCaml's polymorphic functions, and that may
be inconsistent with their design goals or just hard.

Obviously folks won't agree on whether inference is a great thing or not.
Whatever one's used to usually seems easier to read. I've worked more in
dynamically typed langauges than statically, and (so) languages with inference
feel more like home.

------
nwg
There was something similar to this about two weeks ago here, with vars and
lambdas in c99. It was less of a full blown language and more just functions
and preprocessor definitions to be used in C. I am having trouble finding it
now. Does anyone remember the name of this other project? I'd like to check
these both out.

~~~
Doji
[https://github.com/orangeduck/libCello](https://github.com/orangeduck/libCello)

------
hetman
Unfortunately the documentation still states that at this point I can choose
either threads or a dynamically linked run time library. For an embedded
system, static linking isn't much of an option because there are real memory
constraints.

It's a shame that a lot of these new languages focus on creating a really
great language, but don't seem to give as much time to the practical usage of
the language (for example, GHC did not support cross-compilation at all until
very recently).

Ironing some of those fundamental issues out before adding some of the fancier
features could probably really boost interest in the language and programmer
uptake.

------
JulianMorrison
They ported the Erlang scheduler model to a C based language, nice.

------
andrewflnr
On the Clay thread a while back, people liked my list of systems-oriented
languages that I've been compiling for a while. I can't go a good copy-paste
and edit job on my iPad, so I'll just link to the thread here:
[https://news.ycombinator.com/item?id=6117456](https://news.ycombinator.com/item?id=6117456)
. A bunch of other people came in with updates and other entries for the list.
Included were of course Clay, Nimrod, Rust, and D, but also Deca, BitC, ATS,
Habit (a Haskell dialect), and others.

~~~
Dewie
I don't know anything about systems languages, but it seems that there is _a
lot_ of effort getting put into C/C++ alternatives, and many bold efforts at
that. But maybe that is just a historical bias, because so few remembers the
failed (popularity vice) systems languages efforts of yesteryear?

~~~
andrewflnr
I'm only 21, but I definitely get the impression things have picked up in that
area in the last few years.

~~~
pjmlp
Before C became mainstream, Modula-2 and many Pascal dialects like Apple and
Turbo Pascal could already fulfil the same role with better type safety and Go
compile times in 16 bit systems.

However they lacked the bundling to a commercial OS like UNIX, hence C grew in
importance, because developers tend to use the languages supported by the OS
vendors.

------
polskibus
Can someone explain why is this so much better than c++?

~~~
pmb
Nobody can explain to a dedicated C++ programmer why a new language is better
than C++. I have tried for more than a decade many times and all I have ever
gotten across has apparently been a "wah wah wah" noise like the adults in
Peanuts.

Because C++ is multi-paradigm, all paradigms are possible within it (although
they may not be syntactically easy or have reasonable error messages, etc
etc). Therefore, either C++ is the obviously the best language (to its
partisans) or it is a hellish agglomeration of mutually contradictory
confusing crap that takes years to begin to understand (to its detractors).
Unfortunately, those two camps each find their position obvious, and seem to
be unable to communicate with one another.

std::cout << "This does what??!" << endl;

~~~
tomlu
I dunno - I have about 15 years C++ experience, and if anything the better I
have become at the language the less I like it...

Having said that any language with a GC is unlikely to supplant C++. I would
have thought that anything that could get away with using GC is already not
using C++. Ergo what will finally kill C++ in all its final domains is IMO
some sort of better C. Maybe Rust, if they sort out their non-mandatory GC.

~~~
pjmlp
Having used GC enabled systems languages already in the 90's, I am the opinion
it is more a generation issue.

Technology changes fast, but humans take generations to be convinced of
something.

Sometimes the only way for something to get adopted is when the luddites no
longer have a word to say.

------
ballard
Ugh, the community is barely alive and it's an unwieldy collection of non-
orthogonal constructs. Generics and a few whiz-bang features doesn't paper
over the sins upon sins. I see this project cutting back features or dying
under the weight of crushing unmaintainability. (sad.)

~~~
commentzorro
>> ...unwieldy collection of non-orthogonal constructs...

>> ...doesn't paper over the sins upon sins...

Please elaborate. I didn't see any of that and honestly don't know what "non-
orthogonal constructs" means. I'm no language design expert but would like to
know what, to you, are the obvious deficiencies.

~~~
ballard
Non-orthogonality: Multiple features that accomplish nearly the same result in
different ways.

For a language maintainer, this is another piece that will have to be
supported, troubleshooted and documented.

The other problem for users is that it gives a sense of confusion and
uncertainty (Paradox of Choice) about the correctness of a program that may
lead to multiple refactorings that don't add any value. Also, more features
require more learning and makes programs harder to understand.

The goals of any good language should be correctness and understandability.
Arguably, Python learned the lessons from Perl. But there are many different
languages, and some are better in different instances.

What Nimrod turns into will be hard to say, but Go and Erlang need more
competition.

------
pekk
I don't understand why Nimrod has to mostly look like Python, but then make
all kinds of innovations in syntax and formatting which have nothing to do
with performance.

~~~
smilekzs
And I find these "innovation" mostly solving problems that didn't have to
exist.

------
C1D
I know exactly what I'm going to be doing next week!

------
Scramblejams
Now if only it would offer immutability and lightweight threads (like Erlang's
processes)...

------
dubcanada
I wonder how good this would be as a game engine.

------
WayneDB
My favorite example from their tutorial:

    
    
      if yes("Should I delete all your important files?"):
        echo("I'm sorry Dave, I'm afraid I can't do that.")
      else:
        echo("I think you know what the problem is just as well as I do.")

------
sidww2
What would be really killer is if it could have bindings to Java. Then one
could take advantage of the JVM being present everywhere w/o having to do a
separate compilation for every platform.

~~~
mmfZ4e4OqQ7RRwP
Note that nimrod compiles to C, and your JVM may be implemented in C or C++.
So for the measly gain of not having to run a command on the destination
platform (nimrod c name.nim) you are bringing in the runtime performance
drawbacks of the whole JVM and requiring a further layer of abstraction.

Plus bytecode doesn't mean a program will run at all, look at all the java
programs which run on android without modification, oh, wait...

~~~
sidww2
I'm in CompBio and the sense I get is that it's a lot easier to get someone to
try your tool if all you have to do is provide them the jar which they just
have to click on and it runs. Whereas with compilation, you first have to make
sure you have all the platforms covered and then force the potential user to
select the right executable for the platform.

~~~
burntsushi
Just distribute the source.

I'm in CompBio too and actively avoid software distributed as just jar files.
Give me the source so I can fix your (probably) broken software.

(Yes, I have a low opinion of the quality of software in my field.)

~~~
sidww2
I don't think forcing potential users to compile a program is going lower the
barrier much. A lot of the users could be biologists and they would likely not
know how to compile the source. I do agree that the software should be open
source.

~~~
burntsushi
> A lot of the users could be biologists

In my experience, biologists are allergic to the command line. They need web
interfaces.

In the case where they don't mind using the command line, providing Linux x64
binaries (along with the source) is plenty sufficient.

Note that I'm not saying they _shouldn 't_ distribute the jar if that's the
kind of game they want to play. I'm saying they shouldn't restrict themselves
to distributing a jar.

> I do agree that the software should be open source.

Me too. But it's not an ideological point. I wasn't kidding when I said that,
in all probability, I'll have to fix whatever software I'm using. Or at the
very least, read the source code to understand what it is that they've
implemented. (You'd think it'd be clear from the methods section in their
paper...)

/rant

------
wmobit
Dear everyone, please stop using C as a compile target. Thanks.

~~~
codygman
why?

~~~
copx
One good argument I can think of would be compile time. C compiles slowly
compared to almost every other language not C++. And of course you get the C
compile time on top of the compile to C time, so I expect the Nimrod compile
chain to be quite slow.

Doesn't mean that I am generally opposed to compiling to C, it's often a good
trade-off.

~~~
winter_blue
A good solution to this is to go with a language like C-- (if you are too
scared of LLVM).

