Live data from Hacker News

Things Zig comptime won't do

matklad.github.io

81–90 of 252 posts

Re: Things Zig comptime won't do

#81

Earlier quoted context omitted.

Rust, D, Nim, Crystal, Julia

Definitely, you can do most of those things in Nim without macros using templates and compile time stuff. It’s preferable to macros when possible. Julia has fantastic compile time abilities as well. It’s beautiful to implement an incredibly fast serde in like 10 lines without requiring other devs to annotate their packages. I wouldn’t include Rust on that list if we’re speaking of compile time and compile time type a…

Rust has two macro systems, the proc macros are allowed to do absolutely whatever they please because they're actually executing in the compiler.

Now, should they do anything they please? Definitely not, but they can. That's why there's a (serious) macro which runs your Python code, and a (joke, in the sense that you should never use it, not that it wouldn't work) macro which replaces your running compiler with a different one so that code which is otherwise invalid will compile anyway...

Re: Things Zig comptime won't do

#82

Earlier quoted context omitted.

Rust, D, Nim, Crystal, Julia

Definitely, you can do most of those things in Nim without macros using templates and compile time stuff. It’s preferable to macros when possible. Julia has fantastic compile time abilities as well. It’s beautiful to implement an incredibly fast serde in like 10 lines without requiring other devs to annotate their packages. I wouldn’t include Rust on that list if we’re speaking of compile time and compile time type a…

> Rust’s macro system likewise is also very weak.

How so? Rust procedural macros operate on token stream level while being able to tap into the parser, so I struggle to think of what they can't do, aside from limitations on the syntax of the macro.

Re: Things Zig comptime won't do

#83
post #65

Earlier quoted context omitted.

Writing correct code did not start after the introduction of the rust programming language

Nope, but claims of knowing to write correct code (especially C code) without borrow checker sure did spike with its introduction. Hence, my question. How do you know you haven't been writing unsafe code for years, when C unsafe guidelines have like 200 entries[1]. [1] https://www.dii.uchile.cl/~daespino/files/Iso_C_1999_definit... (Annex J.2 page 490)

It's not difficult to write a provably correct implementation of doubly linked list in C, but it is very painful to do in Rust because the borrow checker really hates this kind of mutually referential objects.

Re: Things Zig comptime won't do

#84
post #45

Earlier quoted context omitted.

> What in particular do you find cumbersome about the borrow system? The refusal to accept code that the developer knows is correct, simply because it does not fit how the borrow checker wants to see it implemented. That kind of heavy-handed and opinionated supervision is overhead to productivity. (In recent times, others have taken to saying that Rust is less "fun.") When the purpose of writing code is to solve a pr…

Thank you for the answer! Do you have an example? I'm having a fish-doesn't-know-water problem.

Basically anything that involves objects mutually referencing each other.

Re: Things Zig comptime won't do

#85

Earlier quoted context omitted.

Yes, but I’m not hoping for that. I’m hoping for something like a scripting language with simpler lifetime annotations. Is Rust going to be the last popular language to be invented that explores that space? I hope not.

I was quite impressed with Austral[0], which used Linear Types and avoids the whole Rust-like implementation in favour of a more easily understandable system, albeit slightly more verbose. [0] https://borretti.me/article/introducing-austral

Austra's concept are interesting but the introduction doesn't show how to handle correctly errors in this language..

Re: Things Zig comptime won't do

#86

> When you execute code at compile time, on which machine does it execute? The natural answer is “on your machine”, but it is wrong! I don’t understand this. If I am cross-compiling a program is it not true that comptime code literally executes on my local host machine? Like, isn’t that literally the definition of “compile-time”? If there is an endian architecture change I could see Zig choosing to emulate the target…

The point is that something like sizeof(pointer) should have the same value in comptime code that it has at runtime for a given app. Which, yes, means that the comptime interpreter emulates the target machine.

The reason is fairly simple: you want comptime code to be able to compute correct values for use at runtime. At the same time, there's zero benefit to not hiding the host platform in comptime, because, well, what use case is there for knowing e.g. the size of pointer in the arch on which the compiler is running?

Re: Things Zig comptime won't do

#87
post #17

I like the Zig language and tooling. I do wish there was a safety mode that give the same guarantees as Rust, but it’s a huge step above C/C++. I am also extremely impressed with the Zig compiler. Perhaps the safety is the tradeoff with the comparative ease of using the language compared to Rust, but I’d love the best of both worlds if it were possible

>but I’d love the best of both worlds if it were possible I am just going to quote what pcwalton said the other day that perhaps answer your question. >> I’d be much more excited about that promise [memory safety in Rust] if the compiler provided that safety, rather than asking the programmer to do an extraordinary amount of extra work to conform to syntactically enforced safety rules. Put the complexity in the compi…

I have zero issue with needing runtime GC or equivalent like ARC.

My issue is with ergonomics and performance. In my experience with a range of languages, the most performant way of writing the code is not the way you would idiomatically write it. They make good performance more complicated than it should be.

This holds true to me for my work with Java, Python, C# and JavaScript.

What I suppose I’m looking for is a better compromise between having some form of managed runtime vs non managed

And yes, I’ve also tried Go, and it’s DX is its own type of pain for me. I should try it again now that it has generics

Re: Things Zig comptime won't do

#88
post #84

Earlier quoted context omitted.

Thank you for the answer! Do you have an example? I'm having a fish-doesn't-know-water problem.

Basically anything that involves objects mutually referencing each other.

Oh, that does sound tough in rust! I'm not even sure how to approach it; good to know it's a useful pattern in other langs.

Re: Things Zig comptime won't do

#89
post #86

> When you execute code at compile time, on which machine does it execute? The natural answer is “on your machine”, but it is wrong! I don’t understand this. If I am cross-compiling a program is it not true that comptime code literally executes on my local host machine? Like, isn’t that literally the definition of “compile-time”? If there is an endian architecture change I could see Zig choosing to emulate the target…

The point is that something like sizeof(pointer) should have the same value in comptime code that it has at runtime for a given app. Which, yes, means that the comptime interpreter emulates the target machine. The reason is fairly simple: you want comptime code to be able to compute correct values for use at runtime. At the same time, there's zero benefit to not hiding the host platform in comptime, because, well, wh…

> Which, yes, means that the comptime interpreter emulates the target machine.

Reasonable if that’s how it works. I had absolutely no idea that Zig comptime worked this way!

> there's zero benefit to not hiding the host platform in comptime

I don’t think this is clear. It is possibly good to hide host platform given Zig’s more limited comptime capabilities.

However in my $DayJob an extremely common and painful source of issues is trying to hide host platform when it can not in fact be hidden.

Re: Things Zig comptime won't do

#90
post #82

Earlier quoted context omitted.

Definitely, you can do most of those things in Nim without macros using templates and compile time stuff. It’s preferable to macros when possible. Julia has fantastic compile time abilities as well. It’s beautiful to implement an incredibly fast serde in like 10 lines without requiring other devs to annotate their packages. I wouldn’t include Rust on that list if we’re speaking of compile time and compile time type a…

> Rust’s macro system likewise is also very weak. How so? Rust procedural macros operate on token stream level while being able to tap into the parser, so I struggle to think of what they can't do, aside from limitations on the syntax of the macro.

Rust macros don't really understand the types involved.

If you have a derive macro for

    #[derive(MyTrait)]
    struct Foo {
        bar: Bar,
        baz: Baz,
    }
then your macro can see that it references Bar and Baz, but it can't know anything about how those types are defined. Usually, the way to get around it is to define some trait on both Bar and Baz, which your Foo struct depends on, but that still only gives you access to that information at runtime, not when evaluating your macro.

Another case would be something like

    #[my_macro]
    fn do_stuff() -> Bar {
        let x = foo();
        x.bar()
    }
Your macro would be able to see that you call the functions foo() and Something::bar(), but it wouldn't have the context to know the type of x.

And even if you did have the context to be able to see the scope, you probably still aren't going to reimplement rustc's type inference rules just for your one macro.

Scala (for example) is different: any AST node is tagged with its corresponding type that you can just ask for, along with any context to expand on that (what fields does it have? does it implement this supertype? are there any relevant implicit conversions in scope?). There are both up- and downsides to that (personally, I do quite like the locality that Rust macros enforce, for example), but Rust macros are unquestionably weaker.

Post reply on HN