
I missed Nim (2014) - mapleoin
http://goran.krampe.se/2014/10/20/i-missed-nim/
======
jerf
It seems to me that the evidence is that in the 2010s, it is exceedingly
difficult for a new language to break into what I call the "B-class language
list" (they aren't in the Nobody Was Ever Fired For Choosing (Java/C#) set,
but the languages you can use pretty much anywhere but Big Enterprise without
anybody raising an eyebrow, like Python or Ruby) with some sort of serious
corporate backing.

There hasn't even been much from the 200xs that has broken into that list.
Looking at the Tiobe list for concreteness (yes, it may not be perfect but it
isn't completely wrong, either, so close enough), you have to go to 14 to
Swift to find something not from the 20th century. At 17 (Groovy) you
debateably have something that wasn't pushed by a company (that's actually a
complicated question), and all the way down to 21 to get to D to find the
first thing that clearly comes from a single person anytime recently. (I won't
go any farther because the list probably is getting to be just noise below
that.)

I hypothesize that it is because we expect so much from our languages now. If
you don't have a solution for serving web pages from your new language, don't
even hope to make that list. But it could also be because developers are
nervous about choosing something so obscure and having it just fade away when
the competition that doesn't have that problem is already pretty good.
Compared to 20 years ago we are spoiled for choice, so perhaps getting your
head about the rest even in a niche is simply harder than it used to be. But I
really don't know what it is.... but observationally, it seems to take a lot
more than just "being a good language" nowadays to attain great success in the
computer language area.

PS: This is the sort of thing that leads me to disagree strongly with the idea
that the computer world moves quickly. When it requires more than half an
average career for dominant language to shift, that's not "fast".

~~~
nostrademons
Language adoption is pushed by platforms. New languages get adopted when
there's a new platform that people wish to develop for, and existing languages
aren't suitable for it.

That's behind Swift's rapid rise (it's being pushed as the "new official"
language for iOS) and a lot of historically successful languages. BASIC was
the language of the early microcomputer era. C was the language of the UNIX &
Win32 era. PHP and Perl were languages of the Web 1.0 era, and Javascript,
Ruby, and Python of the Web 2.0 era. Objective-C is for Mac and iOS
development, and Swift is soon to replace it. C# is for .NET development. Java
was pushed as the language for the web, but ultimately found adoption within
the enterprise, and I think Go is headed toward a similar position.

The reason we've seen all the major languages of the past 10 years backed by
large corporations is because all the major platforms are controlled by large
corporations. The web was the last totally-open computing platform to see
widespread adoption, and there was a large renaissance of single-developer
programming languages for it. We've been in a similar position in the late 80s
and early 90s, when C was completely dominant along with Windows & commercial
UNIXes, and it turned out that pattern reversed itself in a few short years.

~~~
joshu
Nitpick: the defining sites of Web 2.0 were PHP and Perl.

------
bluejekyll
So this is an old article. I wonder if his perception of Rust has changed
since it's 1.0 debut.

> Rust is “C syntax” and Nim is Python-ish. Nim wins this one hands down for
> me.

This is always going to be a really personal choice for most people. I
actually prefer all the clarity I get from the curly brackets.

> Nim has Exceptions with tracking (!) and Rust has explicit error handling
> via the return value. Personally… that feels like a big step backwards, much
> like error handling in Go. Again, for me, a clear win for Nim. I know others
> feel differently, but that is ok :)

Rust has made a plain distinction between expected error return behavior (like
parse errors) that you can recover from, and panic! which is the closest thing
to exceptions. If you come from languages and code bases that suffer from huge
amounts of confusion b/c of things like RuntimeExceptions vs.
CheckedExceptions vs. Errors (Java) it's a blessing to have strongly typed
return values that require doing something with the error case.

Though, errors in rust could be easier to work with, they are a bit painful
now. It looks like there is some stuff on the road map to do just this, based
on a merge I saw recently.

