Variable/object data structure in OO languages - oop

In object oriented programming languages when you define a variable it ends up becoming a reference to an object. The variable is not itself the object, and instead points to the object that carries the value that was assigned to that variable.
Question is how does this work so efficiently? What is the mechanism of how a variable is assigned to an object?
The way I think about the organization is as a linked list, however could not find references how the data is structured in languages such as Ruby or Java.

In object oriented programming languages when you define a variable it ends up becoming a reference to an object.
This is not always true. For example, C++ can be considered an object-oriented language, yet a user of the language can use a variable as a reference/pointer or explicitly as a value.
However, you are right in that some (typically higher-level) OO languages implicitly use references so that the user of the language does not have to worry about these kinds of implementation "details" in regards to performance. They try to take responsibility for this instead.
how does this work so efficiently? What is the mechanism of how a variable is assigned to an object?
Consider a simple example. What happens when an object is passed as a parameter to a function? A copy of that object must be made so that the function can refer to that object locally. For an OO language that implicitly uses references, only the address of the object needs to be copied, whereas a true pass-by-value would require a copy of the complete memory contents of the object, which could potentially be very large (think a collection of objects or similar).
A detailed explanation of this involves getting into the guts of assembly. For example, why does a copy of an object to a function call even need to be made in the first place? Why does the indirection of an address not take longer than a direct value? Etc.
Related
What's the difference between passing by reference vs. passing by value?

Related

Hacklang : why were container classes replaced with built-in types?

Just a quote from hack documentation :
Legacy Vector, Map, and Set
These container types should be avoided in new code; use dict,
keyset, and vec instead.
Early in Hack's life, the library provided mutable and immutable
generic class types called: Vector, ImmVector, Map, ImmMap, Set, and
ImmSet. However, these have been replaced by vec, dict, and keyset,
whose use is recommended in all new code. Each generic type had a
corresponding literal form. For example, a variable of type
Vector might be initialized using Vector {22, 33, $v}, where $v
is a variable of type int.
I wonder why this change was made.
I mean, one of PHP weaknesses is that it has bad oop standard library.
Ex : str_replace and array_values methods are outside of the string/array type itself. The PHP standard library is not consistent, sometimes we must pass the array as the first parameter, other times as the second...
I was glad to see that Hack introduced true OOP encapsulation for collections.
Do you know why they stepped back and wrote utility classes such as C\, Dict\, Keyset\ and Vec\ ?
Will there be in the future an addition to add methods to built-in types (ex : Str\starts_with => "toto"->startsWith("t")) ?
Based on Dwayne Reeves' blog post introducing HSL, it seems that the main advantage is the fact that arrays are native values, not objects. This has two important consequences:
For users, the semantics are different when the values cross through arguments. Objects are passed as references, and mutations affect the original object. On the other hand, values are copied on write after passing through arguments, so without references (which are finally to be completely banned in Hack) the callee can't mutate the value of the caller, with the exception of the much stricter inout parameters.
The article cites the invariance of the mutable containers (Vector, Set, etc.) and generally how shared mutable state couples functions closer together. The soundness issues as discussed in the article are somewhat moot because there were also immutable object containers (ImmVector, ImmSet, etc.), although since these interfaces were written in userland, variance boxed the function type signature into tight constraints. There are tangible differences from this: ImmMap<Tk, +Tv> is invariant in Tk solely because of the (function(Tk): Tv) getter. Meanwhile, dict<+Tk, +Tv> is covariant in both type parameters thanks to the inherent mutation protection from copy-on-write.
For the compiler, static values can be allocated quickly and persist over the lifetime of the server. Objects on the other hand have arbitrarily complicated construction routines in general, and the collection objects weren't going to be special-cased it seems.
I will also mention that for most use cases, there is minimal difference even in code style: e.g. the -> reference chains can be directly replaced with the |> pipe operator. There is also no longer a boundary between the privileged "standard functions" and custom user functions on collection types. Finally, the collection types were final of course, so their objective nature didn't offer any actual hierarchical or polymorphic advantages to the end user anyways.

Can using a constant global variable stop the issue of 'side effects' completely?

