Assign the object reference not the object - oop

I have come across a problem with bindings in Julia
When trying to do this:
type Chain
value :: Int
son :: Chain
#Make the last link in the chain point to itself
#so as to spare us from the julia workaround for nulls
Chain(value::Int) = (chain = new(); chain.value = value; chain.son = chain; chain)
end
#Create three separate nodes
c=Chain(5)
d=Chain(2)
e=Chain(1)
#Link an object to another and then modify the linked object
c.son = d
son = d.son
son = e
c
I would like to change the link for the son in the parent, but it only works if I do this:
c.son = d
d.son = e
c
This creates a problem in recursive functions, where if you pass an object to the function which is linked to another object and change it in the body of the function then the link isn't changed, only the object itself.
I have tried using the julia function pointer_from_objref, but this used for handling c functions and the assigning with unsafe_store! didn't work.
How would I go about to create a variable that when assigned to also changes the link to which I referred to?

if i understood you property, you can declare son as an Array=>son::Array{Chain,1} to achieve this.
type Chain
value::Int
son::Array{Chain,1}
Chain(value::Int) = (chain = new(); chain.value = value; chain.son = [chain]; chain)
end
julia> c=Chain(5)
Chain(5,[Chain(#= circular reference =#)])
julia> d=Chain(2)
Chain(2,[Chain(#= circular reference =#)])
julia> e=Chain(1)
Chain(1,[Chain(#= circular reference =#)])
julia> c.son = [d]
1-element Array{Chain,1}:
Chain(2,[Chain(#= circular reference =#)])
julia> son = d.son
1-element Array{Chain,1}:
Chain(2,[Chain(#= circular reference =#)])
julia> son[:] = e
Chain(1,[Chain(#= circular reference =#)])
julia> c
Chain(5,[Chain(2,[Chain(1,[Chain(#= circular reference =#)])])])
this is because by running son = d.son and son = e, you just entirely change the binding.
# NOT using array type
julia> son = d.son
Chain(2,Chain(#= circular reference =#))
julia> son = e
Chain(1,Chain(#= circular reference =#))
julia> son === d.son
false
# using array type
julia> son = d.son
1-element Array{Chain,1}:
Chain(2,[Chain(#= circular reference =#)])
julia> son[:] = e
Chain(1,[Chain(#= circular reference =#)])
julia> son === d.son
true
if you want to reserve the link, a workaround is to use array type and change the content of the array instead of its binding. more details about bindings.

Related

Why can't Kotlin variables assigned from fields change in function?

I'm trying to understand why can't a variable that is assigned from a class field change in a function. Consider this example:
class A {
private var a: String? = "a"
fun hello() {
val b = a
if (b != null) {
// The compiler assumes that 'b' is always not null inside this branch
b.length
} else {
// is null
}
}
}
Variable b is going to always be the same throughout the function (later is implicit non null in the if branch). So even if through concurrency I change the field a, the variable b does not change?
How is this possible? does Kotlin make a copy of the variable and assigns it to b? I thought assignments worked with references and such.
This can happen, as far as I'm concerned, with any type (String, Int, custom class, etc)
Strings are immutable, there's no way you can change them after you instantiated them. Thus, if another thread modifies the value of a after b != null was evaluated, it will not affect b's value.
Actually it's not even the real answer because here we're just talking about nullity. b will point to whatever object was pointed by a at the moment of the assignment, but then nothing can change what b is pointing to because b is a val.
I was just mentioning immutability because the content of b could still change through mutation if the type was mutable, but the reference itself will never change.
For more clarity, let's make a scenario:
[thread 1] a = "hello" <state: a => h: String("hello")>
[thread 1] b = a <state: a => h, b => h>
[thread 2] a = "world" <state: a => w: String("world"), b => h>
In short, b points to the same object as a at the time of assignment, but it doesn't point to a itself, so when a changes, b doesn't care.

Generating a method for each subtype within a module

(Reposted from Julia slack for posterity)
let’s say I have some constants like
const FooConst = 1
const BarConst = 2
and I also have some struct
struct Foo end
struct Bar end
and I now want to define a method for each struct to look up that constant
f(::Type{Foo}) = FooConst
f(::Type{Bar}) = BarConst
how would I achieve that last block using metaprogramming? I'm essentially trying to tack on Const to the end of the name of the Struct and look that up in the code
...
...(this) works outside of a module, but in my module the constants aren't exported. After I import my module, f isn't able to look the constants up. MWE here:
module M
import InteractiveUtils: subtypes
export Foo, Bar, f
abstract type Super end
struct Foo <: Super end
struct Bar <: Super end
const FooConst = 1
const BarConst = 2
for T in subtypes(Super)
#eval f(::Type{$T}) = $(Symbol(T, "Const"))
end
end # module
and then in my REPL:
julia> using Main.M
julia> f(Foo)
ERROR: UndefVarError: Main.M.FooConst not defined
Stacktrace:
[1] f(::Type{Foo}) at ./none:11
[2] top-level scope at none:0
I am however able to access it directly:
julia> Main.M.FooConst
1
From Mason Protter on Julia slack:
Mason Protter 2:26 PM
#Sebastian Rollen The issue was the Symbol(T, "const"). That actually ended up expanding to Symbol("Main.Foo.FooConst") and Symbol("Main.Foo.BarConst") instead of Symbol("FooConst") and Symbol("BarConst") respectively. You can fix that using Symbol(nameof(T), "Const") as shown here:
module M
import InteractiveUtils: subtypes
export Foo, Bar, f
abstract type Super end
struct Foo <: Super end
struct Bar <: Super end
const FooConst = 1
const BarConst = 2
for T in subtypes(Super)
#eval f(::Type{$T}) = $(Symbol(nameof(T), "Const"))
end
end # module
julia> using .M; f(Foo)
1
julia> f(Bar)
2
Make sure you restart Julia before running this code or Julia will continue to use the exported functions from the old version of your module.

Kotlin: Why does val b (Map) change over the iteration even though actions occur over another var a in do-while loop?

Why does such code only occur in one iteration? Why does "b" change simultaneously with "a" after assignment before the end of the iteration?
I made a similar code where (a) and (b) are integers, then (b) does not change until the next iteration. Why does it behave differently with Map?
var a = mutableMapOf("z" to 1)
do {
val b = a
a["x"] = 2
// why here b == a in the first iteration?
} while (a != b)
According to #jsamol comment, it says:
"Similar to Java, Kotlin never implicitly copies objects on assignment. Variables always hold references to objects, and assigning an expression to a variable only copies a reference to the object, not the object itself."
I've changed the condition so I can compare integers, not maps. How it works.
var a = mutableMapOf("z" to 1)
do {
val b = a.size
a["x"] = 2
} while (a.size != b)

Does MATLAB support "callable" (i.e. function-like) classes?

Is it possible to define a MATLAB class such that the objects from this class can be called like any other function?
IOW, I'm asking whether one can write in MATLAB the equivalent of something like the following Python class:
# define the class FxnClass
class FxnClass(object):
def __init__(self, template):
self.template = template
def __call__(self, x, y, z):
print self.template % locals()
# create an instance of FxnClass
f = FxnClass('x is %(x)r; y is %(y)r; z is %(z)r')
# call the instance of FxnClass
f(3, 'two', False)
...
[OUTPUT]
x is 3; y is 'two'; z is False
Thanks!
I do not know, whether MATLAB directly supports what you want, but MATLAB does support first-class functions; closures might therefore provide a useable substitute, for instance:
function f = count_call(msg)
calls = 0;
function current_count()
disp(strcat(msg, num2str(calls)));
calls = calls + 1;
end
f = #current_count;
end
In this case, current_count closes over calls (and msg). That way you can express functions that depend on some internal state. You would use it this way:
g = count_call('number of calls: ') % returns a new function ("__init__")
g() % "__call__"
I will be interested to see if this is possible without simply creating a java method in Matlab. I know you can do the following
classdef ExampleObject
properties
test;
end
methods
function exampleObject = ExampleObject(inputTest)
exampleObject.test=inputTest;
end
function f(exampleObject,funcInput)
disp(funcInput+exampleObject.test);
end
end
end
>> e=ExampleObject(5);
>> f(e,10)
15
But as far as my knowledge goes, if you tried to override the call function you'd run into a conflict with Matlab's parenthetical subscript reference subsref. You can find a reference here showing how to overwrite that, and you might be able to get it to do what you want...but it doesn't seem like good form to do so. Not sure how Matlab would handle a call to an object (as opposed to a function) without it getting confused with this.
One way is to override the feval function for your class:
classdef FxnClass < handle
properties
template
end
methods
function obj = FxnClass(t)
obj.template = t;
end
function out = feval(obj, varargin)
out = sprintf(obj.template, varargin{:});
end
end
end
This would be used as:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> feval(f, 3,'two',false)
ans =
x = 3.000000, y = two, z = 0
Now if you want to provide additional syntactic sugar, you could redefine the subsref function for your class as #Salain suggested. Add the following to the previous class definition:
classdef FxnClass < handle
...
methods
function out = subsref(obj, S)
switch S(1).type
case '.'
% call builtin subsref, so we dont break the dot notation
out = builtin('subsref', obj, S);
case '()'
out = feval(obj, S.subs{:});
case '{}'
error('Not a supported subscripted reference');
end
end
end
end
Now you could simply write:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3,'two',false)
ans =
x = 3.000000, y = two, z = 0
Personally I don't particularly like overriding the subsref or subsasgn functions. They are used for too many cases, and its sometimes hard to get them write. For example all the following will eventually call the subsref method with different input:
f(..)
f.template
f.template(..)
f(..).template
f(..).template(..)
There is also the case of the end keyword which could appear in indexing, so you might have to also override it as well in some cases. Not to mention that objects can also be concatenated into arrays, which makes things even more complicated:
>> ff = [f,f];
>> ff(1) % not what you expect!
That said, I think #Frank's suggestion to use nested functions with closures is more elegant in this case:
function f = FxnClass(t)
f = #call;
function out = call(varargin)
out = sprintf(t, varargin{:});
end
end
which is called as before:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3, 'two', false)
If you mean that you want a class to hold a method which you use like a normal function (eg. defined in an m-file), then yes, Matlab does support static methods.
A static method runs independently of any instances of that class, in fact, you don't even need to instantiate a class to use its static methods.
Matlab does not support static fields, however, so you would have to instantiate such a class first, and then set its fields before using the functions (which presumably make use of these fields, since you are asking this question).
Given the limitation with static members, you might be better off with closures, as described by Frank.

Matlab: Convert superclass to subclass object

I want to create a subclass, ess say, to the built-in ss class. I'd like to be able to convert an existing ss object to an ess object and at the same time add the missing properties, e.g. w, by something like this
sys=ss(a,b,c,d);
esys=ess(sys,w);
but I can't figure out how to setup the constructor correctly. What is the best way to achieve this? My code currently looks like this
classdef ess < ss
properties
w
end
methods
function obj = ess(varargin)
if nargin>0 && isa(varargin{1},'StateSpaceModel')
super_args{1} = sys;
else
super_args = varargin;
end
obj = obj#ss(super_args{:});
end
end
end
But this does not work as I get the following error:
>> ess(ss(a,b,c,d))
??? When constructing an instance of class 'ess', the constructor must preserve
the class of the returned object.
Of course I could copy all the object properties by hand but it seems to me that there should be some better way.
Here is an example of what I had in mind:
classdef ss < handle
properties
a
b
end
methods
function obj = ss(varargin)
args = {0 0}; %# default values
if nargin > 0, args = varargin; end
obj.a = args{1};
obj.b = args{2};
end
end
end
and:
classdef ess < ss
properties
c
end
methods
function obj = ess(c, varargin)
args = {};
if nargin>1 && isa(varargin{1}, 'ss')
args = getProps(varargin{1});
end
obj#ss(args{:}); %# call base-class constructor
obj.c = c;
end
end
end
%# private function that extracts object properties
function props = getProps(ssObj)
props{1} = ssObj.a;
props{2} = ssObj.b;
end
Lets test those classes:
x = ss(1,2);
xx = ess(3,x)
I get:
xx =
ess handle
Properties:
c: 3
a: 1
b: 2
Methods, Events, Superclasses