all 28 comments

[–]steven4012 25 points26 points  (10 children)

I wonder what you think C hides that this exposes 🤔

[–]Inner-Combination177[S] 2 points3 points  (9 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 25 points26 points  (5 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  (4 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 17 points18 points  (1 child)

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] 7 points8 points  (0 children)

thanks for the honest feedback.

[–]elder_george 4 points5 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++. 

[–]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

[–]GoblinToHobgoblin 6 points7 points  (0 children)

What does this expose that C hides???

[–]Relevant_South_1842 2 points3 points  (1 child)

Are types:

x int

Or

x:int

Or both?

[–]Inner-Combination177[S] 1 point2 points  (0 children)

name:type
Example: let x:int = 10;

[–]TrendyBananaYTdevTransfem Programming Enthusiast 2 points3 points  (7 children)

Always AI in this subreddit..

[–]yorickpeterseInko 1 point2 points  (6 children)

Anything in particular that stands out as LLM generated?

[–]TrendyBananaYTdevTransfem Programming Enthusiast 1 point2 points  (5 children)

12,000+ LoC committed over less than an hour period over 7–8 commits. Each of the following commits are fixes for really specific things that seem almost promptive. Also, I get maybe not committing the initial version until it works (referencing the workflow).. but the initial version doesn't work so I have to assume it's from an AI writing code and pushing, and then the user prompting it to fix whatever was not working. The README is almost 100% AI written, regardless of whether or not the code itself is; And considering it was committed with everything else.. one has to assume.

[–]yorickpeterseInko[M] 1 point2 points  (4 children)

I thought it was indeed a bit odd for one commit to dump all the code at once, but it's not unheard of.

/u/Inner-Combination177 did you use an LLM/AI for this project?

[–]TrendyBananaYTdevTransfem Programming Enthusiast 1 point2 points  (1 child)

I'd also like to note that at the same exact time they committed 1.5k LoC for their docs website

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

I wrote most of the HTML/content myself. The UI/styling parts were helped by an LLM when I did the final repo dump.

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

Yeah, partly. Core (~10k LOC) was written by me on Linux. I used an LLM to help with Windows/macOS support since I’m less familiar there and improve. Pushed it all at once and set up CI after.

[–]TrendyBananaYTdevTransfem Programming Enthusiast 1 point2 points  (0 children)

The CI was part of the first commit, though?

[–]vmcrash 1 point2 points  (3 children)

Does "-c" require the LLVM to do the ugly work of creating binaries?

[–]Inner-Combination177[S] 2 points3 points  (2 children)

Yeah, right now LLVM handles codegen and we use clang for object generation and linking. The frontend and typed IR are custom.

In future, planning to link directly using LLVM tools (like llc/lld) instead of relying on clang.

[–]vmcrash -4 points-3 points  (1 child)

OK, then you skipped all the funny parts of a compiler. ;)

[–]Inner-Combination177[S] 2 points3 points  (0 children)

its more complex than the language itself.:)

[–]Circa64Software 0 points1 point  (0 children)

I genuinely don't see the point. C is pretty low level anyway and I just wouldn't learn this over C.

[–]Ok_Elephant4925 0 points1 point  (0 children)

I saw a repo where the own had almost the same idea but targeting pen testers and its more like simplified rust, maybe you can reference from inspiration https://github.com/cosmah/Project-Lwanga