Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you
Trying to figure out the right pattern to use here.



Am using a minimal HTTP client crate, called ehttp, to try and grab data.

It forces us to use a Callback method, so of course we should avoid entering Callback Hell somehow.

In other languages, we'd use Reactive programming and so it looks like we should just add the rxrust crate... but even so, the fetch method doesn't return anything and even so, we don't have any clean way to convert that callback into an Observable/Mono/etc.

Using a Future seems appropriate here, but it seems like a round peg and square hole scenario.

Am currently trying to use Arc's, but probably it's being used incorrectly.

Adbot
ADBOT LOVES YOU

crazypenguin
Mar 9, 2005
nothing witty here, move along
Are you doing web assembly or something?

That crate does have a fetch_blocking that just returns the response. Maybe that's all you need. And it also recommends other crates for promises in its docs.

But it also seems like an odd crate choice (not sure what would be the typical choice here though... reqwest?)

Anyway, if you want to fix up that code, you'll have to do something different for sure. You haven't written any code that tries to accommodate the fetch happening in another thread, you just try to return the result that you might not have yet (which is why Rust is complaining).

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you
My goal is to do this in a non-blocking way, while also avoiding callback hell.

If I run this method in a separate thread, then even if I use fetch_blocking in that separate thread I still have the usual race condition issue where I need to access its result eventually.

