Earlier quoted context omitted.
Whether reference counting is GC or not is arguing about semantics. But correctly implemented reference counting is essentially pause-free. It's consistently "slow", which is better for some cases that unpredictably "fast".
IMO it's not just semantics, rather, GC is too general of a term if it includes ARC. In terms of performance analysis the two are vastly different. One has basically an unbounded worst case but a good average case, the other is the opposite.
Crystal: Fast as C, Slick as Ruby
301–310 of 439 posts
Re: Crystal: Fast as C, Slick as Ruby
#302Earlier 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.
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 tra…
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
#303Earlier quoted context omitted.
> It's crazy I can't tell Java and NodeJS "use the memory you need". Define the 'memory you need'? You know the computer doesn't have a cristal ball to know what latency vs memory usage trade off you want..
"Until the OS refuses to give you more" Just like every compiled, non-GC program gets. It's annoying af to fiddle with interpreter/VM "maximum heap sizes".
Re: Crystal: Fast as C, Slick as Ruby
#304Earlier quoted context omitted.
> UB is simply the latest stick to hit C with. Honest question, which is the case? (0) You find it easy to determine, by visual inspection, whether a piece of code has undefined behavior. (1) Your coding practices make it difficult to accidentally introduce undefined behavior in the first place. > Same with lack of a GC; this is a plus point for C for most applications, not a negative. Agreed. C addresses use cases f…
Its a combination of both. The vast majority of all code you write will not invoke UB, most people tend to stick to an 'easy' subset of syntax, unlike say C++ where everyone uses a different subset of features making it in effect multiple languages. A combination of testing the known edge cases, wraparound issues, size issues, static analysis and tooling means running into an example of UB is extremely rare in most c…
Even integer addition very easily leads to undefined behaviour.
> It used to be that people used dynamic memory allocation to beat C with, but that is just a resource management issue. TBH, this is not rocket science. If you need dynamic memory allocation, you had damn well better know how to use it properly.
If you're going to solve a quadratic equation you should damn well know how to do it properly, by completing the square. But once you know that you should use the formula, because it makes it a lot easier. If you complete the square every time out of pride, you're just wasting everyone's time.
> A combination of testing the known edge cases, wraparound issues, size issues, static analysis and tooling means running into an example of UB is extremely rare in most cases.
Sure. You can do enough work to eliminate it. Or you can use a language where you don't need to.
> Its an example of laziness and people ignoring the machine.
Laziness is one of the cardinal virtues of a programmer
> Another example is performance; saying that a language comes within a factor of 2 of C's performance and therefore is fast is absolutely ridiculous. a factor of 2 is huge.
A factor of 2 is irrelevant most of the time. If you're growing exponentially, a factor of 2 will let you put off the point where you have to start scaling out by maybe a few months. If you're not growing exponentially, you probably won't hit performance limits at all.
> Basically, we're much more aware of the machine than higher-level softies, so what would normally be UB is actually DB in most cases, its defined by the compiler and hardware that we're intimately familiar with.
Until the compiler adds new optimizations. Sure, if you're never going to upgrade the compiler maybe you can get away with C.
> ...and that isn't to say that you can't write high level abstracted code in C, the simplicity of the language lends itself to (properly) efficient implementation, not efficient in the sense of Java or Ruby ;o)
Without native tagged unions you won't get far up the abstraction ladder. You can write your own with macros sure, but they won't interoperate with anyone else's or any libraries you'd want to use.
Re: Crystal: Fast as C, Slick as Ruby
#305Earlier quoted context omitted.
IMO it's not just semantics, rather, GC is too general of a term if it includes ARC. In terms of performance analysis the two are vastly different. One has basically an unbounded worst case but a good average case, the other is the opposite.
Reference counting also has an unbounded worst case: what if you drop the last reference to a very large graph of objects? Then you free the whole thing, which can take an arbitrarily large amount of time.
Re: Crystal: Fast as C, Slick as Ruby
#306Earlier quoted context omitted.
On the other hand, Go has an excellent garbage collector, and really seems to fill the niche for low-level libraries and programs. It's also quite a joy to program in, and I'm a JavaScript developer, so I'm coming from the other side of the spectrum.
Have you ever used a language with a decent type system though? I couldn't stand to use Javascript or Go at this point.
I consider myself a javascript developer because that's what I've done my best work in and that's what I enjoy the most.
Re: Crystal: Fast as C, Slick as Ruby
#307Earlier quoted context omitted.
> But most likely - you simply do not need a language without a GC. Absolutely. That doesn't mean I can't want predictable performance or deterministic destruction. I also think it's a shame that we waste so much electricity and rare earth minerals on keeping ourselves from screwing up (i.e. on the overhead of managed runtimes and GCs). Before, I'd have argued that it was just necessary. Having spent a bunch of time…
The C++ advantage will not be so much after Java 10 comes out and finally have the value types and reified generics the language should have had since beginning. Also I am yet to see any large scale production deployment of those Hadoop alternatives. But it might still be like 5 years from now, so who knows how it will evolve.
Re: Crystal: Fast as C, Slick as Ruby
#308Earlier quoted context omitted.
> 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 The abstract class defines which methods every class that inherits from it must define by using abstract methods. If you write a class that inherits from an abstract class, and you do not define a method that the abstract class says th…
> The abstract class defines which methods every class that inherits from it must define by using abstract methods. In their example, the type checker can infer that Animal has a `talk` method, even if it's never explicitly defined: abstract class Animal # no talk method here! end class Dog In their own words, “Now the code compiles:” john.pet.talk #=> "Woof!" Now, what happens if, in a separate module , I define a S…
Re: Crystal: Fast as C, Slick as Ruby
#309Earlier quoted context omitted.
> It is significantly better than undefined behaviour, as it results in a noisy failure rather than silently incorrect results. This might be true in a deterministic setting, since the likelihood that a test suite will find the error is very high. But in a non-deterministic concurrent setting, throwing an exception that might be only caught once in a blue moon is just as bad as not doing anything about errors.
An occasional exception and silent corruption the rest of the time is still a lot better than silent corruption all the time - it's much easier to notice in the first place, and as long as you have one instance of the exception you have a stack trace to start from. And in practice the JVM/standard library throws ConcurrentModificationExecption pretty reliably.
The fundamental problem still remains, that in neither case can I use the language's semantics to guide the design of my program.
> and as long as you have one instance of the exception you have a stack trace to start from
Oh, really? How am I supposed to find what the problem is in the general case, from just a single exception stack trace that I might or might not get?
Re: Crystal: Fast as C, Slick as Ruby
#310Stopped reading when I saw the `end` keyword... the most annoying part of Ruby. Edit: I'm getting hella downvoted but I'm leaving this here. Ruby fanboys can't silence me!!! ;)