One Week on Crystal
I found a new programming language last week: Crystal (http://crystal-lang.org). This language is a strongly-typed, compile-able language that borrows much of its syntax and standard library from ruby (http://ruby-lang.org). After almost a week, I've started to get a feel for how the language works. Here's what I found:
Ruby Look-alike
Crystal's syntax is close enough to ruby, that if you are fluent in ruby it won't take long to pick up the language. This is valid Crystal syntax:
def fun( i )
puts i
end
fun(15)
fun("test")
What makes this possible for a strongly-typed language is type inference. The compiler looks at everywhere that fun(i)
is called from, and the types passed to it to determine what types can be passed, then compiles the function assuming a union of those types. The following is the same code with types explicitly listed:
def fun( i : String | Int32 )
puts i
end
fun(15)
fun("test")
A few things that are in ruby that are not in crystal are:
- $global variables don't exist in Crystal (you are encouraged to use @@@module variables as a replacement
- the pack/unpack functions don't have an implementation
- dynamic dispatch isn't implemented in the language, but I suspect it could be tacked on with macros
- var.class doesn't exist, but it is replaced with the compile-time typeof(var)
Fighting the Type System
A good portion of the time I've spent learning so far has been spent wrestling with the type system. The biggest thing I've met so far is that, if a type is nilable (has Nil as a possible type), you must explicitly handle that. I suspect that this lends itself to safer code with fewer segfaults. The next biggest thing is instances where the type inference fails. When this happens, the compiler requires you to tag the types explicitly and sometimes the types get messy. Another strongly-typed language, C++, also has this (especially if you try to do any template metaprogramming).
I was also rewarded with hitting a compiler bug:
Module validation failed: Function return type does not match operand type of return inst!
ret i32* %1, !dbg !11
%"Hash(Symbol, Bool | Int32 | String)"* (Exception)
Unhandled exception: Error opening file 'crystal' with mode 'r': No such file or directory (Errno)
Failed to raise an exception: END_OF_STACK
[0x55729af90146] ???
[0x55729a6d1adb] __crystal_raise +43
[0x55729a6d305c] ???
[0x55729a6e386f] ???
[0x55729a6dccfb] ???
[0x55729a6dbdfc] ???
[0x55729a6d8969] ???
[0x55729a70a628] ???
[0x55729a6d54ed] main +45
[0x7fc3f7773223] __libc_start_main +243
[0x55729a6ce3be] _start +46
[0x0] ???
I would expect that if I'm doing something wrong, I should get a compile error. I don't have simple code that reproduces this bug; the code that does this is 359 lines long and hasn't been released publicly (yet). Occurs on archlinux with crystal version 0.26.1-1.
C Bindings
Crystal includes a syntax for specifying bindings to C libraries completely in Crystal; no need to write a binding for a library in another language. The syntax is almost identical to the function definition syntax, except that all types have to be specified explicitly.
class BSON
lib Library
fun bson_append_int( b : Pointer(BSON), name : UInt8*, i : Int32 ) : Int32
end
end
C++ doesn't really work that well with this, but mostly because C++ uses non-standardized name mangling to support overloaded function calls.
Crystal Shards
One of the nicer things about Crystal is shards, which is the module system. Add your dependencies to shard.yml, and it will download the dependencies and add them to the search path. If you put your shard on github, it will show up on this list within minutes of posting it. In the process of learning, I thew together two bindings as shards cr-taglib and ejdb
Still missing are shards for: STEEM, DNS Server, IPFS, and most libraries.
Summary
I may be able to use this language for most programming that I do, replacing ruby and C++ for most tasks. There are a few things I haven't done yet, one of which is: is it possible to write a shared library with Crystal. I don't know, but I'll find out eventually.
Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!
Reply !stop to disable the comment. Thanks!
Congratulations @teknomunk! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!