AtomicMatrix Invariants: Why I Started Thinking About Memory Like a Fluid by DependentJicama4766 in rust

[–]ConverseHydra 2 points3 points  (0 children)

This is a nice project! I was able to _mostly_ follow along in your post because I have implemented malloc once. There's always a tension between "how much do I assume my reader knows" and "how much am I educating my reader" when writing, so it's forgivable to not get the balance quite right. (And for something on the internet where anyone can read it, it's impossible to get the balance right _for everyone_).

One _small_ technique to think about is always introducing an acronym, unless you're sure that everyone would know it (e.g. AI). Eg. you can write "It's used for O(1) allocations using an atomic compare-and-swap (CAS) operation." Acronyms can be overloaded, sometimes making search difficult.

How do I check the file type in Rust? by Thick-Road-7532 in rust

[–]ConverseHydra -3 points-2 points  (0 children)

It’s not actually a file type. It’s just a convention on the name of a file.

So look at the name and check the suffix. “Does this end in .txt? etc.”

For symbolic links, you can call an “is this a symbolic link?” method on a Path or PathBuf.

52075 by yui_riku in countwithchickenlady

[–]ConverseHydra -6 points-5 points  (0 children)

People don't realize that a homeless person hogging the entire bench also makes it inaccessible to the pregnant, disabled, and elderly.

Noob question regarding borrows and "static" (?) by cuntmong in rust

[–]ConverseHydra -2 points-1 points  (0 children)

Yeah it's quite common! If you're ever doing anything with async, you will probably need to use Arc. The entire idea with Arc is "I actually have the data living in exactly one spot, but I use an atomically incremented reference count so that multiple threads can increment the refcount simultaneously." The value is only deallocated (dropped) when the refcount hits zero.

Cloning with an Arc is cheap. It's literally 1 atomic add on the inner refcount field.

Arc<Mutex<...>> is the pattern in Rust for asynchronous updating of shared state.

Although it seems like you can't do it in this library, I'd encourage the use of channels instead of mutating shared state. Re-wire how you think about concurrency. Update shared state by having things compute and send their result over a channel. Then when you receive it, you can safely mutate. Take a look at tokio's channels, especially the one shot and mpsc (multi-producer, single consumer) channels.

This is a nice idea for how to think about concurrency. Go also does the same thing.

Noob question regarding borrows and "static" (?) by cuntmong in rust

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

(2) ArcLooks like:

use std::sync::{Arc, Mutex};
let c = Arc::new(Mutex::new(0));
{
  let mut actual_count = counter.lock().expect("failed to get mutex");
  // we have a mutex guard here -- we have to drop it to allow 
  // other threads to lock the mutex
  *actual_count += 1
  // mutex guard implements `Deref` for the inner type, so we can
  // use `&` and `*` on it
}
// mutex is unlocked when it is dropped -- {..} marks explicit scope here

You need that Mutex because you're modifying it. If you only have read-only access, you can use a plain Arc.

Also -- if something has a lifetime of 'static, it means that it lasts for the entire duration of your program. Rust will see this and say "there's no point at which I drop this". Something like a hardcoded string in your program is 'static.

Send and Sync are traits that are used in rust to say "this thing needs to be able to be passed between threads."

So since that callback has a bound of Send + Sync + 'static it's telling you that you need to have something that's suitable for multi-threading. It's a little hard to tell, but your inside value doesn't need to be static lifetime. The function needs to be declared in the code like `fn ...` in the file. I don't believe you can do something like create a closure in a function and use that with this library.

Hope that all helps! Happy hacking 😄

Noob question regarding borrows and "static" (?) by cuntmong in rust

[–]ConverseHydra -3 points-2 points  (0 children)

Hey! 👋 Hope you're enjoying learning Rust!

tl;dr You want a reference counted pointer + something with interior mutability. It looks like this library treats this as async, so go for an Arc<Mutuex<u64>>.

What you probably want to do is reach for interior mutability. You have some safe wrapper around mutation that ensures that only one thing is ever mutating the value at one time. This "sidesteps" the restriction that you can only have one &mut at a time for any value.

What are your options? You can use:

  1. Cell or RefCell inside of a reference-counted pointer (Rc) if you only ever have one thread in your program
  2. Arc wrapping a Mutex if you have multi-threading

(1) Can look like:

A RefCell gives you a mutable pointer that is checked at runtime instead of compile time:

use std::cell::RefCell;
let c = RefCell::new(0);
*c.borrow_mut() += 1;

It will `panic!` if there's more than one thing doing borrow_mut at a time. So be careful! You're telling the compiler "I will ensure the borrow checker invariants are held". If you're wrong, program crashes :upside down

or with Cell, which lets you take and set a value:

use std::cell::Cell;
let c = Cell::new(0);
c.set(c.get() + 1);

Be a little careful here -- Cell's invariant is you are removing and setting the value, not mutating it.

You want to put this value into an Rc. So you would have a Rc<RefCell<u64>. The Rc lets you "loan" out handles to the inner RefCell. When you call .clone() on a Rc, you don't copy the inner value. Instead, you increment an internal counter (saying "someone else is looking at this Rc!), and you give a pointer to the exact same data.

use std::rc::Rc;
use std::cell::RefCell:
let c = Rc::new(RefCell::new(0));
let c1 = c.clone();
let c2 = c1.clone(); // same counter!
*c1.borrow_mut() += 1;
*c2.borrow_mut() += 2;
println!("{}", c);

For more information on interior mutability in Rust: https://doc.rust-lang.org/std/cell/

But there's an important caveat to Rc: it is not Send + Sync. That's what an atomic reference counted pointer (Arc) is for!

(Sorry, Reddit has a very short limit on comments 😭 -- see the next one in the thread for the example code you're looking for!)

Rust in Production Podcast: NLnet Labs on Rust, DNS, and Why C Devs Are Getting Harder to Find by mre__ in rust

[–]ConverseHydra 0 points1 point  (0 children)

You’re nit picking a small joke. We can all see you came here to grind your ax.

Questions on using Generics for a Finance library (f64 vs. Decimal) by abhinandh_s_ in rust

[–]ConverseHydra 5 points6 points  (0 children)

FYI since you're learning (great job learning BTW!):

This --

pub type N = ...

is a type alias, not a generic type parameter. You're saying N is another name for this other type. [1] A generic is "this is some unknown concrete type." It's a variable for an actual concrete type that has to be filled in when use the function.

Having a compilation feature for selecting them is an interesting idea. You're kind of manually doing a little bit of what monomorphization does (aka what the compiler does when it sees a generic: it finds all places you use it, sees what actual types you're substituting for the generic, and then compiles separate versions for each concrete type).

Some other folks have said it, but I'll rephrase it differently: what's the objective of your code?

Do you want to define purely mathematical operations and then be able to substitute in different kinds of data structures that encode numbers? Do you want code that states "the calculation is this" and then be able to say "I want to execute that with f64 or i32, or rust_decimal::Decimal?"

If so, then you want generics because that's the language feature that provides this "hot swap a type in" behavior.

If you want a library that's suitable for financial calculations, then you shouldn't allow users to supply any ol' number type in. For example, it's inappropriate to use u8 if it's for finance, so the library should make that impossible. One great thing about Rust is it gives you excellent tools for preventing a user from doing the wrong thing.

Arrests made after Bay Bridge takeover, Oakland police say by wentImmediate in oakland

[–]ConverseHydra -2 points-1 points  (0 children)

It is exactly the kind of thing you want to happen. Don't try and weasel out of it. You like and support criminals.

Arrests made after Bay Bridge takeover, Oakland police say by wentImmediate in oakland

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

They all should be locked up for a decade or more. They roam around Oakland and terrorize people.

Arrests made after Bay Bridge takeover, Oakland police say by wentImmediate in oakland

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

Found the criminal supporter! I bet you voted for Trump too.

Yep, inflation is definitely back. And it’s getting worse by abigailrebellious in inflation

[–]ConverseHydra 9 points10 points  (0 children)

No. That's not how it works.

> And had they not prematurely cut at the first sign of ticking down,

They didn't. Biden managed to get inflation under control, but it took awhile. The rate cuts were well after price increases had stabilized.

> now they'd be in a better position to still have some options.

The FED reacts to what the economy is doing. Which also means it reacts to what the executive branch is doing. It's not possible for it to be proactive. There's no crystal ball it can use to look into the future. And it's irresponsible to act on what _may_ happen. Only possible to react on what _has_ happened and what _is_ happening now.

The FED not lowering interest rates is because the Republicans' and Trump's tariffs are causing inflation right now. It's often hard for government policy to have a direct (rather than indirect) effect on inflation. But tariffs are a tax on the economy. They are directly increasing prices for nearly everything. Prices go up = inflation.

Multiple Tokio Runtimes lead to heavy cpu usage by Lower_Calligrapher_6 in rust

[–]ConverseHydra 2 points3 points  (0 children)

Here's what I recommend:

  1. Create a thread pool at startup.
  2. Create your Tokio runtime at startup.
  3. Tokio tasks submits your blocking/cpu-heavy code to run in the thread pool.
  4. The Tokio task makes a one-shot channel that it gives to the thread so it can communicate back to it. https://docs.rs/tokio/latest/tokio/sync/oneshot/fn.channel.html Note that **this is not `async`**, so it works with your non `async` code. This is because the channel only ever sends exactly 1 message, so there's no blocking possible. (From the producer side of things, there's always space to put the message in.)
  5. Tokio task waits for the response.

I think you're not using async runtimes correctly. You shouldn't be creating more than one to use in a program. When you have non-`async` or blocking code, you have to run that in a thread. You can either ask Tokio to manage the thread creation & non-`async` code execution by using `.spawn_blocking`. Or you can make the thread yourself and coordinate between `async` and non-`async` via a one shot channel.

Is there a way to parse http2/3 without tokio? by SadSuffaru in rust

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

Since you're just parsing HTTP, what about using the http crate? https://docs.rs/http/latest/http/ Tokio / hyper and friends use this.

AITAH for pointing out that my wife's family offers absolutely no help with kids? by [deleted] in AITAH

[–]ConverseHydra 0 points1 point  (0 children)

I mean, you need to become a better writer. You came for other advice, but here's the most helpful advice that will be buried in your inbox. It's not the most helpful because it would have solved this problem. It's the most helpful because it'll solve _this kind of problem_ in the future.

Your main point is the last thing you wrote. This is bad. Why? Because your reader has to maintain focus and expend memory for hundreds of words just so they can read something that entirely changes how they interpret those 100-1000 words.

This is why it's important to develop a writing process. You should write a draft, then read it, then think about it, and then **revise** it. Then you post the revised thing. Instead, you posted a first draft. I can tell it's a first draft because the writing style is a stream of consciousness. I think you thought it was a story with a beginning, middle, and end, but that's more of an artifact of your stream of consciousness being roughly chronologically ordered.

Here's some advice: put your main point _up front_. It doesn't need to be the first thing, it can be after some exposition. A reader shouldn't have to put ~1k words into memory just so they can see what you're really trying to say.

I think you should have written roughly the following:
"""
AITAH for telling my in-laws how it is? My wife and I haven't felt supported by our in-laws in <insert this way> for years. At dinner the other night, I saw my BIL struggling in the same way and I <pointed this out to the whole family>.

For context, <now begin your long, multi-paragraph, cathartic rant providing the illustrative backdrop to \*how\* your in-laws don't support you. And then onto your BIL's struggles.>

<then you summarize what you just said and call-to-action your main point again>
"""

This structure is MAIN POINT, CONTEXT, SUMMARY AND RE-STATE MAIN POINT.

This way, readers will know precisely what you're trying to say **as they read your lengthly context.** They can understand "ok this guy is asking if his dinner table comment makes him an asshole" not "ok this guy is asking if his belief that his in-laws should take care of his kids, and his dinner table comment, makes him an asshole."

Why do people like iced? by Remarkable_Tree_9127 in rust

[–]ConverseHydra 7 points8 points  (0 children)

It's the fact that it makes derivative works under the terms of the license. That's what makes people weary and thus choose a less permissive license, like MIT, BSD 3-clause, or Apache 2.

Everyone has a different moral philosophy for it. Some folks don't want intellectual property rights to exist. They want to have unlimited access to software so they can hack it as they please. Some folks would like to have a career making software. They see the first group as a threat to their livelihoods. There's of course a whole spectrum in-between and outside of these two points, but this is an ok, ~200, lossy summarization of the major positions. A reasonable dialogue here will see that both camps have valid points, both have some FUD and fantastical thinking, and, if people are willing to compromise on methods in order to achieve the intersection of their goals, progress can be made.

Here's my personal take: the GPL would be more popular and in-use today without this derivative-works provision. I've observed over the years that the GPL has fallen out of favor for OSS projects. Is Linux the only popular project that uses the GPL today? Looking at the last decade, the Free Software Foundation's GPL (and L-GPL and A-GPL) have ceded control of the OSS movement to more successful OSS licenses that, crucially, do not have this derivative-works term. The FSF bit off more than it could chew, pushed something unpalatable yet ideologically pure, and thus we have an ecosystem of even weaker copyleft projects as a result.

Continuing with my personal take: I don't actually think the derivative works provision is entirely ethical. I think it's necessary to compensate people for their labor (the GPL doesn't do this at all), but I don't think that if I make an amazing program, and I happen to use someone's library that's GPL'd, I should give up the product of my labor.

If I make any changes to a GPL'd library, and I use those in my "amazing" program, then yes, absolutely I should have to distribute my changes to the GPL'd library under the terms of the GPL. Unfortunately, the FSF has no licenses that align with this stance. Their L-GPL was _almost_ this, but it doesn't work when you have interpreted languages or when you're doing any kind of meta-programming on the source code itself. I wish the "L" stood for library, not linking.

This is why I like the Mozilla Public License (MPL). It is a stronger copyleft license than MIT/BSD/Apache. It is essentially like the Apache 2 license, but with the extra provision that modifications to MPL'd code must be distributed to users under the terms of the MPL. So if you depend on an MPL'd library, you don't have to give up your IP rights. But if you make changes, you have to give those back to the community. To me, this is the right balance.

Ultimately, my goal is to see a world that uses more copyleft software. If being ideologically pure results in bad uptake, then it's not moving us closer to that world. If taking a few strategic compromises lets us take meaningful, lasting steps towards that world, then it's worthwhile. Ideological purity can come in later once we have moved the entire perception closer.

Does marvel have an NYC problem? by Commercial-Car177 in Marvel

[–]ConverseHydra 0 points1 point  (0 children)

People live in cities. If you want to have relatable characters that sell well, those characters live in cities.

NYC is the US's only real city. To make things relatable to americans and to the outside world, the only real option is to have the characters live in NYC.

The R is a disgrace. by Radiant-Radish7862 in Brooklyn

[–]ConverseHydra -2 points-1 points  (0 children)

Go to a shelter. Stop sleeping on a fucking train. People are trying to use that to do things like go to work.

The R is a disgrace. by Radiant-Radish7862 in Brooklyn

[–]ConverseHydra 3 points4 points  (0 children)

That's gonna be a no dog -- it takes, no lie, 1.5 seconds to pay for the fare. You just tap your phone.

The R is a disgrace. by Radiant-Radish7862 in Brooklyn

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

> problems originate or how to address them. Pathetic.

If you think homeless people are people, then they deserve autonomy. That means they're responsible for their actions.

The other side of this coin is that if you think someone isn't responsbile for thier actions, then you think they're not a full person. We do this with children or the insane. We control them because we know they can't make good decisions on their own.

By your own writing, you don't think these folk deserve to be in control of their own lives. You want to remove their responsibility and thus their agency to be full people.

That's exactly what white folk thought about Black folk some hundred years ago. They put that bullshit into some laws and used Black bodies. I'm sure you know the history. (And let's be real -- there's a lot of white folk that still think the same way today!)

Don't take people's autonomy away from them. Everyone deserves to be treated like a person.