Hacker News new | comments | show | ask | jobs | submit login

Much as I like Rust, I have to agree. When you have to get it done, use Go. When you want to explore advanced experimental programming constructs, use Rust. The Go guys knew when to stop. Arguably they stopped too early, before generics or parameterized types, and "interface[]" is used too much. But that doesn't seem to be a big overhead item.

Rust has the complexity of C++ plus additional complexity from the functional community. Plus lots of fancy template cruft.

The trouble with language extensibility is that people use it without an overall plan. The end result is a Winchester Mystery House language.[1] LISP went down this rathole, and Scheme had to be developed to get out of it. C++ went that way when nobody stopped the Boost crowd before it was too late. Now it's happening to Rust.

(Anyone involved in language design should see Václav Havel's "The Memorandum". Or at least read it; I've seen it performed, but it's not performed often.)

[1] http://www.winchestermysteryhouse.com/




> Rust has the complexity of C++ plus additional complexity from the functional community.

Not even close. C++ has IIRC whole books just on exception handling. And it's crazy how many styles of writing C++ there really are. Exceptions or not, standard library or not, templates or not, boost or not, etc, etc. C++ templates are a language of their own. A lot of times, if your code made a particular choice, you are stuck with a set of libraries that made the same choice, or you'll be writing an insane amount of boiler place to duck tape it together. This code tends to be some of the most sucky code in existence.

Rust on the other hand feels very cohesive and there seems to be like one style of really writing it.

What parts of Rust do you find experimental? The only thing that's new (in a popular language) is the borrow checker but we can all agree that despite it's novelty, it's a huge step forward.

Another thing about Rust is the community. Just about every Rust package I've come across was very well written. Some even teach me a thing or two. E.g. I haven't seen trees implemented the way they are in this package previously https://github.com/PistonDevelopers/history_tree.

Go packages are more all over the place. Also the community seems to concentrate mostly on web stuff. The recent Vulkan tutorial by the Khronos group (i.e. the people behind the standard) used Vulkano.rs which blew my gourd. https://www.khronos.org/blog/beginners-guide-to-vulkan

> Now it's happening to Rust.

Please elaborate.

> Václav Havel's "The Memorandum"

It's crazy that you are aware of this, I always thought that his work had only a local appeal.

I've written a modicum of Go and the boiler plate was driving me crazy.


Most things about Rust are well thought out and well designed. It's the total weight that gets you. Like LISP, back when too many smart people from MIT were adding to it without an overarching vision. It's hard to keep it all in your head. The add-ons aren't libraries with specific functions; they're new control structures. This gives me the feeling I had dealing with the MIT Loop Macro.[1] Proliferation of control structures is not a good thing.

> Václav Havel's "The Memorandum"

It's crazy that you are aware of this, I always thought that his work had only a local appeal.

Saw it at Fort Mason in SF in the 1990s.

I've written a modicum of Go and the boiler plate was driving me crazy.

That's how I felt about Rust. See some code I wrote at [2], at "Return type and its error handling". Now that's boilerplate. The last time I mentioned this, it was brushed off with "Oh, you'll be able to do that with the '?' operator when it's implemented." Feel free to submit a pull request for the rewrite.

[1] https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/...

[2] https://github.com/John-Nagle/rust-rssclient/blob/master/src...


I get your lisp comparison but the fundamental difference is that in rust even the craziest stuff is bound to be safe. I wouldnt be comfortable doing this sort of stuff in other languages, but I'm OK doing it in rust.

Re error handling, Option's map method doesn't do the trick? Sorry on my phone and reading code is hard.


I think you are describing the "design by committee" kind of problem, that Rust definitely has.


> When you have to get it done

When you have to get what done? Seriously. There are different reasons to pick different technology stacks, some of them because of language features, some of them because of technology stack. Getting it done at my current job is generally Java, b/c that's the tech stack used by most.

> The Go guys knew when to stop. Arguably they stopped too early...

The stuff you mention Go not having is exactly what Rust brings over Go, is it not?

> But that doesn't seem to be a big overhead item.

I disagree, it's the fundamental reason I don't use Go by choice, and instead turn to languages that allow for more expressiveness.

> Rust has the complexity of C++

You say you like Rust, but I find this statement hard to believe if you've learned the language. It has almost none of the complexity of C++. That's not to say that the language isn't more complex than Go, it is. But to say it's anywhere near C++ feels disingenuous.

The Rust RFC process is very good IMO at preventing inappropriate changes from being introduced into the language, "Winchester Mystery House language" is unnecessary FUD.

Look, you don't have to like the language. But, making statements that seem unfounded isn't really appropriate.


> Rust has the complexity of C++ plus additional complexity from the functional community. Plus lots of fancy template cruft.

This is so patently false. C++ contains an order of magnitude more complexity than Rust (as one would expect for a language that continues to evolve radically 30+ years after it was designed; for better or worse, complexity is C++'s game).


> Plus lots of fancy template cruft.

I should start a tally of the number of times that I have told you that Rust doesn't have template metaprogramming. You've been saying this for years; what have you actually written in Rust?


I'm not sure this is a useful distinction. I'm sure you're correct for whatever definition of "template metaprogramming" you're using, but Rust does have a pretty powerful generics system. That gets you most of the way to what C++ templates are used for, albeit less cruftily IMO. Coming at it from a different side, if a C++ person asks you, "does Rust have templates?", you're likely to say "no, but it does have generics which let you do most of what you need templates for". It's definitely enough to let you write complicated, over-general code if you want to. So in an informal context like this, the difference between "template metaprogramming" and generics is probably not one you want to stand on, at least not for your whole argument. There's lots of better arguments to make even if you accept Animats' language.


The claim that Rust's generics system is "fancy template cruft" on top of "all the complexity of C++" is absurd, though.


Yes, which is why I carefully phrased my post to avoid any implication that I might agree with that claim. To nevertheless get a reply like this is profoundly irritating.


I'm sorry.


It's a little unfair to unload on you, I'm just sick to hell of straw men, and it feels like there's no way to make sure people will engage with what I'm actually saying target than what they think I'm saying. It's a pervasive problem. :/


Template metaprogramming is the ability to e.g. say

int x = factorial<5>::value;

and have 'x' initialized to "120" (i.e. execute computation at compile time, not just define new types). Can you do anything like that in Rust? I only read a few about Rust, but my feeling was that it has powerful generics, but NOT template metaprogramming.


We just accepted an RFC for this. So not today's Rust, but tomorrow's.


Which is used more, Common Lisp or Scheme? C++ is as popular as C. Python and JS remain heavily used despite becoming more complex over time. Java is still widely used after adding major features like generics, lambdas, streams.


Is this intended to be a response to the parent comment? What's the connection?


It is. The parent was praising Go's simplicity in comparison to languages like C++, and that Lisp had gone down the complexity rabbit hole, thus the need for Scheme. As a counterpoint to that, complicated languages have seen continued widespread use, so it's not obvious why being simple (intentionally leaving certain language features out) is preferable.

Meaning, the entire programming community hasn't quit on C++, CL, Java, etc in favor C, Scheme, Go or pick your simpler language. Most of the JS community seems very pleased with ES6 & 7 additions.


The problem with templates in C++ is that they are just that. The compiler will hapily generate broken code if you use a map with a type that doesn't implement comparison operators and then spew out hundreds of lines of compiler errors at a location that is another hundred lines deep in library code away from the line of code that caused the error in your application. Something as trivial as type constraints for type parameters like you see in virtually any programming language with generics is the solution.

I don't feel that C++ is complex at all. It just has more crap and every programming language has crappy parts.


Why the duality there ? Rust vs Go. Go is quicker to get hacks done in.

Okay ... so is Python, Ruby, Perl, ... and they will beat Go by a mile on quickly constructing small programs.

Even if it must be fast, there's still C#, Java and quite a few others.


> When you have to get it done, use Go.

Or Java? I mean, I've never seen any reason to use Go over existing, better languages.

Never thought I'd call Java better than anything, but there you go.


> When you want to explore advanced experimental programming constructs

This is a weird euphemism for "get it done correctly". It seems to come up in any discussion about languages that help you to write correct code.


Now what was wrong with that?

I totally subscribe to the view that advanced experimental programming constructs are neither a guaranteed way, nor the only one, to write correct code. Doesn't a language which helps you to get code done (and makes it easy to iterate on it, and has the right psychology to let you move on instead of trying yet another way to get at the old problem) help you write correct code, as well?


Nothing in Rust is an "experimental construct", so I'm not sure why you keep using that phrase.

Lightweight formal tools like those available in Rust do guarantee that your program satisfies certain correctness properties that Go cannot.

To guarantee correctness in all aspects you need more heavyweight tools than Rust provides, but they do exist.

No, languages that let you "iterate" and don't provide any sort of formal guarantees don't help you make correct code. They help you pump out a lot of mediocre code that probably works acceptably enough to satisfy a business with a medium-low focus on correctness.


> Nothing in Rust is an "experimental construct", so I'm not sure why you keep using that phrase.

I don't do Rust (but I did some Haskell), and apart from the fact that both are very small elitist communities, some idioms are definitely evolving or changing as people try to find out what actually works in practice. So, from this practical standpoint, yes, experimental.

What's lightweight lies in the eyes of the beholder. I certainly don't think of the line noise that is Rust code in the wild (again, to an outsider) as "lightweight".

Nor do I think of the bazillions of ways you can obfuscate the simplest things in Haskell (moving 10, 20, or 90 percent of the perceived required invariants from value to type level), requiring large and possibly incompatible sets of language extensions, as lightweight. It's a burden of choice, and changing choices has huge ramifications on the rest of the code (these decisions are inherently unmodular, which is BAD).

> No, languages that let you "iterate" and don't provide any sort of formal guarantees don't help you make correct code. They help you pump out a lot of mediocre code that probably works acceptably enough to satisfy a business with a medium-low focus on correctness.

I'm sorry, but that's a very one-sided view. You can absolutely write correct code in them, and something that helps you to do it faster does help you write correct code. Simple as that.

You seem to think that there is exactly one reasonable, justified level of formal correctness. And that is the level where you stand, Rust in this case.

But that's wrong. Everything has a cost. And formalisms like Rust are still pityful attempts at constructing "formally correct" software. There might be some software that is "completely" verified, but at a cost that is simply not justifiable for the vast number of applications. Ignoring the fact that most real-world problems are ill-specified from the start.

There is more than one valid approach to do things, and more so, to do many different things. It's cool what you're doing, but there are other valid approaches to find things to do and make them work.

Get out of your little corner mate.


> both are very small elitist communities

Yet another irrelevant, unjustified, negatively connoted description that has no basis in realty; first "experimental", now "elitist". Come on.

> What's lightweight lies in the eyes of the beholder.

In terms of formal methods that exist, both type systems simple enough for decidable inference and lifetimes are absolutely "lightweight". But sure, I guess every description is subjective.

> You seem to think that there is exactly one reasonable, justified level of formal correctness. And that is the level where you stand, Rust in this case.

This is untrue. I don't believe Rust is a paragon of correctness-oriented programming; I just think it's a hell of a lot better than something like Go. Rust at least lets you prove a sizeable chunk of practical safety and correctness properties.

> And formalisms like Rust are still pityful attempts at constructing "formally correct" software.

What Rust provides, including type and memory safety and completeness checking, gets you a surprisingly large way towards complete formal verification, imo.

> Get out of your little corner mate.

What was your goal with this statement? This is a fairly technical discussion, not a Reddit politics thread. There's no need for you to stoop to vague insults.


> Rust at least lets you prove a sizeable chunk of practical safety and correctness properties.

Not true in my perception. The things I do with conventional languages, I seldom worry about invariants that could be guaranteed by a more structural language, like null pointer safety or absence of side effects (I seldom worry about them because I seldom get them wrong).

Much more I constantly juggle invariants like "this integer is a power of two and that integer is an odd positive one. This other pointer resource is the one that correlates with the integers in that specific way."

These types of invariants are not practical to encode even in advanced type systems; I've even had a quick look and Agda and what-was-that-other-system-called, but it went quickly over my head.

> Yet another irrelevant, unjustified, negatively connoted description that has no basis in realty; first "experimental", now "elitist". Come on.

Not meant as an insult at all.

>> Get out of your little corner mate. > What was your goal with this statement? This is a fairly technical discussion, not a Reddit politics thread. There's no need for you to stoop to vague insults.

Dito. Your counter-arguments seemed to be heavily implying that there is no way way of getting code done correctly in a language that is somehow "lesser" than Rust. And furthermore you seemed to be preconceived about what others' judgement of the relevance of "correctness" is (which is a vague term - it sometimes seems to be more than "it runs correctly all the time and we could even prove it correct or actually have done so, even if not in some fancy modern type system").

So that little punchline at the end was not meant in an insulting way at all. Just to give note how your comments were perceived. Not that I really need to tell you, but it's good to admit other viewpoints / take interest how problems are typically approached in other domains.

(By the way, I took an interest in John Carmack's recent engagements with static analysis and functional programming. I, for one, LOVE Carmack not only for being undoubtedly a genius who gets shit done, but furthermore for being so undogmatic about his approaches and views. You might have followed some of it, too -- for example, https://www.gamasutra.com/view/news/169296/Indepth_Functiona... , and it's also interesting to see that in the end he backed away after having seriously considered Haskell for game programming. I'm not sure if he backed away from his (actually existing) VRScript implementation written in (untyped) Racket as well)


> Much more I constantly juggle invariants like "this integer is a power of two and that integer is an odd positive one.

You can easily represent exactly these sorts of constraints in a language with something like newtype wrappers (e.g. via a wrapper over integers with an associated injective function from the newtype back to integers).

> These types of invariants are not practical to encode even in advanced type systems;

As I explained, you don't even need an advanced type system if you take the most straightforward approach. You just need a marginally powerful type system like rust's. You could probably even hack it in Go if you wanted, but it would be annoying.

However, these specific examples are also quite easy to represent in either dependent type systems (like Agda's; I'm not sure what your objection is there) or liquid type systems like that of Liquid Haskell.

> a language that is somehow "lesser" than Rust

So you're mad that I think Go is inferior to Rust? Would you like me to expand on why I think that?

> but it's good to admit other viewpoints

Unless you have good reasons for disagreeing with them, which I do. You're not obligated to agree with everyone on everything. I think you're wrong about languages with poor formal systems being acceptable for correctness-oriented programming, so I'm not going to "admit your viewpoint" just because it's polite or something.


> You can easily represent exactly these sorts of constraints in a language with something like newtype wrappers (e.g. via a wrapper over integers with an associated injective function from the newtype back to integers).

This is not even close to reality. In the end they are integers. You will have to add/combine values with different qualities, which means at some point you need to unwrap all these layers of abstraction. The only difference it makes is that you can't recognize anymore what happens in this sea of useless wrapping and unwrapping. You constantly juggle more invariants than you can make newtypes for. Instead of simply writing "x & FOO_MASK" I will not follow some vague idea that if you wrap it in another layer of ad-hoc concept, the complexity will just magically go away and it will all just magically be "correct".

In one sentence, you can move everything to the type level if you insist, but at some point you have to DO it. The complexity does not go away, all you can hope to do is implement a given artifact only a single time. (And plain procedures are pretty good at that for >90% of what I do). Most things are done exactly once in a code base, so moving them to the type level is just a crazy bad idea.

>> a language that is somehow "lesser" than Rust

> So you're mad that I think Go is inferior to Rust? Would you like me to expand on why I think that?

I'm not mad at all. In fact I've never done Go either; I do most of my work in C and Python and sh (and some coding competition style things in C++11 if I need the quick container). I'm perfectly happy with the expressiveness they provide.

Actually I did read your blog post and regarding missing generics I even agree somewhat. But what I think you're missing is that it's not the biggest deal under the sun. I actually like to throw a few void pointers around in C, and it has considerable advantages, for example being highly modular (does not enforce any dependency hell crap, compiles quickly...).

I don't care about NULL-pointer safety. It's one of the least problems I encounter.

I don't care about formalized error handling. In many simple applications you simply die right away, and for many more complex and long lived ones, explicit error handling is the right choice and leads to a consistent code base, and does not force me to second-guess what conditions are "errors" and what not. Frankly error handling in Haskell is a huge mess.

I don't care much about operator overloading either. It wouldn't have been helpful in more than a handful of situations for me, so far. Instead of implementing extra syntactic sugar it's no big deal to simply call the relevant function three or five times. Again, that approach has advantages as well, for example I can easily search the locations where these functions are called. Also I can be sure that '+' means really an add instruction on the CPU.

And as I said I sometimes use std::map<K, V> et. al as well, but actually it's often only an interim solution until I realize I don't need that at all, because a V* would do, or I need an intrinsically linked map instead (which can't really be made as a template class, the only alternative being allocating the V's separately and making std::map<K, V* > instead), or I absolutely die suffering the compile times due to the added dependencies, or I can't bear the allocation overhead.

> Unless you have good reasons for disagreeing with them, which I do. You're not obligated to agree with everyone on everything. I think you're wrong about languages with poor formal systems being acceptable for correctness-oriented programming, so I'm not going to "admit your viewpoint" just because it's polite or something.

That's exactly the point: nobody pulled the correctness-first card. No, you can't disagree that people are productive and stuff EXISTS and works to a large extent, and advanced type systems are niche. I used to play CS:S for example and can't recall having any problems. I'm a heavy Linux user and the kernel is seriously rock solid, with the exception of a few reverse-engineered device drivers.

Not saying that there are not many buggy projects as well. Most of those are financially terribly undersupported.

Also not saying people are not looking for improvements to their methodologies, but you need to acknowledge the methods with which people get their work done, and that correctness-first approaches have largely not worked out so far. I'm not aware of any serious kernels or performant 3D Games written in Haskell. In fact, one of the highest-profile Haskell applications, GHC, does indeed have quite a few bugs, and this is because the type system simply can't encode all THAT many invariants, especially if you need to get something done in the end. (Besides that it's god awful slow sometimes, although I'm in no position to judge whether the implementation language is the reason, or the type system extensions are just not practical from a performance standpoint).

If you can make a little Tetris game in 3h in Haskell (or even Rust), I will tip my hat to you. Tried to do that but eventually gave up due to unsufferable compile times and terrible non-essential complexity due to opionionated framework (and I do have a basic understand how Haskell works, and I went with the most basic dependencies possible). But I did make a working Javascript+CSS Tetris in <3h and I don't think my C version with SDL (no fonts) took much longer.


> But that's wrong. Everything has a cost. And formalisms like Rust are still pityful attempts at constructing "formally correct" software. There might be some software that is "completely" verified, but at a cost that is simply not justifiable for the vast number of applications. Ignoring the fact that most real-world problems are ill-specified from the start.

You seem to be saying "it's hard to verify everything, so we shouldn't even attempt to verify anything," which is silly. I've found having memory safety to be a huge win, even if the Rust compiler can't verify that my program is doing the right thing.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: