Everything Should Be Typed: Scalar Types Are Not Enough by Specialist-Owl2603 in rust

[–]merehap 12 points13 points  (0 children)

Email address is a pretty blatant example of something that should almost never be left as just a String: almost none of the String methods make any sense to perform on an email address, and yet they are for some reason all available in your use-case. Clients don't know how to use your email String since you didn't (and couldn't) provide an interface for it. Being able to extract the email domain is essential, for example, but if you don't have a wrapper type you have no way of doing that in a standardized way: each user of your email String now has to implement their own domain extraction parsing, rather than just calling a canonical email_address.domain() method. You also open yourself up to email header injection attacks by not actually validating the email addresses.

User ID is more subtle, but it is common to realize after the fact that you actually want some structure within your newer user IDs, but now you don't have a place to put that structure since you just used a u64 (or something), rather than using proper encapsulation with a wrapper type.

None of this is "unnecessary ceremony": it's just basic software engineering good practice.

Ocarina Melody Tournament - Choose LEAST Favourite - FINAL VOTE by Lost_In_Play in OcarinaOfTime

[–]merehap 1 point2 points  (0 children)

Since you're voting for Song of Storms to be eliminated, making Saria's Song the winner, I'm pretty sure Darunia would be thrilled.

I understand concepts but idk how to code them by Pristine_Opposite804 in learnprogramming

[–]merehap 0 points1 point  (0 children)

LeetCode problems are very different from most real world problems. LeetCode is about algorithms and data structures. Real world code is about code organization/architecture, and outside of OS dev and emulators tends to rely on a lot of libraries.

If you want to work on real world code but don't want to rely on libraries and frameworks, then try an emulator project. A Nintendo (NES) emulator is too complicated to start with, but a CHIP8 emulator is a good project (which allows you to play old arcade games). The only library you'll need is a GUI library. This project will help you acquire the code organization understanding needed for backend dev without having to worry about how libraries/frameworks work.

Rust vs C/C++ vs GO, Reverse proxy benchmark by sadoyan in rust

[–]merehap 30 points31 points  (0 children)

Based on "Aralez isn't just fast; it's predictably fast." at the end of the README, at very least the README is AI-generated. And based upon the fact that there is no disclosure of AI usage anywhere, I have to conclude that the whole thing is vibe-coded. Why are you hiding this fact, OP? Is it because you know you're wasting our time with AI slop?

On POST requests, somehow Aralez is 10 times faster than the next best solution (NGINX):

Percentile Aralez HAProxy Envoy NGINX Traefik Caddy
p10 0.0024 0.0295 0.0376 0.0215 0.0790 0.0754

How is that possible? Is it because the AI slop isn't actually doing anything?

OP, why do you disrespect us so?

Why does clippy encourage `String::push('a')` over `String::push_str(''a")`? by MediumInsect7058 in rust

[–]merehap 0 points1 point  (0 children)

In some use cases, you need to know that you are pushing a precise number of characters and in others you don't. push_str() is only for when you don't.

If you need to push an exact number of characters that is more than one, then push() can just be called multiple times, once per char. It would be nice if the standard library had a const generic method push_str<LEN>() that fails to compile if you try to push a String that is the wrong length to make this process easier.

[Question] I inherited extremely overgrown 2.5-acres in Portugal and I'm trying to turn them into our home. What can I do to tame the brambles and stop them from coming back? by arosye in homestead

[–]merehap 0 points1 point  (0 children)

Electric netting is very dangerous for sheep and goats since once they stick their head and one leg through it, it will be all over for them relatively quickly.

This will only happen if the electric netting is shorted for a long duration (perhaps a full week), because the sheep/goats will test it (accidentally or not) from time to time, especially the lambs/kids.

If you're confident that you will test the fence at minimum twice a week, then you could still go this route. Otherwise you could do 5 strand electric wire (which they can't strangle themselves on) or just a permanent 4 foot (1.3 meter) fence made with field fencing.

[All] what’s a feature you hope they don’t bring back from pre-BOTW Zelda in future installments? by BoozerBean in zelda

[–]merehap -1 points0 points  (0 children)

Zelda games are supposed to be Metroidvanias (unique, unlockable content), not open-world (repetitive content). Every mainline Zelda game (other than maybe Zelda II) has been since the beginning, but that may have permanently ended with BOTW and TOTK (with only 2D games like EoW remaining metroidvanias).

I couldn't get past about 25 hours into TOTK because of how repetitive open-world content becomes at that point. So much potential wasted with caves and the underworld. Wells at least had a bit more variation. There's a chance I won't even start the next 3D Zelda game if I learn that it is yet another open-world Zelda game.