> Rust is pushed by Mozilla, Nim is a grass root “true open source” language.
> Having a “backer” might be good, but I like grass root efforts since they
> tend to be more open and easier to participate in as a “full” member.

Mozilla is a saint for backing this effort. Love them or hate them, it's like
Redhat's support of Linux. It's great that there are paychecks paying for this
development.

The Rust community is really strong, and doesn't (IMO) suffer from the issues
related to BDFL and has open transparent discussions around requested changes.

~~~
guelo
The main complaint that "Rust is much more complicated to program in." Is
still very valid. The learning curve for Rust's memory handling is steep. But
this is to be expected when comparing any GC to a non-GC language. GC
languages are always going to be easier for the programmer, that's the whole
point of the GC. Rust's claim of being memory-safe without a GC is great but
it's not an advantage if you can afford the GC.

~~~
pcwalton
I think that's a bit oversimplified. The same mechanisms that allow memory-
safe manual memory management also eliminate data races without having to use
a race detector. They also provide a very flexible form of const correctness,
if that's your thing.

I think the cognitive overhead of Rust's memory model outweighs its benefits
only if _all_ of the following are true for your application:

1\. Your application can afford the cost of GC and a runtime.

2\. Your application does not use concurrency, or you are willing to tolerate
data race errors, or you can eliminate all data races with a runtime race
detector (due to extensive test coverage or similar).

3\. The help that compiler-enforced immutability affords to your ability to
reason about the code isn't important enough to you to justify the cost.

I think that there are a lot of apps that meet (1), (2), and (3), don't get me
wrong. But I also think there are a good deal of apps that meet (1) but not
(2) or (3), and they can benefit from Rust as well.

~~~
lobster_johnson
I don't use Rust, so pardon my ignorance, but my impression is that Rust will
be very annoying if you're doing something that does not require safety.

For example, these days I write a lot of data processing stuff that is closer
to scripting than anything else, and is usually "one-offs" that get scrapped
afterwards. But the code needs to be super fast, talk to databases,
parallelize across multiple cores and nodes, which rules out many languages.
On the other hand, safety is the absolute least concern. I've been using Ruby
when it's not performance-sensitive, and Go when it is, and while Go is
significantly less pleasant, it gives me decent performance, concurrency and
access to libraries. Nim would probably also be ideal, if not for the lack of
libraries. But Rust just seems like a terrible choice for this stuff because
of the syntactical overhead of its abstractions, in particular memory.

That limits its usefulness. A single language for all my work would reduce
context switching and allow code reuse.

In general, my impression is that Rust is good at the complex, heavy stuff,
but it doesn't scale _down_.

~~~
pcwalton
Well, since you mentioned performance, the stuff I mentioned also buys you
performance. Rust is in a category of language performance that GC'd languages
with runtimes or JITs never reach in practice. I don't believe Go will be an
exception to this (especially not now, with its lack of an optimizing
compiler).

In general, I think if you're looking for "one language to rule them all",
that can scale up to the highest performance and down to one-off apps you
would write in Rails, you will be disappointed. Even if you don't care about
safety. That's because, no matter what people say, static and dynamic typing
_is_ a tradeoff. Rust is more statically typed than Go is. Go is more
statically typed than Ruby is. Which you should use depends on your
circumstances.

A lot of language designers and enthusiasts, from all communities, believe
there's a "sweet spot" of language design where your language can scale up or
down at will. I don't believe it. That experiment was tried with Lisp and Java
and failed. Multiple languages are here to stay.

At the end of the day, all I can say is: If you're happy with Go, use Go. Rust
was never designed with all use cases in mind, and I don't see that fact as a
failure at all. I see it as just acknowledging reality: trying to make a
language that scales up and down indefinitely to all use cases is chasing the
impossible, and language enthusiasts who believe their language is the one
language that can do that are all mistaken.

~~~
lobster_johnson
But Nim shows that it's possible to have a fast, statically typed language
that is also terse and lean and "script-like".

I actually do believe there exists a sweet spot. I just think that during
design, too little thought it given to the scalability of languages. And I
don't think it's that difficult.

