-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reconsider function return-type annotation #221
Comments
Yes I agree that it would be good to add it. I just don't know how I can easily enforce this at a call site. But I agree it should be possible to check the function itself / or insert type assertions on return values. |
I've achieved some success on trying to implement that. lparser.c static void body (LexState *ls, expdesc *e, int ismethod, int line, int deferred) {
/* body -> '(' parlist ')' block END */
FuncState new_fs;
BlockCnt bl;
new_fs.f = addprototype(ls);
new_fs.f->linedefined = line;
open_func(ls, &new_fs, &bl);
if (!deferred) {
checknext(ls, '(');
if (ismethod) {
new_localvarliteral(ls, "self"); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, ')');
}
// here we try to find expected return value(s) types
if (testnext(ls, ':')) {
TString *typename = str_checkname(ls);
char* str = getstr(typename); // our type is here, what to do with it?
/* maybe we should use this to support typechecking on multiple return values */
// expdesc e = {.ravi_type_map = RAVI_TM_ANY, .pc = -1};
// int nexps = explist(ls, &e);
/* we should also put function (static int explist (LexState *ls, expdesc *v)) behind current function, otherwise compile error */
}
statlist(ls);
new_fs.f->lastlinedefined = ls->linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
codeclosure(ls, e, deferred);
close_func(ls);
} So, I've successfully parsed return type annotation(s), but have no idea what to do with it next. static void ravi_typecheck(LexState *ls, expdesc *v, int *vars, int nvars, int n)
...
int nrets = GETARG_C(*pc) - 1; /* operand C contains
number of return values expected */
/* Note that at this stage nrets is always 1
* - as Lua patches in the this value for the last
* function call in a variable declaration statement
* in adjust_assign and localvar_adjust_assign */
/* all return values that are going to be assigned
to typed local vars must be converted to the correct type */
int i;
for (i = n; i < (n+nrets); i++)
/* do we need to convert ? */ Maybe we can check return values somewhere around that. I still poorly understand the internal logic, so maybe @dibyendumajumdar will tell me what to do next? Thanks |
What we need:
Maybe for single return values
For multiple values:
The parser uses
This can be done in Note that some return values may be constants, so we cannot do any conversions when this is true - or we need to move the constant to a temp register before generating TOINT/TOFLT opcodes.
|
The proposal above validates the return values in the There is no change at callsite. This is harder problem because at callsite we only know at runtime what function we will be calling. We will probably need to store the type signature in |
AFAIK, function return-type are normally specified in statically-typed language for (at least) 3 reasons:
In the manual, you say the following:
Function return types cannot be annotated because in Lua, functions are un-named values and there is no reliable way for a static analysis of a function call’s return value.
But this only apply to #3. #1 and #2 are still valid reasons to annotate the return type. I already know I would write all my functions like this:
This is silly. What I really want, is to write them like this:
Even if the annotation was not validated at all, just for documentation purpose alone I think it is worth having it.
The text was updated successfully, but these errors were encountered: