Draco-lang / Language-suggestions

Collecting ideas for a new .NET language that could replace C#
75 stars 5 forks source link

Code block on method #134

Open CoolCoderSuper opened 3 months ago

CoolCoderSuper commented 3 months ago

Hi, I was playing around with it a bit in the playground and had read through your spec.

func test1(): int32 {// normal function
    return 1;
}

func test2(): int32 = 1;//also a normal function

func test3(): int32 {//doesn't work 'the function test3 does not return on all paths'
    1
}

func test4(): int32 = {1};//works as expected

I would have expected the code block following a function to be treated the same as in test4, or maybe there is a reason for that?

LPeter1997 commented 3 months ago

Hey, there's very much a reason for this, we don't interpret "returning" and "evaluating to" the same way as Rust does. The two different syntaxes of function bodies can be thought of similarly as of in C#:

int Test1() { return 1; }
// Draco:
// func test1(): int32 { return 1; }

int Test2() => 1;
// Draco:
// func test2(): int32 = 1;

Essentially the => of C# and = of Draco can be thought of "return this expression on the right".

So the reason for test3 not working but test4 being valid, is because test4, when desugared is equivalent to:

func test4(): int32 {
    return { 4 };
}

Now it could be argued, that returning and evaluating the main function block to a value should be equivalent. Our reasoning when going against this, is that return is a very significant control flow altering operation, and we didn't want multiple forms of exiting from a function. Also, it would have made it a lot harder to see when we are evaluating a local expression, vs. terminating a function completely.

I hope this helps clearing it up or makes the design choice more reasonable, but I'm open to observations/opinions about this.

CoolCoderSuper commented 3 months ago

Yes, that does make sense and thank you for the explanation.

I personally prefer the more expression based way handling this especially since other areas treat blocks as expressions for example if expressions.

The other reason would be since methods could be declared with the = {} syntax which could lead to confusion and inconsistencies across a code base.