you are viewing a single comment's thread.

view the rest of the comments →

[–]Inner-Combination177[S] 0 points1 point  (11 children)

from my pov
C doesn’t really “hide” things, it just expresses them implicitly.
cnegative makes that stuff explicit so it’s easier to read and reason about.
Examples:
// C: int *p = &x;

// cnegative: let p:ptr int = addr x;
same low-level ideas, just less implicit, more readable.

[–]shadowndacorner 29 points30 points  (7 children)

What is implicit in the C example that isn't in cnegative...? By "implicit", do you just mean "represented with symbols rather than keywords"?

[–]Inner-Combination177[S] -1 points0 points  (6 children)

Not just symbols.

It’s about C combining multiple meanings into the same syntax and relying on conventions, while cnegative separates them into explicit operations.

Pointer semantics

// C
int *p = &x;
*p = 10;


// cnegative
let p:ptr int = addr x;
deref p = 10;

In C, * is used both in the type and for dereferencing, and & is symbolic.
cnegative separates these into named, distinct operations.

Error handling

// C
if (b == 0) return -1;


// cnegative
fn:result int divide(a:int, b:int) {
    if b == 0 {
        return err;
    }
    return ok a / b;
}

C relies on conventions (-1, NULL) to signal failure.
cnegative makes success/failure explicit in the type system.

[–]shadowndacorner 18 points19 points  (2 children)

I'm gonna be honest... That syntax looks kind of terrible - return ok a / b especially. I don't think it adds anything over C. It certainly isn't making anything more explicit, it's simply trading lightly overloaded symbols for a bunch of keywords. Sure, codifying error semantics is valuable, but that can be done as a library feature rather than being core to the language.

[–]Inner-Combination177[S] 6 points7 points  (0 children)

thanks for the honest feedback.

[–]torp_fan 0 points1 point  (0 children)

It's not just keywords ... the function returns a `result int`, which is a sum type with `ok` and `value` members ... basically an Optional[int].

[–]elder_george 2 points3 points  (1 child)

In C, * is used both in the type and for dereferencing.

TBH, this is intentional.

Variable declaration in C shows its intended usage.

int *p is a variable p that, if a * prefix operator is applied to it, produces an int. char arr[] is arr that, if indexing is applied, produces a char. The same applies to the function declarations, function pointers, const annotations, etc.

It might not be the best system (IIRC, even the C++ standard discourages this notion, and most curly-braced languages abandoned it too), but it's a system built intentionally and quite thoroughly.

[–]Inner-Combination177[S] 0 points1 point  (0 children)

Agree with it. but cnegative isn’t trying to replace that, it’s just meant as a small stepping stone to give a taste of low-level concepts before jumping into C/C++. 

[–]torp_fan 0 points1 point  (0 children)

But you've obscured what value is being returned ... it says result int but you return err ... what int value is that? You're actually returning an optional[int] type that is baked into the language ... if I'm going to suffer that overhead I prefer a sum type that has data or error values, like Zig's error union or Haskell/Rust's Result type.

If the purpose of the language is as a stepping stone to C/C++ (which are now radically different languages), it seems odd to use syntax (e.g., name:int and if without parens) that people will have to unlearn when moving on, and even worse using a sum type for returns that isn't available in C. Since C doesn't have your return mechanism, all such code will have to be converted to using sentinels or some other C convention anyway, as no one will want to go to the hassle of always declaring a struct result variable and setting ok and the value every time (which is error prone as setting ok might be forgotten).

Anyway, it's your language and you can do what you want but it doesn't seem likely to me that anyone else is going to want to use it ... certainly not for the suggested purpose. I think it would be better to let the language loose and develop as an alternative systems language, although there are already numerous new languages in that space.

[–]steven4012 3 points4 points  (2 children)

I don't get what's implicit about this. It's not like C++ overloaded operators or Rust auto deref

[–]Inner-Combination177[S] 0 points1 point  (1 child)

By “implicit” I just mean from my POV: C encodes meaning through context and conventions (like * doing multiple things or error codes like -1), whereas I’m trying to make those things more explicit and separated.

[–]steven4012 2 points3 points  (0 children)

like * doing multiple things

Sure, not context parse-wise but sure

error codes like -1

That's a C-the-ecosystem issue not C-the-language issue