I'm exaggerating, of course, but my experience trying to use Piston was absolutely miserable. Next to zero documentation, with endless layers of confusing abstraction. It's designed to have swappable back-ends, and that's a big hassle when you don't care about that.
With a normal OO language I often build/run just to spot the next place I have made some bad assumption that the compiler didn't catch.
But concerning productivity: fighting the compiler sometimes means abandoning perfectly reasonable (and efficient!) designs just because the compiler doesn't like them.
I'm not aware of any type corsets that I think force good designs.
In a really clean design mistakes are not terribly hard to fix, even in a language like C. Granted in C they are in some cases harder to find in the first place, but there might not be any commercial interest in going beyond "it seems to work".
How effective (and thus popular) Rust will be for creating large systems on tight deadlines remains to be seen I suppose - if it isn't competitive with C++ in that respect, then I'd consider that a failure. And a surprise.
Citation needed!
Sum types are a major headache. Is there a good rule for when to use a sum type vs distinct types? The expression problem is very practically relevant to me. Also the typical flat vs hierarchial data storage wisdom applies: Trees and hierarchies are very much encouraged by HM type systems, but the choice of what gets to be parent and what gets the child is arbitrary and often turns out super limiting further down the line. Similarly, there's the choice of what to include in a hierarchy and what to put in a separate one.
Tables on the other hand, supported by light usage of manually coded lookup tables, have been the real game changer for me. When I'm back in a normal imperative language I can be so naturally productive and write efficient programs without relying on black compiler magic. I don't see how most of the invariants in my programs could ever be codified in a practical type system. They are so relational - they involve variables with very diverse lifetimes and expressions depending on dynamic values.
In the end, I feel writing assertions is just much better for me, because I can be somewhat sure in a few tries that my invariants hold, in the same language that I use for coding, and having the same values available. Meanwhile I would waste hours trying to codify a small fraction of them in an HM type system.
I find it best to let confidence guide me. If I'm not confident something's right, that's usually a sign I didn't type it enough. If I think I know it already, then it doesn't need more types. It affects the design but it should affect the design, I would say; decisions about which invariants are important are design decisions.
> Is there a good rule for when to use a sum type vs distinct types?
If at some point you have a value that you know (and care) is one particular, well, type, make it a real type. If you only ever have values that could be one or the other and it doesn't matter which they are (or the section where it matters can be reasonably confined to a match block) then a sum type.
> but the choice of what gets to be parent and what gets the child is arbitrary and often turns out super limiting further down the line.
I find this is much less true in an immutable-by-default language. E.g. in the standard circle/ellipse example it becomes completely obvious which is the parent and which is the child.
> Tables on the other hand, supported by light usage of manually coded lookup tables, have been the real game changer for me. When I'm back in a normal imperative language I can be so naturally productive and write efficient programs without relying on black compiler magic. I don't see how most of the invariants in my programs could ever be codified in a practical type system. They are so relational - they involve variables with very diverse lifetimes and expressions depending on dynamic values.
Heh, this is the opposite of my experience. I find tables always confuse me, and are usually a sign that my model needs to have an intermediate entity - like the experience described in http://wiki.c2.com/?WhatIsAnAdvancer
Synch is short for synchronization.
> Remember, with game production, it's about time-to-market, not about perfect code.
In a way you are over-selling Rust, because it doesn't offer perfect code! I'm not sure why Mozilla would pay to build it if that's what it was about.
What it offers is a lower defect rate, which is something you can definitely leverage to improve productivity. Lower defect rate at any cost is clearly too expensive; but developers seem to have been able to absorb the complexity of C++ alright and it Rust can't be called more complex than C++.
While Rust as a language isn't more complex, the paradigms are different. Games often have trees and lists, which are a real pain in Rust. To do things right in Rust requires learning new ways of doing things - not something game devs want to spend time on. They've been working with the same horse for years, so they keep riding it.
Any time you work in a large team in a corporate environment you want a language that lets you stab yourself in the foot as little as possible.