Live data from Hacker News

Rust Design Patterns as a Book

rust-unofficial.github.io

41–49 of 49 posts

Re: Rust Design Patterns as a Book

#41

Earlier quoted context omitted.

> I want to emphasize that I'm not complaining just to complain, Oh yeah totally! It is very helpful. > It could just be that during my learning stage I learned I mean, I think this is very reasonable and intentional. Trait objects are a pretty niche feature of Rust already, and non-owned trait objects are even more niche than that. The book does guide you towards Box for this reason. > or the String thing (really, t…

> The book does guide you towards Box for this reason. Yeah. And that makes sense, though an aside that explains the broader concept ("Note: dyn is usually paired with Box, but it can be used to describe any reference") would help establish the more generalized understanding (it is possible this aside already exists and I just missed it) Re: the deref coercion, I do think many cases of this class of problem I'm descr…

> (it is possible this aside already exists and I just missed it)

Yeah I am not sure if it does or not; I'll make a mental note to go check sometime.

> I kind of wish the compiler had a "turn off all implicit behavior" option,

The problem is that what is "implicit" is different for everyone. Some people would say that Box::new is "implicit" because you don't see the malloc. Some might even say that malloc is implicit because you don't see the sbrk/memmap!

> But in the context of learning, it is not such a strict win,

Yeah so it's tricky! The thing is, without some way to jumpstart knowledge, people may never even learn in the first place. Like, by this argument, everyone should start with physics, because well, C compiles to asm complies to machine code which is actually just code for a chipset. There is no "I know what everything is doing" starting point. In reality, people jump in, start somewhere, and then expand what they know from there. This is true on every topic in every field. We still teach kids Newtonian physics even though on some level it's "wrong," you know?

Re: Rust Design Patterns as a Book

#42

Earlier quoted context omitted.

> The book does guide you towards Box for this reason. Yeah. And that makes sense, though an aside that explains the broader concept ("Note: dyn is usually paired with Box, but it can be used to describe any reference") would help establish the more generalized understanding (it is possible this aside already exists and I just missed it) Re: the deref coercion, I do think many cases of this class of problem I'm descr…

> (it is possible this aside already exists and I just missed it) Yeah I am not sure if it does or not; I'll make a mental note to go check sometime. > I kind of wish the compiler had a "turn off all implicit behavior" option, The problem is that what is "implicit" is different for everyone. Some people would say that Box::new is "implicit" because you don't see the malloc. Some might even say that malloc is implicit…

Sure, but Rust takes implicity a lot further than most. Implementation details of a function call are one thing; applying an operator in the current context, or adding an invisible generic type (lifetime parameter) to the current context, are something else. I think one key difference is that the unknowns are within the actual code that you're writing, not in places where you explicitly delegate to some other code to do something. The other key difference is that they're highly irregular: they apply sometimes and don't apply other times, which makes them hard to predict. The same syntax means one thing in one situation, and something different (or "nothing", when it doesn't compile) in another situation.

I guess I assumed there was some rustc compiler pass that would match certain patterns where stuff (like dereferences or lifetime parameters) has been omitted, and transform it into code where those things have been inferred and explicitly inserted. In which case it would theoretically be easy to skip that pass and turn those omissions into compiler errors.

Re: Rust Design Patterns as a Book

#43

Earlier quoted context omitted.

> (it is possible this aside already exists and I just missed it) Yeah I am not sure if it does or not; I'll make a mental note to go check sometime. > I kind of wish the compiler had a "turn off all implicit behavior" option, The problem is that what is "implicit" is different for everyone. Some people would say that Box::new is "implicit" because you don't see the malloc. Some might even say that malloc is implicit…

Sure, but Rust takes implicity a lot further than most. Implementation details of a function call are one thing; applying an operator in the current context, or adding an invisible generic type (lifetime parameter) to the current context, are something else. I think one key difference is that the unknowns are within the actual code that you're writing, not in places where you explicitly delegate to some other code to…

Maybe it's my Ruby background, but I don't find Rust very implicit at all, haha. We all have our own things :)

Re: Rust Design Patterns as a Book

#44
post #23

Earlier quoted context omitted.

Design patterns are not necessarily less understandable, much the contrary in fact. They basically encode known good ways to do something, so it should be okay even for beginners who haven't learnt the patterns yet.

What's more or less understandable is a bit subjective. There are some things that are obviously less complex than others. Some things that are obviously more complex than others. And then a lot of gray area. In my experience there is at least a faction of developers, myself among them that have a disdain for "design patterns thinking." Which I would describe as: spending a lot of focus learning various design patter…

Is that really any different from leaning a language, tool, framework, library, service, etc.? You learned the new thing, you're excited to try to out, and you should still be judicious in analyzing whether this is or isn't the place for it. And some developers just want to play with the new shiny.

