save current state in Scala - scala

Let's say I have an instance of a class and I want to duplicate and save the current state of the item, is there a way to do it without using the copy() method? If I just save the class instance somewhere in a variable, then its state changes too when the state of the original one changes, but I don't want that to happen.
Does someone have an idea of how I can save the current class instance without it ever being mutated, so that whenever I want to use it again, I want the class instance to be exactly the same as when I saved it?

The best way to make a copy of a case class is to use copy. If that is not acceptable (for whatever reason) then you have to create a new instance of the case class with the same values.
But you only have this problem because you are using a mutable value in a class. It is much, much better to keep data classes immutable so that you know that the values won't change under your feet. If you need to change the values, create a new instance with different values and use that, leaving the original untouched.
It take a while to learn to code in a functional way without mutable values, but it is worth the effort!

Related

Using Swift reflection to initialize a general class object with data. Cant iterate through properties

I have noticed a class where the coding key for a new property was not added to a Codable object. As a result, data was silently getting dropped. I would like for this to never happen again.
The goal is to write a more general unit test for any object that is Codable that does the following.
Create an instance of the object with "random" data
Encode the object
Decode the object and see if it is equal to the original object
Thus far I have tried Mirror(reflecting: ClassName.self). The goal is that I could essentially go through each property and come up for a way to generally initialize it with random data. The problem is its children object is not particularly useful. Its a very weird object that does not even loop like a collection as I have seen in some example code.
Curious then if it is even possible to initialize an object with random data in its fields using Swift reflection. A lot of the example code for doing on this rely on the object being set up properly with Encode/Decode which is an assumption I cannot take.

Class vs. Struct in Swift (copying)

I am trying to understand the concept of why struct vs. class have difference results. Why is the result the same here but different on structs:
import UIKit
class Message {
var internalText: String = "This is some text"
}
// create new instance
var firstMessage = Message()
//if I assign, its a reference to the original instance
var secondMessage = firstMessage
secondMessage.internalText += " with some more text added on."
//print both
print(firstMessage.internalText)
print(secondMessage.internalText)
output:
This is some text with some more text added on.
This is some text with some more text added on.
Now if you change the above from declaration from "class" to "struct"
struct Message {
var internalText: String = "This is some text"
}
...
output becomes:
This is some text
This is some text with some more text added on.
Why in the class declaration does it change the firstMessage object. Are they the same objects? Is this a rule that if I assign a new object from the old object? Then I would have to declare secondMessage = Message() to make it a new instance.
Thanks in advance.
In Swift, classes are reference types, whereas structs are value types. Value types are copied on variable assignment, whereas reference types are not.
More explanation
The system stores instantiated classes and structs into the memory. There are two main sections of the memory involved in the storage of data, the stack, and the heap. The stack contains the local variables introduced in the current method or function, and the heap is used as a kinda external memory, storing larger values. The program can only access variables stored in the stack, so a reference to the value in the heap should be held in the stack.
When you instantiate a class object by using something like Message(), a free space is reserved in your memory's heap and a reference to it is held in the stack. When you assign the same variable to a new one, the reference is copied and both variables will refer to the same bytes in the heap, so changing one changes another too.
When using structs, all the space is being reserved on the stack and there is no such thing as a pointer or reference, so when assigning to a new variable, all the data gets copied (in fact, the system is smart enough to only copy the necessary values which are being changed).
You can see a nice tutorial covering these subjects here.
Why in the class declaration does it change the firstMessage object. Are they the same objects?
The example you gave is a really nice one because it succinctly illustrates the difference between class and struct, and you came about this close -> <- to answering your own question, even if you didn't realize it. As the other answers have explained, class creates a reference type, which means that when you assign an instance of a class to a variable, that variable gets a reference to the object, not a copy of it. You said so yourself:
//if I assign, its a reference to the original instance
var secondMessage = firstMessage
In your example, firstMessage and secondMessage are really references to the one object that you created. This kind of thing is done all the time in object oriented languages because it's often important to know that you're dealing with a specific object and not a copy, especially if you might want to make changes to that object. But that also brings danger: if your code can get a reference to an object and change it, so can some other code in the program. Shared objects that can be changed create all kinds of headaches when you start writing multithreaded code. When you added text to secondMessage, firstMessage also changed because both variables refer to the same object.
Changing the declaration of Message to struct makes it a value type, where assignment (for example) creates a new copy of the object in question instead of a new reference to the same object. When you added text to secondMessage after changing Message to a struct, the assignment secondMessage = firstMessage created a copy of firstMessage, and you only changed that copy.
Is this a rule that if I assign a new object from the old object?
Whether your assignment creates a copy of the object or a reference to it depends, as you've shown, on whether the thing being assigned has reference semantics (class) or value semantics (struct). So you need to be aware of the difference, but most of the time you don't need to think too hard about it. If you're dealing with an object where you don't care about the object's identity and are mainly concerned with its contents (like a number, string, or array), expect that to be a struct. If you care about which object you're dealing with, like the front window or the current document, that'll be a class.
Then I would have to declare secondMessage = Message() to make it a new instance.
Right -- if Message is a class, assigning one to a new variable or passing it into a method won't create a new one. So again, are you more likely to care about which message you're dealing with, or what is in the message?
Simple answer: Classes are reference types Structs are value types.
In the class, firstMessage is set to Message() which is an instance of the whole class Message. So when secondMessage gets set to equal firstMessage, secondMessage Doesn’t make a new class again, it just makes a note of where firstMessage is at and they both can now operate it. But because they both in the same location, the internalText will be the same for both.
While with the struct, since they are value types, secondMessage copies all the values from firstMessage and creates its own independent object of type Message.
Classes are reference types, meaning that the firstMessage and secondMessage variables you defined in your first snippet stores only a reference to the class instance you created. Imagine your object is located somewhere in your memory heap with an id (for example, id0001), then both firstMessage and secondMessage stores only the id, which is id0001, so they both refer to the same object in memory.
On the other hand, structs are value types, meaning that the struct variables store unique objects directly; unlike reference types, no sharing is going on. So when you are assigning a new struct variable to a previous struct variable, the object gets copied, and the two variables store two unique objects with different memory addresses (IDs).
For more information, check out the official doc on classes and structs.
Let us understand the same concept with an example,
Suppose you have a google sheet in which you are adding some text and at a time you share that sheet to some other person for editing or deleting purpose. So when the other person do any changes you can see at a time. This concept is followed in class.
Moreover, classes are reference types because here you are passing a reference(sheet).
However, you have downloaded that google sheet and send its copy to another person so at that time you are not able to see the changes until and unless the person sends back the sheet. And this is the same concept followed in struct. A struct is value type because we are passing a copy(downloaded sheet).
We can inherit class but cannot inherit struct
Think of structs as a Microsoft Excel file. You create a copy and send it to me. When I change my copy, your copy doesn't get changed.
Classes on the other hand are more like Google Sheets. When I make changes to the file you shared with me, you can see the changes.
Instances of structs make copies and have different places in memory
Instances of classes point to the same place in memory

