How can I pass a null reference in matlab so that isa returns true? - matlab

I have a class Foo and a function that gets Foo as input parameter. In this function I also do some error checking using isa:
function (x)
if ~isa(x,'Foo')
error('Wrong!');
end
I want to pass it something that is like null in Java. However when I pass it [] I get an error. Can you tell me what can I do? I though about always passing a cell array or checking for empty everytime I use isa.

First of all, you can check our condition with
validParam = isa(x,'Foo') || isempty(x);
However, the best way will be to create an empty class using the static method empty:
e = Foo.empty(0);
isa(x,'Foo')
And the result is:
isa(Foo.empty(0),'Foo')
ans =
1
By the way, this is also useful for another case - Suppose you want to grow dynamically and array of Foo objects. You could use a cell array, but then you lose the type safety. Instead, create Foo.empty() .
Nevertheless, there is a caveeat in using this method. It is not smart enough to handle inheritance -
Let Bar be a class that inherits from Foo.
classdef Bar < Foo
end
And you allocate a new array of Foo objects:
x = Foo.empty(0)
x =
0x0 empty Foo with no properties.
Methods
Then try to add Bar :
x(end+1) = Bar()
??? The following error occurred converting from Bar to Foo:
Error using ==> Foo
Too many input arguments.
So the only workaround for this case is to use cell array.
Edit(1): It seems that Matlab have added a special class in order to handle inheritance:
Description
matlab.mixin.Heterogeneous is an abstract class that provides support
for the formation of heterogeneous arrays. A heterogeneous array is an
array of objects that differ in their specific class, but are all
derived from or are instances of a root class. The root class derives
directly from matlab.mixin.Heterogeneous.

Related

Why this map function does not give traits' simple names

I try to get names of all trait a class extends using getInterfaces which returns an array of trait's names. When I manually access each member of the array, the method getName returns simple names like this
trait A
trait B
class C() extends A, B
val c = C()
val arr = c.getClass.getInterfaces
arr(0).getName // : String = A
arr(1).getName // : String = B
However, when I use map function on arr. The resulting array contains a cryptic version of trait's names
arr.map(t => t.getName) // : Array[String] = Array(repl$.rs$line$1$A, repl$.rs$line$2$B)
The goal of this question is not about how to get the resulting array that contains simple names (for that purpose, I can just use arr.map(t => t.getSimpleName).) What I'm curious about is that why accessing array manually and using a map do not yield a compatible result. Am I wrong to think that both ways are equivalent?
I believe you run things in Scala REPL or Ammonite.
When you define:
trait A
trait B
class C() extends A, B
classes A, B and C aren't defined in top level of root package. REPL creates some isolated environment, compiles the code and loads the results into some inner "anonymous" namespace.
Except this is not true. Where this bytecode was created is reflected in class name. So apparently there was something similar (not necessarily identical) to
// repl$ suggest object
object repl {
// .rs sound like nested object(?)
object rs {
// $line sounds like nested class
class line { /* ... */ }
// $line$1 sounds like the first anonymous instance of line
new line { trait A }
// import from `above
// $line$2 sounds like the second anonymous instance of line
new line { trait B }
// import from above
//...
}
}
which was made because of how scoping works in REPL: new line creates a new scope with previous definitions seen and new added (possibly overshadowing some old definition). This could be achieved by creating a new piece of code as code of new anonymous class, compiling it, reading into classpath, instantiating and importing its content. Byt putting each new line into separate class REPL is able to compile and run things in steps, without waiting for you to tell it that the script is completed and closed.
When you are accessing class names with runtime reflection you are seeing the artifacts of how things are being evaluated. One path might go trough REPLs prettifiers which hide such things, while the other bypass them so you see the raw value as JVM sees it.
The problem is not with map rather with Array, especially its toString method (which is one among the many reasons for not using Array).
Actually, in this case it is even worse since the REPL does some weird things to try to pretty-print Arrays which in this case didn't work well (and, IMHO, just add to the confusion)
You can fix this problem calling mkString directly like:
val arr = c.getClass.getInterfaces
val result = arr.map(t => t.getName)
val text = result.mkString("[", ", ", "]")
println(text)
However, I would rather suggest just not using Array at all, instead convert it to a proper collection (e.g. List) as soon as possible like:
val interfaces = c.getClass.getInterfaces.toList
interfaces .map(t => t.getName)
Note: About the other reasons for not using Arrays
They are mutable.
Thet are invariant.
They are not part of the collections hierarchy thus you can't use them on generic methods (well, you actually can but that requires more tricks).
Their equals is by reference instead of by value.

Can I pattern match on JS objects?