For example, type inference is something of a game-changer, capable of making
a statically typed language feel nearly like a dynamic one. Yet it's only
recently being applied in mainstream languages, despite the theory not being
particularly new.

I also think too little thought it given to the cognitive overhead of syntax.
Wirth famously designed his grammars to fit on a single screen. Go (which,
like its earlier incarnations Alef, Limbo and Newsqueak, is very much
influenced by Wirth) gets this syntactical simplicity right. I thought early
Rust syntax showed a lot of promise, but I'm unhappy about the current
jungle::of::punctuation.

> If you're happy with Go, use Go.

To be clear, I'm _not_ happy with Go.

~~~
pcwalton
Nim sacrifices a lot. It's garbage collected with a non-thread-safe GC (last I
checked). It has undefined behavior, which makes me not confident that people
won't discover security problems. It wouldn't be suitable for the project I'm
working on, which has to be as fast as it would be if it were written in C++,
free of GC overhead (which does not just consist of pauses), and absolutely
memory safe. (That doesn't mean I wouldn't use it for other projects.)

Fixing these issues in Nim would make it much more like Rust. In particular,
it would have all the cognitive overhead you're criticizing Rust for.

If you want to show that it's possible to achieve all of the use cases of Rust
without the cognitive overhead, just citing Nim won't cut it. You need to (a)
explain how to do memory safety without garbage collection (reference counting
being, of course, a form of GC) _without_ introducing new concepts like Rust
does, (b) explain why everyone who thinks they can't afford GC is wrong, or
(c) explain why memory safety isn't important even for security-critical
software. I don't think (a) is possible, and I don't think (b) or (c) are
correct.

~~~
andreaferretti
But this is not at all what you said in the parent post. You said "Rust is in
a category of performance that GC languages never reach in practice".

This is not a claim about safety.

Every time I have benchmarked something, Nim has turned out faster than Rust -
or anything else, for that matter. Yet, Nim does have a GC. But since one can
allocate on the stack, and it is per thread, it is not a bottleneck.

About safety: you can tune it with compile time flags, or even annotate per
function what checks to leave.

So, _please_ , stop spreading FUD about Nim.

~~~
pcwalton
\- Non-thread-safe GC is unsafe. The way to make it safe is to make it thread-
safe. Thread-safe GC does not have negligible performance overhead. (Actually,
non-thread-safe GC doesn't either, not by a long shot, but it won't show up in
small benchmarks as easily.)

\- Just being able to allocate on the stack is not enough. You need to be able
to freely make pointers to those stack objects. The ways to do that are to
either (a) accept the lack of safety and admit dangling pointers; (b) use an
imprecise escape analysis; (c) lifetimes and borrowing. Every choice has
costs.

\- Safety with runtime checks is not equivalent to what Rust does. Rust
provides the safety without runtime checks. That yields better performance
than safety with checks.

I'm not intending to spread FUD about Nim specifically. The more interesting
question is whether it's possible to have a safe language with the same
performance as C/C++ without any cognitive overhead. I strongly believe, after
working in this space for over five years, it is not.

That's not to say Nim is a bad language. There are lots of things I like about
Nim. It's just that it won't escape the basic tradeoff between cognitive
overhead and safety/performance.

~~~
kevin_thibedeau
Nim threads don't share memory. Each has its own GC heap with data exchanged
through messages. The lack of thread safety is irrelevant when they can't
normally get to each others memory. This of course has performance
implications for certain types of parallelism. Nim optimizes for a model where
workers don't have to have high speed, high volume inter-communication. If you
need shared memory it is up to you to add it along with whatever safety
measures you need.

~~~
pcwalton
Does Nim now deep copy all messages between threads and start every thread
with a fresh environment? If so, it's safe. But it is really problematic for
any parallelism. (asm.js tried this and developers felt it was unacceptable.)
I think you really can't get away from thread-safe GC in practice.

------
aikah
It's crazy that in 2016, people are still seeking the holy grail of statically
typed, memory safe, no VM programming languages that retains most of the
advantages of dynamically typed languages. My point is it should be there
already!

