News for hackers. Stuff that matters.
Re:Crystal: Fast as C, Slick as Ruby by hubert123 on Thursday August 04, 2016 @01:53AM (#12223671)
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.
Re:Crystal: Fast as C, Slick as Ruby by duaneb on Thursday August 04, 2016 @02:16AM (#12223737)
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 by quotemstr on Thursday August 04, 2016 @12:27PM (#12226642)
> Memory management is difficult, extremely difficult, to get correct in the way rust does

Memory management isn't hard --- you just need to pay attention to detail and not say "YOLO, let's abort on OOM" like the Rust stdlib does. Rust is an unacceptable language for anyone who cares about robustly responding to heap exhaustion.

Re:Crystal: Fast as C, Slick as Ruby by Turing_Machine on Thursday August 04, 2016 @09:40PM (#12229589)
"Memory management isn't hard --- you just need to pay attention to detail"

You're quite right. The problem is that every bit of attention you spend on that detail is attention that you're not spending on details that are actually solving your problem.

I programmed in C for decades. I do not miss malloc() and free() in the least.

(I still do use C when the situation warrants, but the situations where it is warranted are becoming rarer and rarer with each passing year).

Re:Crystal: Fast as C, Slick as Ruby by vardump on Thursday August 04, 2016 @12:20PM (#12226580)
> If you don't have latency, memory restrictions, or embedding requirements

Add power consumption to that list.

Re:Crystal: Fast as C, Slick as Ruby by the_duke on Thursday August 04, 2016 @05:00AM (#12224312)
I think you meant

-> 'extreymely difficult to get INcorrect in the way rust does'

Re:Crystal: Fast as C, Slick as Ruby by Ygg2 on Thursday August 04, 2016 @05:19AM (#12224364)
Unless this is a joke, its meaning is correct, i.e. "proven correct like Rust".
Re:Crystal: Fast as C, Slick as Ruby by StavrosK on Thursday August 04, 2016 @06:32AM (#12224609)
I think he misunderstood the comment to mean "it's hard to get memory allocation wrong when writing a Rust program".
Re:Crystal: Fast as C, Slick as Ruby by yamadapc on Thursday August 04, 2016 @03:32AM (#12224011)
The D Language (http://dlang.org/) has a @nogc pragma (https://dlang.org/spec/attribute.html#nogc).

You just annotate functions that you don't want to use the GC in with it and it'll assert that they don't use it.

Re:Crystal: Fast as C, Slick as Ruby by p0nce on Thursday August 04, 2016 @04:20AM (#12224199)
Since you can:

- disable the GC

- deregister threads so that they are not stopped by GC

- eventually avoid the runtime altogether

There really is no realtime system that D can't do.

The whole anti-GC thing is a giant strawman that consider all GC stop-the-world, unavoidable, and overarching. Academia decided in favor of GC decades ago, and industry has been following suit for good reasons: mental overhead associated with finding owners to everything.

Re:Crystal: Fast as C, Slick as Ruby by gpderetta on Thursday August 04, 2016 @08:38AM (#12225076)
It is not. Languages that are designed to run a GC get crippled when run without: depending on the language you might lose access to closures (if dynamically allocated), rich data structures (standard dictionaries, lists, etc), sometimes even aggregates (if boxed by default) and you have to resort to using arrays of primitive types.

As they say, you can write FORTRAN in any language, but you don't necessarily want to (this is unfair to modern fortran which I hear is actually a decent language).

Re:Crystal: Fast as C, Slick as Ruby by jjnoakes on Thursday August 04, 2016 @08:02AM (#12224920)
You speak as if a GC is unconditionally better than alternatives and it is a solved problem but using a GC has issues as well.

On the theoretical side, not reasoning about ownership means sharing data betweent threads is done with copies (slower) or locking (slower and error prone); if you know about ownership you can share references to data while it can't be mutated for free.

Ownership is also important for any non-memory resource (file handles, mutexes, etc). GCs release those "whenever", maybe never, unless you close manually.

And even though manual memory management has some small non-deterninistic overhead for heap coalescing (which one can usually work around with pools), most GCs I've worked with add measurable overhead. This equates to more cost per server, more load, more battery life drained, higher response times...

Re:Crystal: Fast as C, Slick as Ruby by p0nce on Thursday August 04, 2016 @08:23AM (#12224999)
> On the theoretical side, not reasoning about ownership means sharing data betweent threads is done with copies (slower) or locking (slower and error prone); if you know about ownership you can share references to data while it can't be mutated for free.

I don't think it follows and it's rather the reverse: it what I share has a global owner (ie. the GC), I don't have to lock or copy by definition: once it stops being reachable it will be collected. That's why some lockfree algorithms are enabled by the GC. With ownership you would have to have a unique owner, or reference counts. GC does require write barriers or stop-the-world though so let's say it's a draw :)

> Ownership is also important for any non-memory resource (file handles, mutexes, etc). GCs release those "whenever", maybe never, unless you close manually.

Yeah, it's a big problem that the GC even attempts poorly to close them. But D has scope guards and RAII builtin so for the 50% of non-memory resources you still have to think about ownership indeed. That's more complicated that the C++ situation. But realtime it does not prevent, you may well find yourself having more time to optimize :)

Re:Crystal: Fast as C, Slick as Ruby by jjnoakes on Thursday August 04, 2016 @09:21AM (#12225269)
> if what I share has a global owner (ie. the GC), I don't have to lock or copy by definition

Then how you do avoid data races? Two shared references which can mutate your shared data requires either a copy, a lock, immutability, or a single writer.

Re:Crystal: Fast as C, Slick as Ruby by p0nce on Thursday August 04, 2016 @10:39AM (#12225796)
I use "parallel foreach", sometimes worker queues, implicit single writer... like in C++. It sounds like you think only Rust-style ownership can avoid data-races. Sure, if you want the type system to do it. For me discipline is enough and I've seen it work in teams too. Not seeing such a problem really.
Re:Crystal: Fast as C, Slick as Ruby by jjnoakes on Thursday August 04, 2016 @10:55AM (#12225899)
Nothing specific to Rust, although Rust encodes in the type system what I usually have to keep track of mentally, which is nice.

Trivially parallel algorithms do benefit from constructs like "parallel foreach" and implicit single writers, but in general, one either has to stick to those models (where the cognitive overhead is low but manageable) or if one ventures into more complex territory, one has to either deal with a higher mental complexity (ownership or locks), performance degradation (copying), or immutable data (if it fits your problem and doesn't decrease performance, win-win).

My argument is simply that GC doesn't fix everything, and the mental overhead of tracking ownership of memory (to me) isn't a huge burden, especially since I have to do it for non-memory resources and memory resources shared between threads already.

I'm not against a GC - I like languages that mix GC and non-GC side-by-side - because sometimes I do want to just forget about my memory, but only if it fits my problem domain. But I don't think GC beats non-GC hands-down for-all-cases.

Re:Crystal: Fast as C, Slick as Ruby by bjz_ on Thursday August 04, 2016 @04:17AM (#12224182)
But then you lose memory safety
Re:Crystal: Fast as C, Slick as Ruby by WalterBright on Thursday August 04, 2016 @04:39AM (#12224254)
That's being fixed.
Re:Crystal: Fast as C, Slick as Ruby by Ygg2 on Thursday August 04, 2016 @05:15AM (#12224352)
Wouldn't that cause duplication of interfaces? Rust had that problem when it went down having no-gc and having gc, too.
Re:Crystal: Fast as C, Slick as Ruby by WalterBright on Thursday August 04, 2016 @05:59AM (#12224493)
D's strong support for templates makes that a non-issue.
Re:Crystal: Fast as C, Slick as Ruby by ori_b on Thursday August 04, 2016 @01:57AM (#12223683)
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).

Re:Crystal: Fast as C, Slick as Ruby by jesserayadkins2 on Thursday August 04, 2016 @02:27AM (#12223775)
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?)

Re:Crystal: Fast as C, Slick as Ruby by ori_b on Thursday August 04, 2016 @02:49AM (#12223864)
One of the goals I have is to keep the required runtime absolutely minimal, as well -- I'm ok with the compiler inserting some user-defined code in the appropriate places to initialize or release values, but I'd like to avoid growing the required code in https://github.com/oridb/mc/tree/master/rt unless it's absolutely necessary.

And yes, that ~60 lines per platform is really all that's needed. (And actually, I should be able to merge more of it for SysV platforms.)

So, I've thought about a GC, but I'd really prefer not to have it.

Re:Crystal: Fast as C, Slick as Ruby by girvo on Thursday August 04, 2016 @03:10AM (#12223931)
Can I just say that Lily is amazingly neat, and is exactly the language I was working on myself! Seems we have a shared delusion ;)