qorelanguage / qore

Qore Programming Language
GNU General Public License v2.0
61 stars 10 forks source link

Return value type declaration #65

Closed tethal closed 8 years ago

tethal commented 8 years ago

According to the documentation of %require-types:

Requires all function and method parameters, return types, variables, and object members to have type declarations.

However, this code:

%require-types

sub f() {
    return "xxx";
}

print(f());

Produces this error:

unhandled QORE System exception thrown in TID 1 at 2015-10-30 11:29:58.893542 Fri +01:00 (CET) at test.q:4
PARSE-TYPE-ERROR: return value for this block expects no value, but value given to the return statement is type 'string'

I would expect an error at line 3 - sub f() { complaining about missing return type declaration. The function seems to be declared as nothing sub f() {...} which is not documented. It seems that the directive just changes the default return type from any to nothing.

Furthermore, the documentation of classes does not describe the possibility of return types for methods at all:

[[static|final] [synchronized] [private|public] [deprecated] method_name([[param_type] $param_name [= default_initialization_expression], ...]) { }]

which makes it actually impossible to return anything with the %require-types directive:

%require-types

class C {
    m1() {
        return rand();
    }
}

new C().m1();

Produces:

unhandled QORE System exception thrown in TID 1 at 2015-10-30 11:42:41.205708 Fri +01:00 (CET) at test3.q:5
PARSE-TYPE-ERROR: return value for this block expects no value, but value given to the return statement is type 'int'

And lastly, if the return statement uses a local variable of type any:

%require-types

class C {
    m1() {
        any result = rand();
        #...
        return result;
    }
}

new C().m1();

We get this warning:

warning encountered at test3.q:7
INVALID-OPERATION: the return statement for C::m1() has an expression whose type cannot be resolved at parse time, however the block does not allow any value to be returned; if this expression resolves to a value a run-time error will result; to suppress this warning, move the expression in front of the return statement or use '%disable-warning invalid-operation' in your code
unhandled QORE System exception thrown in TID 1 at 2015-10-30 11:47:20.866515 Fri +01:00 (CET) in C::m1() (test3.q:7, user code)
RUNTIME-TYPE-ERROR: <return statement> expects no value, but got integer instead
call stack:
  1: C::m1() (test3.q:11, user code)

Although the warning correctly predicts a future error, the solutions it suggests are misleading:

davidnich commented 8 years ago

These are doc errors, with %require-types if no return type is declared, the return type is assumed to be "nothing" On Oct 30, 2015 11:54, "tethal" notifications@github.com wrote:

According to the documentation of %require-types http://qore.org/manual/current/lang/html/group__parse__options.html#ga66847391bb96dac88c3fee210720bbb3 :

Requires all function and method parameters, return types, variables, and object members to have type declarations.

However, this code:

%require-types

sub f() { return "xxx"; }

print(f());

Produces this error:

unhandled QORE System exception thrown in TID 1 at 2015-10-30 11:29:58.893542 Fri +01:00 (CET) at test.q:4 PARSE-TYPE-ERROR: return value for this block expects no value, but value given to the return statement is type 'string'

I would expect an error at line 3 - sub f() { complaining about missing return type declaration. The function seems to be declared as nothing sub f() {...} which is not documented http://qore.org/manual/current/lang/html/qore_functions.html#function_return_types. It seems that the directive just changes the default return type from any to nothing.

Furthermore, the documentation of classes http://qore.org/manual/current/lang/html/qore_classes.html does not describe the possibility of return types for methods at all:

[[static|final] [synchronized] [private|public] [deprecated] method_name([[param_type] $param_name [= default_initialization_expression], ...]) { }]

which makes it actually impossible to return anything with the %require-types directive:

%require-types

class C { m1() { return rand(); } }

new C().m1();

Produces:

unhandled QORE System exception thrown in TID 1 at 2015-10-30 11:42:41.205708 Fri +01:00 (CET) at test3.q:5 PARSE-TYPE-ERROR: return value for this block expects no value, but value given to the return statement is type 'int'

And lastly, if the return statement uses a local variable of type any:

%require-types

class C { m1() { any result = rand();

...

    return result;
}

}

new C().m1();

We get this warning:

warning encountered at test3.q:7 INVALID-OPERATION: the return statement for C::m1() has an expression whose type cannot be resolved at parse time, however the block does not allow any value to be returned; if this expression resolves to a value a run-time error will result; to suppress this warning, move the expression in front of the return statement or use '%disable-warning invalid-operation' in your code unhandled QORE System exception thrown in TID 1 at 2015-10-30 11:47:20.866515 Fri +01:00 (CET) in C::m1() (test3.q:7, user code) RUNTIME-TYPE-ERROR: expects no value, but got integer instead call stack: 1: C::m1() (test3.q:11, user code)

Although the warning correctly predicts a future error, the solutions it suggests are misleading:

  • moving the expression in front of the return statement makes no sense (result return;)
  • disabling the warning does not prevent the upcoming error
  • more helpful hint would be something like check the return type in the function declaration
  • the only situation when the warning can be ignored is when the expression is guaranteed to evaluate to nothing - which is IMO rare

— Reply to this email directly or view it on GitHub https://github.com/qorelanguage/qore/issues/65.