A simple question: How do I set the prototype for a function that has not been implemented yet?
I just want to do this, cause I'm referring to a function that does not exist(yet).
In C, we would do something like this:
int foo(int bar);
int myint = foo(1);
int foo(int bar)
{
return bar;
}
How do I do this in Lua (with corona)?
You can't. Amber's comment is correct.
Lua doesn't have a concept of type signatures or function prototypes.
The type of foo is that of the object it contains, which is dynamic, changing at runtime. It could be function in one instant, and string or integer or something else in the next.
Conceptually Lua doesn't have a compilation step like C. When you say "run this code" it starts starts executing instructions at the top and works it's way down. In practice, Lua first compiles your code into bytecode before executing it, but the compiler won't balk at something like this:
greet()
function greet()
print('Hello.')
end
Because the value contained in greet is determined at runtime. It's only when you actually try to call (i.e. invoke like a function) the value in greet, at runtime, that Lua will discover that it doesn't contain a callable value (a function or a table/userdata with a metatable containing a __call member) and you'll get a runtime error: "attempt to call global 'greet' (a nil value)". Where "nil value" is whatever value greet contained at the time the call was attempted. In our case, it was nil.
So you will have to make sure that that the code that creates a function and assigns it to foo is called before you attempt to call foo.
It might help if you recognize that this:
local myint = foo(1)
function foo(bar)
return bar
end
Is syntax sugar for this:
local myint = foo(1)
foo = function(bar)
return bar
end
foo is being assigned a function value. That has to happen before you attempt to call that function.
The most common solution to this problem is to treat the file's function as the "compilation time", that is: declare all of your constant data and functions when the file is executed, ready to be used during "execution time". Then, call a main function to begin the "execution time".
For example:
function main()
greet()
end
function greet()
print('Hello.')
end
main()
As greet has been declared in _G, main can access it.
Related
There are two functions, say func1 and func2. func2 is an inner function of func1 and based on a condition I wish to return from func1, meaning end execution of func1. How do I do that in kotlin?
fun func1(){
fun func2(){
if(someCondition){
...
return#func1 //How do I do this? since it says return not allowed here
}
}
...
func2()
}
This wouldn't make sense in all cases, as a nested function might outlive the scope of the containing function in some cases. Here's an example of that:
var x: () -> Unit = {}
fun func1() {
fun func2() {}
x = ::func2
}
Here, it would not make sense to allow returns for func1 from func2. By the time x is called, there might not even be an active call to func1. This is basically the topic of non-local returns, which you need inline functions for (see the official documentation). Those, unfortunately, are not available as local functions (at least not yet).
For your specific case, you're probably stuck with signaling that you want a return from func1 by using the return value of func2 and checking for it in func1. (Or an exception, which wouldn't be nice to use for control flow like this.)
I've got program below:
#include<type_traits>
#include<iostream>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
struct S {
double operator()(){return 0.0;}
};
int f(){return 1;}
int main()
{
S obj;
call(obj);//ok
call(f);//error!
return 0;
}
It fails to compile in the line of "call(f)".
It's weird that "call(obj)" is OK.
(1) I've a similar post in another thread C++11 result_of deducing my function type failed. But it doesn't tell why functor objects are OK while functions are not.
(2) I'm not sure if this is related to "R call(F& f)": a function type cannot declare a l-value?
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Would you help to give some further explanations on "why" is my case, where did I get wrong?
Thanks.
The problem with call(f) is that you deduce F as a function type, so it doesn't decay to a function pointer. Instead you get a reference to a function. Then the result_of<F()> expression is invalid, because F() is int()() i.e. a function that returns a function, which is not a valid type in C++ (functions can return pointers to functions, or references to functions, but not functions).
It will work if you use result_of<F&()> which is more accurate anyway, because that's how you're calling the callable object. Inside call(F& f) you do f() and in that context f is an lvalue, so you should ask what the result of invoking an lvalue F with no arguments is, otherwise you could get the wrong answer. Consider:
struct S {
double operator()()& {return 0.0;}
void operator()()&& { }
};
Now result_of<F()>::type is void, which is not the answer you want.
If you use result_of<F&()> then you get the right answer, and it also works when F is a function type, so call(f) works too.
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
No, see above. Your call(F&) function takes its argument by reference, so there is no decay.
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Arrays don't decay when you pass them by reference either.
If you want the argument to decay then you should write call(F f) not call(F& f). But even if you do that you still need to use result_of correctly to get the result of f() where f is an lvalue.
A function is returning an anonymous function. I would like to assign the result to a variable. However the compiler thinks that I am trying to assign the function and not the result of the function. How can I resolve this?
program Project9;
{$APPTYPE CONSOLE}
type
TMyEvent = reference to function: string;
var
v1: TMyEvent;
function GetHandler: TMyEvent;
begin
Result := function: string
begin
Result := '';
end;
end;
begin
v1 := GetHandler; // <- Incompatible types: 'TMyEvent' and 'Procedure'
end.
Note: I do have a workaround but I hope that this problem can be solved without introducing a wrapper:
program Project9;
{$APPTYPE CONSOLE}
type
TMyEvent = reference to function: string;
TWrapper = record
FHandler: TMyEvent;
end;
var
v1: TMyEvent;
function GetHandler: TWrapper;
begin
Result.FHandler := function: string
begin
Result := '';
end;
end;
begin
v1 := GetHandler.FHandler; // <- works
EDIT: this is not specific to anonymous or any special kind of functions: that is actual for any function returning the function, it was the same in Turbo Pascal before even the 1st Delphi arrived.
If your anonymous methods/functions are paramless, you must assign with ();
v1 := GetHandler();
Without the parentheses Delphi will try to assign the function to the variable. The parens tell it to invoke the function and assign the function result to the variable.
Delphi's function call syntax is a little different from most other languages. In most languages, in order to call a function you must use parens () after the function name, commonly referred to as the function call operator. If the function is simply named, and no parens supplied, that expression evaluates to the function without invoking a call.
So, with the C++ language as our example,
i = foo();
calls the function and stores the return value in i.
On the other hand,
fn = foo;
stores the address of the function in the function pointer variable fn.
Delphi varies from this, for a parameterless function, by allowing you to omit the parens, and yet still call the function. So in Delphi, the first line of code above could be written
i := foo;
and this would call the function.
Where it gets slightly tricky is if the function return type is a procedural type, a method, or an anonymous method, as you have found out.
In your scenario,
v1 := GetHandler;
is ambiguous in the eyes of the compiler. Because v1 is a variable whose type is an anonymous method, the compiler will never generate a call when parens are omitted. If it did generate a call then you would not be able to make the simple assignment of a function to a procedural type variable.
So the compiler switches to the behaviour that you find in languages like C++. You must supply parens if you wish for the function to be called. To make your code compile and work, write
v1 := GetHandler();
The documentation covers the issue in some detail. The key excerpt is this:
In assignment statements, the type of the variable on the left determines the interpretation of procedure or method pointers on the right.
Now, casting judgement, I find the idea that the context of an expression can determine its interpretation to be rather unsettling. This all stems from allowing function calls to be made when parens are omitted. I would rather have to use parens always and so avoid the ambiguities discussed above. In particular this would allow expression meaning to be independent of context.
To see what I mean, we return to my original example. Let us now be more specific about the types involved:
type
TIntFunc = function: Integer;
function foo: Integer;
begin
Result := 42;
end;
var
i: Integer;
fn: TIntFunc;
At this point we can write:
i := foo; // i is an integer, so the function is called
fn := foo; // fn is a procedural type variable, so the function is not called
I personally find this state of affairs not at all satisfactory.
I have a function where I'd like to make a vector argument optional-- that is, something like this:
public function test(arg1:int, arg2:Vector.<int> = new Vector.<int>(5)) {}
So in that example, I want the first argument to be required, and an optional vector passed in. If the second argument is not provided, create an int vector with 5 elements instead. It throws a compile error: "Parameter initializer unknown or is not a compile-time constant."
Making the argument not optional works, as in:
public function test(arg1:int, arg2:Vector.<int>) {}
But that's not exactly what I'm looking for. Doing some searching I found a supposed workaround, which is
public function test(arg1:int, arg2:Vector.<int> = null) {}
But that doesn't compile either.
I've already moved on in my code with a workaround just to be done with it, but I'm still curious. Can you have a vector as a default argument, and how?
I don't think this is possible. Probably just because the compiler was never programmed to handle this situation because optional parameters do work with many other datatypes in AS3. I did some research and other have reported the same issue as you with no success in setting an empty vector object in the function declaration.
I would simply do the following if you haven't already:
var myDefaultVector:Vector.<int> = new Vector.<int>(5);
function test(arg1:int, arg2:Vector.<int> = null) {
if( arg2 == null ) {
arg2 = myDefaultVector;
}
// rest of your code
}
I have tried compiling the above code in Flash and it compiled successfully.
Suppose, I have the following code (in C-like syntax):
void foo(int arg) { ... }
int bar() {
...
// call with continuation
...
}
foo ( bar() )
// after foo invocation
1) Function foo invokes function bar, which is running until it reaches the line with call with continuation.
2) At this line a continuation function is created. It represents the rest of bar and foo. The continuation function is passed as an argument to call with continuation function.
3) The call with continuation function does whatever it wants with the argument (e.g. it may just store in a global variable) and returns.
4) Once the call with continuation returns we immediately jump to the line with "after foo invocation" and the rest of bar and foo are not executed.
5) In order to continue execution of bar and foo we should explicitly invoke the continuation function (created in (2) and probably stored in (3)). Once the continuation function is invoked the execution continues immediately after the call with continuation.
Is it correct? Am I missing something about undelimited continuations?
No. Typically, undelimited continuations (eg created with Scheme's call/cc) jump when you invoke the continuation, not when you call call/cc (aka call-with-current-continuation).
So, fleshing out your example:
continuation savedk;
void foo(int arg) { ... }
int bar() {
...
call/cc(handler)
// after call/cc
println "after call/cc"
...
}
void handler(continuation k) {
savedk = k
}
foo ( bar() )
// after foo invocation
Execution starts. We enter bar (we haven't entered foo yet; we'll do that when we get done with bar).
When we hit the call to call/cc in bar, the "program context" is turned into an object called a continuation. At this point, the program context consists of "finish executing bar, then call foo on the result, and then do whatever comes after the foo invocation". The continuation is passed to the function given as an argument to call/cc, which is handler in my example above.
handler does something with the continuation. Let's assume it stores it in a global variable. Then it returns to the point right after the call/cc call, still inside of bar.
Let's say we print something out at this point. Then bar finishes and we call foo, and it finishes.
If we now apply the continuation in savedk, control jumps back into bar and restores the program context to "finish executing bar, then call foo on the result, and then do whatever comes after the foo invocation". So we get another line printed. In fact, if we don't clear the savedk variable or test some other state, we might get an infinite loop if "do whatever comes after the foo invocation" is call savedk again!