Live data from Hacker News

Crystal: Fast as C, Slick as Ruby

blog.codeship.com

51–60 of 439 posts

Re: Crystal: Fast as C, Slick as Ruby

#51
post #44

Earlier quoted context omitted.

Is Elixir really fast for web apps though? According to the web framework benchmark [1] the performance of Elixir is pretty bad - it's consistently slower than python and ruby frameworks. [1] https://www.techempower.com/benchmarks/#section=data-r12&hw=...

It is hard to say how they measure and what they measure. According to their "multiple queries" benchmark, which I guess is the real world one? (Unless everyone expects all custumers to line up and send their requests one after another one). https://www.techempower.com/benchmarks/#section=data-r12&hw=... we should all be using Dart on the server coupled with MongoDB perhaps.

The Dart vm is pretty damn fast, way faster for any CPU bound stuff than the BEAM.

Re: Crystal: Fast as C, Slick as Ruby

#52
post #8

From this post, Crystal appears to have some of the things many people have been lusting after in Rust: sophisticated metaprogramming, fewer sigils, a bigger standard library, fibers/coroutines/whatever-they're-called-now. But it still has a GC :(. Rust has completely spoiled me with making it easy to minimize dynamic memory allocation and copies, and to know (almost always) deterministically when something will go a…

Yeah it's weird how Rust has suddenly made me look for no GC languages everywhere I look. It opened up a whole new desire to not accept no for an answer in that regard. I have this burning thought in the back of my head that there just has to be a simpler way to offer it than Rust does it too.

Memory management is difficult, extremely difficult, to get correct in the way rust does. I don't think I've seen a leak or bad dereference in years. The only way it really manages this is by tying references into what amounts to a proof assistant. Every simpler method of which I can think either sacrifices capability (e.g. no references at all; only raii + copy on write) or it becomes a GC with all its wonderful trade offs.

GC isn't terrible, though. Azul has struck an amazing balance between latency and eagerness—even if you can't afford it the technology does exist. If you don't have latency, memory restrictions, or embedding requirements, rust may be overkill.

Re: Crystal: Fast as C, Slick as Ruby

#53

Earlier quoted context omitted.

(0) It does not. It has a GC, and all features you'll likely use are memory-safe. You can of course use unsafe methods and raw pointers, but those are documented that they are unsafe and are usually only used for writing bindings to a C library. Macros for example are evaluated and constructed at compile-time, so no undefined behaviour can come from those. Most methods have different behaviour. For example, one metho…

> (0) It does not. It has a GC, and all features you'll likely use are memory-safe. Nice. > (1) Not at all, look at the source implementation of their language implementation. For example, the lexer: https://github.com/crystal-lang/crystal/blob/master/src/comp... . Seems pretty clear to me. How am I supposed to learn the language's semantics from a lexer? > (2) Not entirely sure what you mean since that is such a bro…

> How am I supposed to learn the language's semantics from a lexer?

Not what I wanted to achieve, but the lexer contains some frequently used methods and is fairly simple and straight-forward, but if you want to learn the semantics why not just go to their docs? https://crystal-lang.org/docs/syntax_and_semantics/index.htm...

> Consider this use case: I spawn five fibers. Can I send the same mutable object to all five? If so, can they attempt to mutate the object without properly taking turns? (e.g., using a mutex)

Taken from the docs:

Crystal has Channels inspired by CSP[1]. They allow communicating data between fibers without sharing memory and without having to worry about locks, semaphores or other special structures.

...

Because at this moment there's only a single thread executing your code, accessing and modifying a global variable in different fibers will work just fine. However, once multiple threads (parallelism) is introduced in the language, it might break. That's why the recommended mechanism to communicate data is using channels and sending messages between them. Internally, a channel implements all the locking mechanisms to avoid data races, but from the outside you use them as communication primitives, so you (the user) don't have to use locks.

[1] - https://en.wikipedia.org/wiki/Communicating_sequential_proce...

Re: Crystal: Fast as C, Slick as Ruby

#54

I'd like to put out there that Crystal is absolutely awesome. The language itself is Crystal clear, but the language documentation and API documentation - oh my! I had never worked with compiled languages before I tried Crystal, but had always had a huge interest in getting into that. When I wanted to learn the compiled ecosystem I looked at languages like Go and Rust, but the learning curve for those was a bit overw…

Maybe the makers of Crystal need to take a leaf out of Go's book. Despite the Go creators not being windows users (AFAIK), they support Windows as a primary target, to help adoption, I assume.

Of course the Crystal people probably don't have the same number of developers working on it as Go did even early on.

Edit: Go took a little while to support windows, not until around July 2010. See this question from November 2009: http://stackoverflow.com/questions/1717652/can-go-compiler-b...

Re: Crystal: Fast as C, Slick as Ruby

#55
post #8

From this post, Crystal appears to have some of the things many people have been lusting after in Rust: sophisticated metaprogramming, fewer sigils, a bigger standard library, fibers/coroutines/whatever-they're-called-now. But it still has a GC :(. Rust has completely spoiled me with making it easy to minimize dynamic memory allocation and copies, and to know (almost always) deterministically when something will go a…

What do you mean by "sophisticated metaprogramming"? Rust has pretty sophisticated (sometimes I wish it was less) macro / compiler-plugin support.

