In an interview I recently attented I was asked to predict the output of a code segment. Even if I got it right, I was not able to explain how got it.
This is the code segment.
int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Can anybody explain why the answer is 10 both times.?
Thanks
The num variable gets copied within the block if not marked with __block. This means that the external scope num and the inner num are actually kept at different addresses in memory and changing one doesn't affect the other. To force the compiler to use the same address, mark the variable with __block
The variable outside the block can't be changed except add '__block' before it. So the num always equal 2.
__block int num =2;
Then you will get 10 and 25
Add __block keyword before declaration so you can access the variable inside the block.
__block int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Try this...
As Ryan Hodson says in his tutorial on Objective-C Blocks:
Non-local variables are copied and stored with the block as const
variables, which means they are read-only. Trying to assign a new
value to the make variable from inside the block will throw a compiler
error.
num is defined as a non-local variable.
The fact that non-local variables are copied as constants means that a
block doesn’t just have access to non-local variables—it creates a
snapshot of them. Non-local variables are frozen at whatever value
they contain when the block is defined, and the block always uses that
value, even if the non-local variable changes later on in the program.
If you want to reflect new value of num in block declare num as block variable
__block int num =2; // *** Declared as block variable, value change will effect inside block ***
Lets understand it with your example only.
Non-local(Non block) variable*
int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Result :
my block call 1 10
my block call 2 10
block variable*
__block int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Result :
my block call 1 10
my block call 2 25
Related
I can't understand how the closure works in Dart. Why does BMW stay? This explanation causes my neurons to overheat. A lexical closure is a functional object that has access to variables from its lexical domain. Even if it is used outside of its original scope.
`void main() {
var car = makeCar('BMW');
print(makeCar);
print(car);
print(makeCar('Tesla'));
print(car('Audi'));
print(car('Nissan'));
print(car('Toyota'));
}
String Function(String) makeCar(String make) {
var ingane = '4.4';
return (model) => '$model,$ingane,$make';
}`
Console
Closure 'makeCar'
Closure 'makeCar_closure'
Closure 'makeCar_closure'
Audi,4.4,BMW
Nissan,4.4,BMW
Toyota,4.4,BMW
Calling car('Audi') is equal to calling (makeCar('BMW'))('Audi');
A lexical closure is a functional object that has access to variables from its lexical domain. Even if it is used outside of its original scope.
in simple english:
String make will stay valid as long as the returned function is not out of scope because the returned function has reference to String make.
In essence, you "inject" information needed for the newly created function. Your car knows that make is "BMW"
I think I figured it out. Here is an example where I left comments. Maybe it will help someone.
void main() {
var pr = funkOut(10); // assign a reference to an object instance
// of the Function class to the pr variable. pr is a closure because
// it is assigned a reference to an instance that contains a lexical
// environment (int a) and an anonymous function from this environment.
// 10 transfer to a
print(pr(5)); // 5 transfer to b //15
print(pr(10)); // 10 transfer to b //20
pr = funkOut(20);// 20 transfer to a
print(pr(5)); // 5 transfer to b //25
print(pr); // Closure: (int) => int
}
Function funkOut(int a) {
return (int b) => a + b;
}
Functions in Dart are first-class objects, allowing you to pass them to other objects or functions.
void main() {
var shout = (msg) => ' ${msg.toUpperCase()} ';
print(shout("yo"));
}
This made me wonder if there was a way to modify a function a run time, just like an object, prior to passing it to something else. For example:
Function add(int input) {
return add + 2;
}
If I wanted to make the function a generic addition function, then I would do:
Function add(int input, int increment) {
return add + increment;
}
But then the problem would be that the object I am passing the function to would need to specify the increment. I would like to pass the add function to another object, with the increment specified at run time, and declared within the function body so that the increment cannot be changed by the recipient of the function object.
The answer seems to be to use a lexical closure.
From here: https://dart.dev/guides/language/language-tour#built-in-types
A closure is a function object that has access to variables in its
lexical scope, even when the function is used outside of its original
scope.
Functions can close over variables defined in surrounding scopes. In
the following example, makeAdder() captures the variable addBy.
Wherever the returned function goes, it remembers addBy.
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
In the above cases, we pass 2 or 4 into the makeAdder function. The makeAdder function uses the parameter to create and return a function object that can be passed to other objects.
You most likely don't need to modify a closure, just the ability to create customized closures.
The latter is simple:
int Function(int) makeAdder(int increment) => (int value) => value + increment;
...
foo(makeAdder(1)); // Adds 1.
foo(makeAdder(4)); // Adds 2.
You can't change which variables a closure is referencing, but you can change their values ... if you an access the variable. For local variables, that's actually hard.
Mutating state which makes an existing closure change behavior can sometimes be appropriate, but those functions should be very precise about how they change and where they are being used. For a function like add which is used for its behavior, changing the behavior is rarely a good idea. It's better to replace the closure in the specific places that need to change behavior, and not risk changing the behavior in other places which happen to depend on the same closure. Otherwise it becomes very important to control where the closure actually flows.
If you still want to change the behavior of an existing global, you need to change a variable that it depends on.
Globals are easy:
int increment = 1;
int globalAdder(int value) => value + increment;
...
foo(globalAdd); // Adds 1.
increment = 2;
foo(globalAdd); // Adds 2.
I really can't recommend mutating global variables. It scales rather badly. You have no control over anything.
Another option is to use an instance variable to hold the modifiable value.
class MakeAdder {
int increment = 1;
int instanceAdd(int value) => value + increment;
}
...
var makeAdder = MakeAdder();
var adder = makeAdder.instanceAdd;
...
foo(adder); // Adds 1.
makeAdder.increment = 2;
foo(adder); // Adds 2.
That gives you much more control over who can access the increment variable. You can create multiple independent mutaable adders without them stepping on each other's toes.
To modify a local variable, you need someone to give you access to it, from inside the function where the variable is visible.
int Function(int) makeAdder(void Function(void Function(int)) setIncrementCallback) {
var increment = 1;
setIncrementCallback((v) {
increment = v;
});
return (value) => value + increment;
}
...
void Function(int) setIncrement;
int Function(int) localAdd = makeAdder((inc) { setIncrement = inc; });
...
foo(localAdd); // Adds 1.
setIncrement(2);
foo(localAdd); // Adds 2.
This is one way of passing back a way to modify the local increment variable.
It's almost always far too complicated an approach for what it gives you, I'd go with the instance variable instead.
Often, the instance variable will actually represent something in your model, some state which can meaningfully change, and then it becomes predictable and understandable when and how the state of the entire model changes, including the functions referring to that model.
Using partial function application
You can use a partial function application to bind arguments to functions.
If you have something like:
int add(int input, int increment) => input + increment;
and want to pass it to another function that expects to supply fewer arguments:
int foo(int Function(int input) applyIncrement) => applyIncrement(10);
then you could do:
foo((input) => add(input, 2); // `increment` is fixed to 2
foo((input) => add(input, 4); // `increment` is fixed to 4
Using callable objects
Another approach would be to make a callable object:
class Adder {
int increment = 0;
int call(int input) => input + increment;
}
which could be used with the same foo function above:
var adder = Adder()..increment = 2;
print(foo(adder)); // Prints: 12
adder.increment = 4;
print(foo(adder)); // Prints: 14
In programming languages such as C you can create an anonymous code block to limit the scope of variables to inside the block can the same be done with Lua?
If so what would be the Lua equivalent of the following C code?
void function()
{
{
int i = 0;
i = i + 1;
}
{
int i = 10;
i = i + 1;
}
}
You want to use do...end. From the manual:
A block can be explicitly delimited to produce a single statement:
stat ::= do block end
Explicit blocks are useful to control the scope of variable
declarations. Explicit blocks are also sometimes used to add a return
or break statement in the middle of another block
function fn()
do
local i = 0
i = i + 1
end
do
local i = 10
i = i + 1
end
end
You can delimit a block with keyword do & end.
Reference: Programming in Lua
Running an anonymous function happens as follows:
(function(a,b) print(a+b) end)(1,4)
It outputs 5.
I've seen the answer about invoking a block that is stored in an array, but I can't get it to work with parameters.
I store the array an a part of an object, then when it's in a method, I want to invoke it, however, I need parameters.
Also, is there any limit to the parameters.
Lastly, I'd rather not use the extra storage to the variable, so invoking directly while in the array would be better.
__block int x = 123; // x lives in block storage
void (^printXAndY)(int) = ^(int y) {
x = x + y;
NSLog(#"X and Y: %d %d\n", x, y);
};
self.blocks = #[printXAndY];
printXAndY(10); // this works
void(^block)(void) = self.blocks[0];
block(); // this works
block(10); // this doesn't work
[self.blocks[0] invoke ];
The problem is this line:
void(^block)(void) = self.blocks[0];
You are declaring 'block' to take no parameters and return nothing. If you want the block to take a parameter, you need to declare it like this:
void(^block)(int) = self.blocks[0];
Note that block(); will no longer work. And when you declared the block incorrectly, that line was undefined behavior.
Example code that produces the problem:
import std.stdio, core.thread;
void main() {
ThreadGroup tg = new ThreadGroup();
foreach (int i; 1 .. 5)
tg.create( () => writeln(i) );
tg.joinAll();
}
Sample output:
3
5
5
5
5
(The expected output was the integers 1 through 5.)
I don't get why this is happening -- i is not a reference type, nor is there a reference to it being used in the delegate, so why does each thread use the value of i as whatever value it happens to have when the thread is scheduled, instead of the presumably pass-by-value value it's given?
I've made a handful of lame attempts like this, but nothing's been successful:
foreach (int i; 1 .. 5) {
scope j = i;
tg.create( () => writeln(j) );
}
I'm curious as to why this doesn't work, either. Is it not declaring a fresh j each time? Why does each thread refer to the same j (whose value is usually 5 by the time the threads get scheduled)?
so why does each thread use the value of i as whatever value it happens to have when the thread is scheduled, instead of the presumably pass-by-value value it's given?
It's pass-by-value as far as the loop body goes, however that does not apply to the threads created in it. The threads will still refer to i by its address.
To fix this problem, you need to create a closure inside the loop:
import std.stdio, core.thread;
void main() {
ThreadGroup tg = new ThreadGroup();
foreach (int i; 1 .. 5)
(i =>
tg.create( () => writeln(i) )
)(i);
tg.joinAll();
}
The lambda parameter will be stored in the closure, giving each thread its own copy.