What gets executed first in a nested function? - xcode

When I create a constant to put my closure to work:
let incrementByTen = makeIncrementer(forIncrement: 10)
Does it skip incrementer() until it's called in the return statement, that way the return statement can run the incrementer() function in the end and receive its value?
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}

The arguments to a function are evaluated when the function is called. In this case that means that when makeIncrementer is called, it's argument (10 in this case) will be evaluated before makeIncrementer is actually called.
Likewise, when makeIncrementer is invoked, it's code will be executed in sequence, initializing runningTotal and then initializing incrementer (note that at this point amount has been evaluated already, so in the returned incremented, it is ALWAYS 10.
Subsequently, when you invoke incrementByTen() there are no arguments to pass and nothing to be evaluated before the call, as part of executing the closure, runningTotal will be incremented by amount, in this case, always 10.

In a comment you have extended your question with:
I've read that this function captures a reference to runningTotal and amount. What's hard to grasp is how it keeps increasing when I repeatedly call incrementByTen().
The function incrementer captures the value of amount and the variable runningTotal. Capturing a value just involves copying the value into the function value (aka closure).
Capturing the variable is more involved: as a local variable runningTotal's lifetime would usually only extend at most to the end of the function invocation it is created by - so a call to makeIncrementer would create a new local runningTotal and when that call returned the variable would be destroyed. However as runningTotal is captured as a variable by incrementer then its lifetime is automatically extended as long as it is required by incrementer, which is as long as incrementer itself is required. As incrementer is the value returned by makeIncrementer the lifetime of runningTotal extends past the lifetime of the call to makeIncrementer.
Later each time the function returned by a single call to makeIncrementer is invoked as it has captured the variable runningTotal from that call it is incremented by 10 and its current value returned.
If you call makeIncrementer twice and store both results, then each result references a distinct function and each of those functions references a distinct variable - so you have two distinct incrementing counters.
HTH

Related

Returning the last return values of an iterator without storing a vararg in a table

Writing a function that takes a generic for loop iterator consisting of the iterator function, the invariant state & the loop control variable to return the value the control variable has in the last iteration is straightforward:
function iterator_last_value(iterator, state, control_var)
local last
for value in iterator, state, control_var do
last = value
end
return last
end
print(iterator_last_value(("hello world"):gmatch"%a+")) -- world
This could be easily extended to support arbitrary constant numbers of arguments up to Lua's local register limit. We can also add vararg iterator return value support by always storing the last vararg in a table; this requires us to get rid of Lua's for loop syntactic sugar:
function iterator_last(iterator, state, control_var)
local last = {}
local last_n = 0
local function iter(...)
local control_var = ...
if control_var == nil then
return table.unpack(last, 1, last_n)
end
last = {...}
last_n = select("#", ...)
return iter(iterator(state, control_var))
end
return iter(iterator(state, control_var))
end
print(iterator_last(ipairs{"a", "b", "c"})) -- 3, c
which works well but creates a garbage table every iteration. If we replace
last = {...}
last_n = select("#", ...)
with
last_n = select("#", ...)
for i = 1, last_n do
last[i] = select(i, ...)
end
we can get away with reusing one table - presumably at the cost of manually filling the table using select being less efficient than {...}, but creating significantly fewer garbage tables (only one garbage table per call to iterator_last).
Is it possible to implement a variadic return value iterator_last without storing a vararg with significant overhead using a table, coroutine or the like, leaving it on the stack and only passing the varargs around through function calls? I conjure that this is not possible, but have been unable to prove or disprove it.

How to measure and capture a script’s execution time in DolphinDB?

I’d like to measure and capture my script’s execution time and assign it to an variable. I tried to assign the return of function timer to variable a, but it raised an exception of “invalid expression”.
a = timer x=1
The exception is raised because timer is not a function but a procedure. It only prints a message that cannot be assigned to a variable. However, you can use function evalTimer, which returns a scalar that can be assigned to a variable.
To use function evalTimer, you can rewrite the statement block as a user-defined function. See evalTimer — DolphinDB 1.3 documentation
You can also check the syntax of a function with syntax:
syntax(evalTimer)
// evalTimer(funcs, [count=1])
funcs: the function(s) for which the execution time is measured
count: the number of times funcs will be executed. The default value is 1.
To measure the execution time of function foo:
def foo(){
x=1
}
a= evalTimer(foo,10);
print(a)
// output: 0.031341
In the above example, the code to be executed is encapsulated into a user-defined function foo. Then use function evalTimer to measure the time of running function foo 10 times, assign the result to variable a, and print it out.

I tried to shorten the code by removing assignments, but the result completely changed somehow., any explanation?

