Live data from Hacker News

Problems of C, and how Zig addresses them

avestura.dev

181–190 of 290 posts

Re: Problems of C, and how Zig addresses them

#181
post #28

I'm no expert on either languages, but I tried Zig for the first time properly the other day. I really liked it up until I hit hashmaps. One thing that I think goes under-appreciated about C (and other languages with a similar paradigm) is thats its pretty upfront and clear about what it can and can't do out of the box. If you want hashmaps in C, you need to create your own implementation, otherwise think of a way ro…

As counter point, the way that Zig implements hash maps is absolutely instrumental for TigerBeetle. Zig hashmaps _are_ quite a bit more cumbersome than, eg, in Rust --- you need to decided whether you want the allocator to be bundled with the hasmap, and its also up to the user of the hash map to provide equality and hash code (and, of course, there's manual defer instead of RAII). However, this flexibility and verbo…

You can achieve the same thing in Rust or any other language that offers some sort of field privacy (which Zig doesn't btw) by wrapping the hash map with your own type and exposing the interface you want.

Re: Problems of C, and how Zig addresses them

#182
post #95

I'm super sold on Zig except that it doesn't make graphics/vector coding with operator overloading possible :( I've heard what Andrew Kelley has to say about it ("that ONE little feature from C++...") but it's just a very sad situation for what otherwise looks like a lovely basis for graphics coding. Actually, I don't even want operator overloading in general (leading to stuff like the C++ stream API), it's JUST for…

Don’t even need operator overloading for vectors/matrices. It would be fine if we could simply define new operators (functions with infix notation) and use those. This would allow us to define an operator for matrix multiplication, matrix-vector product, dot product, and cross product. Having to define these operators as functions with unique text names is extremely ugly and serves no purpose that I can see.

I think the change could be as limited as a change to the parser. You could also enforce hygenicity (limiting scope only to places where it is asked for) by requiring it to be

    const @"..." = @import("my_operator.zig").add;
For example. Then in the code the parser transforms

    (a ... b)
to

    @"..."(a, b)

Re: Problems of C, and how Zig addresses them

#183
post #134
post #78

One thing that was unclear to me based on my prior noodling with Zig was what the plans were for supporting interface or trait-based polymorphism. I've been falling in love with C++'s std::experimental::is_detected and am looking forward to being allowed to use C++20 in my environment since it will bring Concepts, but in my cursory examination it seems Zig seems to prefer vtable abstractions like Allocator.VTable.

Zig does have some kind of interfaces, check [1]. I am interested to learn, how Traits in Rust and Interfaces in Go behave differently from this concept. [1] https://github.com/ratfactor/ziglings/blob/main/exercises/09...

This appears to be done by union-ing the types in question.

The thing about Go interfaces (and C++20 Concepts) is that you can name a type that contains certain methods or behaves a certain way, but you don't actually have to inherit from the interface or concept explicitly - anything shaped correctly that conforms to the interface or concept will work.

And at least with Go, if you try and pass something in that doesn't conform to the interface, it is very particular about telling you what you're missing. One downside of C++ templates is that if you have a problem with what you're passing in, you might get a horrendous error message somewhere deep in the implementation - or worse, your code might compile just fine, but have unexpected behavior - instead of a nice "Hey, you need to add a method named `foo` to this type."

Re: Problems of C, and how Zig addresses them

#184

Earlier quoted context omitted.

+1 (don't want general operator overloading, but a more powerful @Vector builtin type, basically Clang's ext_vector_type: https://clang.llvm.org/docs/LanguageExtensions.html#vectors-... ), plus maybe a similar @Matrix builtin up to 4x4.

I think operator overloading should be fine even for puritans, as long the language requires the type to be numerical in a strict sense, and so they have a well defined semantics. So integers, floating point, complex numbers, vectors, matrices, etc.

The problem with operator overloading is not really numericity, IMO. The problems are:

- hidden control flow (function calls should look like function calls, an operation should never mask a function call)

- global weirdness. If a library changes the language, how does that affect some other code you're pulling in? Where do you effect those changes?

Re: Problems of C, and how Zig addresses them

#185

Earlier quoted context omitted.

As a comptime macro, yes, you should be able to slot in a DSL for all your vector math and essentially "pass in a string, get the function calls back". It would not be that hard, if you're up on your parser-writing skills, and definitely much cleaner than any C-style equivalent.

Yep that seems comptime possible but a little heavy handed with string work, no? With everyone writing their own parsers and language tools... In any case, if something practical is done here I'd be interested. Aesthetically I prefer the "vectors and matrices are first class types" (and maybe complex numbers could be too), but I guess Andrew isn't so sympathetic to these types being part of the standard language :/

There's a proposal for complex numbers: https://github.com/ziglang/zig/issues/16278

Vectors are already first-class types via @Vector, aren't they?

Re: Problems of C, and how Zig addresses them

#186

Earlier quoted context omitted.

The form of safety we are talking about here is not like rust's "safety", it does not color functions, and is strictly scoped to the compiled unit (in this case, function) https://ziglang.org/documentation/master/#setRuntimeSafety

I am aware, my point is about how the following is dealt with: fn foo(x: i32) i32 { return x + 100; } fn bar(x: i32) i32 { @setRuntimeSafety(false); return foo(x + 100); } Particularly when you have arbitrarily deep call graphs where some explicitly enable and disable runtime safety.

You mean overflow checking? It only applies to the `x + 100` in bar. Bar can still panic if the `x + 100` in foo overflows. Why should it be any other way?

Re: Problems of C, and how Zig addresses them

#187

Earlier quoted context omitted.

I think operator overloading should be fine even for puritans, as long the language requires the type to be numerical in a strict sense, and so they have a well defined semantics. So integers, floating point, complex numbers, vectors, matrices, etc.

The problem with operator overloading is not really numericity, IMO. The problems are: - hidden control flow (function calls should look like function calls, an operation should never mask a function call) - global weirdness. If a library changes the language, how does that affect some other code you're pulling in? Where do you effect those changes?

Some CPUs don't have a MUL or (like some 32-bit RISC architectures) DIV instruction, and on these, the C compile has to fall back to a function call.

Re: Problems of C, and how Zig addresses them

#188
post #176

Earlier quoted context omitted.

C++ has all the things you "felt that C needed". So there must be something more that you dislike.

The problem with C++ isn't too few features, it's too many.

Not just too many. But inconsistent ones, hard to use ones and badly designed ones. std::unordered_map anyone? The iterator-based APIs are just cumbersome and error-prone to use, etc... it's really easy to shoot yourself in the foot by forgetting to explicitly implement specific constructors, or by passing the wrong iterator (like begin() vs end()) to an STL template.

The C# specification isn't significantly smaller than the C++ one (can't check the exact length right now) but the language is still much easier to understand, even if it has really hairy corner-cases like the difference between readonly fields and normal fields' generated IL or the logic for defensive copies. Most programmers don't have to care, and even if you do, it's not a nightmare to test or experiment with.

In C++, I kind of feel I'm trying to squeeze water out of a stone. And even with the huge standard library, basic things are missing from it like a string startswith.

Re: Problems of C, and how Zig addresses them

#189
post #185

Earlier quoted context omitted.

Yep that seems comptime possible but a little heavy handed with string work, no? With everyone writing their own parsers and language tools... In any case, if something practical is done here I'd be interested. Aesthetically I prefer the "vectors and matrices are first class types" (and maybe complex numbers could be too), but I guess Andrew isn't so sympathetic to these types being part of the standard language :/

There's a proposal for complex numbers: https://github.com/ziglang/zig/issues/16278 Vectors are already first-class types via @Vector, aren't they?

Whoa, I haven't been keeping up to date about this, there seems to be good related discussion here: https://github.com/ziglang/zig/issues/7295

I'll hope for some future news of Zig having vector and complex number support! It will be a great day for fast ray/path tracers :)

Re: Problems of C, and how Zig addresses them

#190
post #187

Earlier quoted context omitted.

The problem with operator overloading is not really numericity, IMO. The problems are: - hidden control flow (function calls should look like function calls, an operation should never mask a function call) - global weirdness. If a library changes the language, how does that affect some other code you're pulling in? Where do you effect those changes?

Some CPUs don't have a MUL or (like some 32-bit RISC architectures) DIV instruction, and on these, the C compile has to fall back to a function call.

You sure the compiler doesn't inline it? That an operator might take more than one opcode I think is uncontroversial
Post reply on HN