pass by value/ reference / result - pascal

procedure p(x : integer);
begin
a := 5;
x := x + 2;
end
Write down the value of the variable a after execution of the following code:
a := 10;
p(a);
for each of the following parameter passing mechanisms:
(i) call by value. a. 7,10
(ii) call by reference. a. 12,12
(iii) call by value-result. a. 7,7
Got an exam on this next week and I have got the answers for the mock paper but I am confused to how X is assigned to a in the procedure call. help would be awesome
thanks

(i) call by value
Whatever value is passed into p() is copied onto p()'s stack. That copy is used in the body of p(), so the original value is never changed. If a starts as 7 it will end as 7.
(ii) call by reference
A reference to the original value is provided to p(), so that changes to the value that reference points to affect the original variable. a will have a new value after p() returns.
If a starts as 12, it will end as 7 because it is first assigned the value of 5 in the body of p() and then that value is increased by 2.
(iii) call by value-result
This is similar to call by reference, except that no alias is created between the formal and actual parameters. See details.

Related

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.

How to escape from a recursive method in ruby

I created a recursive function that tries to parse the information from the parsed list. It's kind of hard to explain, but it's something like
In a parse function that parses either a wikipedia Movie page or an Actor page, starts by parsing a filmography list from a wikipedia actor page -> call the same function on the parsed list -> repeat
I set a global variable that counts the number of iterations, but when I try to break out from the function and move on to the next step by doing,
if $counter > 10
return nil
end
but it does not immediately ends since there are still functions to be called left (since it's recursive). I tried to use "abort" but this one just terminated the program instead of moving on to the next one.
Is there a way to immedately stop the recursive run and move on to the next step without aborting the program?
A bit hard to answer without more code. But i guess you looking for next or break to jump out of recursiveness.
next
Jumps to the next iteration of the most internal loop. Terminates execution of a block if called within a block (with yield or call returning nil).
for i in 0..5
if i < 2 then
next
end
puts "Value of local variable is #{i}"
end
Result:
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5
break
Terminates the most internal loop. Terminates a method with an associated block if called within the block (with the method returning nil).
for i in 0..5
if i > 2 then
break
end
puts "Value of local variable is #{i}"
end
Result:
Value of local variable is 0
Value of local variable is 1
Value of local variable is 2

Change in between the dbms_output procedure?

i had a problem when i am using dbms_output package. When i am executing the following code it display integer is 0
declare
v integer;
asq dbms_output.chararr;
begin
dbms_output.put('hi');
dbms_output.put_line('hello!');
asq(1):='sun';
asq(2):='ant';
dbms_output.put_line(asq(1));
dbms_output.put_line(asq(2));
dbms_output.get_lines(asq,v);
dbms_output.put_line('integer is '||v);
end;
but when i am executing the following code i am getting integer is 3
declare
v integer:=5;
asq dbms_output.chararr;
begin
dbms_output.put('hi');
dbms_output.put_line('hello!');
asq(1):='sun';
asq(2):='ant';
dbms_output.put_line(asq(1));
dbms_output.put_line(asq(2));
dbms_output.get_lines(asq,v);
dbms_output.put_line('integer is '||v);
end;
can any one help me why the variation is there in the two procedures
As per documentation, the second parameter to GET_LINES
procedure is IN OUT parameter. It tells the procedure, number of lines to be retrieved from buffer. After the procedure call, it holds number of lines actually retrieved.
In your first example, the value of v is null. So no lines are retrieved and v is assigned the value 0.
In your second example, the value if v is 5. So you are requesting 5 lines, but since there are only three lines(hihello!, sun, ant), three lines are put into array asq and v is assigned 3.

how can I get the location for the maximum value in fortran?

I have a 250*2001 matrix. I want to find the location for the maximum value for a(:,i) where i takes 5 different values: i = i + 256
a(:,256)
a(:,512)
a(:,768)
a(:,1024)
a(:,1280)
I tried using MAXLOC, but since I'm new to fortran, I couldn't get it right.
Try this
maxloc(a(:,256:1280:256))
but be warned, this call will return a value in the range 1..5 for the second dimension. The call will return the index of the maxloc in the 2001*5 array section that you pass to it. So to get the column index of the location in the original array you'll have to do some multiplication. And note that since the argument in the call to maxloc is a rank-2 array section the call will return a 2-element vector.
Your question is a little unclear: it could be either of two things you want.
One value for the maximum over the entire 250-by-5 subarray;
One value for the maximum in each of the 5 250-by-1 subarrays.
Your comments suggest you want the latter, and there is already an answer for the former.
So, in case it is the latter:
b(1:5) = MAXLOC(a(:,256:1280:256), DIM=1)

Resources