Earlier quoted context omitted.
No student in any language learns by writing production ready code. Anyone who thinks this is what it means to learn a language is attacking a strawman.
Worked for me when learning Go.
The struggle with Rust
251–260 of 301 posts
Re: The struggle with Rust
#252Earlier quoted context omitted.
I find that unfair. C++ has new as well as other mechanisms such as perfect forwarding into smart objects, but no one seems to think C++ qualifies for the "you can do systems programming without malloc and pointers"? You can't do systems programming without them, what you can do is minimize their use by building abstractions, which other languages, such as C++ and D, already do. So this idea that people somehow think…
I do think that C++ qualifies for that. I don't think there is widespread use of this yet -- I'm talking about the vast majority of "systems" code in C or C++ -- most of it is older and doesn't tend to use abstractions, or has been written from a "C with goodies" perspective. So yeah, (modern) C++ also contests this claim too. Rust contests a stronger claim about safety as well. ------ You're the one who said that "i…
Then there's the C constructor convention through opaque void pointers idiom.
This stuff is not new, not even close to new, NO ONE, not even the kernel developers, would make the argument that you cannot build abstractions around malloc.
If that's really what you're arguing, well you're not saying anything that C developers don't already practice.
Re: The struggle with Rust
#253Earlier quoted context omitted.
> This is pseudo-jargon. How do you measure expressiveness? Actually, not jargon. I had Matthias Felleisen's characterization of expressiveness [1] in mind (incidentally, he's also one of Racket's authors). > Do you have any substantive evidence that "good" typesystems don't reduce it? If we want to be precise, there is a continuum from statically to dynamically typed language. A dynamically typed language is, after…
EDIT: I've been chewing over the following: > This means that we can trivially translate a dynamically typed program into a statically typed program, though obviously we don't gain anything by that at this point (this is essentially an argument that Bob Harper has advanced before) and we pay for it in additional verbosity. This is exactly the opposite of the argument I advance below; you're claiming that there is a "…
That said, with regard to your "kill a branch in your AST" example, you can kill a branch with Void:
import Data.Void
frobnicate :: Either a Void -> a
frobnicate (Right x) = absurd x
frobnicate (Left x) = x
Now you can rely on no-one accidentally handing you a Right expecting you to do something reasonable with it.Re: The struggle with Rust
#254Earlier quoted context omitted.
I do think that C++ qualifies for that. I don't think there is widespread use of this yet -- I'm talking about the vast majority of "systems" code in C or C++ -- most of it is older and doesn't tend to use abstractions, or has been written from a "C with goodies" perspective. So yeah, (modern) C++ also contests this claim too. Rust contests a stronger claim about safety as well. ------ You're the one who said that "i…
like I said, that's a strawman. C++ has had new/new[]/auto_ptr since C++ 98, so almost 20 years. The ideas of smart pointers have been around for a really long time as well. Then there's the C constructor convention through opaque void pointers idiom. This stuff is not new, not even close to new, NO ONE, not even the kernel developers, would make the argument that you cannot build abstractions around malloc. If that'…
smart pointers have been around for a while too. I see some codebases using them. But many don't.
> NO ONE, not even the kernel developers, would make the argument that you cannot build abstractions around malloc.
I never said that kernel devs or whatever would make that argument.
----------------
Look, you seem to think I've said something different than what I did here.
You said "if it's really that painful to do systems level things, then there's a problem somewhere.". I'm saying that Rust contests the claim that malloc/new/whatever must be easy to use for systems level things. Easy-to-use abstractions around them work well too. It's not that C++ doesn't have these abstractions, it does, and has for a while. My statement isn't one against C++.
My point is that the difficulty of using programming paradigms designed around malloc/new should not be a dealbreaker for a systems language, provided that the same tasks can be accomplished without raw allocation using a suitably generic abstraction. C certainly promotes malloc-based-paradigms. C++ has good alternatives, but a lot of the lower-level stuff I find avoids them because ultimately malloc/new aren't hard in C++. Rust makes them harder to use, but provides sufficient abstractions/abstraction-building-power that this should not be an impedance to systems programming. And, again, I'm not saying C++ doesn't -- I'm just saying that C++ also makes it easy to use malloc/new-based patterns, so you will continue to see those in systems programs even if they aren't necessary.
Now, interestingly, an abstraction for a vec-with-header doesn't actually seem to exist in the crate ecosystem, probably because folks don't like unconditional allocation. But it's relatively easy to build, might do it over the weekend.
(You can fake it in safe code using DSTs but it's not so great)
Re: The struggle with Rust
#255Earlier quoted context omitted.
> Great! I believe, by that definition, your assertion that "good" typesystems don't reduce expressiveness is false, at least for common type systems such as Haskell's, Java's, ML's, etc. Haskell is not very good at extensible runtime polymorphism (one of its weaknesses). Try OCaml's polymorphic variants.
Okay, then I can pick another example: A dictionary where the type of the values depends on the key they're inserted under. (For example, a representation of the closure of a function in a typed language.) Of course, then I can go to a dependently typed language, but are you really going to tell me that only dependently typed languages count as "good" static type systems?
The point here is that the type system does not restrict me from implementing a data structure that adheres to this constraint, even if it does not enforce it for me.
Re: The struggle with Rust
#256Earlier quoted context omitted.
That's my point. I think people complaining that Rust (or Haskell, or whichever paradigm shift) "takes too long to learn" have forgotten what it was to learn their first language. It took them long, because some things take long. Learning something different takes time, but it's easy to forget this once you have a couple of languages under your belt.
> I think people complaining that Rust (or Haskell, or whichever paradigm shift) "takes too long to learn" have forgotten what it was to learn their first language Because they are required to be productive fast. A professional usually doesn't learn a new language just for the sake of it. If the language doesn't yield instant benefits then most people aren't going to bother learning it. If a steep learning curve is e…
Re: The struggle with Rust
#257Earlier quoted context omitted.
I believe this. However, my concern is that the number of people willing to make it through that learning curve is small and will limit the adoption of Rust.
I'm hoping that things like the Rust Language Server and it's integration into some of the IDE's out there will help with the initial learning curve; already the rustc error output is a million times better than when I started with it. I definitely share your concern; for me, Rust was like putting on a glove perfectly shaped for my hand. It works and prevents every basic pattern that it took 10 years to learn and sta…
Re: The struggle with Rust
#258Earlier quoted context omitted.
like I said, that's a strawman. C++ has had new/new[]/auto_ptr since C++ 98, so almost 20 years. The ideas of smart pointers have been around for a really long time as well. Then there's the C constructor convention through opaque void pointers idiom. This stuff is not new, not even close to new, NO ONE, not even the kernel developers, would make the argument that you cannot build abstractions around malloc. If that'…
When I say "malloc", I'm including `new` -- programming patterns that use new/delete are the same with malloc/free. new/delete doesn't really change the programming pattern, it just has a slightly nicer API. smart pointers have been around for a while too. I see some codebases using them. But many don't. > NO ONE, not even the kernel developers, would make the argument that you cannot build abstractions around malloc…
You may not like that they tend to be very thin abstractions, but they are abstractions, and the point is that the idea of building abstractions around malloc isn't new and certainly isn't unique.
You said:
>> You can build (or use, from the stdlib) safe abstractions over malloc that have the same performance.
While in defense of the statement:
>> Rust contests the claim that you actually need to do pointer arithmetic and stuff often in systems languages. You need to do it a bit to implement your abstractions, maybe, but it is not the first tool you should need to reach for.
This is presented as something unique to rust, which isn't even close to the accurate. This is why I called it a strawman. No one, not even kernel developers using C, are incapable of building abstractions around malloc to make it easier/safer to use.
The rest of what you say is inconsequential in my opinion. This isn't about C++, this is about your implication that building abstractions around malloc is something new or novel about Rust. It isn't. Not even the idea of safety around malloc is new, new[]/delete[] are themselves abstractions intended to make it less error prone to create/destroy contiguous blocks of memory.
That doesn't even get into the smart objects and RAII which have been around for a very very long time in C++.
None of this is new to Rust, and I think it's a bit disingenuous to imply that it is.
Re: The struggle with Rust
#259Earlier quoted context omitted.
Okay, then I can pick another example: A dictionary where the type of the values depends on the key they're inserted under. (For example, a representation of the closure of a function in a typed language.) Of course, then I can go to a dependently typed language, but are you really going to tell me that only dependently typed languages count as "good" static type systems?
I am not arguing completeness here; a type system is not a full-blown specification language and does not have to be. (I actually tend towards the point of view that trying to make them complete specification languages has limited practical value, but that's a different issue.) The point here is that the type system does not restrict me from implementing a data structure that adheres to this constraint, even if it do…
Re: The struggle with Rust
#260Earlier quoted context omitted.
When I say "malloc", I'm including `new` -- programming patterns that use new/delete are the same with malloc/free. new/delete doesn't really change the programming pattern, it just has a slightly nicer API. smart pointers have been around for a while too. I see some codebases using them. But many don't. > NO ONE, not even the kernel developers, would make the argument that you cannot build abstractions around malloc…
new/new[], delete/delete[] are abstractions around *alloc/free. That's not really under discussion, that's what they are. So when you talk about the ability to build abstractions around malloc, you're also talking about these operators in C++. You may not like that they tend to be very thin abstractions, but they are abstractions, and the point is that the idea of building abstractions around malloc isn't new and cer…
Right, I wasn't talking about just that, I was specifically referring to abstractions that make you change your programming patterns. C++ has those too (the move-based abstractions), but I don't consider new/delete to be them.
My point was sort of "being able to write code that looks like this is not necessary for systems programming". Being able to do the task at hand is, but it need not be done using code like that.
> This is presented as something unique to rust, which isn't even close to the accurate.
Fair. It's not. I didn't intend to mean that. I'm sorry.
I was a C++ programmer for a quite a while, some of which time I used modern C++, so I'm quite aware that these abstractions are not unique to Rust.
The reason I phrased it that way is that C++ doesn't really make it harder to use direct-malloc-based (or raw-pointers-with-new) programming, and most of the lower-level C++ code I've seen (this is anecdotal) still uses this. So C++ doesn't contest the claim the same way Rust does (it does contest the claim though), since Rust codebases doing the same thing (even the kernels in Rust) tend to move strongly in the direction of avoiding unsafe pointer twiddling as much as it can. This is a bit more nuanced (and based on anecdotal evidence on low level codebases I've seen) than I really wrote in my original comment, and I apologize for that.