dynamic setting and getting values from Swift class

I'd like to copy all properties from a NSManagedObject over to a "regular" Swift class. I don't want to do this manually, i.e. make a regular class with all the properties for every NSManagedObject and then manually copy all those values.
I do know how to read property names and values dynamically from my managed object, but how to set them on a Swift class in a way that I can then use those values like
mySwiftObject.name
which returns a String or
mySwiftObject.age
which returns a Number (as those are the types on the Managed Object). Custom subscripting and stuff like that came to my mind, but I didn't manage to achieve this... Is there a nice way to do exactly that?

What are the benefits of an immutable struct over a mutable one?

I already know the benefit of immutability over mutability in being able to reason about code and introducing less bugs, especially in multithreaded code. In creating structs, though, I cannot see any benefit over creating a completely immutable struct over a mutable one.
Let's have as an example of a struct that keeps some score:
struct ScoreKeeper {
var score: Int
}
In this structure I can change the value of score on an existing struct variable
var scoreKeeper = ScoreKeeper(score: 0)
scoreKeeper.score += 5
println(scoreKeeper.score)
// prints 5
The immutable version would look like this:
struct ScoreKeeper {
let score: Int
func incrementScoreBy(points: Int) -> ScoreKeeper {
return ScoreKeeper(score: self.score + points)
}
}
And its usage:
let scoreKeeper = ScoreKeeper(score: 0)
let newScoreKeeper = scoreKeeper.incrementScoreBy(5)
println(newScoreKeeper.score)
// prints 5
What I don't see is the benefit of the second approach over the first, since structs are value types. If I pass a struct around, it always gets copied. So it does not seem to matter to me if the structure has a mutable property, since other parts of the code would be working on a separate copy anyway, thus removing the problems of mutability.
I have seen some people using the second example, though, which requires more code for no apparent benefit. Is there some benefit I'm not seeing?
Different approaches will facilitate different kinds of changes to the code. An immutable structure is very similar to an immutable class object, but a mutable structure and a mutable class object are very different. Thus, code which uses an immutable structure can often be readily adapted if for some reason it becomes necessary to use a class object instead.
On the flip side, use of an immutable object will often make the code to replace a variable with a modified version more brittle in case additional properties are added to the type in question. For example, if a PhoneNumber type includes methods for AreaCode, LocalExchange, and LocalNumber and a constructor that takes those parameters, and then adds an "optional" fourth property for Extension, then code which is supposed to change the area codes of certain phone numbers by passing the new area code, LocalExchange, and LocalNumber, to the three-argument constructor will erase the Extension property of every phone number, while code which could write to AreaCode directly wouldn't have had that problem.
Your remark about copying value types is very good. Maybe this doesn't make much sense in particular language (swift) and particular compiler implementation (current version) but in general if the compiler knows for sure that the data structure is immutable, it could e.g. use reference instead of a copy behind the scenes to gain some performance improvement. This could not be done with mutable type for obvious reasons.
Even more generally speaking, limitation means information. If you limit your data structure somehow, you gain some extra knowledge about it. And extra knowledge means extra possibilities ;) Maybe the current compiler does not take advantage of them but this does not mean they are not here :)
Good analysis, especially pointing out that structs are passed by value and therefore will not be altered by other processes.
The only benefit I can see is a stylistic one by making the immutability of the element explicit.
It is more of a style to make value based types be treated on par with object based types in object oriented styles. It is more of a personal choice, and I don't see any big benefits in either of them.
In general terms, immutable objects are less costly to the system than mutable ones. Mutable objects need to have infrastructure for taking on new values, and the system has to allow for the fact that their values can change at any time.
Mutable objects are also a challenge in concurrent code because you have to guard against the value changing out from under you from another thread.
However, if you are constantly creating and destroying unique immutable objects, the overhead of creating new ones becomes costly quite quickly.
In the foundation classes, NSNumber is an immutable object. The system maintains a pool of NSNumber objects that you've used before, and under the covers, gives you back an existing number if you ask for one with the same value as one you created before.
That's about the only situation in which I could see value in using static structs - where they don't change very much and you have a fairly small pool of possible values. In that case you'd probably want to se up your class with a "factory method" that kept recently used structs around and reused them if you asked for a struct with the same value again.
Such a scheme could simplify concurrent code, as mentioned above. In that case you wouldn't have to guard against the values of your structs changing in another thread. If you were using such a struct, you could know that it would never change.