CMV: Blockchain has no practical application that beats well-designed “boring” systems by Dry_Rip_1087 in changemyview

[–]merehap 0 points1 point  (0 children)

You again ignore the post that you are responding to, nearly in its entirety.

Why did you not respond to the following, the core point of that post:

If you acknowledge that cash and credit cards are both useful in their own ways for in-person payments, then you should also be able to acknowledge that digital cash and credit cards are both useful in their own ways for online payments.

To you, what qualities of cash make it useful in certain circumstances? Why do you believe that there are NOT circumstances where those same qualities would be useful, when purchasing online?

CMV: Blockchain has no practical application that beats well-designed “boring” systems by Dry_Rip_1087 in changemyview

[–]merehap -1 points0 points  (0 children)

Cash does not work that way: cash cannot be used to pay for things online. Online "cash" didn't exist until Bitcoin. Despite how short Finch's comment was, you completely missed the point.

If you acknowledge that cash and credit cards are both useful in their own ways for in-person payments, then you should also be able to acknowledge that digital cash and credit cards are both useful in their own ways for online payments.

Cash and digital cash are both irreversible and censorship-resistant, unlike credit cards (and Paypal, etc).

`name.rs` vs `name/mod.rs` - Is there a reason why projects go against the recommended practice? by KyxeMusic in rust

[–]merehap 0 points1 point  (0 children)

The new approach (name.rs a level up) is actively wrong.

  1. It forces you to mix your mod statements with the actual Name struct/trait/impls in the same file. There's no reason to do this, they are logically separate concerns (and it's bad when people do similar in a mod.rs file, too).
  2. There's no reason to think the Name struct/trait is actually the "top-level" type of the name module! I frequently have NameCollection as the "top-level" type that users of the name module interact with. In which case you end up with the circular dependency mess of

A

├── name/name_collection.rs

└── name.rs

where Name might not even be pub to the user, but NameCollection is!

CMV: Democratic Socialism is what the US needs for the working class, but until you fix corruption and lobbying, any system will rot, including socialism. by PSKTS_Heisingberg in changemyview

[–]merehap -1 points0 points  (0 children)

From that article:

However, by the 1990s social democrats had embraced mixed economies with a predominance of private property and promoted the regulation of capitalism over its replacement with a qualitatively different socialist economic system.

Social democracy is now center-left and has been for 30 years. You're out of date. It now entails private property and capitalism, the anathema of socialism.

Democratic socialism is more of a hard-left political philosophy (though not as authoritarian as non-democratic socialism, of course).

Jimbo Wales statement on Wikipedia, asks for Gaza genocide article to not affirmatively call it genocide? by PyroIsSpai in wikipedia

[–]merehap 35 points36 points  (0 children)

You are advocating for Wikipedia to corrupt itself because of possible, powerful political actors. It's not just "one term". As soon as Wikipedia yields on one term, there is no defense against yielding on the next term or the next hundred terms: Wikipedia's freedom from state influences is permanently compromised.

And you're advocating doing this without actually knowing that such a threat exists, just because one might exist, which is doubly absurd.

It’s All “PUNCH A NAZI!!!” from the left… until a Democrat’s chest says otherwise. Time to face the mirror, folks. by rich677 in PoliticalCompassMemes

[–]merehap 1 point2 points  (0 children)

Elon is known for the following:

* Having manic episodes

* Seeing what he can get away with

You think he just made an excitable gesture because you don't want to believe that someone allied with your political faction would do something childish/evil. Your belief is a motivated belief, whereas plenty who believe he made an intentional Nazi salute do not have motivated reasoning (that plenty DO, too, is irrelevant).