I tried this example code to see if it actually work
--This example is from Programming in Lua Second Edition
function values (t)
local i = 0
return function ()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
iter = values(t)
while true do
local element = iter()
-- calls the iterator
if element == nil then
break
end
print(element) --> 10, 20, 30
end
I decided to change it a bit, I thought the code will get the same result but I think I was wrong
--This example is from Programming in Lua Second Edition
function values (t)
local i = 0
return function ()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
while true do
local element = values(t)()
-- calls the iterator
if element == nil then
break
end
print(element) --> This will print 10 forever if I don't stop the IDE
end
Why is iter important that much?
When you do local element = values(t)(), you are actually creating an iterator function every single time your loop is running. Take a note of your values function, see that it has a local variable called i. Every single time you are running this function, a local variable is initialized and sent to your inner function which handles the iteration. The original example is perfectly fine, however if you want to practice local and global variables, you may change the local i to a global variable i, or a different name and move it outside your function so it will not get called every time you run your iterate function (You may keep it local still, so the scope will be limited to current file). However, that is totally not recommended, since your value may be re-used some time later by another function or file, also it will limit you to one full iteration per run (Unless you set the value back to zero before retrying to iterate.)
local i = 0 -- Notice that the variable is taken out of the function.
-- With your example, the problem was that this variable was set to 0 for every
-- time you called the function.
function values (t)
return function ()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
while true do
local element = values(t)()
-- calls the iterator
if element == nil then
break
end
print(element) --> This will print 10 forever if I don't stop the IDE
end
Also keep performance in your mind, as every time you are iterating with your example, a function is being created, called, and then destroyed by the garbage collection. This is why the original example created an iterator function only once, and then called it multiple times, whereas your example creates an iterator function every time it is looping.
If all you need to do is to iterate through elements of a table, then lua already has generic for loop (pairs), check here and here. Example in your case (which also shortens your code by a lot):
local t = {10, 20, 30}
-- We don't need key in this case, but if you do, replace _ with k or
-- any other variable name you want.
for _, element in pairs(t) do
print(element)
end

Introspecting _ENV from coroutines

