Live data from Hacker News

Zig as an alternative to writing unsafe Rust

zackoverflow.dev

151–160 of 230 posts

Re: Zig as an alternative to writing unsafe Rust

#151
post #129
post #37

Earlier quoted context omitted.

People keep saying this and I just do not get it . It's just… not that bad?

My biggest peeve is types on the right. I would say that C is "humanistic" in its type declarations, while Rust and the rest of Pascal's lineage are "mechanistic". Concretely, look at this: int foo(int a, float b); vs fn foo(a: i32, b: f32) -> i32; In Rust's case you're specifying to the machine what the thing is, i.e. "I am declaring a function called foo. The function has a first parameter called a, of type i32, ..…

This isn’t a Rust thing. Lot’s of new language have the type declaration after the variable because of type inference which makes such declarations optional.

Re: Zig as an alternative to writing unsafe Rust

#152
post #129
post #37

Earlier quoted context omitted.

People keep saying this and I just do not get it . It's just… not that bad?

My biggest peeve is types on the right. I would say that C is "humanistic" in its type declarations, while Rust and the rest of Pascal's lineage are "mechanistic". Concretely, look at this: int foo(int a, float b); vs fn foo(a: i32, b: f32) -> i32; In Rust's case you're specifying to the machine what the thing is, i.e. "I am declaring a function called foo. The function has a first parameter called a, of type i32, ..…

Algol 60, Algol W, and Algol 68 were influential in the historical development of subsequent programming languages. C gets its type on the left order from the Algol family.

Pascal, Modula, and Ada are all type on the right languages and were also very influential in the historical development of programming languages. I happen to prefer types on the right for complex declarations. Note that Pascal and Modula were designed by Niklaus Wirth after he created Algol W; it seems he preferred types on the right.

Re: Zig as an alternative to writing unsafe Rust

#153

Earlier quoted context omitted.

