Menu

Switch to the dark mode that's kinder on your eyes at night time.

Switch to the light mode that's kinder on your eyes at day time.

Switch to the dark mode that's kinder on your eyes at night time.

Switch to the light mode that's kinder on your eyes at day time.

in

Nim vs. Crystal, Hacker News


[email protected] [email protected]

I’ve been wanting to write-up a comparison on Nim and Crystal for quite some time now, and I’m happy that I’m finally able to do so. What I’ve decided on doing; is breaking this up into a three part series as there areSOmany features of both languages ​​I’d like to talk about, and therein many opinions held too. I do have a habit of writingverylong articles, so I’d like to limit the topic scope, to keep each of these a little snappier!crystal vs nim

Before I go into specifics on either of these languages, I’d first like to go into my reasons for first learning both languages, and briefly touch on my past experiences with the two of them. I admit that Ihavehad more experience with Crystal than I have with Nim; However, I will give an objective view of both languages ​​until I go into my personal preference towards the end of each article in this series.crystal vs nim********************** crystal or nim? Both super immature but funcrystal vs nim– @ r4vi (@ r4vi) (June) **************************************************************************************************************************************** ,crystal vs nimBack in mid – (**********************************************************************************************************************, I sent out a tweet asking my dev followers which low-level languages ​​they would recommend I take a look at. For a while before this, I had been waiting for a new systems language for me to learn, but until this tweet, I never really found one that I wasactuallyinterested in taking a look at.crystal vs nimNaturally, both languages ​​have a

TONNEof features, so I’m not going to go into details on things like basic types, etc. I will simply compare the biggest things that attracted me to both languages. For in-depth tutorials on the features of both langs, check out theCrystal Docs

, or the (Nim Docs) ************************.

Anyway, let’s take a look at both languages, and you can make your own mind up as to which you’d rather be programming in. Maybe both. Maybe neither!

************************** (******************************** (Nim) ************************************************ Nim is a statically-typed, imperative, systems programming language; aiming to achieve the performance of C, be as expressive as Lisp, and have a simple, clear syntax like Python. I have to say, from my experience Nim manages to pretty muchfit these criterion.crystal vs nim

By compiling to C, Nim is able to take advantage of many features offered by modern C compilers. The primary benefits gained by this compilation model include incredible portability and optimizations.crystal vs nim

The binaries produced by Nim have zero dependencies and are typically very small. This makes their distribution easy and keeps your users happy.crystal vs nimcrystal vs nimWhen I say itpretty muchmatches the criteria, the only statement that does not quite match is achieving the performance of C. In realise this is an almost impossible task, but Nim actually did fall short on a few occasions when it came to performance. I will go into detail about this later on in the article.crystal vs nim[..3] ********************** Installing NimNim is super easy to install. If you're on Windows,head over here, and download / run the installer.

If you're on any other Unix-based system, you can run:crystal vs nim(**************************************** (****************************************** $ curl https://nim-lang.org/choosenim/init.sh -sSf | sh` (******************************

If you're on Mac, and with Homebrew installed, simply run:

(**************************************** (****************************************** $ brew install nim[email protected] ****************************

You could also consider using choosenim to manage Nim installations in a similar way to pyenv and (rustup) *********************************************** [..3]

Interfacing Other Languages ​​

************************ One of the things that attracted me to both Nim

andCrystal, was the ability to natively interface with other languages, and theeasewith which that is achieved. Nim has bidirectional interfacing not only with C, but also natively with JavaScript. Crystal natively interfaces with C, but is only unidirectional. Definitely a point scored here for Nim!crystal vs nimcrystal vs nimWhen it comes to building DApps, the variety of target hardware they must be run on is already large, and growing all the time. The low-level ability to interop with other languages ​​makes for both languages ​​being a much more attractive proposition.crystal vs nimcrystal vs nimFor a quick demo, let’s take a look at interfacing both C and JavaScript from Nim.

C Invocation [..3] ************************************ [1,true] Firstly, create the file (logic.c) with the following content:crystal vs nim(**************************************** (**************************************** (************************* (int) (addTwoIntegers) **************************************** (**************************************** (int) **************************************** (a,crystal vs nim************************ (int) **************************************** (b) (**************************************************************

{****************************************  (return) ***************************************** (a   b;**************************************************************}
********************************************************************** [..3] ********************************** (************** (Next, create the file) calculator.nimwith the following content:crystal vs nim(**************************************** (**************************************** {. compile: “logic.c”.} (**************************************** () ************
**************************** (*************************************** (proc) ****************************************** (addTwoIntegers) a, b: (cint) ):cint
{. importc. }  (******************************
[..3] ******************
when isMainModule:crystal vs nimecho addTwoIntegers ( (3) *****************************************, ****************************************** (7) )****************************************** (******************************************** Now then, with these twovery simplefiles in place, we can run: (**************************************** (****************************************** $ nim c -r calculator.nim****************************************** (********************************************** The Nim compiler will compile thelogic.cfile in addition tocalculator.nim and link both into an executable; which outputs(****************************************** when run. Very sharp, in my opinion!crystal vs nim
JavaScript Invocation
Even sharper, in my opinion, is the ability to interop with JavaScript. Create a file titledhost.htmlwith the following content:crystal vs nim(**************************************** (**************************************** (
****************************************** (****************************** [email protected] ************************************************** **************************** (=**************************************** "text / javascript" (******************************************>(****************************************
(
function (**************************************** (addTwoIntegers) ( (a, b) ******************
**************
{ (******************************************
(return (a b; [..3] ******************************
**************************************
(************************************************************************************
(**********************************************************************************
****************************************** ("text / javascript"
src="calculator.js" (****************************************>(****************************************
script (******************************************>(****************************************** (******************** (
( (********************************************************************************** (****************** (html) ******************************************>(****************************************** ************************************************ [..3] **********************************

Now, create anothercalculator.nimfile with the following content (or reuse the one from the above C example):crystal vs nim(**************************************** (**************************************** (proc) addTwoIntegers (a, b:********* (int) ):

int  (*********************************** {. importc.}  (***************************************** [..3](******************************
when isMainModule: (******************************
**************************************** (echo addTwoIntegers) (3) ******************************************, ************************************** (7) )******************************************
Compile the Nim code to JavaScript by running:crystal vs nim(**************************************** (****************************************** $ nim js -o: calculator.js calculator.nim
******************************************** (********************************************** [email protected] Once that's done, go ahead and openhost.htmlin a browser and you should see the value (****************************************************************************************************************************************in the browser's console. I think this isREALLYneat. It’s superb how easy it is to achieve that, too.crystal vs nimAside - a ************ Quick (not-so) Secret: (**************** Instead of writing out the HTML above, you could actually use (Nim's native**************** HTML DSL:crystal vs nim(**************************************** (**************************************** (import) html_dsl
********************************************************** html page:******************************  head:**************************************** (title)  “Title”crystal vs nim)crystal vs nim**********************************  (body:) ******************************  (p)  "Hello"(**********************************************  (p) ************************************** (“World”) )  () ************
**************************** (dv:

******************

[email protected] *************************** (p) "Example"

************************** (echo render (page ())crystal vs nim**********************************
Running this will output the following: (**************************************** (**************************************** (********************************************************** () ************
**************************** (**************************************** (class=
'has-navbar-fixed -top '
() **************************************** [..3] ****************** (************************************** ((***************************** ((meta) ****************************************** (charset) ******************************************=“utf-8”>(****************************************
************************** (****************************() **************************************** (******************************************** () ************ [email protected] **************************************** (head) ****************************************>
[email protected] ************************** 'has -navbar-fixed-top '>(******************************************************************************* ( (Hello)
p
(******************************************( (World) **************************************** (****************** (p)>[email protected] ****************************************************************** ( (**************************************** () ************
**************************** (**************************************** (Example
(p
(******************************************************************************** (html) ****************************************>(****************************crystal vs nim**********************************
(Crystal **************************** Crystal is a statically-typed, object-oriented, systems programming language; With the aim of achieving the speed and performance of c / c , whilst having a syntax as simple, readable, and easy to learn as Ruby.crystal vs nimI first came across Crystal when I saw @ sferik

giving a talk on it in Poland back in 2017.Video here.

It was a great talk, and sparked my interest in Crystal right there and then. When I initially explored Crystal I thought it looked awesome, but I was too busy with all the other languages ​​I was using on a daily basis, to be able to focus my time on it properly.

(************************************************** (Installing Crystal)
You can find all of the relevant instructions for installing Crystal, on the (main website installation pagecrystal vs nimcrystal vs nimIf you are on Mac, and have Homebrew installed, you can simply run:crystal vs nim(**************************************** (**************************************** $ brew install crystal
[email protected] ****************************  (******************************************** [email protected] ******************** (However, if you are a Windows user,  for the time beingyou are out of luck. , unless you use the Windows Subsystem for Linux. If I were in a more shocking / pedantic mood, I'd take a (not yet gained) pointaway  from Crystal here, for lack of Windows support.crystal vs nim

[..3] **************** (Interfacing C)

Let's build a simple script in C that says “hi!”. We’ll then write a Crystal app to bind to our C library. This is a great starting point for anyone who wants to know about binding C in Crystal.crystal vs nim

First off, let’s create a project with Crystal’s scaffolding tool (I’ll cover this feature later). Run:crystal vs nim(**************************************** (****************************************** $ crystal init app sayhi_c [email protected] ****************************** (********************************************

then head into the directory sayhi_c / src / sayhi_cand let's create a filesayhi.c

with the following contents:crystal vs nim(**************************************** (**************************************** (#) include(********************************************************************

****************************** (********************************
void
(hi)   ( (const) ******************************************  (char) **************************************  name)crystal vs nim************************  ({**************************************)******************************  (**************************************** (printf) ****************************************** (
"Hi% s! N" (******************************************, name); [email protected] ************************************** (****************************************}
Now we need to compile our C file into an object. On Ubuntu or Mac using gcc we can run:crystal vs nim(**************************************** (****************************************** $ gcc -c sayhi.c -o sayhi.o
******************************************** (********************************************** [email protected] Using the -o flags allow us to create an Object filetype. Once we’ve got our Object file, we can bind it from within our Crystal app. Open up oursayhi_c.crfile, and have it reflect the following:crystal vs nim(**************************************** (**************************************** require

"./ sayhi_c / *"
******************************************@ [Link(ldflags:"#{__DIR__}/sayhi_c/sayhi.o")]
**************************
[email protected] **************************  (************************************** (lib) ******************************
Say (******************************************
(
(fun) ******************************************* (hi) ********************************************************** (name:

************** (LibC:) ******************************************: Char : Void () ************

(end) ******************************************  [..3](******************************
Say.hi (
“Status ((*****************************
(**********************************************

I'll mention now that there are no implicit type conversions except to_unsafe - explained here when invoking a C function: you must pass the exact type that is expected.

Also worth noting at this point is that since we have built our C file into an object file, we can include it in the project directory and link from there. When we want to link dynamic libraries or installed C packages, we can just link them without including a path.crystal vs nim

So, if we build our project file and run it, we get the following:

(****************************************
$ crystal build --release src / sayhi_c.cr****************************************** (****************************** $ ./sayhi_c (******************************(******************************************
>Hi Status!
**************************
As you can see, Nim takes the winners trophy in this case, as it ismuchsimpler to achieve a similar goal. With Nim, we were also able to link both the Nim and C files into the same executable, which Crystal sadly cannot do.crystal vs nim
************************** [..3] ************************************************************** Performance Tests [email protected] ************************ (**********************************************************************
Parsing & calculating values ​​from a large JSON file:

Firstly, we need to generate our large JSON file. For this test, we're going to generate a dataset which includescrystal vs nim1 million [email protected] ********** items.crystal vs nim
crystal vs nimWe can do so with the following Ruby script:crystal vs nim(**************************************** (**************************************** require
'json'
(******************************
**************x=[]crystal vs nim********************************** (**************************************** () ************
**************************** (****************************************** (******************************************. times do [..3] ******************************** (**************************************************************************** h={ (**************************** (
('x')=>rand, (**************************** (
'y'
=>rand,  (********************************************  (************************************** ('z') ****************************************==rand,  (********************************************  (**************************************** ('name') ****************************************** (=>(

'a'
..
'z'
). to_a.shuffle [0..5]. join    ()
 rand (). to_s,
****************************'opts'

=>{'1'

=>[1,true]},

**************************** (**************************************} (******************************************** (x [email protected] **************************** (end) (****************************** (

(******************************File .open (1. json "(******************************************, 'w' () ({***************************************** | f | (f.write JSON.pretty_generate)

'coordinates'=>x,

'info'=="some info"

}**************************************** (**********************************************crystal vs nimThis will generate a JSON fileof around (mb, with the following syntax: (**************************************** (**************************************** {{****************************************** (**************************************** "coordinates" (*******************************************: [email protected] }****************************************} [email protected] **************************** ], (**************************** (**************************************** “info” (******************************************:

"some info"

**************}
****************************  (********************************************
Now that we have our chunky JSON file; we can write our first test -in Nim:crystal vs nim(**************************************** (**************************************** (import) ***************************************** (json)********************************************************** (let) **************************************** (jobj=parseFile)
"1.json")[email protected] ****************crystal vs nim
let coordinates=jobj ["coordinates"]. elems (*****************************
let (len=(float) ******************************************* (coordinates.len) [email protected] ******************************** () ************ [email protected] **************************************** (var [email protected] ****************************** (x=crystal vs nim************************ (0) ******************************************************** (0) ********************************************************************** (var) ****************************************** (y=) **************************************** (0) **************************************** (.
**************************************** [..3](var ["y"] ********************************** (z=[0..3] ****************************** (0) ************************************************************ (0) (******************************************** [..3] ************************************************************************** [..3] **************************** (for************************** (coord) ***************************************** (in

****************** coordinates: () ************

**************************** x =coord ["x"]. fnum (******************************
**************************************** (y =coord ["y"]. fnum
 (z =coord ["z"]. fnum**********************

******************************************************** (**************************** () ************ [email protected] **************************************** (echo x / len) *****************************************

echo y / len (****************************** (************************* (echo z / len)**************************** (**********************************
[email protected] And again; the same simple test, this time writtenin Crystal:crystal vs nim(**************************************** (**************************************** require

"json"
(******************************
************** (text=File.read)"1.json"
)
****************************  jobj=JSON.parse (text)
****************************  coordinates=jobj ["coordinates"]. as_a************************************** (len=coordinates.size [email protected] ********************************  () ************ [email protected] **************************************** x=y=z=(0) ******************************************  (**************************** () ************ [email protected] ****************************************  [..3](coordinates.each) **************************************** (do
| coo rd |  (******************************
x =coord ["x"]. as_f  (**********************************************  (y =coord ["y"]. as_f  (****************************(z =coord)  .as_f

**************************** (************************* (end) (**************************** () ************ [email protected] **************************************** [..3](px / len) ****************************************

py / len

************** (pz / len)******************************

(******************************** (************************************************************************* [..3] ************** (Results:

Building our test files into tiny release packages with the respective commands below:

(****************************************

$ crystal build json_test.cr --release -o json_test_cr --no-debug (******************************

************************************** (********************************************** (**************************************$ nim c -o: json_test_nim -d: danger --cc: gcc --verbosity: 0 json_test.nim
******************************************** (********************************************** [email protected] We ca n then time & run those packages, to obtain our test results:crystal vs nim

(******************************************************************************** (Language) Time (s) [email protected] (Memory (Mb) [email protected] (**********************************************************************************

********************************************** (str2=Base) . strict_encode (str)**************************** (print) "encode# {str [0..3]} (... to

************** (# {str2 [0..3])

...: “ (**********************************************************************************[email protected] **************************** (t, s=Time.local, [email protected] **************************** (0) ********************************************************************************** (TRIES.times) **************************************** do | i |************************************** (str2=Basecrystal vs nimstrict_encode (str)
[email protected] **************************** s =str2.bytesize ****************************************** [..3] ******************

(************************************************************************************** (Nim) ************************************************************************************ (6.) ********************************************************************************************************************************* (**************************************************************************************************************************** (4) (******************************************************************************** (Crystal) 4. ************************************************************************************************************************************** (****************************************************************************************************************************** (7) (****************************************************************************************************************************************************** [email protected] As you can see; in this caseCrystal is the more performant language - taking less time to execute & complete the test, and also fewer Megabytes in memory doing so.crystal vs nim
**************************
Baseencoding / decoding a large blob:

crystal vs nimIn this test; we will firstly encode and then decode a string, with a current timestamp into newly allocated buffers, utilizing the Base 64 algorithm. For starters, let's look at theNimtest:crystal vs nim(**************************************** (**************************************** (import) ***************************************** (base) ************************************************************************************************************************ times, strutils , strformat(********************************

**************
let  (******************************** STR_SIZE=(*****************************************************************************************************************  (******************************************  (******************** (
(let (****************************************** (TRIES) ******************************************==************************************ (******************************************** (****************************** [..3] **************************** (let) ***************************************** (str=strutils.repeat) 'a', (STR_SIZE) )
******************************  (**************************************** (var) ****************************************** (str2=base) ************************************************************************************************************************************. encode (str)  (******************************
(stdout) ******************************************. write ( fmt "encode {str [..3]} ... to {str2 [..3]} ...: ")****************************************  (****************************************************************************  (var) **************************************** t=times.epochTime ()  (******************************  [..3] ****************************** (var) ***************************************** (i=) ************************************** (0) ****************************************  (********************************************** **************** (var) ***************************************** s:  (int) ***********************************************************************************************************************************=(0)
**************************
(while) ****************************************** (i str2=base (**********************************************************************************************************************************. encode (str) (******************************************** s =len (str2)************************************** (i =[email protected] **************************** (1) ******************************************************************************** (echo)
************************** fmt "{s}, {formatFloat (times.epochTime () - t, ffDefault, 6)}"(******************************
(****************************** [email protected] ******************var
str3=base (**********************************************************************************************************************************. decode (str2)  (*****************************
(stdout) *******************************************. write ( fmt "decode {str2 [..3]} ... to {str3 [..3]} ...: "
) [email protected] ******************************************************************** t=times.epochTime () (******************************
************************************** (i=(0) ************************************************************************************* s=(0) ********************************************************************************** (while) ****************************************** (i
str3=base (**********************************************************************************************************************************. decode (str2) (******************************s =len (str3) (****************************** (************************* (i =) **************************************** (1)
(echo) fmt "{s}, {formatFloat (times.epochTime () - t, ffDefault, 6)}") [email protected] **************** ((************************************************

And now the same test, written in Crystal:crystal vs nim(**************************************** (**************************************** require

"base  (***************************************** [..3] ******************************
************************************** (****************************STR_SIZE=131072 (****************************************
************************** (TRIES=) **************************************** (****************************************** (**************************** () ************ [email protected] **************************************** [..3](str=) ************************************* (a) STR_SIZE [..3]

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

I only used an iFrame to crawl and scrape content, Hacker News

Travis Kalanick quits Uber's board, sells off all his Uber stock, Ars Technica

Travis Kalanick quits Uber's board, sells off all his Uber stock, Ars Technica

Back to Top
close

Log In

Forgot password?

Forgot password?

Enter your account data and we will send you a link to reset your password.

Your password reset link appears to be invalid or expired.

Log in

Privacy Policy

To use social login you have to agree with the storage and handling of your data by this website. %privacy_policy%

Add to Collection

No Collections

Here you'll find all collections you've created before.