Well , I guess language design is just hard... Yet the demand exists, and it's
huge no question.

Out of all of these, i still think D is the most interesting one (I like C#, I
want generics ...).

I don't agree with some choices Nim made but it still look interesting. Go is
way too rigid for my programming style. Yet Go set some expectations when it
comes to developer experience, so it was a step in the right direction.

~~~
otabdeveloper
> statically typed, memory safe, no VM programming languages that retains most
> of the advantages of dynamically typed languages

Those requirements contradict themselves in numerous ways. As always,
engineering tradeoffs are paramount.

As for "statically typed, memory safe, no VM" \-- C++ fits all those
perfectly. (Provided you put in the effort of learning C++. There's another
tradeoff you'd need to keep in mind.)

~~~
pjc50
C++ is not memory-safe and cannot be coerced into being so.

You can write nice C++ in the C++14 style, but you can't turn off or ban the
unsafe features. Until I can make my program fail to compile if there is a
bare pointer in it (and how would that work with the standard library and
system API?), it's not a memory-safe language.

------
3pt14159
Nim is great. It is fast and it works everywhere that C works or JavaScript
works since it transpiles to either (and then compiles if transpiling to C).
It is super fucking fast (usually faster than C) and it feels like it has none
of the limitations that you normally find out there.

That being said, there are a couple of issues.

1\. Like Crystal, Nim still doesn't have HTTPS for its webserver, and with
both, the default instructions are insecure. (Download this thing and run it
in your shell, pay no attention to any MITM that can trivially root your
machine).

2\. The community is really pro, but the arguments are too tiring. We had a
huge argument over the equivalent of Ruby's chomp. Everyone is so afraid of
bloat in the standard lib (which I don't really understand, since I've never
found myself wanting _less_ string methods).

3\. While the syntax is way better than Rust, Go, et al. It borrows some
annoyingness from Python where it could have looked to Ruby for better
guidance. For example, sort vs sorted. Sorted is the _safer_ operation in
Python. It returns a new sorted list. Now what normally happens in the real
world is that programmers make the safe version _first_ and _later_ make the
fast version. But imagine that the first version was called "sort" and it
returned a new array, how are you to transition to a fast sort and a safe
sorted? Error prone patching. Ruby's array.sort vs array.sort! is much better
during transition, more legible, just all around better. It means less
mangling around and it means that 99.9% of the time you know the method you're
calling is safe if it doesn't have the bang after it.

4\. There is still some instability here and there when you try to do cute
things. I can't remember exactly what it was, but something along the lines of
passing channels over channels segfaulted. This leaves you a little concerned
about just how much abstraction you build up.

That being said, I fucking love Nim. It's so fun to write, it's super fast,
it's quite legible, and you can do literally _anything_. It's had shared
objects (dlls) since I started using it, so Ruby <-> Nim is possible and fun.
It's very debugable and once it hits 1.0 and gets more mainstream use I'm sure
it's going to be a really popular language.

~~~
scardine
The deal breaker for me is the variable name normalization:

userName == user_name == username == uS_eR_aN_mE

It used to be totally case insensitive now it is case sensitive for the first
letter. Underscores are ignored: two identifiers are considered equal if the
following algorithm returns true:

    
    
        proc sameIdentifier(a, b: string): bool =
          a[0] == b[0] and
            a.replace(re"_|–", "").toLower == b.replace(re"_|–", "").toLower
    

For me it is a capital violation of the "principle of least astonishment".

~~~
3pt14159
I actually _love_ this. It makes it easy to write code in either a JS context
(where you want camel case) or Ruby(ish) context. I really don't see how this
is a deal breaker. It's one of the first things you learn when you start with
Nim and I've never had a problem with it.

To me this is kinda akin to the people that complain about the magic in Rails
or that Ruby includes so many things by default (like rand or sleep) without
working on a couple of projects first. Those really aren't the problems that
slow you down in Ruby and this isn't really something that is an issue in
practice.

~~~
lqdc13
it's a huge problem because in many cases you have no idea that you are
reusing a variable, because in every other language you wouldn't be reusing a
variable.

This plus the crazy global name space pollution. If you import something,
everything is imported from that module. I have no idea what to name things
because everything collides with everything else.

In Python, things are simple. Classes are 'CapitalCase' and functions are
'lower_case'. If I did the same thing in nim, they would collide. Also, in
Python it is considered a terrible idea to do

    
    
        from some_module import *
    

in Nim, it is the way things are done. Although, they are alternative methods
that don't do this.

also, the weird

    
    
        var
            a, b = 0
    

Perhaps you get used to it with time. But still namespace collision is always
a problem for me especially when working with others' libs.

However, it is currently the most painless way to write fast code and
integrate with Python, which says a lot.

Edit: Looks like first letter matters now, so ignore that part of the comment.

~~~
3pt14159
I've never had a namespace collision problem. Not when reusing or when
importing. When was the last time you used Nim?

~~~
lqdc13
Yesterday. But I ran into the issue last week.

I was reusing "paramStr" variable. This is a built in in the os module. I
defined "param_str" in my module. Then wrote another module that was using the
first one. Then realized I was overwriting an OS module function.

I actually have no idea how such collisions are handled. What if I import
another module that overwrites the OS module? What if a 3rd party lib uses
some variable that another 3rd party lib also defined?

A whole set of problems would be gone if such importing was looked down upon.
I mean it is exactly the same situation in Python (but not exacerbated by the
name canonicalization), and people realized a long time ago that doing this is
not a good idea.

~~~
robochat42
Coming from python, I'm also surprised by the way Nim imports but I realised
that it's not the same sitution because nim uses unified function call (ufc)
syntax to implement its method calls. Methods are functions that due to the
UFC sugar can be used as methods and so everything needs to be imported from a
module in order that methods are visible to the calling scope. This works
better than you might expect since the correct function normally gets called
due to static typing. Of course this doesn't fix variable name collisions. I'd
need to program more in nim though to decide how much of a problem this is.

~~~
robochat42
Having looked at the tutorial, I can see now that variable name collisions
(i.e. if defined in two imported modules) are caught as errors by the
compiler. Also only deliberately exposed symbols get imported into the
namespace which reduces the namespace overlap considerably.

------
Manishearth
EDIT: I realized the post was written before Rust's governance was diversified
([https://github.com/rust-
lang/rfcs/blob/master/text/1068-rust...](https://github.com/rust-
lang/rfcs/blob/master/text/1068-rust-governance.md)). Rust at that time was
"Mozilla led", but this isn't really true now.

> Rust is pushed by Mozilla, Nim is a grass root “true open source” language.
> Having a “backer” might be good, but I like grass root efforts since they
> tend to be more open and easier to participate in as a “full” member.

> UPDATE 2014-11-08: I know both languages are open source and have
> communities. But it remains a fact that Rust is lead by Mozilla (I would be
> surprised if not) and Nim is lead by its community.

Whilst the majority (not all!) of the core team consists of Mozilla employees,
the wider governance does not ([http://rust-lang.org/team.html](http://rust-
lang.org/team.html)). Anyone can participate in RfCs, and IIRC people can also
request to join subteam meetings (not exactly sure how this works), though the
main _discussion_ is out in the open on the RfC anyway. Additionally subteam
composition may grow or change over time.

Mozilla certainly is backing a large chunk of Rust development, but as time
passes this is becoming less and less true as large features are being written
by community members. As far as decision making is done it's pretty open now
with a defined process and completely open.

So "Rust is led by Mozilla" isn't exactly true anymore. The core team isn't
100% Mozilla, and the overall governance is even less so.

------
jswrenn
> Most advanced statically typed languages completely SUCK in the
> programmability department. Unless you are some genius of course.

Is this a common opinion? I've certainly heard the criticism that statically
typed languages slow you down because you're fighting the compiler, but not
that they're the only for exceptionally smart people. That's a troubling
conclusion and potentially a self-fulfilling prophecy.

I'm curious how the author came to this opinion. Every "advanced" statically
typed language I can think of isn't exclusively complicated type constructs;
it's very much possible to write programs with simple type constraints. I
wonder this opinion stems from a leak of Haskell's popular reputation.

~~~
adrusi
I think the author was referring to programmability as in language
extensibility. So the "geniuses" he references would be C++ template
metaprogramming wizards. I don't think he was claiming that statically typed
languages require you to be a genius to use.

~~~
gokr
Yeah, well, I actually meant both. One can't claim C++ is an "easy language"
no matter what you are doing with it. And let's face it, most languages that
are considered "easy to use" are dynamically typed. So yes, I do think it's a
common opinion. And yes there are surely exceptions you can find :)

