Why He's Dropping Rust



  • Why I’m dropping Rust

    Turns out this big idea academic circlejerk language falls apart when people try to use it in practice.



  • @cartman82 Bah, I don't expect that Thelema will ever have such problems. A truly academic language doesn't need trivial things like 'a working implementation'.

    Filed Under: that's the sad, sorry truth, and I will probably never get past that



  • @cartman82 said in 🔗 Quick links thread:

    Why I’m dropping Rust

    Hey @Gąska, aren't you our Rust guy? What's your take on this?



  • @boomzilla said in 🔗 Quick links thread:

    Hey @Gąska, aren't you our Rust guy? What's your take on this?

    We have a guy for everything


  • Impossible Mission Players - A

    @cartman82 said in 🔗 Quick links thread:

    @boomzilla said in 🔗 Quick links thread:

    Hey @Gąska, aren't you our Rust guy? What's your take on this?

    We have a guy for everything

    :giggity:



  • suppose you have a base class Widget and want all your actual Widgets such as a Label or a Button or a CheckBox to have certain easily-shared functions.

    I suppose the author has the Java-style OOP brain worm. Unfortunately, Rust doesn't support class inheritance, so most Java-style OOP patterns don't translate to Rust.

    In Rust, to do something similar to this, you have Traits.

    Vaguely similar. About as similar as light waves and sound waves.

    So a trait can define abstract functions, but can't access any underlying fields. Let that sink into you. My first reaction to this was "Sorry, what?!".

    I wonder what his reaction was when he learned about Java interfaces. Or maybe he still didn't?

    I'm not the only one who thinks this is a severely limited part of the language and there's currently an RFC going to make it less silly.

    You know that "Everyone I don't like is Hitler" book picture? I have to learn Photoshop one day and make it into "Every language construct I don't understand is silly".

    However, this has been going on at least since March 2016.

    Look, compiler development is hard, okay? If you think half a year is enough to make a giant feature that heavily interacts with about every other part of codebase, why won't you make it yourself?

    Traits as a concept have been part of the language for numerous years.

    Just like variable assignment. You know why variable assignment was part of language since the beginning? Because it's fundamental part of the language and not much could be done without it. Same with traits.

    Why is such an important and vital part of the language missing, still?

    Because other Rust programmers don't suffer Java-style OOP brain worms and took the time necessary to learn basic language concepts instead of complaining that copy-paste from Java doesn't work?

    In some cases you can work around this by adding a function to the trait that is not implemented in the trait itself but on an actual object, then use that function to do your function with.

    Now it's really starting to sound like he indeed never encountered interfaces in his entire life.

    So you either don't use abstract functions and have a lot of code duplication or use the setup of the example and have slightly-less-but-still-too-much code duplication AND a leaky API.

    Or you might actually learn Rust and start taking advantage of trait system instead of working against it. Or pick another language if you want to make GUI application, because honestly, Rust's lack of class inheritance makes it very hard if not impossible, despite being well suited in many other areas. Part of being a half-decent programmer is knowing your tools and what they're good for.

    Another example. For nanogui, and CEGUI uses this concept as well, each widget has a pointer to a parent and a vector of pointers to its children. How does this concept map to Rust?

    By solving the ownership problem. Which is pretty hard, since the cyclic reference problem is part of spec.

    Option 1
    This is the option someone new to the language would choose.

    Specifically, the people who don't know that you can't have dynamic polymorphism when you store objects in a container by value.

    Option 2
    This is the option that I chose next. It offers the advantage that it's reasonably similar to the C++ style of nanogui.

    Similar enough to reintroduce all the pain of manual memory management that Rust desperately tries to run away from.

    But the major breaking point of this option is that it is currently impossible to create a self-reference counting object. Note that I don't mean the equivalent of C++'s smart pointers or Rust's very own Rc type. I mean an object that counts how many times it's been referenced and deletes itself when this counter reaches 0.

    Yep, that's definitely not what either C++'s shared_ptr or Rust's Rc are. Not at all.

    You can find an example in the C++ version of nanogui.

    Oh, I see. You didn't mean something like shared_ptr. You meant something like shared_ptr, but with reference count public. Because unlike what you said previously about traits, making refcount public is totally not leaky abstraction.

    For this to work, you need to be able to tell the compiler to only allow deleting/dropping oneself from inside the object.

    That, or just never delete it from ouside the type's methods. You're already managing memory by hand - why not go all the way?

    Alright, I said. Have it your way, Rust. What IS the idiomatic Rust way to do a cyclical directed graph?

    I'm almost certain there's a lib for that.

    Option 3
    After some searching I found a nice Rust library for creating trees called rust-forest.

    Oh look, there is!

    However, the implementation given in rust-forest doesn't allow nodes of different T types to be in the same graph, a requirement for a library such as nanogui.

    Protip: Box<T> is Box<T> is Box<T> regardless of what type the object inside is.

    I like the idea behind traits much like the interfaces in Go

    Oh, so he knows about interfaces after all? This makes the upper half of the article rather confusing.

    If you’ve read the whole article so far and stuck with it, thanks for reading my rant. If not, there's no TL;DR here, sorry.

    Yes there is."Michael Cannot Into Programming Without Class Inheritance".



  • @Gąska said in Why He's Dropping Rust:

    Yes there is."Michael Cannot Into Programming Without Class Inheritance".

    So I'm someone whose contact with Rust is pretty much reading about it on here, but I have thought about picking it up for a particular project.

    But let me ask you, what would be a "proper" Rust way to build something like a bunch of different types of widgets like he was talking about? Where Java / C# / C++ class inheritance seems like a straightforward approach?


  • Impossible Mission - B

    @Gąska said in Why He's Dropping Rust:

    I suppose the author has the Java-style OOP brain worm. Unfortunately, Rust doesn't support class inheritance, so most Java-style OOP patterns don't translate to Rust.

    Class inheritance is not a "Java-style OOP" thing, it's an OOP thing, period. It's been around since the invention of OOP with Simula, and it's the OOP thing, in fact, the sine qua non of object-oriented programming, Alan Kay's trollish attempts to hijack the narrative and redefine basic principles notwithstanding.

    Without inheritance and virtual methods supported at the language level, you don't have Liskov substitution, and without Liskov substitution, you don't have OOP; you have procedural programming with weird dot syntax.



  • @Gąska said in Why He's Dropping Rust:

    Or you might actually learn Rust and start taking advantage of trait system instead of working against it. Or pick another language if you want to make GUI application, because honestly, Rust's lack of class inheritance makes it very hard if not impossible, despite being well suited in many other areas. Part of being a half-decent programmer is knowing your tools and what they're good for.

    Wait, isn't the whole point of rust to drive the next generation web browser?

    If your native compiled language can't handle desktop apps, what use it is at all?



  • @Gąska said in Why He's Dropping Rust:

    Or pick another language if you want to make GUI application, because honestly, Rust's lack of class inheritance makes it very hard if not impossible, despite being well suited in many other areas.

    Hold on one goldurn minute. Isn't the desire to rewrite Firefox in it pretty much the whole reason Rust even exists?


  • Winner of the 2016 Presidential Election

    @cartman82 said in Why He's Dropping Rust:

    @boomzilla said in 🔗 Quick links thread:

    Hey @Gąska, aren't you our Rust guy? What's your take on this?

    We have a guy for everything

    *Sudden Clarity Clarence*
    WTDWTF is an extremely diverse forum.

    Though, to be fair, I've always known that diversity isn't always a good thing for every situation. It's just, you know, much more likely to be good in general. Case in point: if we have an esoteric question about almost any subject, someone here probably has an answer to it, or at least knows where to find it.


  • Winner of the 2016 Presidential Election

    @Fox said in Why He's Dropping Rust:

    : if we have an esoteric question about almost any subject, someone here probably has an answer to it, or at least knows where to find it will mock you for asking it.

    WTDWTFTFY



  • @masonwheeler said in Why He's Dropping Rust:

    Class inheritance is not a "Java-style OOP" thing, it's an OOP thing, period.

    One of several ways to do OOP. Another is what Rust does. And JavaScript is yet another style, closely related to classes but not quite.

    @masonwheeler said in Why He's Dropping Rust:

    Without inheritance and virtual methods supported at the language level, you don't have Liskov substitution

    Rust does have virtual methods. It also has trait inheritance, which is very much like interfaces. Does Liskov substitution strictly requires using base class's data fields? Because if not, then it's perfectly applicable to Rust.

    @cartman82 said in Why He's Dropping Rust:

    Wait, isn't the whole point of rust to drive the next generation web browser?

    If your native compiled language can't handle desktop apps, what use it is at all?

    Well, I made some simplification. Rust doesn't have class inheritance, and the most popular desktop GUI frameworks use class inheritance. So you cannot really use any of them in Rust, and neither can you port them directly. And the libraries written in C tend to be pretty fucked up. So Rust is seriously constrained in using existing GUI libraries, and last I checked, no one was rolling a new one from scratch. And even if someone did so, it would differ significantly from how "classy" libs work, which would make it rather hard to learn (and I think it would come out worse, because classes play very nicely with GUI).

    That was about desktop GUI. A completely different situation is with games. Here, there are numerous libraries for GUI, and they're pretty good. The difference from desktop is that in games, you control the whole screen, and don't have to use native controls. In this regard, browser engine is more similar to games than other desktop apps. Servo (the Rust browser engine by Mozilla) will probably be embedded in browsers written in other languages, that better deal with desktop GUI. That, or Rust gets class inheritance and Qt bindings.



  • Also

    @cartman82 said in Why He's Dropping Rust:

    If your native compiled language can't handle desktop apps, what use it is at all?

    Libraries. Number crunching, encryption and other security stuff, drivers, OS kernels, encoders/decoders, bottom five layers of OSI...


  • Impossible Mission - B

    @Gąska said in Why He's Dropping Rust:

    @masonwheeler said in Why He's Dropping Rust:

    Class inheritance is not a "Java-style OOP" thing, it's an OOP thing, period.

    One of several ways to do OOP. Another is what Rust does. And JavaScript is yet another style, closely related to classes but not quite.

    JavaScript is a toy language designed explicitly for tiny scripts "to make the monkey dance when you moused over it". There's a reason why modern Web development has a strong tendency to use class-based OO languages that get compiled down to JS: because they're designed based on principles that actually work for managing non-trivial complexity, and JS isn't.


  • Winner of the 2016 Presidential Election

    @masonwheeler ES6 has class syntax now.


  • Winner of the 2016 Presidential Election

    @masonwheeler said in Why He's Dropping Rust:

    for tiny scripts "to make the monkey dance when you moused over it".

    I'm pretty sure you could do that with some CSS to overlay a .png over an animated .gif and hide the .png on hover or something. As an added bonus, it would probably work 100x faster than javascript.


  • Impossible Mission - B

    @Fox Eric Lippert's words, not mine.


  • Winner of the 2016 Presidential Election

    @masonwheeler said in Why He's Dropping Rust:

    @Fox Eric Lippert's words, not mine.

    I know. I'm just saying that even the purpose of JavaScript is irrelevant and inefficient.


  • Impossible Mission - B

    1995 - Brendan Eich reads up on every mistake ever made in designing a programming language, invents a few more, and creates LiveScript. Later, in an effort to cash in on the popularity of Java the language is renamed JavaScript. Later still, in an effort to cash in on the popularity of skin diseases the language is renamed ECMAScript.

    -- James Iry, A Brief, Incomplete, and Mostly Wrong History of Programming Languages



  • @Fox said in Why He's Dropping Rust:

    I'm pretty sure you could do that with some CSS to overlay a .png over an animated .gif and hide the .png on hover or something.

    I don't think you could in 1995.


  • Winner of the 2016 Presidential Election

    @hungrier said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    I'm pretty sure you could do that with some CSS to overlay a .png over an animated .gif and hide the .png on hover or something.

    I don't think you could in 1995.

    Possible. But it's been 21 years since then, sooooooooo fuck JS for most of the shit it's currently used for.



  • CEGUI is pretty cool. It integrates with quite a few rendering engines and it feels a lot like writing Winforms code with its event model.



  • @Gąska said in Why He's Dropping Rust:

    In Rust, to do something similar to this, you have Traits.

    Vaguely similar. About as similar as light waves and sound waves.

    Actually. waves are a pretty good example for inheritance of properties. And before you tell me about the wave-particle-duality of light, that also exists for sound waves. The particles in that case are called "phonons".


  • Winner of the 2016 Presidential Election

    @Fox said in Why He's Dropping Rust:

    @hungrier said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    I'm pretty sure you could do that with some CSS to overlay a .png over an animated .gif and hide the .png on hover or something.

    I don't think you could in 1995.

    Possible. But it's been 21 years since then, sooooooooo fuck JS for most of the shit it's currently used for.

    More specifically, fuck using JS for most aspects of UI/page design. CSS can do nearly everything that JS is used for as far as UI/page design goes. If you need to have client-side pages communicate back to your webserver or to another one like Google Analytics or something, then JS is your best bet. But if you want to make sure that a button is placed properly or that a set of buttons are in the right order, use CSS, you fucking caveman.



  • @Fox said in Why He's Dropping Rust:

    Case in point: if we have an esoteric question about almost any subject, someone here probably has an answer to it, or at least knows where to find it.

    Fox: Where do I go for tips on how to deal with cultural appropriation by privileged white CIS males?

    WTDWTF: Go to Hell.

    Fox: Thanks guys!


  • Winner of the 2016 Presidential Election

    @cartman82 said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    Case in point: if we have an esoteric question about almost any subject, someone here probably has an answer to it, or at least knows where to find it.

    Fox: Where do I go for tips on how to deal with cultural appropriation by privileged white CIS males?

    WTDWTF: Go to Hell.

    Fox: Thanks guys!

    True story.



  • @Fox said in Why He's Dropping Rust:

    More specifically, fuck using JS for most aspects of UI/page design. CSS can do nearly everything that JS is used for as far as UI/page design goes.

    But how will CSS make it so that page automatically guides you to carefully prepared waypoints, instead of allowing the stupid user to scroll any way they want and miss all your cool designs!?



  • @Gąska said in Why He's Dropping Rust:

    Rust does have virtual methods. It also has trait inheritance, which is very much like interfaces. Does Liskov substitution strictly requires using base class's data fields? Because if not, then it's perfectly applicable to Rust.

    The Liskov substitution principle requires that the public non-private fields and members of the declared class/type be present in the substitute.

    Which is why it works so well with inheritance.


  • Winner of the 2016 Presidential Election

    @cartman82 said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    More specifically, fuck using JS for most aspects of UI/page design. CSS can do nearly everything that JS is used for as far as UI/page design goes.

    But how will CSS make it so that page automatically guides you to carefully prepared waypoints, instead of allowing the stupid user to scroll any way they want and miss all your cool designs!?

    Make a CSS Animation traversing all of those cool designs in the same view space and don't let the user scroll anywhere. :thumbsup:


  • Winner of the 2016 Presidential Election

    @Fox said in Why He's Dropping Rust:

    @cartman82 said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    More specifically, fuck using JS for most aspects of UI/page design. CSS can do nearly everything that JS is used for as far as UI/page design goes.

    But how will CSS make it so that page automatically guides you to carefully prepared waypoints, instead of allowing the stupid user to scroll any way they want and miss all your cool designs!?

    Make a CSS Animation traversing all of those cool designs in the same view space and don't let the user scroll anywhere. :thumbsup:

    :doing_it_wrong:


  • Winner of the 2016 Presidential Election

    @pydsigner said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    @cartman82 said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    More specifically, fuck using JS for most aspects of UI/page design. CSS can do nearly everything that JS is used for as far as UI/page design goes.

    But how will CSS make it so that page automatically guides you to carefully prepared waypoints, instead of allowing the stupid user to scroll any way they want and miss all your cool designs!?

    Make a CSS Animation traversing all of those cool designs in the same view space and don't let the user scroll anywhere. :thumbsup:

    :doing_it_wrong:

    Oh, you're right, sorry.

    What you should do is make a CSS Animation that progressively displays and hides iframes containing autoplaying max-volume Flash videos (using a Flash player your organization designed and programmed from scratch) depicting each of those designs with background music which your target audience generally hates, as well as a narration by each developer responsible for each design explaining the entire development process for that design. And don't let the user scroll anywhere. :thumbsup:


  • Impossible Mission Players - A

    @Fox said in Why He's Dropping Rust:

    @pydsigner said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    @cartman82 said in Why He's Dropping Rust:

    @Fox said in Why He's Dropping Rust:

    More specifically, fuck using JS for most aspects of UI/page design. CSS can do nearly everything that JS is used for as far as UI/page design goes.

    But how will CSS make it so that page automatically guides you to carefully prepared waypoints, instead of allowing the stupid user to scroll any way they want and miss all your cool designs!?

    Make a CSS Animation traversing all of those cool designs in the same view space and don't let the user scroll anywhere. :thumbsup:

    :doing_it_wrong:

    Oh, you're right, sorry.

    What you should do is make a CSS Animation that progressively displays and hides iframes containing autoplaying max-volume Flash videos (using a Flash player your organization designed and programmed from scratch) depicting each of those designs with background music which your target audience generally hates, as well as a narration by each developer responsible for each design explaining the entire development process for that design. And don't let the user scroll anywhere. :thumbsup:

    Someone help, it sounds like @SpectateSwamp has infected @Fox!!!



  • @Gąska said in Why He's Dropping Rust:

    Oh, so he knows about interfaces after all?

    Go interfaces are nothing like Java interfaces at all.



  • @powerlord said in Why He's Dropping Rust:

    The Liskov substitution principle requires that the public fields and members of the declared class/type be present in the substitute.

    What about a class without fields - just methods? Can it be Liskov-substituted too or not?

    @ben_lubar said in Why He's Dropping Rust:

    Go interfaces are nothing like Java interfaces at all.

    Yes. Java ones are infinitely better. :trolleybus:


  • mod

    @Gąska said in Why He's Dropping Rust:

    Can it be Liskov-substituted too or not?

    I mean, the basic principle is "If B derives from A, anywhere you can use A, you can use B". A lack of fields can be inherited. You can also add fields, but not subtract.



  • @ben_lubar said in Why He's Dropping Rust:

    @Gąska said in Why He's Dropping Rust:

    Oh, so he knows about interfaces after all?

    Go interfaces are nothing like Java interfaces at all.

    The only difference I can see between Go and Java/C# interfaces is that Java/C# interfaces are explicit.

    See also: Principle of Least Astonishment.


  • Winner of the 2016 Presidential Election

    @powerlord said in Why He's Dropping Rust:

    The Liskov substitution principle requires that the public non-private fields

    You lost me at non-private fields. If you write classes that are not POD (and therefore should not be inherited from) which have public or protected fields, you're doing OOP wrong.



  • @asdf said in Why He's Dropping Rust:

    @powerlord said in Why He's Dropping Rust:

    The Liskov substitution principle requires

    What does it require?! What?!



  • @asdf said in Why He's Dropping Rust:

    @powerlord said in Why He's Dropping Rust:

    The Liskov substitution principle requires that the public non-private fields

    You lost me at non-private fields. If you write classes that are not POD (and therefore should not be inherited from) which have public or protected fields, you're doing OOP wrong.

    Cutting that quote by two words changes things considerably. I didn't say non-private fields, I said "non-private fields and members."

    And yes, originally that said public, but then I realized later that would be interpreted as not including protected members, which much be present for Liskov substitution as well for cases like copy constructors.



  • @powerlord Random :pendant:-ry; Aren't fields members in OOP though? I always thought fields were dataum members and methods were behavioral members, but I didn't really pay that much attention in OOP 150 in school...


  • Winner of the 2016 Presidential Election

    @powerlord What you said was technically correct, but I still felt the need to stress that if you have non-private fields in the first place, you're :doing_it_wrong:..



  • @MathNerdCNU said in Why He's Dropping Rust:

    @powerlord Random :pendant:-ry; Aren't fields members in OOP though? I always thought fields were dataum members and methods were behavioral members, but I didn't really pay that much attention in OOP 150 in school...

    As a general rule, you don't want public fields in OOP. The reason being that other parts of the program can make changes to your values when you don't expect it.

    Thus, getters and setters were born.

    Some languages handle this more gracefully than others, such as C#'s properties. C# Properties are a pair of methods that look like fields.

    For example, someObject.Something = 5 looks like you're setting a Field named Something, but in C# this is more likely to be a property that looks like this:

    private int _something;
    public int Something
    {
        get { return _something; }
        set { _something = value; }
    }
    // value is a "magic" value above, I could have written out the entire signature for get and set, but C# understands these implicit shorter forms
    

    Having said that, you can have other logic in these two methods that do things like validation. Heck, you may not even provide a set method, which would make it a readonly property.

    Edit: Having said that, converting from a public field to a property in .NET requires a recompile of anything that references it, so it's best to start with a property in the first place.



  • @powerlord Super Sayian:pendant:-ry level 2!

    My real "beef"/confusion was explicitly calling out fields vice members. A field is-a member, least from what I can remember from OOP theory. A member may not be a field.

    On to OOP best-practices:
    A naive Property (dumb getter/setter) would still be a field, just with an extra level of indirection. But now we are bordering on :trolleybus: -es all the way down. Something about INotifyPropertyChanged vs DependencyPropery(s) et al. :trollface:



  • @Gąska said in Why He's Dropping Rust:

    What about a class without fields - just methods?

    Then how the hell is that a class? It's more like a library.


  • Dupa

    @powerlord said in Why He's Dropping Rust:

    @MathNerdCNU said in Why He's Dropping Rust:

    @powerlord Random :pendant:-ry; Aren't fields members in OOP though? I always thought fields were dataum members and methods were behavioral members, but I didn't really pay that much attention in OOP 150 in school...

    As a general rule, you don't want public fields in OOP. The reason being that other parts of the program can make changes to your values when you don't expect it.

    Thus, getters and setters were born.

    Not only. The point of having getters and setters is that fields should be an implementation detail and getters and setters allow you to hide it. Also, it makes changing return values down the line easier. You can be sure that IncludingTax will always return value including tax, no matter how many sections were added in the meantime.



  • @Yamikuronue said in Why He's Dropping Rust:

    I mean, the basic principle is "If B derives from A, anywhere you can use A, you can use B". A lack of fields can be inherited. You can also add fields, but not subtract.

    If type A implements trait T, it inherits all public methods and all (0) public fields. You can use A wherever T is needed. If type B also implements T, then everywhere you use A, you could have also used B, and vice versa. That looks very like Liskov substitution to me.

    @asdf said in Why He's Dropping Rust:

    You lost me at non-private fields. If you write classes that are not POD (and therefore should not be inherited from) which have public or protected fields, you're doing OOP wrong.

    TIL that WinForms, Qt, WPF, JavaFX and Swing are doing OOP very, very wrong, with all the dozens of public properties/getters and setters that each control has... Because, let's be honest - if there's a public trivial getter and setter for a private field, this field is effectively public.



  • @anonymous234 said in Why He's Dropping Rust:

    Then how the hell is that a class? It's more like a library.

    Or an interface. That post was written in context of "hurr durr no Liskov substitution for Rust because traits cannot into fields".


  • Discourse touched me in a no-no place

    @kt_ said in Why He's Dropping Rust:

    You can be sure that IncludingTax will always return value including tax

    :wtf: says no, you can't be sure of that. :headdesk:


  • Discourse touched me in a no-no place

    @Gąska This whole “fields and properties and LSP” stuff is a total sideshow.

    The key objection in the original article was to do with problems between owning references and non-owning references. A container widget/component/thingy has within it some other controls — perhaps a few buttons or an entry field — and is responsible for getting rid of them when it goes away, so it clearly has some ownership responsibility for them. Yet the contained controls reasonably need to know about their container despite not owning it. Apparently, the problems could be fixed if all the contained objects were of exactly the same type, but GUIs really aren't like that.

    Ultimately, we collections of things that aren't all exactly the same. Because of that, we also need to have operations for extracting a reference to one of the objects from the collection and acting on its real type (or at least a more precise supertype of its real type). This is an operation that can fail at runtime but that cannot be helped without making the code utterly horrific.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.