I think inout makes you passes in a reference (is that accurate?), then if the reference gets changed many times, as you might do with an array, the array then does not have to copied many times because its now a reference type?
The semantics for in-out parameters in swift is different from passing value by reference. Here's exactly what happens when you're passing an in-out parameter:
In-out parameters are passed as follows:
When the function is called, the value of the argument is copied.
In the body of the function, the copy is modified.
When the function returns, the copy’s value is assigned to the original argument.
This behavior is known as copy-in copy-out or call by value result. For example, when a computed property or a property with observers is passed as an in-out parameter, its getter is called as part of the function call and its setter is called as part of the function return.
See https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID545
Array is value type in swift so it's fully copied in this scenario. Of course the swift compiler may optimize that but anyway you're guaranteed to see exact same behavior as it'd be with full copies performed.
If you want to pass an array by reference and allow the called function to modify elements quickly, you have the choice of either explictly creating an NSMutableArray, or creating a class where instances have an array as their single member.
Related
While writing a rather simple code for an exercise i was assigned, I run into this problem.
The exercise asks me to create a function (what it does it's not important, but it loops through each element of the matrix to do something) getting as parameters a 2D array (NxM) and a double (which is used in the function).
The function so looks something like this:
int function(int (*myarray)[M], double y){}
Now if I'm not missing anything, this is not enough because I can't loop through the elements without using the value N as range. Am I right? If there is no way to use the number of rows inside this function without passing it as a parameter, it means that the exercise took for granted that passing the matrix meant also passing N (rows) as a parameter.
(I thought about using sizeof to get the number of rows somehow, but sizeof(myarray) inside function(){} doesn't work as expected. What is the difference between myarray inside this function and the original myarray I declared in main()?)
myarray is declared as int myarray[N][M]; and then initialized with a loop which contains myarray[i][j] = rand()%(max-min+1)+min;. I don't think this is too relevant to the problem but I include it to explain it is automatically allocated.
I already checked some similar discussions like thisand this but since everyone gives the dimension as parameter I didn't find an answer yet.
Can I use a matrix in a function without specifying ROWS?”
The answer is largely no. The function must have some way of knowing how much data to use from the array. That is not necessarily the original size of the array; it could be the amount of the array, or portions of the array, the caller wants the function to operate on. The C standard does not provide any way to know the original size of an array from a pointer.
That information can be made available to the function in multiple ways: By a parameter, by an external variable, including by a sentinel value.
Now if I'm not missing anything, this is not enough because I can't loop through the elements without using the value N as range. Am I right?
Passing the number of rows in the array is one way of being able to iterate through them. The information could be made available in other ways. In your circumstance, passing the number of rows is likely the intended method.
What is the difference between myarray inside this function and the original myarray I declared in main()?)
When a function parameter is declared as an array, it is automatically adjusted to be a pointer. So, if a parameter were declared as int myarray[N][M], it would be automatically adjusted to int (*myarray)[M]. Then myarray inside the function is not an array; it is a pointer.
When an array is passed to a function as an argument, it is automatically converted to a pointer to its first element. This automatic conversion occurs whenever an array is used in an expression except as the operand of sizeof or the operand of unary & or when it is a string literal that is used to initialize an array.
For my simulation, I have a field that is called particle.current_theta. When this field is a single variable, I assign it a new value that is called just "theta" on my line 177. This theta has its value changed further down within my code, on lines 202 and 206. I want what I have printed in my terminal as tree_theta and current_theta to be very similar to each other but not quite identical (This part of the code basically detects whether or not my particle is entering or exiting a region). You can see all this in the image below:
Now, I need to make the field I have called particle.current_theta a [1x1] array, and assign the entry in my [1x1] array the "theta" value, as usual. However, simply making particle.current_theta a [1x1] array radically changes its value within the terminal and causes my simulation to break. You can see how the value for particle.theta (printed in terminal as "current theta") is now drastically different in the code below:
I suspect that making particle.currenttheta an array is making it mutate whenever theta is changed in some of those lines below. How do I prevent that from happening, and get results that are identical to using just a single variable. To be precise, I want particle.current_theta to save the numerical information that theta has at line 177 of code but not be changed afterwards. Because of the large size of my code now and the function calls within function calls, it would be infeasible for me to be able to create a mwe that replicates this issue. However, all help and advice is appreciated, and I will respond to and clarify any questions that people may have.
If theta is a scalar (and it appears to be), then it's unlikely that changing its value is what is changing particle.currenttheta. What is more likely is that you're passing the currenttheta to some function, and changing the value of the passed argument inside the function. Julia arrays are passed to functions "by reference", in the sense that a copy is not made, and instead any changes made inside the function change the original array. When you had currenttheta as a scalar (which are passed "by value" instead), when you pass that to a function, changes made inside the function do not affect the original currenttheta's value.
So if you're passing currenttheta to a function somewhere and don't want it to be modified inside the function, pass copy(particle.currenttheta) in that call instead.
If you're not doing that, or that doesn't solve the problem, we need more of the code to figure out where the change might actually be happening. If not the whole of it, at least the parts that handle currenttheta, and the parts that print it. (Also, it would massively help with clarity if you would use consistent names in the output. Sometimes it's treetheta and current theta, other times it's theta and particle.currentheta, and it's not clear where these are being printed from and what the difference - if any - is.)
Can React.useMemo second argument array contains an object?
I ask this question because I have an expensive computation based on an object's value.
I don't know should I expand the object, or just simply pass the object into that array.
It is possible to use an object as 2nd argument. But it depends on how the object behaves. If there will be always a new instance of this object each time the affected value(s) has changed, React.useMemo will be able to detect the change. Since React.useMemo will only do an instance compare in case of an object, it will not detect changes within that object if the instance remain the same. If the instance changes more often then the affected properties, it would be better to extract only the required properties and hand them over individually. This will ensure the calculition will only be done if need.
This is a sort of followup to my previous question about nested registered C functions found here:
Trying to call a function in Lua with nested tables
The previous question gave me the answer to adding a nested function like this:
dog.beagle.fetch()
I also would like to have variables at that level like:
dog.beagle.name
dog.beagle.microchipID
I want this string and number to be allocated in C and accessible by Lua. So, in C code, the variables might be defined as:
int microchipIDNumber;
char dogname[500];
The C variables need to be updated by assignments in Lua and its value needs to be retrieved by Lua when it is on the right of the equal sign. I have tried the __index and __newindex metamethod concept but everything I try seems to break down when I have 2 dots in the Lua path to the variable. I know I am probably making it more complicated with the 2 dots, but it makes the organization much easier to read in the Lua code. I also need to get an event for the assignment because I need to spin up some hardware when the microchipIDNumber value changes. I assume I can do this through the __newindex while I am setting the value.
Any ideas on how you would code the metatables and methods to accomplish the nesting? Could it be because my previous function declarations are confusing Lua?
The colon operator (:) in Lua is used only for functions. Consider the following example:
meta = {}
meta["__index"] = function(n,m) print(n) print(m) return m end
object = {}
setmetatable(object,meta)
print(object.foo)
The index function will simply print the two arguments it is passed and return the second one (which we will also print, because just doing object.foo is a syntax error). The output is going to be table: 0x153e6d0 foo foo with new lines. So __index gets the object in which we're looking up the variable and it's name. Now, if we replace object.foo with object:foo we get this:
input:5: function arguments expected near ')'
This is the because : in object:foo is syntactic sugar for object.foo(object), so Lua expects that you will provide arguments for a function call. If we did provide arguments (object:foo("bar")) we get this:
table: 0x222b3b0
foo
input:5: attempt to call method 'foo' (a string value)
So our __index function still gets called, but it is not passed the argument - Lua simply attemps to call the return value. So don't use : for members.
With that out of the way, let's look at how you can sync variables between Lua and C. This is actually quite involved and there are different ways to do it. One solution would be to use a combination of __index and __newindex. If you have a beagle structure in C, I'd recommend making these C functions and pushing them into the metatable of a Lua table as C-closures with a pointer to your C struct as an upvalue. Look at this for some info on lua_pushcclosure and this on closures in Lua in general.
If you don't have a single structure you can reference, it gets a lot more complicated, since you'll have to somehow store pairs variableName-variableLocation on the C side and know what type each is. You could maintain such a list in the actual Lua table, so dog.beagle would be a map of variable name to one or two something's. There a couple of options for this 'something'. First - one light user data (ie - a C pointer), but then you'll have the issue of figuring out what that is pointing to, so that you know what Lua type to push in for __index and what to pop out for __newindex . The other option is to push two functions/closures. You can make a C function for each type you'll have to handle (number, string, table, etc) and push the appropriate one for each variable, or make a uber-closure that takes a parameter what type it's being given and then just vary the up-values you push it with. In this case the __index and __newindex functions will simply lookup the appropriate function for a given variable name and call it, so it would be probably easiest to implement it in Lua.
In the case of two functions your dog.beagle might look something like this (not actual Lua syntax):
dog.beagle = {
__metatable = {
__index = function(table,key)
local getFunc = rawget(table,key).get
return getFunc(table,key)
end
__newindex = function(table,key,value)
local setFunc = rawget(table,key).set
setFunc(table,key,value)
end
}
"color" = {
"set" = *C function for setting color or closure with an upvalue to tell it's given a color*,
"get" = *C function for getting color or closure with an upvalue to tell it to return a color*
}
}
Notes about the above: 1.Don't set an object's __metatable field directly - it's used to hide the real metatable. Use setmetatable(object,metatable). 2. Notice the usage of rawget. We need it because otherwise trying to get a field of the object from within __index would be an infinite recursion. 3. You'll have to do a bit more error checking in the event rawget(table,key) returns nil, or if what it returns does not have get/set members.
That's an issue I still don't understand.
Sometimes I have to write:
NSString* myVariable;
myVariable = #"Hey!";
Then, for example I define a Structure "DemoStruct" and get an Variable that uses it. Lets say I have a Structure that has x and y vars from type double.
I want to pass this var to a method which then manipulates my var, and I want that this manipulation has effect on the context from which I passed the var to that method. So I need a pointer, right.
I pass it to the method like that:
[someObject someMethod:&myVarThatUsesTheStruct]
that method now looks like that:
- (void)someMethod:(DemoStruct*)myVar {
(*myVar).x += 10;
}
Before the call, the component x of the struct was lets say 1000. Now, 10 is added and it is 1010 after the method call.
But I really really hardly dont get it why I have to use the Asterisk * for myVar in the Method, since I say already in the Method Header that myVar is a POINTER to a DemoStruct. I just pass with &myVarThatUsesTheStruct the memory address.
Can someone explain why this is like it is?
As you say, myVar is a pointer. As such, myVar.x is not correct: it would by a field of a pointer, which has no sense in C/Objective-C.
If you want to access to the variable pointed to by a pointer, you have to add the asterisk: myVar is a pointer, *myVar is the variable pointed to by myVar.
Moreover, in your case, you can use a special construct of C by writing myVar->x, which is strictly equivalent to (*myVar).x.
All of this is standard C, not specific to Objective-C.
About your first example, you don't have to put an asterisk because you change the value of the pointer, not the value of the variable: myVariable is a pointer to an object which at declaration time is assigned the nil value. The next instruction (myVariable = #"Hey!") is an assignment of pointer values: #"Hey!" is a pointer to a NSString object. The value of this pointer (not the value of the pointed constant) is assigned to myVariable, which then points to the object #"Hey!".
Yes, this is diffucult to follow at first time...
* is the dereference operator. All that *myVar means is "Get me the thing that the pointer myVar points to". You need this distinction because you need to tell the computer that you want to change the thing that myVar points to, not myVar itself.
taken from the learning objective c link via the developers portal for iphone devs:
Objective-C supports both strong and weak typing for variables
containing objects. Strongly typed variables include the class name in
the variable type declaration. Weakly typed variables use the type id
for the object instead. Weakly typed variables are used frequently for
things such as collection classes, where the exact type of the objects
in a collection may be unknown. If you are used to using strongly
typed languages, you might think that the use of weakly typed
variables would cause problems, but they actually provide tremendous
flexibility and allow for much greater dynamism in Objective-C
programs.
The following example shows strongly and weakly typed variable
declarations:
MyClass *myObject1; // Strong typing
id myObject2; // Weak typing
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.