Classes: Public vars or public functions to change local vars?

Exactly what the topic title says,
In which cases would you prefer using public functions to change local variables over just defining that variable as public and modifying it directly?
Don't expose the data members directly: using opaque accessors means you can change the implementation at a later date without changing the interface.
I should know. I take the short cut from time-to-time, and have had occasion to regret it.
Obviously if you want changing the variable to have some other effect on the object's state (like recalculating some other property of the object) you must use a mutator function.
If it's possible to set the variable to something that places the object in an invalid state, you should probably also use a mutator function. This way you can throw an exception (or return an error, or just ignore) if something illegal is about to happen. This does wonders for debugging.
But if some variables can be modified with mutator functions, and others are public, the programmer needs to keep track of which is which. This is a waste of time and effort so in some cases it's easiest to just use mutator functions for everything.
If you look at an object purely in term of service, you realize that exposing a variable is not a good way to expose those services.
The API must reflect what the object is all about (for it to achieve a high cohesiveness), and if you define a setValue(...), it is not so much because you need a way to -- today -- changes a variable, but because it makes sense for the object to expose this service.
So:
Don't provide accessors or mutator function to every single member of every single class you write. Only provide accessors/mutator functions if the accessors/mutator methods are a sensible and useful part of the class's interface (API).
Don't think of these methods as accessors or mutators. Instead, think of them as methods that access or mutate a certain abstract property of the object that happens to be represented by a single member today, but may be computed in a more complex manner tomorrow.
You should mention what language you are dealing with, since that will affect the answer.
Your first thought should be about the API to your class. If you want to keep that API stable (and you should!), then consider how you might change today's simple variable into a full-blown method later.
In many languages, you can't change a variable to a method without changing the calling code. C, C++, and Java fall into this category. Never use public variables in these languages, because you won't have any wiggle room later.
In Python, you can change a variable to a property without changing the callers, so you don't have to worry up front: use public variables.
C# I believe has properties that can let you change variables to methods transparently, but I am not sure.
If you want to change a variable inside a class, your best doing it through Properties.
Its not good practice to have variable's modified on the outside.
Think of future development too. You could put some logic behind a Property without changing the whole program.