There are a number of sources of noise in rust, but the one I find most annoying (because it's also so common) is the double colon. My current theory is that it's because the colon is the same height as lowercase letters. If you end up with a long::run::of::module::names, I find it all just blurs into one.

Okay but who is writing code like this instead of using `use`? Also this is an no-win situation. C++, Ruby, Perl, and others have used `::` as module-scoping syntax for decades. If Rust does something novel, it's penalized for being unfamiliar. If Rust uses syntax for which there's ample prior art, it's apparently line noise. If rust used a `.` as a separator, it's unclear if you're descending into modules or calling…

I did use the example of long run of module names, and I do take your point about `use` (though I have to sometimes read the very top of a file too!)...but the same applies to a lesser extent to the "last mile" module (e.g. `String::from`, `Vec::new`) which will be seen throughout any rust code.

> If rust used a `.` as a separator, it's unclear if you're descending into modules or calling a function chain

Interestingly, from the zig documentation:

    Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. @import returns the struct type corresponding to the file.
This means that there isn't really any difference between accessing a struct field and accessing something in module...the module is also a kind of struct (and rust, as in zig, differentiating struct field access vs function invocation is possible because of the parens in the latter).

Re: Zig as an alternative to writing unsafe Rust

#154

Earlier quoted context omitted.

Ah interesting approach, thx for the answer. 1. Doesn't that risk introducing accidental breaking changes by adding a new error to the set in the implementation, since the set of errors is inferred from the implementation? Having a compile error in this case in Rust is often the last barrier standing between me and an accidental major semver bump (since callers have to exhaustively match on the error conditions) 2. C…

> Doesn't that risk introducing accidental breaking changes by adding a new error to the set in the implementation, since the set of errors is inferred from the implementation? Do you have an illustrative example? (I'm not implying it's not possible, just trying to think of a good example so I can give a good answer) > since callers have to exhaustively match on the error conditions If it's exhaustiveness that you're…

> Do you have an illustrative example?

Illustrative, I don't know, but I'll try to give more context.

When writing a library, it is important that public items (like functions and enum) don't change between minor versions so that client code doesn't need to update their calls to the library.

Sometimes when refactoring code you end up modifying how a library function is implemented. Maybe it will now depend on some file being present on the system, while previously it wouldn't, meaning that the absence of that file adds a new error variant to this function.

In today's Rust, since the Error type of a Result is an explicit part of a function's signature, such a change is very noisy to the library's maintainer: it entails either modifying the signature of the public function to return a different error type, or modifying the Error type itself, which is also public.

When this happens, the change needs to be reconsidered: either you can defer it to later, provide an additional function with that new implementation and error variant, try to make it work with the error types you already have, or decide in that it actually warrants a major version bump, in conscience.

By contrast, if the set of errors of a function is inferred rather than part of its explicit signature, it means that modifying the implementation you can add a new variant without even realising it (for instance, by mixing the variant name with a variant returned by a sibling function that you thought was already used by this function) and break semver in a much more silent way.

I guess it also makes life harder for tooling, since it has to parse the implementation of a function (and all its subfunctions) to rebuild the set of errors, as opposed to simply parse the signature of the top-level function.

> Essentially it compiles to the same as C function that returns an `int` representing the error

That feels very limiting, I often use error types to e.g., attach data about the error. Is there a more general mechanism for sum types for when this shorthand doesn't apply?

Re: Zig as an alternative to writing unsafe Rust

#155
post #9

This pretty much mirrors my experience. Rust is the inverse of Perl: It makes the easy stuff hard. Writing basic data structures isn't a niche, esoteric edge case. There may be a crate that "solves" what you're trying to do. But does it rely on the std---(i.e., is it unusable for systems programming)? Is it implemented making gratuitous copies of data everywhere? Does it have a hideous interface which will then pollu…

> Writing basic data structures isn't a niche, esoteric edge case

writing data structures _properly/well_ was never easy

it just looks easy and is nearly always a sub-par solution

e.g. a list in many lisp like languages seems simple, until you look under the hood what magic tends to be used by more advanced compilers to make that list work fast

the think people most commonly got wrong which was supposedly easy when programming when I was school/stadium where data structures, even comparatively simple ones like double linked lists

it's like sorting, sure you find docents easy to implement sorting algorithms everywhere, but then when you look at the properly implemented sorting build ins of standard libraries their complexity is hundreds of times that of quick sort or similar

Re: Zig as an alternative to writing unsafe Rust

#156
post #112
post #70

Earlier quoted context omitted.

> It seems to consist solely of extremely online people who get a dopamine hit from both telling people they're doing things wrong and creating the most complex solutions possible. I've observed that certain programming languages have a culture of complexity. I'm not sure why this is. I can only speculate its because these programmers are working on "boring" problems so they make busy work for themselves OR their beg…

I don’t know, people who go too hard on simplicity often don’t even grasp the underlying problem in a given case (looking at this utterly dumb piece of text as an example: http://harmful.cat-v.org/software/ ) - sure, no sane people would want to deliberately introduce complexity/abstractions, but abstraction is the only weapon we have against complexity. Problems have an inherent complexity which simply cannot ever b…

>abstraction is the only weapon we have against complexity

I don't agree with this. We also have stinginess and stubborness as potent weapons against complexity. If we are stingy with our time and effort then we insist on getting much use out of every tool we learn. We are stubborn, and so we do not add new tools quickly, or throw old ones away quickly, and we are skeptical of easy solutions. tldr: first cut away needless complexity, then use abstraction on what remains.

Re: Zig as an alternative to writing unsafe Rust

#157

Earlier quoted context omitted.

> Rust is the inverse of Perl: It makes the easy stuff hard. It's a bargain. Rust is pretty great, but it doesn't make some things easy because it would make everything else hard. This comment is amusing, mostly because Perl is so full of tradeoffs. Do you want to write something to do some string parsing quickly? Great language, maybe. Do you want to understand what you've written later? Maybe not so great. > Writin…

[flagged]

I've actually read the full comment you're referencing and your take absolutely mischaracterizes what was said. Whether your take is malicious or merely reckless, I don't know, but I do know your take is the precise opposite of what was said.

Others can read the entire comment themselves[0], but the pertinent part re: this individual discussing 'unsafe' can be found in the second graph:

    "[W]hen you're learning new things and thus reading introductory material, you'll often see pithy statements that you may interpret as being commandments or something that is supposed to always be true, but in reality they are imprecise statements because it is just impossible to explain everything up front."
[0]: https://old.reddit.com/r/rust/comments/11eyu50/i_love_rust_i...

Re: Zig as an alternative to writing unsafe Rust

#158
post #112

Earlier quoted context omitted.

I don’t know, people who go too hard on simplicity often don’t even grasp the underlying problem in a given case (looking at this utterly dumb piece of text as an example: http://harmful.cat-v.org/software/ ) - sure, no sane people would want to deliberately introduce complexity/abstractions, but abstraction is the only weapon we have against complexity. Problems have an inherent complexity which simply cannot ever b…

>abstraction is the only weapon we have against complexity I don't agree with this. We also have stinginess and stubborness as potent weapons against complexity. If we are stingy with our time and effort then we insist on getting much use out of every tool we learn. We are stubborn, and so we do not add new tools quickly, or throw old ones away quickly, and we are skeptical of easy solutions. tldr: first cut away nee…

Do note that I was talking about essential complexity, not accidental. The latter can and should indeed be dealt with.

Re: Zig as an alternative to writing unsafe Rust

#159

Earlier quoted context omitted.

> Doesn't that risk introducing accidental breaking changes by adding a new error to the set in the implementation, since the set of errors is inferred from the implementation? Do you have an illustrative example? (I'm not implying it's not possible, just trying to think of a good example so I can give a good answer) > since callers have to exhaustively match on the error conditions If it's exhaustiveness that you're…

> Do you have an illustrative example? Illustrative, I don't know, but I'll try to give more context. When writing a library, it is important that public items (like functions and enum) don't change between minor versions so that client code doesn't need to update their calls to the library. Sometimes when refactoring code you end up modifying how a library function is implemented. Maybe it will now depend on some fi…

I see you what you mean. Yeah, I suppose if you are writing a library you might want to be more deliberate in the error set. Maybe explicitly writing out the error set is what you want in that situation. Rewriting the example:

    fn someFunction(a: usize) MyError!usize {
        if (a 
> That feels very limiting, I often use error types to e.g., attach data about the error. Is there a more general mechanism for sum types for when this shorthand doesn't apply?

I agree it's limiting. It obviously is going to depend on your application, but I have largely done without annotating errors with extra information (that maybe speaks more to the seriousness of my zig projects than to that approach to error handling as being sufficient!).

One pattern I have used (in e.g. a parser) is additionally passing in a pointer to a sum type:

    fn parse(allocator: *mem.Allocator, tokens: Tokens, parse_error: *ParseError) !AST
The `parse_error` can be set if an error condition occurs. I concede that that's a little clumsy

Re: Zig as an alternative to writing unsafe Rust

#160

Earlier quoted context omitted.

[flagged]

I've actually read the full comment you're referencing and your take absolutely mischaracterizes what was said. Whether your take is malicious or merely reckless, I don't know, but I do know your take is the precise opposite of what was said. Others can read the entire comment themselves[0], but the pertinent part re: this individual discussing 'unsafe' can be found in the second graph: "[W]hen you're learning new th…

[flagged]
Post reply on HN