------
matt_wulfeck
In my opinion, if a language really wants to compete with Go in my space
(devops/infrastructure), then it absolutely _must_ have static-linked
binaries. This feature has been such a huge win, and I continue to appreciate
it every time I go back to something else.

As far as I can tell Nim doesn't have statically-linked and compiled binaries
out-of-the-box. Even if it wins in other language-specific features, Go will
continue charging on in the infra space.

~~~
davexunit
Static linking is one of the worst possible things you can do in terms of
system security. When you run N applications that are all statically linked
against library Foo and a 0-day drops for Foo, how does a systems
administrator identify the applications that statically link against a
vulnerable version of Foo and then patch it? Suddenly that sysadmin is
dependent upon N upstreams to provide security fixes for a library they don't
even maintain! Static linking is only feasible in the "app" world of
proprietary software that gets shipped to customers without any concern for
their safety.

Go is a bold step backwards in so many other ways, but this is one of the most
egregious, especially since support for dynamic linking appears to be only an
experimental feature.

~~~
bkeroack
If you have a good CI pipeline, "patching" is all automatic.

A security bugfix just got pushed for Go 1.5. Since all my apps are dockerized
based on the official golang image and are built by CI, as soon as the fix was
published it was included in the next commit and pushed as part of that build.
No intervention required. Similarly all dependent packages are pulled as part
of the build so patches/fixes in them are automatically updated as well (note
that vendoring would break this).

