Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm working on a (maybe) serious programming language and want to learn about implementing memory management. I want this language to enforce RAII, similar to Rust, but, unlike rust, this language is Object-Oriented and I hope I can implement objects that manage their own memory (like Boxes in Rust). Can anyone go into detail about how Rust handles references to Heap memory?
I think the most obvious way to implement classes is:
Your class variables are implemented as pointers, like in C# and Java.
There is a single owner of the object and all class variables have move semantics in order to enforce this, like in Rust.
Memory is a resource that needs to be cleaned up, so all class variables, after calling the destructor (if any) of the referent object, also call the deallocation routine of your memory allocator, like in C++.
You introduce lifetimes in your type system in order to ensure that lending/borrowing the object doesn't allow any non-owning references to outlive it, like in Rust.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 months ago.
Improve this question
As long as there are smart pointer types in Rust, are ownership and borrowing semantics in Rust really needed? If yes, in what cases how do they used?
Yes!
Smart pointers come with quite a performance overhead. In many cases, a quick reference is all that is needed, for example if you want pass a value to a function without moving it into the function. Creating a smart pointer just for that use case would be really hurtful for performance.
Rusts primary goals are performance and safety, and that's why Rust has ownership and borrowing semantics. Otherwise there are many languages that follow the everything-is-a-smartpointer principle (actually, many of them go even one step further and use a garbage collector). It's a valid principle for memory safety, but comes with a performance hit.
Almost all languages are either memory safe or fast. Rust is unique in that sense as it tries to be both. And references/lifetimes are some of the principles that helped it to achieve that goal, at the cost of a steeper learning curve.
EDIT: Avoiding dangling pointers is just a small part of what the borrow checker can be used for. There are many more reasons to have it, like mutability, fearless concurrency, slicing, compile time ownership checks (like avoiding duplicate pin usage in embedded) and so on. How much power the borrow checker really has is probably not even completely understood yet, it was discovered that many usecases benefit from it for which it was never intended. It's just a really useful tool in general.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
If a global variable is being cloned (as implemented within the standard library) while being written to will it create a data race?
Cloning data involves reading it. Writing to data involves, well, writing it.
We can safely access data in the following ways
Any number of threads can read data at a given moment, or
One thread can write to data at a given moment, provided no one else is reading or writing
Neither of these conditions applies (we're reading for the clone and we're writing at the same time). Therefore, yes, it's a data race.
As pointed out in the comments, Rust forbids data races. You can't so much as look at a global variable in Rust without an unsafe block, since it's never safe to do so, by Rust's rules. But if you wrap your code in unsafe and don't provide additional protection then yes, this is a data race.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
Rust is very actively developed and the language itself is extended regularly through the RFC process. Some of these changes, such as the Generic Associated Types RFC, have a strong impact on API-design, because new, better APIs suddenly become possible, where they weren't before.
As example, consider the mentioned GATs RFC: with this feature, we could have collection traits and could write a better version of some traits, e.g. Deref. Or take the impl Trait RFC: with that, it would be desirable to change the Iterator trait such that methods like map() would return impl Iterator instead of Map.
This is a conflict: we could improve std, but not in a backwards-compatible manner. I heard something about "Rust Epochs" (discussed here) and I think they would allow for backwards-incompatible changes.
My question is: Are there already plans on how to change the standard library's API in order to use new language features? Is a new design considered for the Rust 2019 Epoch?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
What factors are important? How do you know if a given programming language is "simple" or "simpler" than another language?
I'm not sure if this is a fair question to ask, since different languages serve different purposes and it might not really be comparing apples to apples.
However, with that said, memory management would come to mind. One can argue that Java is a "simpler" language than C++, since it has a garbage collector that can deal with some of the complexities around memory management, instead of forcing you to do it yourself.
In my perspective, these are the points that define the complexity of a language.
Variation of syntax from common pseudocode and constructs
Ease of developing a structure for real-life entities like objects
Methods of structure enforcement at compile time.
Memory management strategy allocation/deallocation
Code reusability
Ease of code headers and directives management
Inbuilt libraries
Relative installation package sizes
Data exchange capabilities like over network of files
Process handling like thread management
Relative brevity of the code
Speed of compilation
Developer community size and documentation
OpenSource implementations
Platform dependence
And many more could be added to this list.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
In the UML reference manual page 18
Full specifications of a final system:
An implementation model includes enough information to build the system. It must include not only the logical semantics of the system and the algorithms, data structures, and mechanisms that ensure proper performance, but also organizational decisions about the system artifacts
that are necessary for cooperative work by humans and processing by tools
What the highlighted sentence means?
It basically means that with UML modeling, you can go far beyond describing algorithms. You can (and should) put the technical information in context and describe what the system you describe is good for, how it will be used, for what purpose and by whom.
Perhaps because it's an obscure usage, you might be wondering about the use of the word "artifacts" here. In this context, it refers to any of the persisted entities in your design, which can include databases, files, archives, cloud-storage, tapes, printouts, etc. Basically any component in the system that has a lifetime or can serve as long-term memory.