How to model changing state in functional programming - list

I am new to FP and new to Scala and I have a question on how to solve a problem efficiently in a functional way.
Let's say I have:
case class Store(storedObjects: List[StoreObject])
and
case class StoreObject(name: String)
and I want to store all the StoreObjects in the Store.
How can I add new StoreObjects to the List the Store case class owns when it's immutable?
To take a second example: Suppose I have a case class Person as shown here,
case class Person(name: String)
and an object called object PersonController
which owns an immutable list of Persons and every time I create a new Person I want to add it to the list in PersonController.
Is there a way how to do this in fp or a pattern?
Or is switching to mutability the only efficient way to do stuff like this (which would be painful because of multithreading).
Thanks for your help
Exagon

I think the main idea you're missing right now is the possibility to not mutate at all but actually create a new object with the result of your addition/removal operation.
For adding... something along these lines for example:
def add(sObject: StoreObject, store: Store) = store.copy(storedObjects = store.storedObjects :+ sObject)
This will return a new Store holding the list.
Hope this makes sense and answer your doubts.

how can i add new StoreObjects to the List the Store Class owns
Define a regular class with field
var list = List()
or
val list = mutable.List()
You can change this field in both cases: in first case by reassigning the var and in second by mutating the underlying mutable.List.
I would prefer the first way - var with immutable list, because you can safely share it among threads. But you have to ensure that update operations on list are correctly synchronized.

Related

Question about List of Objects in dart Language (Flutter)

Question About List of Objects in dart (Flutter)
Hello
class Cartoon {
.
.
}
List<Cartoon> L1 = [];
….
...
List<Cartoon> L2 = [];
I define below a new list L2 containing objects from List L1 meeting some condition
List<Cartoon> L2 = [];
L2.clear();
for (Cartoon _thisObjet in L1) {
if (_thisObjet.xxx == yyyy) { //
L2.add(_thisObjet);
}
}
I check with the debugger that anytime I modify a member Value in an Object L2 , the member is is also modified in member of. original Object in List L1.
This is not expected result
In my mind I was thinking these 2 Lists should be independent ,So if someone has an explanation, I would be grateful
All variables in Dart is references to objects. The same for lists where lists only contains references to objects.
So your List<Cartoon> contains references to Cartoon objects. That means that when you look though L1 you are going though references to Cartoon objects and when you insert one of these references to the L2 list, you now have two lists containing a reference to the same object.
That also means that when you are making changes inside this object, the change can be observed when iterating though both of the lists since there are only one object.
So if you want to prevent a change to a Cartoon object to be observed in your other list, you need to make a copy of your Cartoon object and make the change on the copy. The best you can do here is to make a method on Cartoon which returns a copy of the object or make a constructor which takes a Cartoon object to create another Cartoon object.
(An important note related to this topic is immutable objects like int, String and so on (e.g. your own type of objects which only contains final fields). These type of objects cannot change their inner state but you are forced to create a new object every time you want to impose a change. By making immutable objects, you can prevent this kind of issues since any change to the object forces you to get a new object. But note, like everything, immutable is not a silver bullet to solve all problems.)

c++ dynamic array of pointers - when i need to use it?

I'm trying to understand when I need to allocate an array of an object that each pointer to some object for example array of Student that point to Student:
Student** db = new Student*[size]
when do I need to use it? I know that is a general question, but I'm trying to solve some Exam that combines inheritance, and in some class, one of the data member they declare it as I said above.
in my solution i wrote:
Student * db = new Student[size];
thanks.
TL;DR version:
Use std::vector<std::unique_ptr<Student>> db.
Explanation
Student** db = new Student*[size]
could be used to represent an array of classes derived from Student.
eg:
Student** db = new Student*[size];
db[0] = new Grad_Student();
db[1] = new Coop_Student();
db[2] = new Elementary_Student();
If you elect the second option
Student * db = new Student[size];
db[0] = Grad_Student();
db[1] = Coop_Student();
db[2] = Elementary_Student();
you save a lot of pesky manual memory management by directly holding Students rather than pointers to Students, but Object Slicing will turn the derived Students into plain old Students. A box sized and shaped to fit a Student can only store a Student, so all of the additional features of, for example, the Grad_Student assigned to db[0] will be lost. Only by storing a reference to the Grad_Student can the Grad_Student's extensions be preserved. You just have to remember that the Grad_Student is actually stored somewhere else.
Sounds good right? It is until you look at all of the dynamic allocations you have to make sure are cleaned up. Memory management is one of the hardest things to get right in C++, and one of the best ways to manage memory management is through Resource Allocation Is Initialization or RAII. std::vector and std::unique_ptr are fabulous examples of RAII in action.
vector is a dynamic array all nicely wrapped up inside a class that handles virtually every aspect of list management right down to adding, removing, resizing, and making sure everything gets cleaned up. unique_ptr is a Smart Pointer that ensures exactly one owner of a resource, and this owner will clean up the resource when it is destroyed. The result, std::vector<std::unique_ptr<Student>> will allow you to add, remove, access, and move any Students without any direct intervention. This allows you to write simpler code. Simpler code is less likely to have bugs. Fewer bugs means more leisure time and happier clients. Everybody wins.
Suppose you already have a collection, for example a linked list of Students which is in order by Student ID. You want to sort them by Student last name. Instead of changing your linked list, or messing up its order, you just allocate an array of pointers and sort that. Your original list remains intact but you can do fast binary searches by last name using your array.

