Hacker News new | ask | show | jobs
by vunie 2357 days ago
It's amazing what credible competition can do. If only C had the same kind of pressure.
2 comments

Don't you even dare. C is near-perfect in the simplicity of its core. You want bells and whistles, you hook up a library.
Typesafe generics via a better void* would make me super happy. There are definitely other quality of life improvements that could be added or reworked that wouldn't affect the simplicity too much.
I'd say Rust is the improvements to C that I've always been wanting: better type safety, real generics, first-class closures, and OOP without inheritance, only using structs to structure data, leaving code execution to just functions. It's what I hoped Go would become. (Take with grain of salt, I'm just starting to learn Rust.)
I really don't like the monomorphization approach to generics (I think that's the concept?), where the function/struct essentially gets duplicated for each type. It seems to mess with linkage, increase binary sizes, and increase compile times.

Other than that, Rust does seem to be an improvement and less... stressful to program in.

You can always role dynamics dispatch yourself
Dynamic dispatch is in the language too.

    use core::fmt::Display;
    
    fn show_monomorphic<T: Display>(first: T, second: T) {
        println!("{} then {}", first, second);
    }
    
    fn show_polymorphic(first: &dyn Display, second: &dyn Display) {
        println!("{} then {}", first, second);
    }
    
    pub fn main() {
        show_monomorphic(17, 23);
        show_monomorphic("fnord", "slack");
    
        show_polymorphic(&42, &"quirkafleeg"); // mixed types!
    }
There are things you can do with each that you can't do with the other, but they are often both viable choices.
If you're doing dynamic dispatch then there is still code that's living for each specialization. Sort of solves linking because symbols don't have to be generated and compile times because you hand write the code.

To be fair, I'm only considering basic data structures and algorithms where you can get away with something like foo(void *ptr, size_t size). Maybe generics is too broad a term for that.

C has many rough spots too, especially in organising large and complex programs. There is always scope for innovation and improvements.
>>> There is always scope for innovation and improvements.

but not in C because C has no scope

Could you refer me to a good/standards-compliant library for typesafe generic lists, hashmaps, pattern matching, closures, etc?
You are missing the main strength of C - the transparency and predictability of what machine code gets generated from the source code.

When you write "a + b", you won't end up with kilobytes of machine code just because someone in some header overloaded the + operator.

Ditto for template-style generics and overloaded functions. If you call a function and it doesn't exist, it won't get auto-generated for you on the fly. You get an error. You want a function, you define that function. That's not the flaw of the language. That's its strength.

Ditto for switch-case constructs.

Ditto for closures.

All of these constructs, should they be added to the language, will result in a compiler generating heaps of code from a simple code snippet. But this will no longer be C, because in C what you see is what you get.

> the transparency and predictability of what machine code gets generated from the source code.

This gets said a lot, but unless you're writing C code for a microcontroller (or a PDP11), that isn't even close to being true.

> When you write "a + b", you won't end up with kilobytes of machine code just because someone in some header overloaded the + operator.

You can't overload "+" for integers or floats. If you add two numbers together, you get what you expect, always. If they're not numbers, and somehow you expected `a + b` to work without an overloaded operator, then I don't know what to say.

> You want a function, you define that function.

Then you define it again for another type, then again, then again...

Then you write a macro and now your colleagues hate you.

> All of these constructs, should they be added to the language, will result in a compiler generating heaps of code from a simple code snippet

Not necessarily.

>> You can't overload "+" for integers or floats. If you add two numbers together, you get what you expect, always. If they're not numbers, and somehow you expected `a + b` to work without an overloaded operator, then I don't know what to say.

You can't overload the + operator in C. If you see a+b in code you know it is adding two numbers (or a compile error). In C++ it could be doing anything. In C you may question the size or type (fp vs int) of the variables, but not the operator. + does addition. Always.

> This gets said a lot,

No, this actually doesn't get said a lot, however the simplicity of C compilation semantics is one of its biggest strengths.

> ... but unless you're writing C code for a microcontroller (or a PDP11), that isn't even close to being true.

Do humor us with an example of a C code that compiles into something that is "not even close" to what you'd reasonably expect.

I'm not missing anything, I'm responding to a specific claim--that libraries allow C to compensate for missing language features. This is patently false irrespective of the merits of the features in question.

That said, I think your entire criteria for determining whether a language or feature is good boils down to its intuitiveness to experienced C programmers, which seems like a particularly poor, subjective criteria and it probably doesn't actually even hold for C considering all of the security issues and undefined behaviors that are introduced by and continue to surprise experienced C programmers.

For my money, closures, pattern matching, and templates (not any implementation in particular) are easy enough to reason about and much better than the corresponding bugs they address, but to each his own.

> I think your entire criteria for determining whether a language or feature is good boils down to its intuitiveness to experienced C programmers ...

I see this tired argument over and over. It is especially thrown out when some esoteric language syntax is criticized.

In this case it seems to miss the authors point entirely. My understanding of his argument is that the C language maps reasonably well to machine code. Adding new features to the language could hamper that intuitive mapping between the language syntax and the actual machine code generated.

A valid criticism (which others have made) is that the actual mapping between C code and machine code on modern machines is far less intuitive than one might expect. Another valid response would be a demonstration that "closures, pattern matching, and templates" can be intuitively mapped directly to machine code.

I would be happy if I never see the "you are too blinded by your own language to understand" argument ever again. It borders on ad-hominem and extends no benefit of doubt to the original author.

>For my money, closures, pattern matching, and templates (not any implementation in particular) are easy enough to reason about and much better than the corresponding bugs they address

Then write C++ only using closures, pattern matching and templates outside of the C feature set.

Oh no, did my previous comments read as an exhaustive list of issues with C?
> If you call a function and it doesn't exist, it won't get auto-generated for you on the fly.

People want these features and the end up making them (badly) using Macros. Also, as to "a + b", it's either trivial enough to be inlined immediately by the compiler or obvious enough that it's your fault.

> If you call a function and it doesn't exist, it won't get auto-generated for you on the fly

As opposed to you writing the function manually every time and then it guaranteeing your binary gets cluttered?

C is also not portable assembler as some people claim, modern compilers are way to complicated for it to be that simple (unless you're working on microcontrollers)

If you call function and it doesnt exist you get a warning "implicit declaration of function". Unless you use additional compiler flags.
Not since C99.

But even regardless of that you still get a linking error.

No, you write macros (duck and hide).
> If only C had the same kind of pressure.

ATS :p

Who is using ATS in production?

When I learned it I wondered why would somebody use it instead of Rust or Idris.