~~~
notacoward
"as soon as the fix was published it was included in the next commit and
pushed as part of that build"

Lovely for your developers, or if you're deploying it yourself as part of a
service. Not so hot for people who are actually running the code you shipped
them last week, on their own hardware. Monolithic statically-linked blobs
aren't doing _them_ any favors.

~~~
matt_wulfeck
I would heartily disagree, as a guy that runs the code.

One of the benefits of these statically compiled binaries is that they are not
coupled to each other. Everything doesn't have to be upgraded at the very same
time.

~~~
notacoward
There's good coupling and there's bad coupling, and a semi-famous quote about
learning the wrong lesson.

"If a cat sits on a hot stove, that cat won't sit on a hot stove again. That
cat won't sit on a cold stove either."

It sounds like you've been burned by bad coupling. Sure, upgrading one thing
and having something else break sucks. However, having to upgrade a hundred
things because that one thing that's statically linked into all of them (like
your SSL library) had a bug _also_ sucks. It's like Scylla and Charybdis.
They're both bad, but it _is_ possible to steer between them.

The dual nature of this problem was recognized decades ago. It's why we came
up with things like API versions and even the symbol versioning that you
probably don't realize is already supported by your system's loader.
Responsible developers can use these things to make sure that compatible fixes
take effect where they need to without relinking, while incompatible changes
affect only new code compiled and linked with the new header files etc. That's
good coupling - the kind that reduces risk and total work.

Unfortunately, responsible developers are in short supply. Worse, faced with a
plethora of irresponsible developers who don't know how to make a change
without breaking stuff, a lot of people are reaching for the ugly workaround -
static linking, including the kind that's disguised as containers - instead of
solutions that will last. They've veered away from Scylla, right into
Charybdis's maw. I made that mistake once myself once - perhaps more than once
- until I realized I was getting just as burned by the "solution" as I was by
the original problem. I suppose more people will have to go through that same
process before the situation really improves.