None of that is an argument against learning new things. Just keep adding tools to your toolbox, so you don't end up with every problem looking like a nail.

Re: Rust Design Patterns as a Book

#45
A list of design patterns for a language amounts to a list of weaknesses in the language or in its library.

If the pattern could be captured in a library, that pattern would just be using the library. If the core language provided the feature, the pattern would just amount to using the feature.

Generally it is better to improve the language to the point where the feature can be added as a library component, but sometimes that is too hard. Thus, for most languages nowadays a "dictionary" type is provided in the core language, because a useful hash table library cannot be written with language primitives. In C, hash tables are open-coded again in each place where one is needed, because the language provides neither the feature, nor facilities sufficient to capture it in a library. Rust is powerful and expressive enough that hash tables are library components.

Conversely, pattern matching and coroutines are built into Rust. It should never be forgotten that (1) this was because the language was not expressive enough to capture the features satisfactorily in a library; and that (2) it would be better if, someday, the core feature became unnecessary because the language became expressive enough provide it as a library.

One reason it is better for features to be provided in a library is that another library can implement a variation on the feature that might not be as widely useful as the core version, but is better tuned to a less-common but still important use.

Another is that users can invent whole new features by combining powerful primitives that the language designers would not have time, or possibly inclination, to implement themselves.

Thus, in a certain sense, all patterns are anti-patterns.

Re: Rust Design Patterns as a Book

#46
post #44

Earlier quoted context omitted.

What's more or less understandable is a bit subjective. There are some things that are obviously less complex than others. Some things that are obviously more complex than others. And then a lot of gray area. In my experience there is at least a faction of developers, myself among them that have a disdain for "design patterns thinking." Which I would describe as: spending a lot of focus learning various design patter…

Is that really any different from leaning a language, tool, framework, library, service, etc.? You learned the new thing, you're excited to try to out, and you should still be judicious in analyzing whether this is or isn't the place for it. And some developers just want to play with the new shiny. None of that is an argument against learning new things. Just keep adding tools to your toolbox, so you don't end up wit…

That's an interesting comparison. I can understand the argument that design patterns are just like learning another service or tool or library. But aggressive use of design patterns is taking a language we already agree on, say Rust or Javascript, and adding a dialect to the language that can easily divide the existing commonality we have within idiomatic use of the language. Design patterns just strike me as incredibly non-utilitarian, divisive and non-additive in a field that already struggles to find agreement.

I wouldn't say adding a service, framework or external library to your stack is as divisive for code readability as being a big fan of utilizing design patterns.

Re: Rust Design Patterns as a Book

#47
I'm a bad man, and I have sinful [ooo] thoughts, but...

Is-a inheritance is extremely useful for creating extensible components. "It may be wrong, but it's much too strong."

In rust, how can you make a component that is just like another component, but ever so slightly tweaked without copying the entire external API of that other component? I understand I can wrapper with has-a relationship, intercept the correct API, and then pass through the rest of the entire interface, but how can I avoid copying the entire interface of the object when I only want to tweak something tiny?

With a car, I can swap out the engine with another, I just have to make sure the external interface is the same.

It may be a "bad thing", but it is extremely useful for the scenario where I say, "I want a Chevy smallblock, but I want to only tweak metal alloy on the interior piston."

    class MyBlock(ChevySmallBlock):
       def get_interior_alloy(self):
           return metals.Unobtanium
        
           
Bam. I have same item; slightly tweaked. I've used this type of pattern to great effect and I find that style of inheritance manipulation invaluable in python.

How can you do this with rust? I know that is-a inheritance is sinful, but show me the better way! I truly want to know it, and I've been trying to find a pattern for this.

Re: Rust Design Patterns as a Book

#48
post #40
post #22

Earlier quoted context omitted.

I find that this kind of pattern can be useful if you have a default implementation for each visit_foo method. For example, suppose that you want to create a traversal that walks through the entire Ast and does something special on just the Name nodes. And another traversal that does something special on just the integer literal nodes. One way to do this is to create a default traversal that walks through the entire…

Or create an iterator and use Iterator::filter, which is probably a bit more idiomatic.

In many languages, creating a pull-based iterator for a tree-shaped data-structure can be tricky. It might require turning the recursion inside out to use an explicit stack... Do you know how well Rust can handle this? I'm not familiar with the details.

In any case, while an iterator might help in the "ast_iterator" example, in the "ast_mapper" example I am not sure if there is a way around it.

Re: Rust Design Patterns as a Book

#49
kinda related topic: im debating if I should learn Rust.

I'm attracted to Go, but at the end of the day I can do everything that Go can with Nodejs minus the speed part.

Rust has just way to many new concepts to simply learn it.

Why did you learn Rust over Go. How are you using it?

Post reply on HN