c3c icon indicating copy to clipboard operation
c3c copied to clipboard

Maybe change the optional declaration syntax?

Open lerno opened this issue 2 weeks ago • 20 comments

Currently we have return io::EOF?;, but this complicates the grammar. Consider alternatives:

return ^io::EOF;
return %io::EOF;
return ?io::EOF;
return /io::EOF;
return .io::EOF;
return io::EOF~;
return io::EOF~~;
return io::EOF@;
return io::EOF$;
return io::EOF#;
return [io::EOF];
return (?)io::EOF;
return ?(io::EOF);
return io::EOF#?;
return io::EO?$;
return %%io::EOF%%;

Also

int? a = foo() ?? ^io::EOF;
int? a = foo() ?? %io::EOF;
int? a = foo() ?? ?io::EOF;
int? a = foo() ?? /io::EOF;
int? a = foo() ?? .io::EOF;
int? a = foo() ?? io::EOF~;
int? a = foo() ?? io::EOF~~;
int? a = foo() ?? io::EOF@;
int? a = foo() ?? io::EOF$;
int? a = foo() ?? io::EOF#;
int? a = foo() ?? [io::EOF];
int? a = foo() ?? (?)io::EOF;
int? a = foo() ?? ?(io::EOF);
int? a = foo() ?? io::EOF#?;
int? a = foo() ?? io::EO?$;
int? a = foo() ?? %%io::EOF%%;

Let's make an exhaustive list of alternatives.

lerno avatar Dec 09 '25 22:12 lerno

is there already a #x prefix operator? maybe add #io::EOF to the list if not (Though, might just be partial to prefix operators over postfix ones)

cheese3660 avatar Dec 09 '25 22:12 cheese3660

In use. #foo would be a lazily evaluated argument.

lerno avatar Dec 09 '25 22:12 lerno

Ahh yeah, I forgot about that

cheese3660 avatar Dec 09 '25 22:12 cheese3660

I love return io::EOF?; as it is.

But if you really want to change, I vote for

    return ?io::EOF;
    int? a = foo() ?? ?io::EOF;
    // or a better 'or_else'
    int? a = foo() ||| ?io::EOF;

nomota avatar Dec 10 '25 05:12 nomota

If it does not complicate things, IMO using direct return (return io::EOF;, int? a = foo() ?? io::EOF;) would be better.

If an error indicator is really needed and postfix ? must be changed, I would also vote for prefix ? (return ?io::EOF;, int? a = foo() ?? ?io::EOF;).

erenjanje avatar Dec 10 '25 05:12 erenjanje

After some time I conclude that ?-prefix is best. To add more readability, I also propose \\ as a replacement of ??. I guess it looks nice: int? index = find_index(array) \\ ?NOT_FOUND!!;

EroMrinin134 avatar Dec 10 '25 06:12 EroMrinin134

If it does not complicate things, IMO using direct return (return io::EOF;, int? a = foo() ?? io::EOF;) would be better.

If an error indicator is really needed and postfix ? must be changed, I would also vote for prefix ? (return ?io::EOF;, int? a = foo() ?? ?io::EOF;).

A counterpoint to the first part that lerno put in the discord, what does this do?

fn fault? some_function() => io:EOF;

cheese3660 avatar Dec 10 '25 09:12 cheese3660

 // or a better 'or_else'
 int? a = foo() ||| ?io::EOF;

||| is compile time || where the right hand side is not evaluated if the left hand side is constant true.

lerno avatar Dec 11 '25 01:12 lerno

Compare:

fn fault? some_function() => io:EOF~;

or

fn fault? some_function() => ?io:EOF;

lerno avatar Dec 11 '25 15:12 lerno

// or a better 'or_else' int? a = foo() ||| ?io::EOF;

||| is compile time || where the right hand side is not evaluated if the left hand side is constant true.

Can we consider \\ as a replacement for ?? ? \\ has a similar look with '||' so it even may be easier to remeber.

int? a = foo() \\ ?io::EOF;

EroMrinin134 avatar Dec 11 '25 15:12 EroMrinin134