~~~
matt_wulfeck
> Responsible developers can use these things to make sure that compatible
> fixes take effect where they need to without relinking, while incompatible
> changes affect only new code compiled and linked with the new header files
> etc. That's good coupling - the kind that reduces risk and total work.

I admit I do not know very much about this. Thanks for sharing! I admit I'm
definitely not the most competent developer but I try.

------
cookiecaper
I'm really excited to try Nim out in a project. It's been at the top of my
list for a while, despite the evident rise of Elixir as the next hot new
thing. Really love the Pythonish syntax and the ability to compile down to C
and run as a native program.

Edit: just noticed this was posted on Oct 20th, 2014. Nim has been evolving _a
lot_ over its short lifetime and it's possible that some statements in this
article are no longer pertinent.

~~~
Jach
Give it a shot! I finally sat down and did it recently, porting an old simple
pygame:
[https://github.com/Jach/dodgeball_nim_pygame_comparison](https://github.com/Jach/dodgeball_nim_pygame_comparison)
I'm glad I did.

~~~
dom96
Nice! I really like your analysis of Nim in the readme too. As somebody coming
from Python, a REPL has been on my wishlist for Nim for a while now :)

One suggestion: you can get rid of the makefile and use `nimble build` to
build instead. Take a look here for info on how to create Nimble packages:
[https://github.com/nim-lang/nimble#creating-packages](https://github.com/nim-
lang/nimble#creating-packages). You should basically be able to execute
`nimble init`, then add `bin = @["dodge"]` to your .nimble file.

------
jfb
"I ended up sifting out the 5 most interesting in my not so humble opinion -
Go, Rust, Dart and Julia."

Five?

~~~
Swizec
There are only two hard things in Computer Science: cache invalidation, naming
things, and off-by-one errors.

~~~
david-given
Now I'm going to have to link to one of my favourite sources of engineering
wisdom, The Codeless Code (which deserves to be way better known than it is).

[http://thecodelesscode.com/case/220](http://thecodelesscode.com/case/220)

~~~
darkmighty
This is absolutely fantastic.

[http://thecodelesscode.com/case/128](http://thecodelesscode.com/case/128)

------
z3t4
I seem to disregard languages that imports to global name-space by default,
because such programs tend do create spaghetti nightmare inception.

------
kiliancs
It's interesting to see how some URLs are already invalid. For example the
ones pointing to nimrod-lang.org

~~~
gokr
I will fix it, Nimrod was renamed.

------
robohamburger
I tried Nim last year after getting burnt out on rust beta. My impression is
that it has a lot of the same issues Haxe has in that it seems to be a
transpiler. The specific problem I hit was returning a list or vector
particular way caused strange C++ code to get generated.

It would be cool if they redid the backend so it functions as a real compiler
with llvm.

The transpiler issues + the smallish community pretty much scared me off. I am
not sad I "missed it" even if it was a cool experiment.

~~~
dom96
The C code generator is definitely much more mature than the C++ code
generator. Sorry to hear that you had problems with it. Did you report it as
an issue on Github? If not do you still have the code somewhere, I'd be more
than happy to take a look and submit a bug report for you if you don't have
the time.

~~~
robohamburger
Filed and probably fixed now (I hope). As the sibling mentions it sounds like
there is llvm support coming/available?

It is probably superstition instilled from my compilers course but having a
byte code producing compiler does tend to keep you honest.

------
k__
Rust with Nim syntax and I'm sold!

~~~
steveklabnik
[https://github.com/mystor/slag](https://github.com/mystor/slag)

(To expand on the README, this project was mostly made as part of as silly
bet, you shouldn't actually use it)

~~~
k__
This looks awesome.

------
systems
my list of 5 most interesting languages would be

    
    
        * Rust
        * Perl6
        * Clojure
        * F#

