(no title)
fm77 | 3 years ago
Interesting - being an absolute non-expert in closures - but isn't it the other way around? That is, in Pascal, functions are first-class values but not closures?
Unless I am miss something here, but functions can be assigned to variables:
function add(a,b:integer):integer; { far; in Turbo Pascal }
begin
add := a + b;
end;
type MyFunc = function (a,b:integer):integer;
var f:MyFunc;
x:integer;
begin
f := add; { here we assigning a function to a variable }
x := f(3,4);
end;
> Some dialects - notably, Turbo Pascal - don't allow pointers to local functions at all.I know what you mean here, but that's not entirely true. In Turbo Pascal you had two ways to receive a pointer to a function:
1.) the way just shown, and here you are right, Turbo Pascal doesn't allow local functions, but that’s because how local functions in Turbo Pascal were implemented. Local functions have a hidden parameter (a 16-bit pointer to the caller's stackframe) pushed onto the stack, how do you handle this hidden parameter when you deal with a function pointer with a defined function signature? To avoid headaches I guess Hejlsberg simply choose to not allow local functions here.
2.) via a regular pointer - you simply store the function address in a pointer variable (or pass the function address to a pointer parameter), so:
procedure MyProc;
{ a local function }
function sub(a,b:integer):integer; { far; in TP }
begin
sub := a - b;
end;
type MyFuncHidden = function (a,b:integer; hidden:word):integer;
var p:pointer;
x:integer;
begin
p := @sub; { assigning a local function to a variable }
x := MyFuncHidden(p)(7,8,0);
end;
The problem here, now you as a programmer are in charge of handling the parameter passing.Look at the implementation of ForEach/FirstThat in the Turbo Vision library. Both ForEach and FirstThat accept local functions as parameter (and only local functions).
int_19h|3 years ago
In your second example, what you're doing is the equivalent of reinterpret_cast between two incompatible pointer types (if they were compatible, you could have just assigned @sub to a variable of type MyFuncHidden). You cannot safely assume that your new signature faithfully corresponds to what the compiler does under the hood - that's an implementation detail. Furthermore, in this case, your function doesn't even try to access variables from the outer scope, and this would break if it did.