What I dislike about ?io::EOF is that it combines poorly with ?? visually. Compare these:

int? a = foo() ?? ?io::EOF;
/* ... */
int? a = foo() ?? ^io::EOF;
/* ... */
int? a = foo() ?? (?)io::EOF;

lerno avatar Dec 11 '25 15:12 lerno

No more opinions?

lerno avatar Dec 14 '25 15:12 lerno

No more opinions?

Remove optional from the language completely and implement it in std like C++17 std::optional.

data-man avatar Dec 14 '25 15:12 data-man

Wat

lerno avatar Dec 14 '25 16:12 lerno

perhaps ?? could be replaced by else or otherwise, or_else, default, then, if_not, lest, or ... then the ? prefix would work

int? a = foo() else ?io::EOF;
int? a = foo() otherwise ?io::EOF;
int? a = foo() or_else ?io::EOF;
int? a = foo() default ?io::EOF;
int? a = foo() then ?io::EOF;
int? a = foo() if_not ?io::EOF;
int? a = foo() lest ?io::EOF;
int? a = foo() or ?io::EOF;

joshring avatar Dec 15 '25 00:12 joshring

or_else quite fits with existing foreach_r, but I'm not sure if anything with else is intuitive for optional semantics... but for regular person it would probably more obvious then \\. I wonder if Christoffer would be ok with adding another keyword.

EroMrinin134 avatar Dec 15 '25 05:12 EroMrinin134

No more opinions?

Remove optional from the language completely and implement it in std like C++17 std::optional.

If speaking seriosly:

  1. C3 already has traditional optionals with Maybe
  2. C3 wants strongly differentiate between a potential empty value (Maybe) and value that can not be gotten due some issues (Optional)
  3. Moreover, the mechanism with implisitly unwraping options is extremely good so the lang will 100% stay with that

EroMrinin134 avatar Dec 15 '25 05:12 EroMrinin134

perhaps ?? could be replaced by else or otherwise, or_else, default, then, if_not, lest, or ... then the ? prefix would work

No, we'll keep ??, I'm aware of those alternatives, but find them less clear.

lerno avatar Dec 15 '25 08:12 lerno

With ?? standing, I found ?(io::EOF) fine because:

  • ? pointing to optional semantics
  • due braces, pops out with ?? and shows order with ! and !!
  • actually looks like wrapping to on optional (I found (?) weird)

EroMrinin134 avatar Dec 15 '25 09:12 EroMrinin134

?(io::EOF) is not bad.

lerno avatar Dec 15 '25 13:12 lerno

?(io:EOF) vs (?)io::EOF

I think it would be easier for the user to see they got it right with (?), for example a longer fault name you would need to parse to the end of the line to see if had a matching brace:

it also seems intuitive to cast to a fault (?), even if it's not exactly what's going on

faultdef MEMORY_CORRUPTION_IN_CORE;

int? reading_data = ?(MEMORY_CORRUPTION_IN_CORE);

vs

faultdef MEMORY_CORRUPTION_IN_CORE;

int? reading_data = (?)MEMORY_CORRUPTION_IN_CORE;

mistakes could more easily happen like this for example:

faultdef MEMORY_CORRUPTION_IN_CORE;

int? reading_data = ?(MEMORY_CORRUPTION_IN_CORE;

or with nested function calls it could get messy

int? reading_data = ?(some_function(arg1, arg2, arg3, arg4));

vs

int? reading_data = (?)some_function(arg1, arg2, arg3, arg4);

joshring avatar Dec 17 '25 14:12 joshring

I can live with (?), it has a benefits. The most important is to end up with something containing the ?.

EroMrinin134 avatar Dec 17 '25 16:12 EroMrinin134

in c#,

int? y = 3;
int useY = y ?? 0;

aubreychao avatar Dec 18 '25 03:12 aubreychao

in c#,

int? y = 3; int useY = y ?? 0;

How this exactly this corresponds to the topic? (C3 already has ??, we are figuring out operator for fault -> optional conversion)

EroMrinin134 avatar Dec 18 '25 15:12 EroMrinin134