Crystal is a statically typed, compiled programming language that looks a lot like Ruby. Let’s try it out! Maybe even work on a Taskwarrior thing I’ve been wanting to do.
Motivation
I want to play with a compiled language, but I’m not in the mood for Go or Rust.
Crystal looks friendly. Similar syntax to Ruby. Statically typed, ruling out a category of silly mistakes I always make (passing the wrong kind of value). Uses type inference, which means it can figure out what type a variable is without us telling it. Compiled, so you can run things quicker than in Ruby.
The philosophy summarized on the front page of the Crystal home page is “Fast as C, slick as Ruby”. That works for me.
I don’t care if it compiles super fast or the executable is super fast. An executable that runs quicker than my utility scripts, written in a language just as friendly, will be nice.
Installation
The documentation provides instructions on how to install Crystal across several platforms. Today I’m on my Windows partition. Though they’re working on a full Windows port, the best path for now is to use Homebrew on WSL.
crystal
provides a collection of subcommands.
Oh my there are some interesting commands in there! I’ll just focus on the ones that result in me running code.
One-liners with eval
Crystal does not ship with an interactive shell. Makes sense, considering that it’s supposed to be a compiled language. Still, it’s more flexible than I expected. If all I want is a one-liner, Crystal can do that!
Okay, that wasn’t super exciting. What about pretty-printing the current environment variables?
ENV is a Hash-like accessor. You can access and iterate through environment variables as if they were keys in a Hash.
Except that the pp
output was sorted. That’s fine. We’ll sort the keys.
Printing data as JSON is a pretty common task. Common enough that it’s a Hash method here. Except ENV isn’t a Hash. It’s a “Hash-like accessor.”
No problem, we can make a Hash from ENV
.
Well. I lost my sorting and the JSON isn’t exactly pretty-printed. I know I can fix this from inside Crystal, but my one-liner would get clunky. Hey, this is a one-liner. Let’s pipe it to jq!
There, now it’s all pretty-printed.
One-liners are fun.
What was I doing next? Oh right. Crystal source files.
Shell scripts with run
I have no idea how to do dependency management in Crystal yet. Something
about shards. But even stock Crystal looks like it would work as a glue language for shell scripts. Plus, the run
command lets you ignore the build process and pretend your code is being run directly.
hello-user.cr
- Since
run
is the default command, you could make a plain old Crystal script! What can I say, I like the old ways. - Crystal ignores trailing whitespace in
to_i
. You’ll still want tochomp
when examining the output of a command.
Remember, this is just me using #!
to say crystal run hello-user.cr
It looks a lot like Ruby. You could take out that #!
and it would almost work as-is.
Almost.
build
Okay, directly running scripts is great for testing or quick tasks, but Crystal is a compiled language. Let’s compile something.
Paul Fenwick and Dave Jacoby have — or had, no idea if they still do — a neat trick to show quick task status in their shell prompt. I’ll do the same thing, but in Crystal.
task-indicator.cr
Does it work?
Yeah, I know. I’m working on it. Anyways let’s build this thing.
There’s a new executable called task-indicator
. It’s not exactly small, but it produces the same output. Yes, the screaming face.
build --release
The default build includes a lot of debugging information that I won’t need in my daily usage. I’ll make a release version.
I didn’t have to give it a different name. I wanted to see the size difference between debug and release builds.
Then over in my .bashrc
:
~/.bashrc
Nice.
At first I put the output of task-indicator
in a variable, and put the variable in $PS1
. Except that variable was only evaluated on shell start. Instead put the invocation directly in $PS1
with a leading backslash. Now the indicator is live, as I expected it to be.
Done!
I wanted to learn some basic Crystal usage and find ways to work the language into my daily shell routine. With eval
, run
, and build
all at my disposal, it sure looks like a success! I even used Crystal to make a Taskwarrior indicator, which has been on my task list since last year.
I don’t know yet if Crystal is better than Ruby. Even at this early point it’s just as useful and just as much fun. Since “be useful and have fun” is a major thing for me, I’ll be exploring Crystal more!
Backlinks
Got a comment? A question? More of a comment than a question?
Talk to me about this page on: mastodon
Added to vault 2024-01-15. Updated on 2024-02-01