Don Wrote:

> In the docs for "return statement" in statement.html it says:
> ---
> ReturnStatement:
>      return;
>      return Expression ;
> 
> Expression is allowed even if the function specifies a void return type. 
> The Expression will be evaluated, but nothing will be returned.
> 
> ----
> This makes sense for things we definitely want to allow, such as:
> void foo() { return bar(); }
> where bar() is another void function. But as currently implemented, it 
> also allows bug-prone code. Here's an example from std.utf in Phobos2:
> 
> // BUG: should return size_t, not void!
> void encode(wchar[2] buf, dchar c){
>     if (c <= 0xFFFF)
>          return 1;
>      return 2;
> }
> 
> I think that instead, inside a void function, return expression; should 
> be the same as: { expression; return; }, ie, like any other expression 
> statement, it should be required to have side-effects. I found while 
> patching the ICE bug 3344 that this is happening because the expression 
> never gets the semantic pass run on it.
> 
> In DMD, in statement.c.
> Statement *ReturnStatement::semantic(Scope *sc)
> 
> =====
>       /* Replace:
>        *      return exp;
>        * with:
>        *      exp; return;
>        */
>       Statement *s = new ExpStatement(loc, exp);
> +     s->semantic(sc);
> =====
> 
> After making this change, it showed up that bug in Phobos.
> I'm not sure if the current behaviour is intended, or is a bug. It 
> certainly looks unhelpful, unexpected, and bug-prone to me. As well as 
> the one-line compiler patch, I suggest the following change in the spec:
> 
> -The Expression will be evaluated, but nothing will be returned.
> +The Expression will be evaluated as an ExpressionStatement, but nothing 
> will be returned.
> 
> Or is there something desirable about the existing behaviour which I 
> have missed?

How about making a judgement based upon consistency & (co/contra) variance with 
"type is" operator?

Try this for size:

    if ( is( int: void)) {
        writefln( "IT IS");
    }

    else {
        writefln( "IT ISN'T");
    }
    
    if ( is( void: int)) {
        writefln( "IT IS");
    }

    else {
        writefln( "IT ISN'T");
    }

Therein either lies the answer, or proves that the type system is broken.

Fan, do you have a comment about Unit type in Scala?

Reply via email to