Take that with a grain of salt, though, since I have a deep-seated hatred of Java stemming from experiences in the early 00s.
The simplicity and predictability are key with Crystal; everything is an object, and the control structures are limited in number.
Crystal code is very concise and legible. You might say it's crystal clear.
def foo_then_bar(a, b)
a.foo
b.bar
end
and it will just work for any two types that implement `foo` and `bar`, respectively. This isn't something I do often - I like the clarity that type-annotated parameters give - but it's a really nice feature to have available in the 2% of cases where I want it.Then there's all the ecosystem stuff - Kotlin makes me do extra work to target native, and has little bits of weirdness inherited from Java all around the edges. None of it's deal-breaking, but it is friction.
Note that Kotlin has union types through this compiler plugin: https://github.com/arrow-kt/arrow-meta/issues/570 However it is experimental and shouldn't yet be used in production. Btw sealed classes take care of many uses of union types.
What kind of extra work is needed? I'd say that graal native is transparant for any library that doesn't do weird use of reflection but it's true that many libraries do abuse of reflection.
I did try Kotlin/native hoping it would make it easier to remain in blissful ignorance of the JVM ecosystem, but as of a year or two ago it had significant holes in the standard library (most notably no file abstractions other than thin bindings to libc) and pretty atrocious compile times (something like 10s for hello world, and 30+ for a couple thousand lines of code).
Also, Crystal was first released in 2014, when Kotlin was like 3 years old, and 100% JVM-bound.
This was not the case when Crystal development started.
Also there is no ABI so you cannot use anything like a native DLL.
Native compilation while possible is clearly second class on the JVM platform. For Crystal it is first class.
Pretty sure this isn't the case with Kotlin Native[1].
[1] https://kotlinlang.org/docs/native-dynamic-libraries.html
Try creating a small command line tool for a JVM language. You need to distribute a virtual machine with it. You got the overhead of firing up a VM or JIT just for a short lived session.
Also JVM gobbles memory. You would not want a system made up of lots of tiny command line tools all running on a JVM. That would be a lot of overhead.
swift support for windows is non-existent
I was prepared to suggest WSL, but apparently Swift support for Windows is existent[1].
See Babashka[0] for an example scripting toolkit written in Clojure.
That many didn't want to buy those compilers and settled with the free beer that could get hold of is another matter.
Sadly, people often confuse "prevailing mindset of the noisiest authorities of some programming language" with "the programming language itself" { not that this is the only confusion or maybe even the worst... :-) }
In the words of David Heinemeier Hansson:
> In fact, Ruby, to me, so much of the enjoyment in Ruby is these incredible subtleties, of how many different ways you can structure a conditional. Like, Ruby has, I don't know even the count, there's gotta be 60 different ways you can say `if something`, right? And it is in those 60 different ways that I find half the enjoyment of writing Ruby. Like, it was one of those things where I knew, very early on, that Python was not a language for me because it said, right in the manifesto, there should be preferably one and only one way to do things. Ruby has the exact opposite approach, there should be preferably ten thousand subtle different ways of doing things, that will allow you to write that particular conditional, with just the right emphasis, do you write it in the front, do you put it at the back, is it multi-line, is it single line? Like, there's so much variety and it's in that variety that I find poetry. And it is the poetry of writing Ruby code, of making those subtle distinctions where, at the end, you can like, "Ehh, should we move it around" like, where I just go like, giggles, right? Like, this where like we talked about that big smile, right? So much of that big smile comes from, not just like solving the problem, but solving it in a poetic way.
This doesn’t sound elegant (meaning “pleasingly ingenious and simple”) at all.
It also only seems readable in the most shallow sense - certainly not understandable.