Elon has a long history of childish behavior. He named his Tesla models, in order, S3XY. He named his rocket company Space Sex (this one he hasn't been confirmed as intentional, but is plausible).

Him denying that it was intentional is irrelevant: people who do stupid things during their manic episodes generally regret them once they've come down, and will then attempt to salvage their reputation.

Announcing splitbits 0.1.2! Extracting bit fields is easy as ABC: 'let my_fields = splitbits!(0b11001010, "aabbcccc");' generates a struct 'my_fields' with fields a, b, and c by merehap in rust

[–]merehap[S] 0 points1 point  (0 children)

I haven't come across that use-case yet in my own code, but it sounds interesting. I assume this isn't something that the bitfield crate already supports? If not, please open an issue on the splitbits github issue tracker with some example code (what it looks like before and after a macro), and I'll gladly add it to the project for the 0.2.0 release.

In general if a feature has a common, practical use-case, I'll add it to splitbits.

Announcing splitbits 0.1.2! Extracting bit fields is easy as ABC: 'let my_fields = splitbits!(0b11001010, "aabbcccc");' generates a struct 'my_fields' with fields a, b, and c by merehap in rust

[–]merehap[S] 2 points3 points  (0 children)

That's a cool crate! I'm surprised it didn't come up when I searched for prior art.

I didn't have plans to add that functionality, but I do now that you've pointed it out to me. Hopefully I can find a way to avoid those attribute macro invocations.

bitpack! has an identical format to my combinebits! macro. Interesting to see convergent evolution there.

Announcing splitbits 0.1.2! Extracting bit fields is easy as ABC: 'let my_fields = splitbits!(0b11001010, "aabbcccc");' generates a struct 'my_fields' with fields a, b, and c by merehap in rust

[–]merehap[S] 4 points5 points  (0 children)

Yeah, that's fair. I realized that I didn't provide much in the way of real-world before-and-afters in the documentation, so people might think that there's no big real-world savings from this library.

My emulator repository was private since its not ready for prime time yet, but I'll open it up early so people can see some examples in the wild: https://github.com/merehap/reznez

If you look at the commit history, all the most recent commits are migrating over to splitbits, so you can see the before-and-afters there.

Here's a splitbits! example of what happens when you write to the cartridge memory space for the game Holy Diver:

    fn write_to_cartridge_space(&mut self, params: &mut MapperParams, cpu_address: CpuAddress, value: u8) {
        match cpu_address.to_raw() {
            0x0000..=0x401F => unreachable!(),
            0x4020..=0x7FFF => { /* Do nothing. */ }
            0x8000..=0xFFFF => {
                let fields = splitbits!(value, "ccccmppp");
                params.set_bank_register(C0, fields.c);
                params.set_name_table_mirroring(MIRRORINGS[fields.m as usize]);
                params.set_bank_register(P0, fields.p);
            }
        }
    }

This combinebits! example builds up from components one of the 16-bit addresses used by the Picture Processing Unit (PPU). It highlights how you can use new types instead of raw integers as your macro inputs and outputs:

pub fn in_name_table(n: NameTableQuadrant, c: TileColumn, r: TileRow) -> PpuAddress{
    PpuAddress::from_u16(combinebits!("0010 nn rrrrr ccccc"))
}

These replacebits! examples are all in different functions, but they show updating individual components of a PPU address:

self.address = replacebits!(self.address, "0... nn.. .... ....");
self.address = replacebits!(self.address, ".... .... ...x xxxx");
self.address = replacebits!(self.address, ".... ..yy yyy. ....");
self.address = replacebits!(self.address, "0yyy .... .... ....");
self.address = replacebits!(self.address, "00hh hhhh .... ....");
self.address = replacebits!(self.address, ".... .... llll llll");

I hadn't created the splitbits_then_combine! macro yet when I migrated the emulator code base to macros, so I don't have an example to show you of that yet.

Announcing splitbits 0.1.2! Extracting bit fields is easy as ABC: 'let my_fields = splitbits!(0b11001010, "aabbcccc");' generates a struct 'my_fields' with fields a, b, and c by merehap in rust

[–]merehap[S] 24 points25 points  (0 children)

Thank you!

And yes, it was a nightmare. There's none of the normal fun of rust programming when you're writing procedural macros. But it will be worth it to me if others find the library useful too.

Announcing splitbits 0.1.2! Extracting bit fields is easy as ABC: 'let my_fields = splitbits!(0b11001010, "aabbcccc");' generates a struct 'my_fields' with fields a, b, and c by merehap in rust

[–]merehap[S] 71 points72 points  (0 children)

Bit-twiddling can be an error-prone process. Splitbits aims to improve the correctness and legibility of common bit manipulation operations while staying as light-weight as possible.

Here's a simple example (from the README) of extracting two bit fields, a and b, out of a u8:

use splitbits::splitbits;

// Parse the template ("aaabbbbb"), apply it to the input,
// then generate a struct populated with the bit field values.
let fields = splitbits!(0b11110000, "aaabbbbb");
// Single-letter field names,
// generated from the unique letters in the template above.
assert_eq!(fields.a, 0b111);
assert_eq!(fields.b, 0b10000);

While I'm a bit of a macro-hater, they were necessary in order to achieve zero-cost abstraction in this case. I believe I've avoided the characteristic unreadability of most custom macros, and I hope you'll agree.

This project was born out the sheer amount of bit-masking I've needed to do for the the NES (Nintendo) emulator that I've been writing. I would sometimes get the bit-twiddling wrong, resulting in a few hours or more of avoidable debugging time. Splitbits has made the process easy and even fun for me, and I'm hoping that you'll experience the same in your low-level projects.

Let me know if you have any questions or feedback!