Given a function that accesses a property of a JavaScript object—
let useFoo x => Js.log x##foo;
useFoo {"foo": 10};
—is there a way to rewrite it to pattern match for the property?
I'd hoped that something like this would work, but the syntax is invalid:
let useFoo {"foo"} => Js.log foo;
There's no way to do this, and the reason for this is that Javascript objects - which are little more than mappings of keys to values - are handled using Reason's (ie. OCaml's) object-oriented system. In Reason/OCaml, you cannot pattern match over functions ie. if I have a record containing a lambda, I cannot pattern match over the result of applying that lambda:
type t = {foo: int => int};
let bar {foo} => foo 5;
Notice that I can pattern match and get the foo lambda out of the record, but I can't apply foo inside the pattern match -- I have to apply it to the argument '5' after I extracted it.
Here's the problem with objects: the only interface to objects in Reason is via their public methods. Methods are like lambdas, except that their first argument is always self, which is the object itself. So every time we access x##foo, we're really dispatching the foo method, feeding it x as an argument, and getting the result back. Just as we can't pattern match in Reason over function application, we can't pattern match over objects either, since objects are just collections of functions that get applied automatically.

Pass copy of object to method

I've run into an issue where, when using a loop and passing an object into a method, my object is being modified when the method returns, breaking the next iteration.
The code I'm using is quite elaborate, so I'll simplify with the following:
val car: Car = expensiveMethod("greenCar")
for (i <- 1 to 5) {
foo(car)
}
def foo (car: Car) = {
assert(car.name == "greenCar")
car.name = "redCar"
}
expensiveMethod is, as it sounds, expensive, so I'd prefer not to call it inside the for loop every time.
Car is also not a case class, so I can't use the built in copy method.
Is there a simple way to send a copy of car into foo, or an alternate approach?
It may be that name member of your Car class is public and mutable.
Also from definition of foo function the signature is foo: (car: Car)Unit, which could mean that it is not a pure function, a side effecting function (or procedure) in this case as its modifying the parameter. You should explicitly create a copy of parameter and mutate the copy.

OPAL: null-value in operandsArray

I am currently developing a static analysis of Java code using the OPAL framework.
I want to analyze the following Java method:
private void indirectCaller2b(double d, Object o1, Object o2) {
indirectCaller1(d, o1, o2);
}
I know, that indirectCaller2b is only called with the parameters (double, ArrayList, LinkedList).
Having this in mind, I constructed an IndexedSeq of DomainValues, which I pass to the perform-method ob BaseAI.
It looks like this:
Vector({ai.native_methods_parameter_type_approximation.PublicClass, null}[#0;t=101], ADoubleValue, {_ <: java.util.ArrayList, null}[#-4;t=102], {_ <: java.util.LinkedList, null}[#-5;t=103])
The this-parameter ({ai.native_methods_parameter_type_approximation.PublicClass, null}[#0;t=101]) was created with the following code:
domain.TypedValue(0, project.classFile(caller).thisType)
The other domain values were created using the parameterToValueIndex method:
org.opalj.ai.parameterToValueIndex(caller.isStatic, caller.descriptor, index), t)
Here, caller stands for the method indirectCaller2b and t is the known runtime type of the parameter (ArrayList for parameter index 1 and LinkedList for parameter index 2).
When I now perform the abstract interpretation of the method with
BaseAI.perform(classFile, caller, domain)(Some(parameters))
and print the stack index at the program counter, where the call of indirectCaller1 happens with the following code,
for (i <- 0 to analysisResult.operandsArray(pc).size - 1) {
println(s"stack index $i: ${analysisResult.operandsArray(pc)(i)}")
}
I get the following output:
stack index 0: null
stack index 1: {_ <: java.util.LinkedList, null}[#-5;t=103]
stack index 2: ADoubleValue
stack index 3: {ai.native_methods_parameter_type_approximation.PublicClass, null}[#0;t=101]
This is a bit confusing, since I just pass the arguments of indirectCaller2b to indirectCaller1. Therefore, the output should be the same as the IndexedSeq is passed to the perform method.
But in the output, parameter after the double parameter is LinkedList instead of ArrayList. The ArrayList parameter somehow disappeared, and the last parameter on the operandStack is "null".
Can anyone explain me, how this can happen?
Representation of "this"
To get the correct representation for the "this" reference you should use the method
InitializedObjectValue(
origin: ValueOrigin,
objectType: ObjectType ): DomainReferenceValue
to create a representation of the this value. The difference is that in this case the AI will try to use the information that (a) the value is guaranteed to be non-null and is also guaranteed to be initialized. In particular the former property is often interesting and generally leads to more precise results.
Initializing Locals
The function: org.opalj.ai.parameterToValueIndex only calculates the logical origin information (the "pc" that is associated with the value to make it possible to identify the respective values as parameters later on).
To correctly map operands to locals you can either use the method mapOperandsToParameters or you just add all values to an IndexedSeq but add another null value for computational type category 2 values.

Perfect hash in Scala

I have some class C:
class C (...) { ... }
I want to use it to index an efficient map. The most efficient map is an Array.
So I add a "global" "static" counter in companion object to give each object unique id:
object C {
var id_counter = 0
}
In primary constructor of C, with each creation of C I want to
remember global counter value and increase it.
Question 1: How to do it?
Now I can use id in C objects as perfect hash to index array.
But array does not preserve type information like map would, that a given array is indexed by C's id.
Question 2: Is it possible to have it with type safety?
Update:
Type safety in question 2 concerns type of index of map, to avoid mixing two not related ints.
The value of course is (type) safe..
Question 1 asks how to increment a variable in default contructor?
Ie: Where to put?
id_counter += 1
Answer to your question 2:
case class C_Id(val asInt: Int)
object C {
private var list: ArrayBuffer[C]
// resizable array in scala.collection.mutable
// you can also use ArrayList
def apply(id: C_Id) = list(id.asInt) // only accepts an id of C
...
}
class C (...) {
// in constructor:
list += this
}
To edited question 1: The default constructor is just the body of the type, except the definitions of methods and other constructors.
I don't see the problem. I would probably make the counter private so code outside class and object C cannot alter it. Incrementing a var of type Int is trivial:
idCounter += 1
Arrays are type-safe in Scala, since they are implemented directly by JVM arrays (starting in 2.8).
I suspect I've not really understood your questions...
Update:
Increment the counter in the constructor, presumably.
As for creating an actual perfect hash function, I don't think you're really on the right track. (You've just pushed the mapping from whatever your actual keys are into your own code.) You should read up on techniques for creating minimal and / or perfect hash functions.
Could you make the default constructor of C private, and provide a factory method in the companion object (which could easily handle updating the counter)?