I am aware that the purpose of Functional Programming (FP) is to disallow 'side effects', that traditionally appear in object-oriented, imperative languages due to the use of global variables (for example).
However, in OOP (Non-FP) languages, can 'side effects' disappear if one uses a global variable that is constant (so it's value will never change)?
Not sure what you mean by "global variable" but seem like the answer is No.
What is more important is whether variables are mutable or immutable. That means that if you send some class to function you can be sure that is not changed.
Now it also depends on what is "side effects" - which have nothing to do with mutability. e.g you can send an imutable instance to method, you are not going to change the instant but you are going to do some other operation like adding/deleting records base on that instance or create/delete files on the FS

Why does COM interface return different values for same invoking method?

When I invoke a method on a COM interface that returns another interface, the punkVal is different each time.
Yet if I use the old punkVal's to invoke that interfaces methods, it too works. It seems like a lot of unnecessary objects(or probably pointers to objects) are being created but I need someway to determine if the returned interface is unique. All I know is that I invoke is returning an interface(punkVal) and the value is different every instance. The value pointed by that value is always the same, but I think it is because it points to the vtable or something, doesn't seem to be a reliable check. That, or even seemingly disparate interfaces are all actually the same interface.
To be clear:
someCOMInterface foo();
I call invoke on foo and expect punkVal to be someCOMInterface, which I must later on query to call it's methods using invoke. But each time I call the first invoke I get a different someCOMInterface(the "same" but "different" in that the value returned by invoke).
This isn't uncommon. It is entirely up to the developer of the COM library whether interface pointers returned from multiple calls to the same method will return the same pointer or not.
One of the reasons that different pointers may be returned is that the core object model used within a specific COM library may not be COM. I have, for example, written object models in C++ using things like shared_ptr, which arguably yields a better object model for C++ clients. But when I expose my C++ object model for interoperability (or, more generally, expose it as a DLL), COM is often a better choice. Since keeping an complex, hierarchical object model in sync with a set of wrapper classes can be difficult, wrapper objects may just be temporary -- created as necessary and destroyed whenever clients no longer use them.
In these circumstances, the client may still need to know that the objects are "equal" -- two different objects that wrap the same inner object can be considered "equal." To determine that, Microsoft defines the IObjectEquality interface. This interface may be implemented by COM wrapper classes so that a client can explicitly check if two non-equal pointers are conceptually "equal" objects. The objects you're using may or may not implement this interface. This blog post shows a complete example of determining object equality using this interface.
If IObjectEquality is not implemented, it is up to the developer of the COM object to provide some means of making such a determination, usually by providing some sort of Name or ID or other identifying property. For example, Excel's Application.Range property will return different pointers from subsequent calls with the same arguments. To determine if two ranges are equal, you can use the Range.Address method to get an "identifier" of that range, and then compare those identifiers.

Can an Object-oriented type system be implemented by a language with an Object-oriented type system?

Suppose you have an imaginary type system for an imaginary scripting language which is written in C++ (for example), and each type (and object) in the scripting language has a corresponding type (and object) in the underlying implementation language. The base class in this imaginary type system is a class called Object, and all other classes must derive from this class. Now, you have another class called HashTable, which is the basis for all variable storage (I might have said that wrong): namespaces are implemented via HashTables (associating one object with another object), global variables are stored via HashTables, and, to the point of the problem, instance variables are also stored in HashTables.
Instance variables are such that every Object has an HashTable in which to store its instance variables. However, HashTable necessarily derives from Object, therefore each HashTable has an HashTable in which to store its instance variables. And every HashTable for every HashTable has an HashTable, and so on ad infinitum.
My question is, can this type system be implemented in an object-oriented way in the underlying C++ code? If no precautions are taken, the program will enter an infinite loop and cause a stack overflow on the mere instantiation of an Object, because it will instantiate an HashTable which will call its parent constructor for Object, which will instantiate an HashTable...
Are there any viable workarounds for this design flaw which don't involve breaking the desired OO design (each type has its corollary type in the underlying code)?
Pardon the grammar in this post, English is not my first language and I might not have explained something in a comprehensible manner.
implement two different HashTable types: one for user code (UserHashTable), derived from Object and so no violating your "everything is Object" rule, and another for internal use (CoreHashTable) to implement your type system.
[EDIT] CoreHashTable can be automatically convertible to UserHashTable, e.g. UserHashTable can contain internal smart pointer to CoreHashTable.
Yes. You can emulate your own "object system" with another programing language.
That concept its called a "virtual object system".
O.O. Programming languages have its own "Object System". By an "Object System", I don't mean "O.O. libraries or O.O. Class hierarchy". By an "Object System" I mean its way of declaring and using classes and objects.
But, sometimes, your programming language its not object oriented, or even if its object oriented, some stuff is missing. C# and Java doesn't have real properties & events, C# and Object Pascal does.
When O.O. started, many programmers use non O.O. programming languages, and learn about O.O. Some make their own "plain C" to "C++" preprocessors (Objective-C maybe), some did full compilers.
And some emulate them. The programmer, conceptually, thinking, he was using classes and objects, but, in code, use structures & pointers.
I have seen several "virtual object system (s)", where a group of classes or objects is simulated by another programming language.
Once, I worked with a database conectivity tool called "Borland Database Engine", where developers read and write data into objects like "databases", "tables", "fields".
One famous, is the GLib library ("GObject" is the root object), used in the GNome visual interface for GNU/Linux. It's done in "plain C", but simulates objects and classes, using pointers.
More Info:
http://en.wikipedia.org/wiki/Gobject
You want to use a group of objects conceptually speaking, but in code, you won't have a class declaration for your conceptual class, but, some data stored in hash tables, using another O.O. programming language. Yes it can be done.

Mutable vs immutable objects

I'm trying to get my head around mutable vs immutable objects. Using mutable objects gets a lot of bad press (e.g. returning an array of strings from a method) but I'm having trouble understanding what the negative impacts are of this. What are the best practices around using mutable objects? Should you avoid them whenever possible?
Well, there are a few aspects to this.
Mutable objects without reference-identity can cause bugs at odd times. For example, consider a Person bean with a value-based equals method:
Map<Person, String> map = ...
Person p = new Person();
map.put(p, "Hey, there!");
p.setName("Daniel");
map.get(p); // => null
The Person instance gets "lost" in the map when used as a key because its hashCode and equality were based upon mutable values. Those values changed outside the map and all of the hashing became obsolete. Theorists like to harp on this point, but in practice I haven't found it to be too much of an issue.
Another aspect is the logical "reasonability" of your code. This is a hard term to define, encompassing everything from readability to flow. Generically, you should be able to look at a piece of code and easily understand what it does. But more important than that, you should be able to convince yourself that it does what it does correctly. When objects can change independently across different code "domains", it sometimes becomes difficult to keep track of what is where and why ("spooky action at a distance"). This is a more difficult concept to exemplify, but it's something that is often faced in larger, more complex architectures.
Finally, mutable objects are killer in concurrent situations. Whenever you access a mutable object from separate threads, you have to deal with locking. This reduces throughput and makes your code dramatically more difficult to maintain. A sufficiently complicated system blows this problem so far out of proportion that it becomes nearly impossible to maintain (even for concurrency experts).
Immutable objects (and more particularly, immutable collections) avoid all of these problems. Once you get your mind around how they work, your code will develop into something which is easier to read, easier to maintain and less likely to fail in odd and unpredictable ways. Immutable objects are even easier to test, due not only to their easy mockability, but also the code patterns they tend to enforce. In short, they're good practice all around!
With that said, I'm hardly a zealot in this matter. Some problems just don't model nicely when everything is immutable. But I do think that you should try to push as much of your code in that direction as possible, assuming of course that you're using a language which makes this a tenable opinion (C/C++ makes this very difficult, as does Java). In short: the advantages depend somewhat on your problem, but I would tend to prefer immutability.
Immutable Objects vs. Immutable Collections
One of the finer points in the debate over mutable vs. immutable objects is the possibility of extending the concept of immutability to collections. An immutable object is an object that often represents a single logical structure of data (for example an immutable string). When you have a reference to an immutable object, the contents of the object will not change.
An immutable collection is a collection that never changes.
When I perform an operation on a mutable collection, then I change the collection in place, and all entities that have references to the collection will see the change.
When I perform an operation on an immutable collection, a reference is returned to a new collection reflecting the change. All entities that have references to previous versions of the collection will not see the change.
Clever implementations do not necessarily need to copy (clone) the entire collection in order to provide that immutability. The simplest example is the stack implemented as a singly linked list and the push/pop operations. You can reuse all of the nodes from the previous collection in the new collection, adding only a single node for the push, and cloning no nodes for the pop. The push_tail operation on a singly linked list, on the other hand, is not so simple or efficient.
Immutable vs. Mutable variables/references
Some functional languages take the concept of immutability to object references themselves, allowing only a single reference assignment.
In Erlang this is true for all "variables". I can only assign objects to a reference once. If I were to operate on a collection, I would not be able to reassign the new collection to the old reference (variable name).
Scala also builds this into the language with all references being declared with var or val, vals only being single assignment and promoting a functional style, but vars allowing a more C-like or Java-like program structure.
The var/val declaration is required, while many traditional languages use optional modifiers such as final in java and const in C.
Ease of Development vs. Performance
Almost always the reason to use an immutable object is to promote side effect free programming and simple reasoning about the code (especially in a highly concurrent/parallel environment). You don't have to worry about the underlying data being changed by another entity if the object is immutable.
The main drawback is performance. Here is a write-up on a simple test I did in Java comparing some immutable vs. mutable objects in a toy problem.
The performance issues are moot in many applications, but not all, which is why many large numerical packages, such as the Numpy Array class in Python, allow for In-Place updates of large arrays. This would be important for application areas that make use of large matrix and vector operations. This large data-parallel and computationally intensive problems achieve a great speed-up by operating in place.
Immutable objects are a very powerful concept. They take away a lot of the burden of trying to keep objects/variables consistent for all clients.
You can use them for low level, non-polymorphic objects - like a CPoint class - that are used mostly with value semantics.
Or you can use them for high level, polymorphic interfaces - like an IFunction representing a mathematical function - that is used exclusively with object semantics.
Greatest advantage: immutability + object semantics + smart pointers make object ownership a non-issue, all clients of the object have their own private copy by default. Implicitly this also means deterministic behavior in the presence of concurrency.
Disadvantage: when used with objects containing lots of data, memory consumption can become an issue. A solution to this could be to keep operations on an object symbolic and do a lazy evaluation. However, this can then lead to chains of symbolic calculations, that may negatively influence performance if the interface is not designed to accommodate symbolic operations. Something to definitely avoid in this case is returning huge chunks of memory from a method. In combination with chained symbolic operations, this could lead to massive memory consumption and performance degradation.
So immutable objects are definitely my primary way of thinking about object-oriented design, but they are not a dogma.
They solve a lot of problems for clients of objects, but also create many, especially for the implementers.
Check this blog post: http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html. It explains why immutable objects are better than mutable. In short:
immutable objects are simpler to construct, test, and use
truly immutable objects are always thread-safe
they help to avoid temporal coupling
their usage is side-effect free (no defensive copies)
identity mutability problem is avoided
they always have failure atomicity
they are much easier to cache
You should specify what language you're talking about. For low-level languages like C or C++, I prefer to use mutable objects to conserve space and reduce memory churn. In higher-level languages, immutable objects make it easier to reason about the behavior of the code (especially multi-threaded code) because there's no "spooky action at a distance".
A mutable object is simply an object that can be modified after it's created/instantiated, vs an immutable object that cannot be modified (see the Wikipedia page on the subject). An example of this in a programming language is Pythons lists and tuples. Lists can be modified (e.g., new items can be added after it's created) whereas tuples cannot.
I don't really think there's a clearcut answer as to which one is better for all situations. They both have their places.
Shortly:
Mutable instance is passed by reference.
Immutable instance is passed by value.
Abstract example. Lets suppose that there exists a file named txtfile on my HDD. Now, when you are asking me to give you the txtfile file, I can do it in the following two modes:
I can create a shortcut to the txtfile and pass shortcut to you, or
I can do a full copy of the txtfile file and pass copied file to you.
In the first mode, the returned file represents a mutable file, because any change into the shortcut file will be reflected into the original one as well, and vice versa.
In the second mode, the returned file represents an immutable file, because any change into the copied file will not be reflected into the original one, and vice versa.
If a class type is mutable, a variable of that class type can have a number of different meanings. For example, suppose an object foo has a field int[] arr, and it holds a reference to a int[3] holding the numbers {5, 7, 9}. Even though the type of the field is known, there are at least four different things it can represent:
A potentially-shared reference, all of whose holders care only that it encapsulates the values 5, 7, and 9. If foo wants arr to encapsulate different values, it must replace it with a different array that contains the desired values. If one wants to make a copy of foo, one may give the copy either a reference to arr or a new array holding the values {1,2,3}, whichever is more convenient.
The only reference, anywhere in the universe, to an array which encapsulates the values 5, 7, and 9. set of three storage locations which at the moment hold the values 5, 7, and 9; if foo wants it to encapsulate the values 5, 8, and 9, it may either change the second item in that array or create a new array holding the values 5, 8, and 9 and abandon the old one. Note that if one wanted to make a copy of foo, one must in the copy replace arr with a reference to a new array in order for foo.arr to remain as the only reference to that array anywhere in the universe.
A reference to an array which is owned by some other object that has exposed it to foo for some reason (e.g. perhaps it wants foo to store some data there). In this scenario, arr doesn't encapsulate the contents of the array, but rather its identity. Because replacing arr with a reference to a new array would totally change its meaning, a copy of foo should hold a reference to the same array.
A reference to an array of which foo is the sole owner, but to which references are held by other object for some reason (e.g. it wants to have the other object to store data there--the flipside of the previous case). In this scenario, arr encapsulates both the identity of the array and its contents. Replacing arr with a reference to a new array would totally change its meaning, but having a clone's arr refer to foo.arr would violate the assumption that foo is the sole owner. There is thus no way to copy foo.
In theory, int[] should be a nice simple well-defined type, but it has four very different meanings. By contrast, a reference to an immutable object (e.g. String) generally only has one meaning. Much of the "power" of immutable objects stems from that fact.
Mutable collections are in general faster than their immutable counterparts when used for in-place
operations.
However, mutability comes at a cost: you need to be much more careful sharing them between
different parts of your program.
It is easy to create bugs where a shared mutable collection is updated
unexpectedly, forcing you to hunt down which line in a large codebase is performing the unwanted update.
A common approach is to use mutable collections locally within a function or private to a class where there
is a performance bottleneck, but to use immutable collections elsewhere where speed is less of a concern.
That gives you the high performance of mutable collections where it matters most, while not sacrificing
the safety that immutable collections give you throughout the bulk of your application logic.
If you return references of an array or string, then outside world can modify the content in that object, and hence make it as mutable (modifiable) object.
Immutable means can't be changed, and mutable means you can change.
Objects are different than primitives in Java. Primitives are built in types (boolean, int, etc) and objects (classes) are user created types.
Primitives and objects can be mutable or immutable when defined as member variables within the implementation of a class.
A lot of people people think primitives and object variables having a final modifier infront of them are immutable, however, this isn't exactly true. So final almost doesn't mean immutable for variables. See example here
http://www.siteconsortium.com/h/D0000F.php.
General Mutable vs Immutable
Unmodifiable - is a wrapper around modifiable. It guarantees that it can not be changed directly(but it is possibly using backing object)
Immutable - state of which can not be changed after creation. Object is immutable when all its fields are immutable. It is a next step of Unmodifiable object
Thread safe
The main advantage of Immutable object is that it is a naturally for concurrent environment. The biggest problem in concurrency is shared resource which can be changed any of thread. But if an object is immutable it is read-only which is thread safe operation. Any modification of an original immutable object return a copy
source of truth, side-effects free
As a developer you are completely sure that immutable object's state can not be changed from any place(on purpose or not). For example if a consumer uses immutable object he is able to use an original immutable object
compile optimisation
Improve performance
Disadvantage:
Copying of object is more heavy operation than changing a mutable object, that is why it has some performance footprint
To create an immutable object you should use:
1. Language level
Each language contains tools to help you with it. For example:
Java has final and primitives
Swift has let and struct[About].
Language defines a type of variable. For example:
Java has primitive and reference type,
Swift has value and reference type[About].
For immutable object more convenient is primitives and value type which make a copy by default. As for reference type it is more difficult(because you are able to change object's state out of it) but possible. For example you can use clone pattern on a developer level to make a deep(instead of shallow) copy.
2. Developer level
As a developer you should not provide an interface for changing state
[Swift] and [Java] immutable collection