Perhaps that's not the right way to phrase it. I guess I'm mostly thinking of compiler plug-ins which are very unstable right now. Which means that most users probably never write procedural macros in their own code. (I certainly don't)

Re: Crystal: Fast as C, Slick as Ruby

#56

Earlier quoted context omitted.

> (0) It does not. It has a GC, and all features you'll likely use are memory-safe. Nice. > (1) Not at all, look at the source implementation of their language implementation. For example, the lexer: https://github.com/crystal-lang/crystal/blob/master/src/comp... . Seems pretty clear to me. How am I supposed to learn the language's semantics from a lexer? > (2) Not entirely sure what you mean since that is such a bro…

> How am I supposed to learn the language's semantics from a lexer? Not what I wanted to achieve, but the lexer contains some frequently used methods and is fairly simple and straight-forward, but if you want to learn the semantics why not just go to their docs? https://crystal-lang.org/docs/syntax_and_semantics/index.htm... > Consider this use case: I spawn five fibers. Can I send the same mutable object to all five…

> but if you want to learn the semantics why not just go to their docs? https://crystal-lang.org/docs/syntax_and_semantics/index.htm...

Yep, fair enough. I'm somewhat worried about how abstract classes work: https://crystal-lang.org/docs/syntax_and_semantics/virtual_a...

Apparently, Crystal can infer the methods of an abstract class from the methods of its subclasses. In the Animal/Dog/Cat example, what happens if, in a separate module, if define a Snake class that doesn't have a `talk` method? There are several possibilities, sadly all pretty bad:

(0) Does the type checker retroactively decide that not all Animals can talk?

(1) Does the type checker decide that Animal subclasses can't be defined in a separate module?

(2) Does the type checker decide that, if an Animal subclass is defined in a separate module, it must have all the common methods to all Animal subclasses defined in the same module as Animal?

(3) Is type checking not modular?

> That's why the recommended mechanism to communicate data is using channels and sending messages between them.

I'm asking about the errors that the language prevents, not the community's conventions.

Re: Crystal: Fast as C, Slick as Ruby

#57
post #4

Looks very nice. I hope it gains momentum. For now, if you want a fast language with the beauty and productivity of Ruby, check out Elixir [0] and its web framework, Phoenix [1]. I've been using Phoenix for a year, and it's the first framework that I've actually liked more over time. And I've been a web developer for a decade. With its recent 1.0 release, Phoenix is gaining a lot of momentum. If you want some idea of…

Elixir is not a fast language. Not even close. Yes, it handles concurrency and parallelism beautifully which in turn enable distributed applications to perform quite well. But the language itself is significantly slower than Crystal / Rust / Go / Swift. It's not in the same category at all. That said, it's a great language worth recommending.

I'm not sure why you're grouping those four languages as they overlap very little. Go has latency and emphasizes network bound services (and randomly docker for some reason, I'm sure a good one); rust is a c replacement; swift is for writing iOS/Mac apps; and crystal is a newborn. I'd actually call it quite close to go: a high emphasis on concurrency and services. Single thread performance matters much less when scaling horizontally is mandatory to smooth latency spikes, and I'm betting on io bound work erlang would be competitive with go.

I've never used elixir but I assume it has a similar performance profile to erlang as it shares the vm.

Re: Crystal: Fast as C, Slick as Ruby

#58
post #41

Earlier quoted context omitted.

Elixir is not a fast language. Not even close. Yes, it handles concurrency and parallelism beautifully which in turn enable distributed applications to perform quite well. But the language itself is significantly slower than Crystal / Rust / Go / Swift. It's not in the same category at all. That said, it's a great language worth recommending.

> Elixir is not a fast language. Depends what we mean by fast. I have seen Erlang VM handle 100k requests per second on a distributed cluster. That's plenty fast. Moreover, because of fault tolerance, it means ability to have a better uptime, with less people on-call. "Fast" can also be measured to include that, if system goes 200k requests per second, but crashes at midnight and stays down for a few hours, the avera…

I have seen Erlang VM handle 100k requests per second on a distributed cluster

A single JVM server can do that load, scaling and providing fault tolerance for a server that just accepts requests is trivial these days, also, if your requests do computationally intensive stuff you are going to have a very bad time with Erlang.

It all depends on the problem domain.

Exactly, and the domain for Elixir/Erlang is way more niche and specialized than applicable domains of other languages.

I don't have anything against Elixir but part of its crowd just advertises it as the best thing for everything.

Re: Crystal: Fast as C, Slick as Ruby

#59
post #39

Earlier quoted context omitted.

Yeah it's weird how Rust has suddenly made me look for no GC languages everywhere I look. It opened up a whole new desire to not accept no for an answer in that regard. I have this burning thought in the back of my head that there just has to be a simpler way to offer it than Rust does it too.

Yes. I'm currently trying to think of a good way to add it to Myrddin, which currently makes it more or less manual. Doing it in a simple way is a tough problem. The simplest solution is to add the moral equivalent of 'null' -- objects that transition to an idempotently destructable state, which solves a lot of complexity with the data flow and analysis (yay!) at the cost of some safety (boo), and nulls (louder boo).

My language (Lily) handles the problem by trying to avoid the gc where it can.

Lily is statically-typed, built-in classes can't be inherited from, and there's no C-like casting.

With those rules in mind, most objects can't become cyclical. It's impossible for a list of strings to loop back onto itself, for example. It helps that the value classes backing enums (like Option and Either) are immutable, which I so far suspect prevents a cycle.

That at least allows you to group classes into three groups:

These never cycle (Integer)

These may cycle (List)

These always cycle (Dynamic, linked lists?)

Post reply on HN