#mutable and immutable in rust
Explore tagged Tumblr posts
govindeducation · 4 months ago
Text
youtube
0 notes
aeriavelocity · 2 years ago
Text
Rust is DOOM Eternal
Rust makes you want to learn functional programming just by the fact that variables are immutable by default - and if you want to pass a mutable variable through a function, good luck.
You have to declare "&mut variable" in not only the function call, but also the damn function signature.
Compare that to Python where variables can't even be immutable.
Of course - this is probably a good thing. I'm a devotee of functional programming myself, so I'm biased, but to be fair, I didn't even know what functional programming WAS before I learned Rust.
If C is the Dark Souls of programming, Rust is the DOOM Eternal. (and Python is the Garry's Mod)
56 notes · View notes
squareseal · 9 months ago
Text
RUST: OWNERSHIP & BORROWING
In Rust, we have some concepts that no other lang has; ownership and borrowing are great examples of this. But what are these two features? Well, I'll try to explain:
OWNERSHIP
Imagine you have an apple, and you take this apple to your friend. Now your friend has this apple, and you don't. Basically, this is what Rust does with the variable values when you write something like this:
let a = String::from("example"); let b = a; println!("{}", a);
If you try to run this code, it won't work. But why? Well, basically we just need to read the apple example again, but i gonna explain better why this happens:
Rust has the Copy Trait. This trait makes it possible to copy a variable's value using another variable, just like: let a = 10; let b = a;. In this case, the code won't throw an error because 10 implements the Copy Trait! In summary, the Copy Trait applies to values that are stored in stack memory, and Rust knows their size, making it easier to copy the variable's value. Maybe I'll write about this topic later, but all you need to know for now is this.
Strings aren't part of the Copy Trait; the String value is in Heap memory, so Rust can't automatically know its size, making it impossible to copy. Knowing this, Rust is just going to take the "a" value and transfer it to "b", leaving "a" as an empty variable (just like in the apple example: I no longer own the apple, my friend takes ownership of it).
BORROWING
We learned that a String cannot belong to two different variables at the same time; only one of them can take ownership of it. Well, if you want to make b = a and not lose the value of a, you’re going to need to borrow "a" value to "b". Before the technical explanation, take a look at the example:
I have a pen. I lend this pen to my friend; however, unlike the apple example, my friend will not take ownership of it. He will just borrow it, and I will still be the owner of the pen.
To borrow a value in Rust, you will use & before the variable from which you want to copy the value. See:
let a = String::from("example"); let b = &a; //if you print b, you will see: "example" too println!("{}", a);
Now the code will work because "b" doesn't take ownership of the "a" value; it just point to the "a" value and use it.
We have two possibilities in borrowing:
1- only read the value and point it
2- point to the value and add something to it.
In the example, i used the first possibility; nothing has been changed; "b" just point to "a". If you want to add something to the reference (&a), you need to create a mutable var first (in rust variables are immutable by default), take a look:
fn main() { let mut a = String::from("example"); //"mut" makes "a" mutable modify(&mut a); //calls modify function println!("{}", a); } //function that add a string (str != String) fn modify(new: &mut String){ new.push_str(" cool"); }
Now "a" will be printed like this: "example cool".
I hope it was possible to understand a bit. This is my first post here, and also my first time teaching something like this.
9 notes · View notes
soophia-studies · 2 years ago
Text
100 days of code - day 02
Hi, Today I didn't do much :/
But I did something, I continued my studies in Rust, I'm reading the book that the own Rust documentation recommends, I'm on chapter 3 and read about variables and mutability.
Basically, the variables in Rust follow the same rules as other languages like C, with some syntax changes, but the major difference is that for default variables in Rust are immutable (can't be modified), and if I want to change its value I need to explicitly declare this variable as mutable. That's interesting.
While reading, I realized that I should use more constant variables when they do not need to be redefined, and use more unsigned int when I do not need negative numbers, sometimes I don't do it out of laziness O_o
Also, I learned about shadowing, that allows you to create a new variable with the same name as an existing one, shadowing it, and now the new one will be the valid. This can be useful sometimes.
Writing to this blog helps me to revise what I've studied though the day, I like it.
Today I did not have too much time (my fault), but I'm glad I studied at least a little :)
Sorry for the raw text hahaha, I'll find out ways to make it more pretty, but it can take while 😅, maybe some code snippets ? I just hate that tumblr markdown doesn't accept code blocks, that's unacceptable @staff 😭
> my github
20 notes · View notes
ceausescue · 6 months ago
Text
of course the distinction that actually matters is mutable vs immutable. once you have that explicit reference minding only matters in rust
2 notes · View notes
souhaillaghchimdev · 2 months ago
Text
Learning Rust for Programmers
Tumblr media
Rust is a modern programming language that prioritizes safety, performance, and concurrency. Originally developed by Mozilla, Rust is designed for systems programming but has grown in popularity for a wide range of applications, including web development and game programming. In this post, we’ll explore what makes Rust unique and how you can get started learning it.
Why Learn Rust?
Memory Safety: Rust's ownership model ensures memory safety without the need for a garbage collector.
Performance: Rust offers performance comparable to C and C++, making it suitable for system-level programming.
Concurrency: Built-in support for concurrent programming helps avoid data races.
Growing Ecosystem: A vibrant community and ecosystem with libraries and tools (crates) available via Cargo.
Interoperability: Can easily integrate with existing C and C++ codebases.
Getting Started with Rust
To start programming in Rust, follow these steps:
Install Rust: Use rustup, the Rust toolchain installer. Follow the instructions at rust-lang.org.
Set Up Your Environment: Use an IDE like Visual Studio Code with the Rust extension for syntax highlighting and IntelliSense.
Create a New Project: Use Cargo, Rust’s package manager and build system.
Basic Syntax and Features
Here are some fundamental concepts in Rust:
Variables and Mutability
fn main() { let x = 5; // immutable let mut y = 10; // mutable y += 5; println!("x: {}, y: {}", x, y); }
Control Flow
fn main() { let number = 6; if number % 2 == 0 { println!("Even"); } else { println!("Odd"); } }
Functions
fn add(a: i32, b: i32) -> i32 { a + b } fn main() { let result = add(5, 3); println!("Result: {}", result); }
Key Concepts in Rust
Ownership: Each value in Rust has a single owner, preventing data races.
Borrowing: References allow functions to access data without taking ownership.
Lifetime: Rust tracks how long references are valid to prevent dangling references.
Learning Resources
The Rust Programming Language: The official book, available for free online.
Rust by Example: Hands-on tutorials to learn Rust through examples.
Exercism: Practice Rust coding exercises with mentorship.
Rustlings: Small exercises to get you familiar with Rust syntax and concepts.
Best Practices
Write clear and concise code with meaningful variable names.
Use the Rust compiler's warnings to improve code quality.
Leverage Cargo for dependency management and building projects.
Participate in the Rust community through forums, Discord, or local meetups.
Conclusion
Learning Rust can open doors to systems programming, high-performance applications, and much more. Its focus on safety and concurrency makes it an ideal choice for modern development. Dive into Rust today, and start building efficient and robust applications!
0 notes
this-week-in-rust · 2 years ago
Text
This Week in Rust 476
Hello and welcome to another issue of This Week in Rust! Rust is a programming language empowering everyone to build reliable and efficient software. This is a weekly summary of its progress and community. Want something mentioned? Tag us at @ThisWeekInRust on Twitter or @ThisWeekinRust on mastodon.social, or send us a pull request. Want to get involved? We love contributions.
This Week in Rust is openly developed on GitHub. If you find any errors in this week's issue, please submit a PR.
Updates from Rust Community
Foundation
A Q4 Recap & 2022 Reflection from Rebecca Rumbul
Project/Tooling Updates
rust-analyzer changelog #162
fltk-rs in 2022
shuttle - Release v0.8.0
This Week in Fyrox
gitoxide - The year in retrospective, and what's to come
The AeroRust community - 3 years birthday (and the roadmap for 2023)
SeaQuery 0.28.0 - A dynamic query builder for SeaORM
Databend 2022 Recap
Observations/Thoughts
State Machines III: Type States
Rust — vim — code completion
How to Test
Embedded Rust and Embassy: DMA Controllers
Parsing TFTP in Rust
Rustdoc JSON in 2022
From PHP to Rust: Migrating a REST API between these two languages. (Part I)
React + Rust + Wasm: Play an Animated 3D Model
Open Source Grindset Explained (with a Rust example)
Rust Walkthroughs
Building a Simple DB in Rust - Part 1
Microservices with Rust and WASM using Fermyon
Compiling Brainfuck code - Part 4: A Static Compiler
Rusty Circuit Breaker 🦀
Zero-dependency random number generation in Rust
Miscellaneous
Rust 101: an open-source university course
[video] If Rust Compiles, It WORKS (Testing not needed 📚)
[video] Introduction to Axum
[video] Ergonomic APIs for hard problems - Raph Levien
Crate of the Week
This week's crate is Sniffnet, a cross-platform GUI application to analyze your network traffic.
Thanks to Gyuly Vgc for the suggestion!
Please submit your suggestions and votes for next week!
Call for Participation
Always wanted to contribute to open-source projects but did not know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!
No calls for participation this week. Keep an eye out for more places to contribute next week!
If you are a Rust project owner and are looking for contributors, please submit tasks here.
Updates from the Rust Project
291 pull requests were merged in the last week
CFI: monomorphize transparent ADTs before typeid
account for match expr in single line
account for macros in const generics
account for multiple multiline spans with empty padding
adjust message on non-unwinding panic
allow trait method paths to satisfy const Fn bounds
always suggest as MachineApplicable in recover_intersection_pat
detect diff markers in the parser
detect when method call on LHS might be shadowed
dont use --merge-base during bootstrap formatting subcommand
emit fewer errors on invalid #[repr(transparent)] on enum
encode spans relative to the enclosing item -- enable on nightly
error parsing lifetime following by Sized and message + between them
fix confusing diagnostic when attempting to implementing trait for tuple
format only modified files
on unsized locals with explicit types suggest &
only deduplicate stack traces for good path bugs
give the correct track-caller location with MIR inlining
implement allow-by-default multiple_supertrait_upcastable lint
improve heuristics whether format_args string is a source literal
make trait/impl where clause mismatch on region error a bit more actionable
merge multiple mutable borrows of immutable binding errors
partially fix explicit_outlives_requirements lint in macros
properly calculate best failure in macro matching
provide a better error and a suggestion for Fn traits with lifetime params
provide local extern function arg names
recover fn keyword as Fn trait in bounds
remove unreasonable help message for auto trait
silence knock-down errors on [type error] bindings
suggest Pin::as_mut when encountering borrow error
suggest impl Iterator when possible for _ return type
suggest rewriting a malformed hex literal if we expect a float
suppress errors due to TypeError not coercing with inference variables
trim more paths in obligation types
miri: cargo-miri: use rustc to determine the output filename
miri: handle unknown targets more gracefully
miri: simplify path joining code a bit
miri: support using a JSON target file
miri: tweaks to retag diagnostic handling
use some more const_eval_select in pointer methods for compile times
more inference-friendly API for lazy
more verbose Debug implementation of std::process:Command
add #[inline] markers to once_cell methods
unify id-based thread parking implementations
available_parallelism:gracefully handle zero value cfs_period_us
catch panics/unwinding in destruction of thread-locals
cargo: asymmetric tokens
cargo: reasons for rebuilding
clippy: fix false negative in needless_return
clippy: fix match_single_binding suggestion introducing an extra semicolon
clippy: move mutex_atomic to restriction
rust-analyzer: derive Hash
rust-analyzer: enum variant discriminants hints
rust-analyzer: diagnose private assoc item accesses
rust-analyzer: diagnose private field accesses
rust-analyzer: implement yeeting
rust-analyzer: fall back to inaccessible associated functions and constants if no visible resolutions are found
rust-analyzer: improve exit point highlighting for for and while loops in tail position
rust-analyzer: merge multiple intersecting ranges
rust-analyzer: prefix prelude items whose name collides in current scope
rust-analyzer: type check unstable try{} blocks
rust-analyzer: support multi-character punct tokens in MBE
rust-analyzer: write down adjustments introduced by binary operators
Rust Compiler Performance Triage
Fairly busy week with some massive performance improvements at the expense of some significant albeit smaller regressions. The main wins came in a long-standing PR from @cjgillot to enable encoding spans in metadata relative to their enclosing item. This causes more work in full compilation which causes some regressions up to 5% but can lead to very large wins in incremental compilation scenarios (up to ~70%). For example, the clap crate compiles 68% faster after a small 1 line change than it did previously.
Triage done by @rylev. Revision range: b38a6d..b43596
Summary:
(instructions:u) mean range count Regressions ❌ (primary) 1.6% [0.3%, 4.6%] 97 Regressions ❌ (secondary) 1.8% [0.2%, 7.6%] 60 Improvements ✅ (primary) -9.7% [-68.7%, -0.2%] 53 Improvements ✅ (secondary) -1.7% [-15.3%, -0.1%] 62 All ❌✅ (primary) -2.4% [-68.7%, 4.6%] 150
1 Regressions, 1 Improvements, 4 Mixed; 1 of them in rollups 47 artifact comparisons made in total
Full report here
Approved RFCs
Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:
No RFCs were approved this week.
Final Comment Period
Every week, the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.
RFCs
No RFCs entered Final Comment Period this week.
Tracking Issues & PRs
[disposition: merge] Only include stable lints in rustdoc::all group
[disposition: merge] Don't derive Debug for OnceWith & RepeatWith
[disposition: merge] PhantomData layout guarantees
[disposition: merge] Add O(1) Vec -> VecDeque conversion guarantee
[disposition: merge] Stabilize ::{core,std}::pin::pin!
[disposition: merge] Stabilize main_separator_str
[disposition: merge] Loosen the bound on the Debug implementation of Weak.
New and Updated RFCs
No New or Updated RFCs were created this week.
Call for Testing
An important step for RFC implementation is for people to experiment with the implementation and give feedback, especially before stabilization. The following RFCs would benefit from user testing before moving forward:
No RFCs issued a call for testing this week.
If you are a feature implementer and would like your RFC to appear on the above list, add the new call-for-testing label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature need testing.
Upcoming Events
Rusty Events between 2023-01-04 - 2023-02-01 🦀
Virtual
2023-01-04 | Virtual (Indianapolis, IN, US) | Indy Rust
Indy.rs - with Social Distancing
2023-01-04 | Virtual (Stuttgart, DE) | Rust Community Stuttgart
Rust-Meetup
2023-01-05 | Virtual (Charlottesville, VA, US) | Charlottesville Rust Meetup
Part 2: Exploring USB with Rust
2023-01-10 | Virtual (Dallas, TX, US) | Dallas Rust
Second Tuesday
2023-01-11 | Virtual (Boulder, CO, US) | Boulder Elixir and Rust
Monthly Meetup
2023-01-12 | Virtual (San Francisco, CA, US; Stockholm, SE; New York, NY US) | Microsoft Reactor San Francisco | Microsoft Reactor New York
Crack code interview problems in Rust - Ep. 1 | Stockholm Mirror | New York Mirror
2023-01-12 | Virtual (Nürnberg, DE) | Rust Nuremberg
Rust Nürnberg online
2023-01-14 | Virtual | Rust GameDev
Rust GameDev Monthly Meetup
2023-01-16 | Virtual (San Francisco, CA, US; São Paulo, BR; New York, NY, US) | Microsoft Reactor San Francisco and Microsoft Reactor São Paulo and Microsoft Reactor New York
Primeros pasos con Rust - Qué es y Configuración el entorno de desarrollo | São Paulo Mirror | New York Mirror
2023-01-17 | Virtual (Berlin, DE) | OpenTechSchool Berlin
Rust Hack and Learn
2023-01-17 | Virtual (San Francisco, CA, US; São Paulo, BR, New York, NY, US) | Microsoft Reactor San Francisco and Microsoft Reactor São Paulo and Microsoft Reactor New York
Primeros pasos con Rust - Creación del primer programa de Rust | *São Paulo Mirror | New York Mirror
2023-01-17 | Virtual (Washington, DC, US) | Rust DC
Mid-month Rustful
2023-01-18 | Virtual (San Francisco, CA, US; São Paulo, BR; New York, NY US) | Microsoft Reactor San Francisco and Microsoft Reactor São Paulo and Microsoft Reactor New York
Primeros pasos con Rust: QA y horas de comunidad | Sao Paulo Mirror | New York Mirror
2023-01-18 | Virtual (Vancouver, BC, CA) | Vancouver Rust
Rust Study/Hack/Hang-out
2023-01-26 | Virtual (Charlottesville, VA, US) | Charlottesville Rust Meetup
Rust Lightning Talks!
2023-01-31 | Virtual (Dallas, TX, US) | Dallas Rust
Last Tuesday
2023-02-01 | Virtual (Indianapolis, IN, US) | Indy Rust
Indy.rs - with Social Distancing
Asia
2023-01-15 | Tokyo, JP | Tokyo Rust Meetup
Property-Based Testing in Rust
Europe
2023-01-12 | Enschede, NL | Dutch Rust Meetup
Rust Meetup - Subject TBA
2023-01-20 | Stuttgart, DE | Rust Community Stuttgart
OnSite Meeting
2023-01-25 | Paris, FR | Rust Paris
Rust Paris meetup #55
North America
2023-01-05 | Lehi, UT, US | Utah Rust
Lightning Talks 'n' Chill (a.k.a. Show & Tell), with Pizza!
2023-01-09 | Minneapolis, MN, US | Minneapolis Rust Meetup
Happy Hour and Beginner Embedded Rust Hacking Session (#2!)
2023-01-11 | Austin, TX, US | Rust ATX
Rust Lunch
2023-01-17 | San Francisco, CA, US | San Francisco Rust Study Group
Rust Hacking in Person
2023-01-26 | Copenhagen, DK | Copenhagen Rust group
Rust Hack Night #32
2023-01-26 | Lehi, UT, US | Utah Rust
Building a Rust Playground with WASM and Lane and Food!
If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.
Jobs
Please see the latest Who's Hiring thread on r/rust
Quote of the Week
You haven’t “fooled” rustc, you are using unsafe code. Unsafe code means that all you can do is fool yourself.
– Frank Steffahn on rust-users
Thanks to Quine Dot for the suggestion!
Please submit quotes and vote for next week!
This Week in Rust is edited by: nellshamrell, llogiq, cdmistman, ericseppanen, extrawurst, andrewpollack, U007D, kolharsam, joelmarcey, mariannegoldin, bennyvasquez.
Email list hosting is sponsored by The Rust Foundation
Discuss on r/rust
0 notes
itsjunetime · 2 years ago
Text
Tumblr media
my specific use-case was in writing a character management system (specifically for the ttrpg HEART: The City Beneath - it's really fun, everyone should check it out), for managing items in the character's inventory/equipment. in this system, there are a lot of classes, and each class has some items you can pick from to put in your inventory when you create a character, and i wanted the list of classes to always be easily accessible in the code so that the user could always view a class if they wanted to reference something about it, or change their class, or make a new character and pick a class, etc.
so there were a few clear options for achieving this goal:
a manager struct of some sort that would manage all the 'reference' data for the system (all the classes, callings, beats, fallout, etc, that comes with the ttrpg system) and would instantiate all that data at runtime - this seemed fine, but would require me to pass the manager struct around to every fn/struct/etc that wanted any data from it at all, and that seemed like it would be really annoying to do.
initializing all that data behind a OnceLock (along with a global wrapper function to ensure I always got valid data when I requested it and didn't have to deal with unwrapping the OnceLock's data) - this seemed slightly more appealing, but also required initializing at runtime, which wasn't ideal, and would require more wrapper functions to handle initialization of each class and calling and such, and a lot of nested structures to store all that data together, and that seemed like more code than i wanted to write as well.
making them all as individual items at compile-time! which is what i ended up doing, of course. that way, i could just put all the classes together into a &'static [] and iterate over them wherever i needed to. no complicated passing around of data, no wrapper initialization functions, no possible twice-initialization, etc. (also technically this would speed up startup, but that effect was probably negligible) however, i did want users to be able to copy items from inside a class into their inventory and edit them however they pleased, and that's how i ran into this problem, and that's why this is the solution i came up with.
so the actual struct i'm working with ended up being like so:
#[derive(Clone)] pub struct Item< S: 'static + AsRef<str>, V: 'static + AsRef<[&'static Tag]> > { pub name: S, pub skill: ItemSkill, pub die: DieLevel, pub tags: V, pub notes: S }
and i implemented the helper function like so:
impl Item<&'static str, &'static [&'static Tag]> { pub fn owned(&self) -> Item<String, Vec<&'static Tag>> { Item { name: self.name.to_owned(), skill: self.skill.clone(), die: self.die, tags: self.tags.to_vec(), notes: self.notes.to_owned() } } }
(i didn't directly impl ToOwned 'cause Clone implicitly impls ToOwned, and i needed Clone for something else, i can't remember)
so now the user can store their class as a &'static Class, (and the class will store the item as an Item<&'static str, &'static [&'static Tag]>) and grab an item from it with just self.inventory.push(self.class.item.owned()) and then edit it to their heart's content! you can also see here how it wouldn't really make sense to have an Item<&'a str, &'a [&'static Tag]> where 'a is not 'static - where would we be referencing data from? the item is supposed to only be owned by the class or character, and thus needs to either be 'static and immutable or owned and mutable, and a non-'static lifetime doesn't fulfill either of those requirements.
i hope that helps, and obviously i love talking about rust so feel free to ask any other questions :)
rust structs you can instantiate at compiletime or runtime
i ran into a problem recently where I wanted a struct in rust that I could create at runtime or compile time, but it needed to own data that was traditionally allocated on the heap (String, Vec, etc), and that's not possible to instantiate at compile time. rust has compile-time analogs for those (&'static str, &'static []), but those can't be created at runtime (yes, I know about Box::leak and mem::transmute, but that's evil).
the initial clunky but seemingly rusty solution: enums! Just use something like
StringWrapper { String(String), StaticStr(&'static str) }
but that seemed clunky and would require a lot of destructuring that i wouldn't be the biggest fan of writing (also, yes, this is basically a Cow, but i felt this would be better for visualization)
maybe a wrapper struct around a StringWrapper enum, i thought? that way we can impl Display and such to make it a bit easier on us? no, then we'd still have to do a lot of weird destructuring and such whenever we wanted to try to edit the data in it, and that meant that we could still have an invalid state (have a StaticStr where we expected a String, etc), and we don't want that (also still a problem with a Cow)
what about just making it store a reference? e.g.
struct Person<'f> { name: &'f str, age: usize, // sky's the limit attributes: &'f [&'f str] }
this way, we could create it at compile-time, and it would be a Person<'static>, so it could live forever (as we want). Then we could also create it at runtime. but the caveat is that I want to OWN the data in it - nothing else will be holding onto that name or those attributes, so we can't hold them as references to something else.
the solution (that i just learned about, which is why i'm sharing this): the 'static bound! don't we already have that, you may say? not exactly - here's what I'm talking about
struct Person< S: 'static + AsRef<str>, A: 'static + AsRef<[S]>, > { name: S, age: usize, attributes: A }
this way, we can have both a Person<String, Vec<String>> and Person<&'static str, &'static [&'static str]>, which fulfills all our use cases! the 'static bound binds the parameter itself, as opposed to the 'f bound earlier, which only bound the lifetime of the references (preventing owned data).
and, with the AsRef bounds, we can do something like the following:
impl<S, A> ToOwned for Person<S, A> where S: 'static + AsRef<str>, A: 'static + AsRef<[S]> { fn to_owned(&self) -> Person<String, Vec<String>> { Person { name: self.name.as_ref().to_owned(), age: self.age, attributes: self.attributes.iter() .map(|a| a.as_ref().to_owned()) .collect() } } }
(some of that syntax may be slightly off, but whatever, you get the point) - this'll allow us to easily convert any Person instance to a Person which we can modify easily (since a Person<&'static str, &'static [&'static str]> was probably created at compile-time and is thus immutable)
now, to be fair, we could just remove the 'static bounds and make a struct like the following:
struct Person<S: AsRef<str>, A: AsRef<[S]>> { ... }
and it would work everywhere our old struct (with the 'static bounds) would, and more! isn't that cool?
no! at least, i don't think so. making it impossible to construct invalid states is very important imo, and (in my use of this struct, at least), it would be an invalid state to instantiate this struct with non-'static lifetimes (e.g. where those parameters reference something else). maybe that'll change in the future as the uses of this struct change, but maybe not.
also check out Code and Bitters' article on the same topic, which talks about similar stuff but more in the context of thread spawning and how they ensure lifetime bounds are valid
18 notes · View notes
cerulity · 3 years ago
Text
“you fucked up. fix it now.” - other languages
“you fucked up, you fucker. here you set yourself up to fuck up and there you started fucking up, making this over here fuck up as well. now i have to tell you how you don’t fuck up again because you’re too much of an idiot to comprehend this, clumsy bitch” - rusts borrow checker
7 notes · View notes
nil-ebooks · 3 years ago
Text
that feeling when you're thinking about parallel usage of resources and how to prevent (ideally at compile-time) threads from reading and writing to them at the same time, like two people writing over each other in a shared document or someone writing over their own text while you're trying to read it, and the first thing that comes to mind, even though you're writing in C++, is the model of "either as many immutable borrows as you want, or exactly one mutable borrow" from Rust
Tumblr media
2 notes · View notes
eightyonekilograms · 5 years ago
Text
@tototavros:
what else do you like about C#?
It’s popular and illustrative to describe C# as “Java done correctly”. Java gets a lot of deserved hate for its many shortcomings, but it does do a lot of things right if you’re in an enterprise environment where legibility, maintainability, and “programming in the large” are vital.
C# basically starts from Java, but fixes all the things that suck about it:
C# moves way faster. Especially now that it’s open-source and community-developed, there’s a major release with handy features every 18 months or so, and the upgrade cycle is actually decent. 
C# has real reified generics, not Java’s half-assed compile-time auto-unboxing.
C# has LINQ (a.k.a. the other thing besides JavaScript that introduced enterprise developers to functional programming and blew their minds). Java did eventually get its own version of LINQ, but it sucks and people don’t seem to use it much.
C# has async/await. Again, I think Java either got this recently or is getting it soon, but at Java’s usual pace it will be a long time before anyone uses it.
Immutable data types are much easier to work with in C#
No checked exceptions. My god what a mistake checked exceptions were. (I mean, exceptions in general were a mistake, but if you have to have them, at least don’t do them the way Java did)
Related to the above, even though C# started out as a Java clone with exceptions, preference for mutable data, it is rapidly evolving to be a lot more functional. In another few years it may be able to excise nulls completely from the language, at least if you’re starting a fresh codebase.
C# has value types (i.e. user-defined types that live on the stack), Java does not. Funny/tragic story about this: apparently there was a particular Minecraft version that had a huge performance regression, and it was traced down to a project-wide replacement of (int x, int y, int z) calls with a new Point data type, but since integers live on the stack and user-defined types in Java have to be on the heap, this made almost every function call that previously could be in registers require a memory lookup. Wouldn’t have happened in C#.
Anyway, C# isn’t the sexiest language, but I find it’s a very dependable workhorse. When I want to play around I’ll use Rust or Ocaml or Python, but when I want to knuckle down and get work done I use C#.
13 notes · View notes
mansoorahmed-stuff · 4 years ago
Link
Raw Pointers Unsafe Rust has two new kinds called raw pointers, which are similar to references. They may be immutable or mutable and can be written as: *const T (Immutable) *mut T (Mutable) Note: Asterisk “*” is not a dereferencing operator, its part of type name. Let’s know how to make an immutable and mutable ... Read more
0 notes
twocubes · 3 years ago
Text
well, i was appending a slice of the front of the string to the back of the string, right
if you borrow that slice (as mutable or immutable) this conflicts with the simultaneous mutable borrow of the string itself
split_at_mut gets close to what i'd want, in that it would split a mutable string into two mutable string slices. however, this means that I wouldn't be able to append things to the end of the string
now, the rustonomicon talks about the implementation of split_at_mut, and why it uses an unsafe block there; this, yknow, given that i'm only on chapter 8 of the rust book (i know basically nothing lol) suggests that using an unsafe block for this sort of thing might be, like, defensible at least.
now... of course, this would all be easier if i just used extend_from_within, which does exactly the thing I want, but, like...
i mean i'd have to install nightly and that's sooo much effffort....
i could also like, not do this stupid thing in-place and instead create a new string, which is probably what the exercise intended for you to do, or possibly copy the consonants into a different buffer string, but... eh
Tumblr media
doing homework like a stupid idiot
51 notes · View notes
khuey · 8 years ago
Text
Lazy Initialization in Rust
Today I published lazy-init, a Rust crate that scratches an itch I’ve had for a while.  lazy-init is designed for when:
you want to do some work (a computation, disk I/O, etc) lazily,
the product of this work is immutable once it is created,
and you want to share this data across threads.
Rust has a good built-in solution if you only require #s 1 and 2: the Option type.  But requirement #3 makes things much harder.  Both of the built-in, thread-safe primitives for interior mutability have significant drawbacks, as we’ll see later.  But first, the API!
impl<T> Lazy<T> {    /// Construct a new, uninitialized `Lazy<T>`.    pub fn new() -> Lazy<T>;
   /// Get a reference to the contained value, invoking `f` to create it    /// if the `Lazy<T>` is uninitialized.  It is guaranteed that if multiple    /// calls to `get_or_create` race, only one will invoke its closure, and    /// every call will receive a reference to the newly created value.    ///    /// The value stored in the `Lazy<T>` is immutable after the closure returns    /// it, so think carefully about what you want to put inside!    pub fn get_or_create<'a, F>(&'a self, f: F) -> &'a T        where F: FnOnce() -> T;
   /// Get a reference to the contained value, returning `Some(ref)` if the    /// `Lazy<T>` has been initialized or `None` if it has not.  It is    /// guaranteed that if a reference is returned it is to the value inside    /// the `Lazy<T>`.    pub fn get<'a>(&'a self) -> Option<&'a T>; }
There’s a constructor and two methods, one to get an existing value and another to get_or_create the value if it does not already exist.  get_or_create will ensure that the closure is invoked only once even if multiple threads race to call it on an uninitialized Lazy<T>.  Simple enough, right?
Lazy<T> is actually a degenerate version of a more generic LazyTransform<T, U> included in the crate which is initialized with a T that is later converted to a U.  Lazy<Foo> is essentially LazyTransform<(), Foo>.  For simplicity, I’ll refer to them interchangeably.
Rust provides two primitives for threadsafe interior mutability, std::sync::Mutex and std::sync::RwLock.  Lazy<T> is better than both of them because:
Unlike the locking types, Lazy<T> guarantees immutability after the value is created. This also means you can hold an immutable reference to the interior value without having to hold the lock.
Unlike std::sync::Mutex, Lazy<T> does not exclude multiple readers after the value is created, and a panic while reading the value will not poison the Lazy<T>.
Lazy<T> is at least no worse in performance compared to either locking type, and likely much better.
The first two are self-explanatory, so lets dive into the third one.  On Unix systems, std::sync::Mutex and std::sync::RwLock boil down to pthread_mutex_t and pthread_rwlock_init respectively.  Lazy<T> meanwhile, becomes a single std::sync::Mutex and a std::sync::atomic::AtomicBool.
The (slightly simplified, to elide details not relevant to synchronization) code inside get_or_create looks like
if !self.initialized.load(Ordering::Acquire) {     // We *may* not be initialized. We have to block to be certain.     let _lock = self.lock.lock().unwrap();     if !self.initialized.load(Ordering::Relaxed) {         // Ok, we're definitely uninitialized.         // Safe to fiddle with the UnsafeCell now, because we're locked,         // and there can't be any outstanding references.         let value = unsafe { &mut *self.value.get() };         *value = f(value);         self.initialized.store(true, Ordering::Release);     } else {         // We raced, and someone else initialized us. We can fall         // through now.     } }
// We're initialized, our value is immutable, no synchronization needed. *self.value.get()
Where self.value is an UnsafeCell.  This is a standard double-checked locking pattern.  Jeff Preshing has a great explanation of how this pattern actually works, and why the various Ordering values are what they are here.  The simple explanation is that the AtomicBool::store call with Ordering::Release after the closure synchronizes with the AtomicBool::load call with Ordering::Acquire at the top of the function.  So if a thread sees the write to self.initialized it must also see the write to self.value.  If a thread doesn’t see that write, it grabs the lock. Memory accesses cannot be reordered across a lock acquisition or release (because, internally, a mutex uses semantics that are at least as strong as the acquire/release semantics mentioned before) so self.initialized is now a definitive source of truth.  The lock also ensures that only one thread invokes the closure no matter how many threads are racing.
The code inside get is even simpler
if self.initialized.load(Ordering::Acquire) {     // We're initialized, our value is immutable, no synchronization needed.     Some(&*self.value.get()) } else {     None }
We use the same acquire semantics as before to check if we are initialized.  You’ll notice that we don’t have to acquire a lock at all here.  Even in get_or_create, we only have to acquire the lock if self.initialized appears to be false.  Once that write propagates to all threads, Lazy<T> allows lock-free access to the underlying value at the cost of a single load-acquire check.
Best of all, with x86′s strong memory model, every load from memory has acquire semantics.  The atomic operations here really just tell the compiler not to do anything crazy with reordering.  This is not true on other architectures with weaker memory models.  On ARM, for instance, getting load-acquire semantics does require a DMB instruction.  Peter Sewell maintains a list of what the various atomic orderings map to on different architectures.
Depending on your pthreads implementation and architecture the performance of pthread_mutex_t and pthread_rwlock_t can vary wildly.  But as any sort of read-write lock needs to, at the bare minimum, both ensure there are no outstanding writers and increment the read count, a pthread_rwlock_t is never going to be any faster than the single load-acquire that Lazy<T> performs.
I hope others find this crate useful.  Bug reports and pull requests are always welcome!
EDIT: Thanks to Huon for pointing out that I needed to bound the contained type with Sync
1 note · View note
holytheoristtastemaker · 5 years ago
Link
Tumblr media
 Image from Real Life Programming
When we creating a struct in Rust, we use the struct keyword firstly. After that, the struct name is coming.
struct OrderItem { // struct body }
In the above example, we've created a struct called Basket. This will store order information. For example, this is a part of an e-commerce website.
Actually, we haven't completed it yet. This struct should have fields. Because when you add a product to the basket, it actually adds other product specific information. The product name, quantity, price, etc. Let's add these fields to our struct.
struct OrderItem { product_name: String, price: f64, quantity: f64, user_id: u32 }
It looks good. Now, we have some thoughts about our struct. It will store a product name, price, quantity, and user id.
Can't We Do That Without Structs?
Of course, you can but. Let's say you have too many arguments and you pass them to a function. It should be annoying for a developer. Of course, structs didn't implement only for this approach.
Initializing a Struct
Now, we have a struct, but we don't know how we can initialize it. How we can create an instance from it? Let's see
let product_name = String::from("Algorithms"); let order = OrderItem { product_name: product_name, price: 60.0, quantity: 1.0, user_id: 12851 };
We initialized our struct this way. As you see, we use key-value pairs. In the above example, we created an immutable struct. This means, once you create an immutable struct, you can't change it later. To make it mutable, use mut keyword
let mut order = OrderItem { product_name: product_name, price: 60.0, quantity: 1.0, user_id: 12851 };
You can't make fields mutable in a struct. Rust doesn't allows to you do that. Instead of that, make structs mutable.
Initializing Fields with Shorthand
When your fields and variable names are the same, you can initialize fields without key-pair notation. Because variable names and field names are exactly the same. Let's see how we can do that;
let product_name = String::from("Algorithms"); let price: u64 = 60.0; let quantity: u64 = 1.0; let order = OrderItem { product_name: product_name, price, quantity, user_id: 12851 };
The Struct Update Syntax
You can update your struct using the other one;
let order2 = OrderItem { product_name: String::from("Rust by Example"), ..order }; println!("Order detail {:?}", order2);
In the above example, you update your struct's fields using first order. It’s often useful to create a new instance of a struct that uses most of an old instance’s values but changes some. If you used JavaScript before, you should be familiar with this syntax.
Example Usage of Structs
We know how we can create a struct and initialize it. We also know about functions. Let's use them together.
fn build_order_item(product_name: String, price: f64, quantity: f64, user_id: u32) -> OrderItem { OrderItem { product_name, price, quantity, user_id } }
In the above example, we created a function called build_order_item. It takes four parameters. It returns OrderItem. Let's use it :)
let mut basket : Vec<&OrderItem> = Vec::new(); let product_name = String::from("Rust by Example"); let order_item = build_order_item(product_name, 45.0, 2.0, 19241); basket.push(&order_item);
We've created a vector. I won't talk about this for now. But this is a kind of list. C# or Java programmers know that. In C#, you can create a list like that;
List<OrderItem> basket = new List<OrderItem>(); basket.add(/* your code*/);
Okay, we create a function for example, and it returns an OrderItem. When we get a value from this function, we add it to the basket.
Tuple Structs
As we mentioned before, you can also create tuple structs in Rust. Let's see
struct Color(i32, i32, i32);
And we can use it like that;
let rgb_color = Color(250, 128, 114); // Salmon
As you remember, we discussed tuples in A Trip to Data Types in Rust section. So, we know how we can access a tuple value.
println!("First color is {}", rgb_color.0);
Or we can destruct our struct;
let Color(red, green, blue) = Color(250, 128, 114); println!("Red is {} Green is {} Blue is {}", red, green, blue);
Unit Like Structs
You can also structs that don’t have any fields. We called these types of structs as unit-like structs. Unit-like structs can be useful in situations in which you need to implement a trait on some type but don’t have any data that you want to store in the type itself.
A library may ask you to create a structure that implements a certain trait to handle events. If you don’t have any data you need to store in the structure, you can create a unit-like struct.
We'll it later.
struct User;
And we can use it like that;
fn main() { let user = User; }
That's all for now. Let me know if there is something wrong.
0 notes
repmywind02199 · 6 years ago
Text
What lies ahead for Python, Java, Go, C#, Kotlin, and Rust
What lies ahead for Python, Java, Go, C#, Kotlin, and Rust
O’Reilly authors and instructors explore the near-term future of popular and growing programming languages.
Change is the only constant in the technology world, and programming languages are no exception. Competition among languages has led to improvements across the board. Established players like Java have added major features, while upstart languages like Go and Rust look to improve packaging and exception handling to add “fit and finish” to their ecosystems. As we enter 2019, we asked some of our O’Reilly authors and training course instructors for their thoughts on what’s in store for established players and fast-growing languages.
Python
Python's incredible growth over the past decade shows no signs of slowing. In addition to maintaining its position as the most popular introductory language for students, scientists, and knowledge workers, Python will continue its widespread adoption in web development, DevOps, data analysis, and machine learning circles. Matt Harrison, who runs the Python and data science training and consulting company MetaSnake (and is a frequent instructor of Python courses on the O'Reilly online learning platform), offers his take:
Python has traditionally been more focused on small data, but I think that as other tools that enable big data—such as Dask and flexible Python solutions on top of Kubernetes—continue to improve, we will see Python dominate in big data as well. I’m continuing to see large companies that have traditionally used Java or proprietary languages replacing those with Python.
In 2019, the Python community will cohere around Python 3, as maintenance for Python 2 will end on January 1, 2020. And it will do so under a new governance model, as Guido van Rossum, the creator of the language, stepped down as "benevolent dictator for life" in July 2018. After months of debate, the community recently voted to go forward under a steering council model.
Java
The release of Java 11 in September introduced major new features, such as nest-based access controls, which eliminate the need for compilers to insert bridge methods; dynamic class-file constraints; the new HttpClient, which removes the need for an external dependency when writing applications to communicate with web services; and the adoption of the Unicode 10 standard for localization. As Ben Evans, coauthor of Optimizing Java and Java in a Nutshell, explains: "Java has adapted well to new frontiers such as cloud and microservices. Java 8 had problems with microservice startup times, but Java 11 solves that problem. It's a much better environment for developing new microservice applications from scratch."
Looking ahead to future versions of Java, Evans says that bringing value types to Java is a major current project. Value types are intended to be a third form of data type (to complement the existing primitive types and object references), which Evans sees as one way to future-proof the JVM, calling it one of the major changes to the language that "will change the character of Java development in fundamental ways."
Go
The Go team is working on a prototype command called vgo. Currently, when you install third-party libraries with the go get tool, the latest available version of a package is retrieved, even if it includes incompatibilities that can break your code. The vgo tool will “help you manage the versions of the various packages your app requires, without introducing conflicts,” explains Jay McGavren, author of the forthcoming Head First Go.
The late 2018 release of Go 1.11 provided experimental support for compiling Go to WebAssembly, a binary format for code that can run in a web browser. “This promises to be faster and more efficient than JavaScript,” McGavren says. “And it’s supported by all the major browsers. The ability to make apps using Go that can run inside the browser offers new possibilities that I’m excited to explore.”
C#
The upcoming release of C# 8.0 will include a number of new features, notably nullable reference types. Andrew Stellman, coauthor of Head First C#, calls it “code safety for the rest of us,” as it causes the compiler to give warnings any time a reference type variable can potentially be assigned a null value, thus “giving developers a new way to write safer code.”
Stellman notes that another upcoming feature that has C# developers talking is asynchronous streams—foreach await is a new version of the familiar foreach keyword that will consume an asynchronous stream, represented by the IAsyncEnumerable interface, automatically pausing the loop until the next value is available. Other expected new features include an asynchronous version of yield return and asynchronous disposables.
Kotlin
Kotlin's latest release (Kotlin 1.3, released in late October 2018) saw coroutines—lightweight threads that allow code to scale-out efficiently—graduated from experimental to stable status. Coroutines enable the creation of multiple pieces of code that can run asynchronously; for example, you can launch a background job (such as reading data from an external server) without the rest of your code having to wait for the job to complete before doing anything else. “This gives users a more fluid experience, and it also makes your application more scalable,” says David Griffiths, coauthor (along with Dawn Griffiths) of the forthcoming Head First Kotlin. Coroutines are also at the heart of Ktor, a new framework for building asynchronous servers and clients in connected systems using the Kotlin language.
Looking ahead to 2019, Kotlin is “likely to see significant use beyond the Java world,” says Griffiths. “It is proving to be an excellent language for library builders. If you have an application that performs some complex financial calculation on the server, Kotlin allows you to convert that server code into a Kotlin library which can run on both the server and the client.” Also anticipated for Kotlin, according to Griffiths, are first-class immutability support for the language and features that reduce or eliminate shared mutable state in concurrent code.
Rust
Rust 2018, released in December, was the first major new edition of the language since Rust 1.0 in 2015. Rust 2018 introduced async (asynchronous) functions and await expressions in order to make Rust more effective for writing network servers and other I/O-intensive applications. “An async function can use an await expression to suspend its execution until the data it needs becomes available,” says Jim Blandy, coauthor of Programming Rust. “Rust has supported asynchronous programming in one form or another for a long time,” he notes, “but async functions provide a syntax for this sort of code that is a major improvement over what Rust has had before.”
Another in-the-works enhancement to Rust is improvement of Rust’s existing support of the WebAssembly standard for running code as part of a web page. “This will make it easier to integrate WebAssembly packages written in Rust with the existing JavaScript ecosystem, ” says Blandy.
What's next?
“What’s next?” is the question that's always on every programmer’s mind. In 2019 and beyond, language design will continue to look for new ways to help programmers manage complexity and abstraction, as applications and data grow ever larger and become more crucial to the modern enterprise.
Continue reading What lies ahead for Python, Java, Go, C#, Kotlin, and Rust.
https://oreil.ly/2RNBJAj
0 notes