
Make a Lisp in Nim - def-
http://hookrace.net/blog/make-a-lisp-in-nim/
======
pkuki
I thought it could be interesting to see ratio of program performance to its
length. If I didn't make any mistake it looks like that:

    
    
                  perf3                   perf3 / 
                  macros      chars       chars * 100
      -------------------------------------------------
      scala       15963       24885       64,15
      nim         11121       20263       54,88
      java        17969       53223       33,76
      ocaml       7063        24371       28,98
      coffee      2326        15653       14,86
      racket      2461        17229       14,28
      cs          5414        45039       12,02
      clojure     1174        10099       11,62
      ruby        1255        13247       9,47
      go          3048        36321       8,39
      vb          4523        58099       7,78
      rust        4084        56516       7,23
      js          1726        26437       6,53
      c           3649        73047       5,00
      haskell     1163        30115       3,86
      python      304         19632       1,55
      forth       563         44715       1,26
      php         331         27332       1,21

~~~
pjmlp
What is perf3?

Also, which specific interpreters/AOT compilers/JIT compilers are being used
for each language being measured?

~~~
pkuki
Look at the original blog post. I just added third column to show ratio
between given data.

~~~
pjmlp
I will do it at home. Currently behind a corporate firewall.

------
shared4you
Are your graphs up to date ? Seems just an hour ago [1]:

> Rust: build with --release. 10X performance boost!

That might mean that Rust would top the charts instead of Nim.

[1]:
[https://github.com/kanaka/mal/commit/434516e0d172904e06b05f6...](https://github.com/kanaka/mal/commit/434516e0d172904e06b05f6dee83ce2e7859b950)

~~~
Dewie
It's weird that people that make benchmarks don't investigate which flags to
pass for getting the most optimized build. Many compilers don't do max
optimization by default. In particular, people making benchmarks with rust
code seem to tend to forget or be unaware of the `release` flag.

~~~
pcwalton
Yeah, this is happening again and again in Rust: people publish Rust
benchmarks without optimization on. In fact, we just decided this week to
change "Compiling" to "Compiling (Debug)" in Cargo if optimization isn't
turned on to address this problem. It's sad :(

~~~
pjmlp
If it helps it doesn't happen only to Rust but to all languages.

There is this misunderstanding between implementations and languages where
people equate whatever they have installed on their computer with all
implementations of the said language.

Also not knowing about profilers and optimization flags.

So yeah, it is sad.

------
jeremycw
Can someone explain the huge performance difference between nim and C? I
though nim compiled to C, therefore I would think that good handwritten C
would more or less be the upper performance bound for nim.

~~~
tel
Here's a similar, comically pathological, example:

"Haskell compiles to C therefore good, handwritten C ought to upper bound
performance for Haskell"

    
    
        main :: IO ()
        main = do
          x <- return ([1..100000001] !! 100000000)
          putStrLn "done"
    

As Haskell is lazy and pure it "automatically" eliminates the `x` and returns
nearly immediately avoiding all work. The correspondingly written C code would
do much more work despite its waste.

Of course, the human writing the C version might automatically perform this
optimization, but similar things can arise in far less obvious locations in a
more genuine compilation.

~~~
jlarocco
I'm not sure that distinction matters.

Any C compiler worth using will optimize out 'x' in that case. The details of
why (laziness vs code analysis saying it's unused) is pretty much irrelevant.

Saying "the human writing the C compiler" is an odd way to put it. It's "the
human writing the Haskell compiler" deciding it shouldn't be evaluated in
Haskell, too. Totally meaningless distinction.

~~~
tel
Freudian slip, I meant "C version". It was only meant to illustrate.

------
perturbation
I had this idea as well (after seeing Make a Lisp on HN). Anything that you
found challenging in porting the Python version to Nim?

~~~
def-
It wasn't a direct port of the Python one. Instead I mostly followed the guide
and looked at the Python code when something was unclear to me. Nim being
statically typed meant I had to create many MalTypes instead of just using the
built in Python ones. But nothing particularly challenging.

~~~
def-
Now that I think about it, I could have used implicit converters to make it
look more like Python, but that would probably lead to confusion.

