Draco-lang / Language-suggestions

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

main function return type #63

Closed Binto86 closed 2 years ago

Binto86 commented 2 years ago

Introduction

what should be the return type of main function

why do we need to return anything

because of return codes, which can be very useful in CLI development

Options

1) return int - oldschool version just return in form of int

func main():int32
{
    return 0;
}

2) return unit - just no return

func main()
{
    //don't need any return
}

3) make both options possible if you need return code, just use the first option, if you don't need one just use the unit solution 4) Peters comment 5) if someone has some other idea write it in the comments

size of int

If we decide to implement option 1 or 3 there is also disscusion about the size of the returned int. Should it be int32 which is common in the c language family or should it be just int8, because we don't need anything bigger?

WhiteBlackGoose commented 2 years ago

It must be int32 because that's how it works in OS.

I'd vote for option 3.

thinker227 commented 2 years ago

I'll just put this here because I think it would be neat (but it'd probably not work for a variety of reasons). Would be cool if you could have string as the return type and have the contents of the string upon exit be written to the console as a form of very simplistic IO without the requirement of WriteLine.

LPeter1997 commented 2 years ago

While I think that encoding random behavior for types like that is generally weird, it gave me an idea that I'd also like to note down. We could make the signature of main optionally return a library type (either a DU or a trait implementer) that would perform, what would happen on application exit.

DU version

// Somewhere in the standard library
type AppExit =
    | Void
    | Code(int32)
    | Log(string)
    ;

// ...

// Usage
func main(): AppExit { // If none is specified, AppExit::Void is assumed
    return AppExit::Log("Hello, World!"); // Logs "Hello, World!"
}

Trait version

A more flexible approach would be to allow a trait implementer type to be provided. int32 would implement it automatically to call Environment.Exit.

// Somewhere in the standard library

trait AppExit {
    func exit(this);
}

impl AppExit for unit {
    func exit(this) {}
}

impl AppExit for int32 {
    func exit(this) {
        Environment.Exit(this);
    }
}

// ...

// Usage

// If the user wants to, they can create a log type that performs something when exiting
type Log(Msg: string);

impl AppExit for Log {
    func exit(this) {
        Console.WriteLine(this.Msg);
    }
}

func main(): Log { // If none is specified, unit is assumed
    return Log("Hello, World!"); // Logs "Hello, World!"
}
thinker227 commented 2 years ago

I was thinking of this as well. I think the trait version would be really neat as it would allow for extending the return type of main depending on the needs of a library.

Binto86 commented 2 years ago

ok i will add this to the original post

333fred commented 2 years ago

I really think this is far too complex. A console log works well for a console app, but what about any other type of application? I think it would be significantly clearer and less error prone if it's just "int or nothing (which is converted to 0)".

Binto86 commented 2 years ago

With the traits you can just have int/nothink, or you can implement it in custom way and then have it as some kind of log

333fred commented 2 years ago

You can, but I still think it's far too complicated. Keep it simple. This is totally a case of YAGNI.

LPeter1997 commented 2 years ago

It definitely smells like YAGNI. But the trait version of this idea is also something we can just introduce later on (if we need it), I don't think there would be any compatibility problem with that.

jl0pd commented 2 years ago

Worth mentioning that main can also be async: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.1/async-main