Go Tour #18: understanding pic.Show - function

I did not understand how the function call pic.Show(Pic) works and what it does.
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
pic := make([][]uint8, dy)
for y := range pic {
pic[y] = make([]uint8, dx)
for x := range pic[y] {
pic[y][x] = uint8(5 * (x + y))
}
}
return pic
}
func main() {
//pic.Show(Pic(40,30)) // doesn't work, but why?
pic.Show(Pic) // works, but why? Where are the values for dx and dy set?
}
There is, starting at line 5, a function, named Pic, and it receives two integer variables (dx, dy). So I think, a correct function call might be Pic(40,30) (with 40 and 30 being the values for dx and dy).
But why does line 17 throw an error? (pic.Show(Pic(40,30)))
Why does line line 18 work? (pic.Show(Pic))
And where do the values of dx and dy come from when line 18 is executed?
I tried to look up http://golang.org/x/tour/pic which redirects me to https://godoc.org/golang.org/x/tour/pic. There I can read, that the function Show is defined this way:
func Show(f func(int, int) [][]uint8)
Which I understand as:
Show is a function that needs one parameter. This parameter is a function that needs two parameters, both of type int, and it has to return a value of type [][]uint8 (a slice of slices of unsigned 8-bit integers). Show itself doesn't return anything.
So, here again, I read that the inner function (the parameter of Show) needs two parameters. But why do I get an error, when I try to provide those parameters? Why is it ok to call the function Pic without parameters? And where do the values for those parameters come from, when Pic is executed?

When you say Pic(40, 30) you call the function Pic and it returns a [][]uint8 (as seen in the function definition). This means that in your commented-out code you pass a [][]uint8 to Show.
When you say Show(Pic) you pass Pic as the parameter, which is a function. That is what Show expects. Pic is of type func(dx, dy int) [][]uint8.
Go allows you to pass functions around as parameters and that is what is happening here.

You are quite right about definition of Show - it is a function which accepts another specific format notion as a parameter.
Pic is such a function matching this criteria - so you pass it to Show successfully.
But when you call Pic(30,40) that means not a function but a result of calling the function with such parameters. So in this case you passs to Show not a function Pic but a slice returned by it [][]uint8. Of course Show can’t accept it.

Your function, Pic, takes two parameters, Show takes one. You're calling Show with a single parameter, which is a function; that function takes two parameters. When you pass a function to another function, the assumption is that the function you're calling (Show) will call the function you passed in (Pic) and provide the necessary parameters when it makes that call.

Related

How to declare (and pass) Julia function parameters when the parameter could be one of two types

My goal is to pass an IOStream variable to a Julia function (if I want to write to an open file), or nothing (or possibly something else that would be considered an empty or null value). The reason is that I might call this function numerous times and would like to keep the file handle open regardless of how many times I enter the function. If the intent is not to write to the file, I would simply pass nothing indicating to the function not to attempt writing to a file.
I have tried declaring as:
function f(x, y, f)
and as:
function f(x, y, f::IOStream)
and as:
function f(x, y, f::Any)
while passing in a variable set to either nothing or an IOStream resulting from a
open("filename.txt", "a")
statement. In all cases, I get an error of some sort. Is there some other way to achieve my goal, or should I be using a different type of function declaration/call?
You should not have the same name for function and parameter. Anyway there are two approaches - either you use type Union or multiple dispatch.
Hence your code can be either:
function f(x, y, fs::Union{IOStream,Nothing}=nothing)
#code goes here
end
or you can do:
function f(x, y, fs::IOStream)
#code goes here
end
function f(x, y, fs::Nothing)
#code goes here
end
Instead of the second function you could as well just do:
function f(x, y)
#code goes here
end

function handle to nested function not working for some values of parameter

This function is supposed to return a function handle to the nested function inside, but if the variable x is set to a negative value in the outer function, it doesn't work.
The inner nested function is just a constant function returning the value of the variable x that is set in the outer function.
function t=test(x)
x=-1;
function y=f()
y=x;
endfunction
t=#f;
endfunction
If I try to evaluate the returned function, e.g. test()(3), I get an error about x being undefined. The same happens if x is defined as a vector with at least one negative entry or if x is argument of the function and a negative default value is used for evaluation. But if I instead define it as some nonnegative value
function t=test(x)
x=1;
function y=f()
y=x;
endfunction
t=#f;
endfunction,
then the returned function works just fine. Also if I remove the internal definition of x and give the value for x as an argument to the outer function (negative or not), like
function t=test(x)
function y=f()
y=x;
endfunction
t=#f;
endfunction
and then evaluate e.g. test(-1)(3), the error doesn't occur either. Is this a bug or am misunderstanding how function handles or nested functions work?
The Octave documentation recommends using subfunctions instead of nested functions, but they cannot access the local variables of their parent function and I need the returned function to depend on the input of the function returning it. Any ideas how to go about this?
This is a bug that was tracked here:
https://savannah.gnu.org/bugs/?func=detailitem&item_id=60137
Looks like it was fixed and will be gone in the next release.
Also, to explain the different behavior of negative and positive numbers: I experimented a bit, and no variable that is assigned a computed value is being captured:
function t=tst()
x = [5,3;0,0]; # captured
y = [5,3;0,0+1]; # not captured
z = x + 1; # not captured
function y=f()
endfunction
t=#f;
endfunction
>> functions(tst)
ans =
scalar structure containing the fields:
function = f
type = nested
file =
workspace =
{
[1,1] =
scalar structure containing the fields:
t = #f
x =
5 3
0 0
}
The different behavior of negative and positive numbers are probably caused by the minus sign - before the numbers being treated as a unary operator (uminus).
As of octave version 5.2.0 the nested function handles were not supported at all. I'm going to guess that is the novelty of the version 6.
In octave functions are not variables, the engine compiles\translates them at the moment of reading the file. My guess would be that behavior you are observing is influenced by your current workspace at the time of function loading.
The common way for doing what you are trying to do was to generate the anonymous (lambda) functions:
function t = test1(x=-1)
t = #()x;
end
function t = test2(x=-1)
function s = calc(y,z)
s = y + 2*z;
end
t = #(a=1)calc(a,x);
end
Note that default parameters for the generated function should be stated in lambda definition. Otherwise if you'd call it like test2()() it would not know what to put into a when calling calc(a,x).
If you are trying to create a closure (a function with associated state), octave has limited options for that. In such a case you could have a look at octave's object oriented functionality. Classdef might be useful for quick solutions.

