(saying something more realistic like “2015” or whatever your inexperience or AI told you to)
User input is probably the big one where this API is gonna get stress-tested…
(saying something more realistic like “2015” or whatever your inexperience or AI told you to)
User input is probably the big one where this API is gonna get stress-tested…
Hmm, I can believe that it was based on java.util.Date
, but I don’t remember that being as unpredictable. I guess, a different API to begin with, would have avoided a lot of problems, though…
A few years ago, all the languages I would use started to have automatic unused variable warnings built-in. And yeah, by now when I hear of people that don’t have that, it’s very much a feeling of “Man, you live like this?”.
Yeah, Lemmy is actually a decent software for this use-case…
Not if you never get your application into production…
I wish this was as much of a joke as I’m pretending. It’s so common for software projects to get cancelled that lots of tooling differences are just in terms of how long they let you not deal with long-term problems and how violently they do then explode into your face.
For most of the development lifecycle of a GCed project, you’re gonna ignore memory usage. And if you’re lucky, it can be ‘solved’ by just plonking down a thiccer piece of hardware…
I mean, he did fuck up a good chunk of everything…
Ah, interesting. I went from garbage-collected languages where thinking about ownership might be useful for keeping complexity low and occasionally comes up when you manage lists of objects, but ultimately isn’t needed, to Rust where well-defined ownership is enforced by the language.
So, I wasn’t aware that ownership is even as concrete of a thing in other languages…
Hmm, not sure, if I’ve heard of it. I’m guessing, we’re not talking about simply drawing a UML class diagram…? Is it for figuring out which object will have to clean up which other objects, in non-GCed languages?
The last one seems to be mostly like Brainfuck, just with different capitalizations of “moo”: https://esolangs.org/wiki/COW
Yeah, these become a lot less relevant with routine.
Avoiding the main-thread panicking is mostly just a matter of not using .unwrap()
and .expect()
.
String
vs. &str
can mostly be solved by generally using owned datatypes (String
) for storing in structs and using references (&str
) for passing into function parameters. It does still happen that you forget the &
at times, but that’s then trivial to solve (by just adding the &
).
“temporary value dropped while borrowed” can generally be avoided by not passing references outside of your scope/function. You want to pass the owned value outside. Clone, if you have to.
“missing lifetime specifier” is also largely solved by not storing references in structs.
The thing with OOP, particularly how it’s used in GCed languages, is that it’s all about handing references out to wherever and then dealing with the complexity of not knowing who has access to your fields via getters & setters, or by cloning memory whenever it’s modified in asynchronous code.
Rust has quite the opposite mindset. It’s all about tracking where references go. It pushes your code to be very tree-shaped, i.e. references typically¹ only exist between a function and the functions it calls underneath. This is what allows asynchronous code to be safe in Rust, and I would also argue that the tree shape makes code easier to understand, too.
But yeah, some of the patterns you might know from OOP will not work in Rust for that reason. You will likely need to get into a different mindset over time.
Also just in case: We are talking OOP in the sense of the paradigm, i.e. object-oriented.
Just using objects, i.e. data with associated functions/methods, that works completely normal in Rust.
¹) If you genuinely need references that reach outside the tree shape, which is mostly going to be the case, if you work with multiple threads, then you can do so by wrapping your data structures in Arc<Mutex<_>>
or similar. But yeah, when learning, you should try to solve your problems without these. Most programs don’t need them.
Yeah, we onboarded some folks into a Rust project last year and a few months in, they were genuinely surprised when I told them that unwrapping is pretty bad. Granted, they probably did read about it at some point and just forgot, but that isn’t helped by lots of code using .unwrap()
either.
Can still use .is_positive()
, though…
It’s the same thing as ternary, just without the ? :
syntax.
In the case of Rust, you can also omit the type annotation in the vast majority of cases and the compiler will infer it.
It should be noted that theoretically, we don’t know how this external API is implemented. The vast majority of APIs are REST APIs and with REST APIs, there’s a decent chance that you can download an OpenAPI definition from the server which provides the API.
REST APIs are basically APIs which use HTTP(S) for transport and then there’s some specific rules how the API should be designed. Often times, these rules are not strictly followed and people still refer to such an API as “REST”, because they assume that any HTTP API is a REST API. But yeah, similarly the guides you’ll find will likely also work with general HTTP APIs.
Sounds to me like they’re not trying to create a website for now, but rather just process some data, which they can later display in a static webpage.
So, I’m guessing something like this:
+--------+ +---------+ +----------+
| Static | | Their | | External |
| Web |---->| Own |---->| API |
| Page | | Backend | | |
+--------+ +---------+ +----------+
But yes, unless there’s a lot of data to crunch, the design one would usually go for is rather:
+-----------+ +----------+
| *Dynamic* | | External |
| Web |---->| API |
| Page | | |
+-----------+ +----------+
So, the data calculations would happen in the user’s browser. You would still need some hosting for that webpage, but there’s lots of free services to put a simple webpage up.
And yes, when you go with that latter design, then JavaScript would be the typical choice. It’s still possible to do it with Rust, using WebAssembly (e.g. a colleague of mine has built a small statistics webpage which gets data directly from GitHub, using the Leptos framework), but it is definitely the less beaten path.
Having said all that, frankly, fuck the usual way of doing things. If you’re comfortable with Hugo for frontend work, then I think it’s legit to build a little backend to take over the dynamic part. Better to build a useful project and learn something than to get stuck trying to learn the ‘correct’ path of doing it. Especially if you’d rather learn about Rust than JS.
Yeah, the wording is confusing. A long time ago, there was no paid software, there was only software where you got the source code and other software where e.g. it was pre-installed on some hardware and the manufacturer didn’t want to give the source code.
In that time, a whole movement started fighting for software freedom, so they called their software “free”.
It’s mainly horrid, because it means you have to code extremely defensively (or I guess, use a different API).
You can’t rely on
new Date("not a date")
aborting execution of your function by throwing an error. Instead, you have to know that it can produce anInvalid Date
object and check for that. Otherwise a randomNaN
shows up during execution, which is gonna be extremely fun to try to find the source of.I understand that it’s implemented like that partially for historical reasons, partially because it’s often better to display “NaN” rather than nothing, but it’s still the sort of behavior that puts me in a cold sweat, because I should be memorizing all kinds of Best Practices™ before trying to code JavaScript.