List of Uninitialized Objects

So here is my goal, I would like to instantiate an object based on a string and an integer. My current thought was this:
1) Create a list of possible objects
2) Each object has a static method that takes a string and integer and returns true, if what was passed matches the static members that object.
3) Then iterate over the list of possible objects, call the static function of that object if it returns true then instantiate that particular object:
pseudocode:
// Pseudo Definitions
class CoolObject
class CoolObject2: public CoolObject ....
class CoolObject3: public CoolObject ....
// List of Objects
std::list<CoolObject> list_of_possible_objects;
list_of_possible_objects.push_back(CoolObject);
list_of_possible_objects.push_back(CoolObject2);
list_of_possible_objects.push_back(CoolObject3);
// Inside of the matching function
for (std::list<CoolObject>::iterator it=list_of_possible_objects.begin(); it != list_of_possible_objects.end(); it++) {
if(*it::is_cool_object(string, int)) {
return *it(string1, string2); //Assume the constructor takes some objects that were passed into the function
}
}
However, this seems like a dream since C++ does not allow to have objects that are not instantiated.
I am sure I can do this with some kinda map and a switch statement but this seemed lot more elegant in my head so I went for it first.
Is there any pattern out there that is similar to this, that I can follow? Or is there a way to make what I am asking be legal?
I would rather not maintain a huge map and I would rather just have a list of objects and ask each object if its the one and then instantiate, if having a huge map and a switch statement is the only way, thats fine. I thought maybe ask some gurus, if this is possible or is there a better way of doing it before giving up on this way.
Thanks for all the help!
Store std::optional<T>, that's probably what you're looking for: basically just a flag to tell if the object is constructed and a reference to the object iff constructed. Note that you can't spare the flag, as you need to know whether to run the destructor or not.

Copy list objects value not reference

I'm try to create a new list object. I set the new object to an old existing object.
List<string> names = new List<string>();
names = olderList;
The problem I have is that the names list points to the olderList as a result when olderList changes, names changes too. I tried copying the values with a foreach but it's still doing the same thing, refering to the olderList.
When you make an assignment in Java, you copy the reference, not the content. Therefore, names will point to the same memory address that olderList does.
When you copy all the values, you do the same thing - you are assigning to the names list another reference to each String stored in the olderList.
An idea that might solve your problem is to use the foreach but instead of adding each element, creating a new String that is a copy of the old one. It would be something like this:
names=new List<String>();
foreach (String s: olderList) {
names.add(new String(s));
}
Check the constructor I used and its meaning at Oracle's reference site.
You must create a new list and clone every element.
If you call
olderList.clone()
it will give you a shallow copy (i.e. a new list with references to the objects of the first list). You must do something like this:
for(String name : olderList){
newList.add(name.clone());
}
reference: java api Cloneable, Object.clone()

Saving pointers to file in C++

I'm developing a game for a course at my school. One of the assignments is to enable saving the game to a file and later load the game from the same file.
The problem I'm having are pointers. I'm not allocating anything on the stack (due to ownership of an item for example) so all the classes have pointers to whatever they want a reference to.
While this is quite easy to solve (assign an ID to each object and store that id instead of the pointer) the real problem comes with multiple inheritance.
Let's take the class Actor for example. It looks like this: class Actor : public Object, public ItemOwner where Object is a Obj-C-style base class which has a retain count and release, retain and autorelease methods. ItemOwner is simply an Interface which has some methods such as virtual bool add(Item *item) = 0;, virtual void remove(Item *item) = 0; and virtual bool transfer_ownership(Item *item, ItemOwner *new_owner) = 0;
Now the real question comes, which class(es?) should have ID's. And Item has a pointer to an ItemOwner while a Room has a pointer to an Actor.
The actor should only be saved once.
I've thought about assigning ID's to each superclass (Object, ItemOwner, etc) but if I have a pointer to an Actor will that actor always have the same adress as the Object it contains (Actor *foo = new Actor(); foo == (Object *)foo)? If not every single class in the game will need to have an ID.
Any thoughts or suggestions would be greatly appreciated.
By using UIDs, you create a mapping:
serialized_object -> UID -> deserialized_object.
Why bothering? You already have UIDs, and these are pointers to objects. By using this mapping:
&serialized_object -> &deserialized_object
you drop a level of indirection, UIDs as created automatically, and all you have to do is to deduce this mapping in deserealization process.
The simpliest way is to serialize the objects with all the pointers as is, and to store together with each object its address. This will also help you check if an object was serialized alraedy.
While serialization would be simple, deserialization will have its tricks. You'll have to be carefull to update each old pointer (remember? they contained adresses that are no more valid) with the correct object address.
One option is to define a class who's purpose in life is to hold an ID, and make it a virtual base class of every class you intend to save to disk.
I would put a single per object instance, for the actor, its ID should be the same for the Object and ItemOwner, because they are all the same instance.
Also, instead of using pointers you can think about using handlers, like described here: http://gamesfromwithin.com/managing-data-relationships