The choice of crate here is mostly because it's the most minimal and versatile: it will work for both native and wasm, while not being dependent on larger crates with features I don't need (most things such as reqwest, hyper, etc, have tokio in their dependency tree... and I don't need all of those features to just do a simple call).

It sounds like backpressure (i.e. ReactiveX) is what I need, so maybe I can't avoid it. I just wonder whether there's a cleaner way to do avoid callback hell while still being able to return something useful.

Running the method in a different thread and then returning a Future of its result might make sense, but I would need to share it across threads and poll the Future it until it's available. Just feels weird, is all.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
It sounds like you literally want futures and async/await. What makes you say that it feels like a "round peg and square hole scenario"?

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you
Because I'm bad and I suffer from Java Brain

gonadic io
Feb 16, 2011

>>=
Essentially you have only those two choices, futures or blocking. When using futures the old busted way is to manually return future combinators and then use methods from FutureExt or TryFutureExt traits, and the new hotness is just to use async/await syntax. Either way your whole app needs to be wrapped in the tokio::main macro. It's not a huge amount of setup tbh but yes it's more setup than the equivalent java http-world app would have

With blocking it's more like how you'd expect it, spawning threads then communicating with children as needed using either channels or just a straight up sqlite connection pool or whatever

fritz
Jul 26, 2003

Had a failure of intuition today.

code:
struct Dummy {
   pub data : Vec<f64>
}

let mut data : Vec< (usize, Dummy) > = Vec::new();
let mut table : HashMap< usize, Dummy > = HashMap::new();
// data gets filled somewhere along the way
for (i,j) in data {

   table.entry(i)
   .and_modify(|v| *v = j)
   .or_insert(j)
}
rustc errors at the or_insert because j is already moved in the and_modify. I'm confused because I would have thought that it wasn't possible for both code paths to execute, i.e. if it goes thru .and_modify, it won't go thru .or_insert, and vice versa.

Mr. Glass
May 1, 2009

fritz posted:

Had a failure of intuition today.

code:
struct Dummy {
   pub data : Vec<f64>
}

let mut data : Vec< (usize, Dummy) > = Vec::new();
let mut table : HashMap< usize, Dummy > = HashMap::new();
// data gets filled somewhere along the way
for (i,j) in data {

   table.entry(i)
   .and_modify(|v| *v = j)
   .or_insert(j)
}
rustc errors at the or_insert because j is already moved in the and_modify. I'm confused because I would have thought that it wasn't possible for both code paths to execute, i.e. if it goes thru .and_modify, it won't go thru .or_insert, and vice versa.

your intuition is correct about the code paths, but j is moved into the closure when it is created (because it cannot be copied), and now the closure owns it (regardless of whether it gets called). for example, this causes the same error:

code:
for (i, j) in data {
      let closure = |v: &mut Dummy| {*v = j};
      table.entry(i).or_insert(j);
}
...even though closure is never called.

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you

fritz posted:

Had a failure of intuition today.

code:
struct Dummy {
   pub data : Vec<f64>
}

let mut data : Vec< (usize, Dummy) > = Vec::new();
let mut table : HashMap< usize, Dummy > = HashMap::new();
// data gets filled somewhere along the way
for (i,j) in data {

   table.entry(i)
   .and_modify(|v| *v = j)
   .or_insert(j)
}
rustc errors at the or_insert because j is already moved in the and_modify. I'm confused because I would have thought that it wasn't possible for both code paths to execute, i.e. if it goes thru .and_modify, it won't go thru .or_insert, and vice versa.

Looks like the problem is the = sign: because Dummy doesn't/can't #[derive(Copy, Clone)] due to the Vec<> inside of it, it defaults to using the = sign as an opportunity to move ownership of j into the FnOnce, because the FnOnce owns V, which is the thing it's assigning ownership. The Programming Rust book explains it on p90 using Strings instead of structs.

edit: since it's functional, even though only one code path will end up happening, the lambda closure (FnOnce) stuff will still act as its own scope and be entitled to owning anything that gets moved into it.

gonadic io
Feb 16, 2011

>>=
With stuff like that, ditching the functional constructs and using an explicit match is usually enough to fix it these days, because the borrow checker can see through them in a way it can't for closures . Or just clone or copy.

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you

gonadic io posted:

With stuff like that, ditching the functional constructs and using an explicit match is usually enough to fix it these days, because the borrow checker can see through them in a way it can't for closures . Or just clone or copy.

And there's a special matching pattern syntax you can use for those situations where you just want to map something that cannot be Copy+Cloned. You just add an @ symbol. https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html#-bindings

fritz
Jul 26, 2003

Thanks for the wisdom everybody, I think I get it now.

gonadic io
Feb 16, 2011

>>=
Hopefully one day your code would be valid, it's 100% a valid complaint against rust, that sometimes code that is 100% perfectly verifiably safe is disallowed. A thing that sometimes you still have to do is e.g.

code:

let foo_clone = foo.clone();
butt(foo_clone);

Instead of

code:

butt(foo.clone())

Although tbh maybe that's not even true any more, I'm not as good at keeping up with modern developments these days

gonadic io
Feb 16, 2011

>>=
Wait one more thing sorry, in that particular case that `entry` api is specifically set up to make actual pattern matching (on VacantEntry and OccupidEntry) and thus borrow checker appeasing possible. I've not seen anything like it in other langs that don't need to do that.

gonadic io fucked around with this message at 14:34 on Oct 23, 2022

Dominoes
Sep 20, 2007

Hey, just wanted to say, Rust owns.

It has warts; Async can DIAF, the all collection-related functional syntaxes are a mess (escape hatch: the for loop), and generics are IMO a choice of last resort, not first option.

The more dogmatic/idealistic parts of the community need to go away. (Ie the safety woke)

That said... Show me else where you can find a language that respects user time, battery life, electricity use etc, and is also memory-safe, relatively smooth experience, has the good parts of functional programming etc. Bottom line is, you could imagine a language better than Rust, but it's currently the best we've got. C and C++ have so many syntax and program-structure warts and traps, ADA is impractical for many uses, and almost all other languages are slow. (Which IMO is disrespectful and rude, and why computer programs still have noticeable impact lag, laptops are crap battery life etc even as hardware improves).

Dominoes fucked around with this message at 18:30 on Oct 25, 2022

ploots
Mar 19, 2010
the biggest thing Rust has over C/C++ is cargo and it's not even close

if i never have to touch make, cmake, qmake, qtcreator, conan, ninja, ant/maven for some godforsaken reason, autotools, or an msvc project again i'll die happy

ploots fucked around with this message at 05:19 on Oct 26, 2022

Ranzear
Jul 25, 2013

Dominoes posted:

The more dogmatic/idealistic parts of the community need to go away. (Ie the safety woke)
Even the most diehard safety adherents are usually just wrong and dumb. It's wild to me how stuff like private RefCell is still looked upon as a terrible nightmare incarnation that could never ever be seen in competent code. This has come up three different times in online discourse now, two of those persons I almost respected the opinion of.

They're so stuck on following cargo culty "safe patterns" because that was the only way in other languages that they blow right past the protections rust enforces perfectly well on its own. What's really weird to me are the diehard borrow users. Never Rc/Arc, never private members, never thread anything. Always borrow, never think. A lot of footguns with async are related to borrowing too.

Anyway, Tokio just needs to go core. The mere existence of std even beyond weak attempts at Future and whatnot is what makes async a nightmare because then they're forced to completely reimplement instead of just being a drop-in or overload for all these blocking methods. Stop importing std at all and just use Tokio with Full feature and poo poo gets really easy to slam together.

Is that a nuclear hot take that std is the true wart on rust?

Edit: I feel like I should clarify I don't mean the full no_std monty, but just pulling in stuff like alloc explicitly. Treat std like a shopping list. I could probably make the jump to no_std though.

Double edit: Derp, it wasn't Tokio but async_std that had async working with no_std. Looks like that project has cleaned up a bit since I last looked. Still running down the list on my current project and I'm using Tokio's LengthDelimitedCodec too. Bleh. I'm just slamming a single control struct through, wouldn't be hard to replace or frame it myself.

Ranzear fucked around with this message at 10:12 on Oct 26, 2022

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
I think any big enough programming language community is going to have people who have bad or unbalanced opinions, especially about what sets the language apart from other languages, and it sounds like the “safety to the max!” and other crowds are just that, for Rust

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
nice nice nice
https://twitter.com/dwizzzlemsft/status/1578532292662005760

Music Theory
Aug 7, 2013

Avatar by Garden Walker

ploots posted:

the biggest thing Rust has over C/C++ is cargo and it's not even close

if i never have to touch make, cmake, qmake, qtcreator, conan, ninja, ant/maven for some godforsaken reason, autotools, or an msvc project again i'll die happy

This, 1,000,000%. Cargo isn't perfect, but I will never take any new language seriously that doesn't try to nail down early a standard build system at least as good as it.

Dominoes
Sep 20, 2007

Yea def. Rust's built in tooling is outstanding. C and C++ build systems are a relative disaster. Feels like it comes down to a project -sprcific recipe that may or may not work depending on OS state

Ranzear
Jul 25, 2013

My only tripping point is it seems like msvc just uninstalls itself at random, or maybe wipes its own path entry, and I have to go fix it with MS's stupid installer. That's not really a rust issue but it'd be nice if they'd just circumvent that trash somehow.

StumblyWumbly
Sep 12, 2007

Batmanticore!

Dominoes posted:

That said... Show me else where you can find a language that respects user time, battery life, electricity use etc,

Wait what? Is this just a reference to how efficiently it executes, or does Rust have some kind of sleep state support? I'm coming from a low port ARM microcontroller world, and Rust has been on my "maybe someday" list for a while.

Dominoes
Sep 20, 2007

StumblyWumbly posted:

Wait what? Is this just a reference to how efficiently it executes, or does Rust have some kind of sleep state support? I'm coming from a low port ARM microcontroller world, and Rust has been on my "maybe someday" list for a while.
I was referring to the former! I think generally on desktop PCs the OS handles the latter. Not sure if an application could (or should?) bypass that by firing off the correct reg writes or w/e.

You should try Rust on ARM. IMO well-suited to that domain. Which MCUs specifically?

Dominoes fucked around with this message at 14:53 on Oct 27, 2022

StumblyWumbly
Sep 12, 2007

Batmanticore!

Dominoes posted:

I was referring to the former! I think generally on desktop PCs the OS handles the latter. Not sure if an application could (or should?) bypass that by firing off the correct reg writes or w/e.

You should try Rust on ARM. IMO well-suited to that domain. Which MCUs specifically?

I'm moving to STM32U5, ARM Cortex-M devices with or without FreeRTOS. Nothing you'd find in a PC, this is for small sensor packages. Also some ESP32 communication work.

Dominoes
Sep 20, 2007

Nice! U5 is cutting edge. I made a Rust HAL for STM32 that works on most newer families. Intent is to support U5, but waiting on the PAC (named register definitions generated from SVD) to come out from the `stm32-rs` team on that. Hopefully is pretty similar to L5.

StumblyWumbly
Sep 12, 2007

Batmanticore!

Dominoes posted:

Nice! U5 is cutting edge. I made a Rust HAL for STM32 that works on most newer families. Intent is to support U5, but waiting on the PAC (named register definitions generated from SVD) to come out from the `stm32-rs` team on that. Hopefully is pretty similar to L5.

Point me to it! I'm still very new to Rust but I'd like to use it more in the future.

Dominoes
Sep 20, 2007

https://github.com/David-OConnor/stm32-hal

Dominoes fucked around with this message at 19:04 on Oct 27, 2022

Dominoes
Sep 20, 2007

Oh God. In a diff thread, someone recommended a molecular dynamics software. It's a classic C compile-it-yourself disaster. There's no way they expect people to actual do this! The windows version has 20 steps!!

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I'm trying to figure out the local IP address on a Linux system with only creates in Debian Bullseye being available to me. It has sysinfo, but a version that only gives the device names and byte transfer sizes; it doesn't have the IP addresses. Is there something else?

This is harder problem that I first thought when I staggered into it. I have multiple interfaces and have to do some guesswork on which one is the real one. What I figured I'd do is look at them all, determine which one has the most bytes sent and received, and omit anything starting with 127 or 192. I'm not even getting into IPv6 stuff.

Parsing ifconfig is possible but I've had it drilled into me that output is not standardized, so I can expect surprises. This is leaving me with using "ip --json address show" and then cross referencing /sys/class/net/[interface]/statistics/tx_bytes and rx_bytes to get the traffic. At least I get to use JSON instead of trying to parse the ip command, I guess.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
What do you want to do if your machine legitimately has multiple actively-used IP addresses? What are you using the IP information for?

My gut feel is that you should look at the routing tables to figure out what interface is used to reach some well-known public address, and then pick the IP address associated with that interface.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender
Yeah, you want to do something like "ip --json route get 8.8.8.8" and look at the "prefsrc" field.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Yeah that's a good command right there. Thanks.

Hadlock
Nov 9, 2004

I'm running rust-analyzer in vs code on a laptop with 8gb memory

:negative:

It told me to upgrade to rust-analyzer but holy hell this thing is a hogggg

gonadic io
Feb 16, 2011

>>=
Try setting "rust-analyzer.cache.warmup": false?

notwithoutmyanus
Mar 17, 2009
So I read the OP, and I know a beginner-ish level of javascript, a middling level of python, and I dabble a little bit in SQL queries. I've never really broken into full developer understanding of any language I think, maybe lacking fundamentals. Is rust okay for me to dive in and try to make that big jump or is that a bad idea at this point? I feel holistically my programming background is not at all up to proper practice, but I'd rather make the things I want to make myself than end up hoping someone else can, starting with some baby steps. I do know some folks in my circles who develop who have felt strongly Rust is the language to want to learn.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

You’ll be fine. The Rust Book is free and great and designed with non-experts in mind. Enjoy!

gonadic io
Feb 16, 2011

>>=
Rust is a good language to learn, however if you just want to get to work on your ideas immediately it is, loathe as I am to say this in this channel, probably a better idea that you just do them in python unless they involve the things that python is somewhat bad at (being fast, low resource, or easy to maintain, etc). it's not like rust magically unlocks functionality that python doesn't have for most devs (subject to the above constraints)

depends what your priorities are really

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

gonadic io posted:

Rust is a good language to learn, however if you just want to get to work on your ideas immediately it is, loathe as I am to say this in this channel, probably a better idea that you just do them in python unless they involve the things that python is somewhat bad at (being fast, low resource, or easy to maintain, etc). it's not like rust magically unlocks functionality that python doesn't have for most devs (subject to the above constraints)

depends what your priorities are really

seconded. if you want to learn programming in general and not in some specific arena that another language would do better (JavaScript or TypeScript would be this for web stuff, Rust would be one option for “””close to the metal”””, there’s other area-language pairings) Python is good.

On the other hand, Rust educational materials are supposed to be really good and extra guidance/constraints can be helpful when you start learning a generalist skill… the Rust books may presume some familiarity with programming concepts but it sounds like notwithoutmyanus has some of that familiarity?

Adbot
ADBOT LOVES YOU

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

I know two people whose introduction to programming was the Rust Book, coming from being generally fluent with computers, and they both had a good time. I only have two nickels but still etc etc

One of them did almost get scared off because I accidentally sent them the link for the ‘nomicon instead of the Book, but that was easily remedied.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply