Earlier quoted context omitted.
It depends on how you quantify cost. There isn't any performance cost, yes (which is what 'zero-cost abstractions' usually means in C++), but there is a) an increase in code size, and b) an increase in complexity/difficulty of understanding of implementation (and to some extent use). These may be good tradeoffs to make (in many of the areas where C++ is used they make sense), but I think 'zero-cost' is a disingenuous…
There might actually be a performance cost due to increased code size (by way of increased amount of icache misses).
Why Go Is Not Good
311–320 of 367 posts
Re: Why Go Is Not Good
#312Earlier quoted context omitted.
> Lack of generics is part of the reason why…the Go compiler is faster than, say, Rust. The speed of the Rust compiler has little to do with generics and everything to do with LLVM and its optimizations and code generation. (Run with -Z time-passes if you don't believe me.)
I don't know if it has to do with generics , but you can't blame it on LLVM. /usr/src/rust/src/libsyntax % time /usr/src/rust/x/x86_64-apple-darwin/stage2/bin/rustc lib.rs -o /tmp/x.dylib --crate-type dylib -C prefer-dynamic -Z time-passes [most output removed...] time: 6.186 s type checking time: 5.084 s translation time: 7.221 s LLVM passes /usr/src/rust/x/x86_64-apple-darwin/stage2/bin/rustc lib.rs -o /tmp/x.dylib…
"translation" is mostly LLVM (in particular, allocation of LLVM data structures).
> I do not know enough to have a definitive opinion of why this difference exists, but judging from the difference between C and C++, I wouldn't be surprised if it were related to Rust's complexity, which includes generics.
If you look at the amount of code in a typical large Rust program that is related to generic instantiations, then it's pretty miniscule (less than 10%).
Typechecking is known to be slow because the way we do method lookups is not well optimized. I don't believe that this is a fundamental issue; it's more that nobody has gotten around to improving it yet.
Re: Why Go Is Not Good
#313"A Good Solution: Operators are Functions" NO. No. No. Allowing users to change the language specification and side effects on a per-file, per-project, per-anything basis is a terrible terrible terrible idea. "This is all covered in Knuth, and we don't have time to go over it again."
There are no "built in" operators in Haskell, other than " ", which is function application, and which cannot be overridden. Additionally, any "infix operator" can be used in prefix form, by surrounding it in parens - and any function name can be used in infix form, by surrounding it in `backticks`.
All other operators, like +, -, $, , >>=, are defined in libraries (specifically in Prelude, the "standard library") - these operators cannot be overloaded in ad-hoc manner as operator overloading is done in other languages (bar qualified module imports) - to make use of one of these operators you must implement an instance of the class which contains it, such as Num for +, -. There's also the requirement to implement fromInteger, signum, negate, etc in Num. (If you can't think of a valid "fromInteger" implementation for your custom type, it's obviously not a Num). Also, some classes have associated laws which should prevent you from using them incorrectly
Admittedly the class/instance scenario could be improved with further checking of these "laws", but that would basically require a full theorem prover baked into the language - something that Haskell will probably get sooner or later.
There's still what I would consider "operator abuse" in Haskell - it's not that of overloading existing operators, but that of introducing new operator aliases for virtually every function in your library, as http://hackage.haskell.org/package/lens-4.1.2/docs/Control-L... does (yuck).
A nice convenient feature of Haskell is that you can scrap the official Prelude library (-XNoImplicitPrelude) and roll your own, as some others have done (e.g, http://hackage.haskell.org/package/classy-prelude). This allows you to effectively "clean up" some of the warts from the early design of the language, so it can continually improve - rather than needing to invent a whole new language when we decide it's not what we want. Num is an example of a class which gets lots of stick, because we'd often like to implement either of addition or mulitplication, but not both.
Re: Why Go Is Not Good
#314Earlier quoted context omitted.
It's much more than just at the start end return of every function. But OTOH, it's much less than assertions, since they're restricted to a subset that can be proven (usually automatically). Note the Scala verbosity here is Scala-specific. In HM-style languages, type inference works much better and you don't have to do such things. You might still have to explicitly "lift" a value from one type to another (e.g: Wrap…
Lifting in Scala is not at all verbose; I'm talking about casting, calling a method that the type system doesn't know is present.
Have to make an explicit cast with a structural type? Surely you can do better, like, say, a trait.
> I'm talking about casting, calling a method that the type system doesn't know is present.
I think a larger example is necessary to see how you ended up in such a situation, but I suppose it's off-topic...
Re: Why Go Is Not Good
#315Earlier quoted context omitted.
Lifting in Scala is not at all verbose; I'm talking about casting, calling a method that the type system doesn't know is present.
> I do think that some strongly typed languages make it too difficult to step outside the type system; in Scala I have to do something like (x.asInstanceOf[{def foo(): String}]).foo() whereas in Python I can just write x.foo() Have to make an explicit cast with a structural type? Surely you can do better, like, say, a trait. > I'm talking about casting, calling a method that the type system doesn't know is present. I…
Usually, yes. But the only way that's as general as the Python line is to use the structural type.
Re: Why Go Is Not Good
#316Earlier quoted context omitted.
Exactly! Go makes the cost of generic code explicitly visible. Generics encourage over-generalizing behavior that runs counter to writing highly performant code. If you care about speed, you don't spend time making your code generic. You optimize closely to your use case.
>Go makes the cost of generic code explicitly visible. Generics encourage over-generalizing behavior that runs counter to writing highly performant code. I think you may be missing some info regarding generics in Rust and Haskell. As I mentioned in the article, there is zero runtime overhead for generic programming in Rust and Haskell. Zip. Zilch. Nada. That's why their constraint-based static generics system is awes…
I really hate it in Java when I need an array of bytes but don't know the size in advance, or the size changes, and I have to incur all the cost of boxing those bytes up. On 64-bit systems (most of them), pointers are 64 bits which is at least twice as large as the most common things you put in a list (int, float, byte).
Re: Why Go Is Not Good
#317Earlier quoted context omitted.
> No, Go's solution to generics is not interface{}. The moment you say that, you have lost. You are trying to fight Go and make it a language that it is not. What is the solution?
There isn't one. Go, by design, does not provide generics as they would complicate the language and for insufficient benefit. (according to at least one of the authors) While I do agree that Generics can open up a whole new dimension of programming concerns. I think they are worth the additional syntactic complexity, because they allow you absolute accuracy when it comes to types. If we as a programming community wan…
Re: Why Go Is Not Good
#318Earlier quoted context omitted.
But the fact that Go proponents don't actually have solutions to those problems is an issue. How do you make a custom, generic data structure without syntax overhead? I have not seen any counter proposal to this aside from "maps should be enough for everybody". How do you avoid the noise from not having operator overloading or a similar alternative? This, again, goes unadressed. What are the succint alternatives to f…
How do you make a custom, generic data structure without syntax overhead? In real-world code, the need for generic data structures is shockingly uncommon. It really is. This requirement exaggeration comes about by people acting as language tourists, building amorphous code of uncertain purpose, where things like "I'm going to sum up a bunch of unknown objects" seems like a serious need. For most people who find Go to…
Re: Why Go Is Not Good
#319Earlier quoted context omitted.
> the docs aren't the best. This week is week two of my being contracted by Mozilla to write docs full time. First up, a new tutorial. You can see my work from last week http://doc.rust-lang.org/guide.html , and my first task after I finish breakfast is to clean up https://github.com/rust-lang/rust/pull/15229 , which got some review over the weekend. So, you're right (at least about the docs) but I'm on it.
Steve - thanks for your reply and work on the docs. Is there currently a place - or will there be one, that describes precisely build/deployment options? This really in the end is the most important thing to me. I've searched unsuccessfully for this wrt Rust. It seems that as it sits, items built on a newer machine won't run on an older machine due to libc library mismatches. Will this always be a potential issue? Or…
Different linking options are found here: http://static.rust-lang.org/doc/master/rust.html#linkage
Basically, as of right now, when you link statically, Rust will not build in glibc (and jemalloc, IIRC). So, you'll need to make sure that your glibc versions line up. My understanding is that glibc isn't able to be statically linked in without breaking things.
You can use `objdump -T` to see these dependencies. On my system, compiling 'Hello world,' I get symbols for glibc and gcc.
(Go gets away with this by reimplementing the world, rather than relying on glibc. The benefit is a wholly-contained binary, as you've seen. The downside is compatibility bugs, like https://code.google.com/p/go/issues/detail?id=1435)
Re: Why Go Is Not Good
#320Earlier quoted context omitted.
>Go makes the cost of generic code explicitly visible. Generics encourage over-generalizing behavior that runs counter to writing highly performant code. I think you may be missing some info regarding generics in Rust and Haskell. As I mentioned in the article, there is zero runtime overhead for generic programming in Rust and Haskell. Zip. Zilch. Nada. That's why their constraint-based static generics system is awes…
Please correct me if I am wrong about boxing in Rust, but doesn't boxing produce some overhead, by creating extra heap allocations (and therefore possible memory fragmentation and almost certainly poor cache locality), as well as pointer dereferences? I really hate it in Java when I need an array of bytes but don't know the size in advance, or the size changes, and I have to incur all the cost of boxing those bytes u…
You don't need to box something to make it generic.