What happens when you pass an expression to a function which has passing by value-result?

I'm attending a course of principles of programming languages and there's this exercise where I'm supposed to tell what gets printed by this program:
{
int x=2;
void A (val/res int y)
{
x++;
write(y);
y=y+2;
}
A(x)
A(x+1)
write (x);
}
A is a function with value/result parameters passing, so right before returning it should copy the final value of its formal parameter (y) in the actual parameter. When A first gets called its actual parameter is x, so there's no problem there. However, the second call to A has x+1 as the actual parameter.
What does that mean? Maybe the final value of y gets lost because there's no variable where to copy it? Or maybe I should consider it like an equation, so if the final value of y is 7 I get that x + 1 = 7, and then the value of x is 6?
It means the value of the argument is copied to y:
When x=2, A(x) copies 2 to y at the start of A
When x=4, A(x+1) copies the value of x+1, or 5, to y at the start of A
However, as you pointed, out, passing x+1 for a value/result parameter is problematic, and I would expect any language supporting this type of parameter would not consider it legal, for just the reason you cite. If it is considered legal, how it is accomplished would be up to the language definition; I do not believe there is a standard way to handle this.

Scilab not returning variables in variable window

I have created a function that returns the magnitude of a vector.the output is 360x3 dimension matrix. the input is 360x2.
Everything works fine outside the function. how do i get it to work ?
clc
P_dot_ij_om_13= rand(360,2); // 360x2 values of omega in vectors i and j
//P_dot_ij_om_13(:,3)=0;
function [A]=mag_x(A)
//b="P_dot_ijOmag_"+ string(k);
//execstr(b+'=[]'); // declare indexed matrix P_dot_ijOmag_k
//disp(b)
for i=1:1:360
//funcprot(0);
A(i,3)=(A(i,2)^2+A(i,1)^2)^0.5; //calculates magnitude of i and j and adds 3rd column
disp(A(i,3),"vector magnitude")
end
funcprot(1);
return [A] // should return P_dot_ijOmag_k in the variable browser [360x3 dim]
endfunction
mag_x(P_dot_ij_om_13);
//i=1;
//P_dot_ij_om_13(i,3)= (P_dot_ij_om_13(i,2)^2+P_dot_ij_om_13(i,1)^2)^0.5;// example
You never assigned mag_x(P_dot_ij_om_13) to any variable, so the output of this function disappears into nowhere. The variable A is local to this function, it does not exist outside of it.
To have the result of calculation available, assign it to some variable:
res = mag_x(P_dot_ij_om_13)
or A = mag_x(P_dot_ij_om_13) if you want to use the same name outside of the function as was used inside of it.
By the way, the Scilab documentation discourages the use of return, as it leads to confusion. The Scilab / Matlab function syntax is different from the languages in which return specifies the output of a function:
function y = sq(x)
y = x^2
endfunction
disp(sq(3)) // displays 9
No need for return here.

Lua - Higher-order Derivative function

How does returning functions work in Lua? I'm trying to wrap my head around this derivative function but I'm having trouble understanding it.
function derivative(f, delta)
delta = delta or 1e-4
return function(x)
return (f(x + delta) - f(x))/delta
end
end
Any help is appreciated, thanks.
First see here.
Shortly, functions are first-class citizens and you an store them in variable and return from functions.
Second. In your example there is a closure to be created. It will have upvalues f and delta, wich can be used in inner function.
So when you call your derivative function, new closure will be created with copy of f and delta. And you can call it later like any other function
local d = derivative(f, 1e-6)
d(10)
EDIT: "Answer on but I'm having trouble understanding how the x argument is treated in the anonymous function in my example"
Each function have a signature, number of formal attributes, it will get.
In Lua you can call function with any number of arguments. Let's consider an example.
local a = function(x1, x2) print(x1, x2) end
a(1) // 1, nil
a(1, 2) // 1, 2
a(1, 2, 3) // 1, 2
When you call function in variable a, each given argument value, one by one will be matched with function argumentList. In 3-rd example 1 will be assigned to x1, 2 to x2, 3 will be thrown away. In term's of vararg function smth like this will be performed.
function a(...)
local x1 = (...)[1]
local x2 = (...)[2]
// Body
end
In your example x is treated as inner function argument, will be visible inside it, and initialized when you call your inner function instance.
f and delta will be unique for each function instance, as I mentioned above.
Hope my clumsy explanations will hit their goal and help you a little.