NB: I am using Lua version 5.3.
This question is motivated by Exercise 25.1 (p. 264) of Programming in Lua (4th ed.). That exercise reads as follows:
Exercise 25.1: Adapt getvarvalue (Listing 25.1) to work with different coroutines (like the functions from the debug library).
The function getvarvalue that the exercise refers to is copied verbatim below.
-- Listing 25.1 (p. 256) of *Programming in Lua* (4th ed.)
function getvarvalue (name, level, isenv)
local value
local found = false
level = (level or 1) + 1
-- try local variables
for i = 1, math.huge do
local n, v = debug.getlocal(level, i)
if not n then break end
if n == name then
value = v
found = true
end
end
if found then return "local", value end
-- try non-local variables
local func = debug.getinfo(level, "f").func
for i = 1, math.huge do
local n, v = debug.getupvalue(func, i)
if not n then break end
if n == name then return "upvalue", v end
end
if isenv then return "noenv" end -- avoid loop
-- not found; get value from the environment
local _, env = getvarvalue("_ENV", level, true)
if env then
return "global", env[name]
else -- no _ENV available
return "noenv"
end
end
Below is my enhanced version of this function, which implements the additional functionality specified in the exercise. This version accepts an optional thread parameter, expected to be a coroutine. The only differences between this enhanced version and the original getvarvalue are:
the handling of the additional optional thread parameter;
the special setting of the level parameter depending on whether the thread parameter is the same as the running coroutine or not; and
the passing of the thread parameter in the calls to debug.getlocal and debug.getinfo, and in the recursive call.
(I have marked these differences in the source code through numbered comments.)
function getvarvalue_enhanced (thread, name, level, isenv)
-- 1
if type(thread) ~= "thread" then
-- (thread, name, level, isenv)
-- (name, level, isenv)
isenv = level
level = name
name = thread
thread = coroutine.running()
end
local value
local found = false
-- 2
level = level or 1
if thread == coroutine.running() then
level = level + 1
end
-- try local variables
for i = 1, math.huge do
local n, v = debug.getlocal(thread, level, i) -- 3
if not n then break end
if n == name then
value = v
found = true
end
end
if found then return "local", value end
-- try non-local variables
local func = debug.getinfo(thread, level, "f").func -- 3
for i = 1, math.huge do
local n, v = debug.getupvalue(func, i)
if not n then break end
if n == name then return "upvalue", v end
end
if isenv then return "noenv" end -- avoid loop
-- not found; get value from the environment
local _, env = getvarvalue_enhanced(thread, "_ENV", level, true) -- 3
if env then
return "global", env[name]
else
return "noenv"
end
end
This function works reasonably well, but I have found one strange situation1 where it fails. The function make_nasty below generates a coroutine for which getvarvalue_enhanced fails to find an _ENV variable; i.e. it returns "noenv". (The function that serves as the basis for nasty is the closure closure_B, which in turn invokes the closure closure_A. It is closure_A that then yields.)
function make_nasty ()
local function closure_A () coroutine.yield() end
local function closure_B ()
closure_A()
end
local thread = coroutine.create(closure_B)
coroutine.resume(thread)
return thread
end
nasty = make_nasty()
print(getvarvalue_enhanced(nasty, "_ENV", 2))
-- noenv
In contrast, the almost identical function make_nice produces a coroutine for which getvarvalue_enhanced succeeds in finding an _ENV variable.
function make_nice ()
local function closure_A () coroutine.yield() end
local function closure_B ()
local _ = one_very_much_non_existent_global_variable -- only difference!
closure_A()
end
local thread = coroutine.create(closure_B)
coroutine.resume(thread)
return thread
end
nice = make_nice()
print(getvarvalue_enhanced(nice, "_ENV", 2))
-- upvalue table: 0x558a2633c930
The only difference between make_nasty and make_nice is that, in the latter, the closure closure_B references a non-existent global variable (and does nothing with it).
Q: How can I modify getvarvalue_enhanced so that it is able to locate _ENV for nasty, the way it does for nice?
EDIT: changed the names of the closures within make_nasty and make_nice.
EDIT2: the wording of Exercise 25.3 (same page) may be relevant here (my emphasis):
Exercise 25.3: Write a version of getvarvalue (Listing 25.1) that returns a table with all variables that are visible at the calling function. (The returned table should not include environmental variables; instead it should inherit them from the original environment.)
This question implies that there should be a way to get at the variables that are merely visible from a function, whether the function uses them or not. Such variables would certainly include _ENV. (The author is one of Lua's creators, so he knows what he's talking about.)
1 I am sure that someone with a better understanding of what is going on in this example will be able to come up with a less convoluted way to elicit the same behavior. The example I present here is the most minimal form I can come up with of the situation I found by accident.
local function inner_closure () coroutine.yield() end
local function outer_closure ()
inner_closure()
end
The function make_nasty below generates a coroutine for which getvarvalue_enhanced fails to find an _ENV variable; i.e. it returns "noenv"
That's a correct behavior.
The closure outer_closure has upvalue inner_closure but doesn't have upvalue _ENV.
This is how lexical scope works.
It's OK that some closures don't have _ENV upvalue.
In your example the closure inner_closure isn't defined inside the body of outer_closure.
inner_closure is not nested in outer_closure.
It's impossible.
If a closure doesn't make any use of the global environment _ENV, then it doesn't have that upvalue whatsoever.
A function like
local something = 20
local function noupval(x, y)
return x * y
end
Doesn't need or have any upvalues, not even to the global environment.
This question implies that there should be a way to get at the variables that are merely visible from a function, whether the function uses them or not.
There really isn't though. You can easily confirm this by looking at the output of luac -p -l <your_code.lua>, more precisely at the upvalues of each function.
If anything, I think using the word visible is somewhat misleading there. Visibility really only matters when creating a closure, but once it has been closed, that closure only has a set of upvalues which it can access.
Exercise 25.3: Write a version of getvarvalue (Listing 25.1) that returns a table with all variables that are visible at the calling function. (The returned table should not include environmental variables; instead it should inherit them from the original environment.)
You may have misunderstood that exercise; the way I understand it is something like this:
local upvalue = 20
local function foo()
local var = upvalue -- Create 1 local and access 1 upvalue
type(print) == "function" -- Access _ENV so it becomes an upvalue
return getvarvalue_enhanced()
end
and the above would return {var = 20, upvalue = 20, _ENV = <Proxy table to _ENV>}
After all, it asks specifically about the calling function, not one you pass as a parameter.
This doesn't change the fact that you still only get _ENV if you access it though. If you don't use any globals, the function won't have any reference to _ENV whatsoever.

Ruby Recursion Counter Without Global Variable

I am trying to count the number of times the method recurses during the life of the program. The code below gets the desired result, but uses global variables. Is there a way around this or a better way?
$count = 0
def AdditivePersistence(num)
return 0 if num.to_s.length == 1
numarr = num.to_s.chars.map!(&:to_i)
i = numarr.inject(&:+)
$count+=1
if i.to_s.length!=1
AdditivePersistence(i)
end
$count
end
Since you want the total number of recursive calls during the lifetime of the program, a global variable in some form is the only way you can do it. You can either use an explicit global variable, as you have done, or a global variable in disguise, such as a singleton class, or a thread-local variable. I will not illustrate those here since they are inferior to plain global variables for this use case.
You could take in an array with the first variable in the array being num and then the second being the count. then you just will do return [num, count]
Another option would be to update your method definition to accept the counter as an argument.
Using this approach, your method can just increment whatever counter value it receives and then pass the incremented value along in the recursive call.
def AdditivePersistence(num, counter)
return 0 if num.to_s.length == 1
numarr = num.to_s.chars.map!(&:to_i)
i = numarr.inject(&:+)
counter +=1
if i.to_s.length!=1
AdditivePersistence(i, counter)
end
counter
end
# usage
AdditivePersistence(12, 0)

Resources