HN2new | past | comments | ask | show | jobs | submitlogin

Oh go on then - how do you make a zig interface that has equivalent behaviour to a rust trait? I want something that has a documented interface, default function implementations, can be stored in other structs, and allows both monomorphization and dynamic dispatch.

If the authors of the zig standard library can't do it, I assume its impossible. And hence this article talking about 3 different definitions of a "writer" appearing in the standard library, each trying to make up for shortcomings of the others. You have anytype, AnyWriter and GenericWriter. All with weird and complex tradeoffs and interactions. Not only do people need to learn 3 different interfaces, they also need to figure out how to convert from one kind of writer to another!

I talked to Rob Pike, back before Go hit version 1.0. I told him I really thought he should have not only enums, but parametric enums in Go. Of course, he disagreed. He said enums don't add enough value. Honestly I'm not sure if he'd ever used a language with parametric enums - and he didn't understand their value. Having used typescript, and now rust and swift, going back to C or Go and needing to build my own enums out of union structs and so on is awful. It feels like I'm trying to build a house using a rock and a piece of flint.

I see rust's trait system as just like that. What a pity that Zig doesn't have something similar. To me, traits seem like an obvious thing to copy into the language.



It'd be a bit gnarly, but somebody could absolutely write a utility capable of providing those features in the userspace of the language:

1. Documented Interface: Documentation would be a struct with the desired function declarations (combined with some type-checking, I spit-balled an idea for that recently [0]).

2. Default Function Implementations: The exact tool you'll use will vary since the language hasn't hit 1.0, but a `pub usingnamespace FakeInheritanceFooBarBaz(TheTrait, @This());` could have the desired effect.

3. Stored in other structs: Rust doesn't even really give you this. It has syntactic sugar to make the dynamic case easier, and it has the ability to store concrete implementations. For the latter, Zig just works. For the former, you want something that automagically wraps any trait-conforming object in a dynamic pointer-based structure. That's a weak point in the language since the metaprogramming facilities for creating functions and for creating objects with decls aren't very solid (that will get fixed by 1.0). You could make do for now by using comptime fields instead of decls in the wrapper logic that generates this thing (think `foo: fn (A) B` instead of `fn foo(A) B {}`), and that generation code would have to handle different argument counts by hand.

4. Monomorphization: You'd get that for free, since this is just ordinary comptime duck-typing.

5. Dynamic (runtime dispatch: This is really identical to the work for (3).

[0] https://hackernews.hn/item?id=42899354


I followed 80% of what you've said, but not all of it. I'd love to read a sketch of this in code.

How would you clean up Writer in std?


I'll try to put together a PoC a little later. I won't have time till at least this evening though, maybe later.


It's a very nontrivial amount of code to make the library that provides all of those features, even worse to do it well. Here's a PoC for one of them [0] (default implementations).

The broad theme is that other languages use keywords for traits or subclasses or whatever. In Zig, you can define libraries using the language's metapgrogramming facilities that do the same thing (or similar things).

Zig doesn't have a complete metaprogramming story yet either, which makes it harder (no custom types with custom decls, can't create a function dynamically, ...), but there are still a few options for creating something that looks like an interface.

In my mind, all the obvious solutions have something like a "template" and utilities that operate on that template. The template serves as documentation and also a hint to the LSP. Its exact semantics aren't important; they just have to match however that library decides the implementation should look.

[0] https://github.com/hmusgrave/zinter


Awesome! Nice work. I’m still astounded by what you can pull off with comptime.


Comptime is amazing. It's a new language, but I'm excited. I got my team excited too, for some fantastic benefits at work.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: