@sir looks like untagged unions are not playing well with the first rust implementation.

@sir They're tagged in the wire format, but not in the IDL. Tagged unions would typically take an enum as a parameter and map each case to a message.

See for example zig: ziglang.org/documentation/mast

@c_cube they're tagged in both. They don't have to have a separate enum to qualify

@sir I don't see a tag in `(a|b|c)`. I see an anonymous union where the order of declarations matters.

It's the same thing as removing `struct` (with named fields)` and replacing it with tuple syntax `(string, string, i32, bool, i64)` without names. Still technically a struct, but the code generated from that gives you accessors by position, not name, of fields.

@c_cube @sir I think Drew has it right here.

By anonymous union, I think you mean that each item in the union is not given a name. This does not mean that the union is untagged. The difference between a tagged an untagged union is that tagged unions carry which item of the union they are, but untagged unions do not. The "tag" refers" to the data which determines the type, and not to the name given to the alternative.

In Zig, for example, a plain `union` is untagged, but if you simply add `union(enum)`, it becomes tagged. In both of those cases, each alternative is given a name.

@philipwhite @sir note that in `union(enum)` in Zig, each case of the union has the shape `name: type`, so it has an explicit name for the tag, which is still an enum and not an integer.

So I agree that technically, BARE has tagged unions, but they should be tagged with enums, not integers. Again, same as structs having names, not just field numbers.

@c_cube @philipwhite I don't see any reason to tag them with enums. Different tech exists in different circumstances and arrive at different solutions. You were wrong, that's all, and that's fine.

@sir @philipwhite Indeed, they're tagged. They also seem pretty useless to me in that form, since you asked for feedback.

@c_cube @philipwhite I assure you they're useful. You just haven't encountered tagged unions outside of the context with which you are familiar.

@sir @philipwhite I think you might not have encountered tagged unions or sum types outside the context with which you are familiar either.

What does codegen for encoding/decoding such a union look like?

`type person = Zero(user) | One(admin)`? I'd rather have names for each case.

@sir @philipwhite Ah I see the Go code has a special case for registering unions, and uses reflection. I'm not too surprised, Go hates unions anyway.

@c_cube @philipwhite the names of the tagged types are the names for each case

@sir @philipwhite what are the names for `(i16 | i16 | i16 | i16)`?

@sir @philipwhite but granted, if you use a ton of type aliases… it could work. I need to try and write a codegenerator for rust.

@c_cube @philipwhite tagged unions are a set, you are not allowed to do this

@sir @philipwhite is there a `void` type that takes 0 bytes on the wire?

Usage is as follows:

type Tag1 void
type Tag2 void
type Tag3 SomeOtherStuff

type Foo (Tag1 | Tag2 | Tag3)

this is useful if some cases of the union don't have any interesting payload.

@c_cube @philipwhite I understand the enum/union system you're familiar with and deliberately did not design it this way

@sir @philipwhite that's sad, but well, everyone has their own taste I guess. Have you ever written on why you hate sum types so much? I can understand not liking FP, but I do struggle with the idea of not liking sum types.

@c_cube @philipwhite if I hated sum types I would not have added them to BARE lol

Show more
Show more

@sir @c_cube This whole discussion belongs in your public inbox probably, but since it's gone this far, I'll add another related thought.

It would seem to me that struct field names have as little use as enum tag names (obviously, I'm on the opposite side of @c_cube here) since all the names are stripped away anyway. We can get by with just tuples and unions.

@philipwhite @c_cube the field names and enum names are used in the schema DSL, from which code generators can utilize them to assign field names to language-native representations

@sir @c_cube Oh! Duh. I wasn't even considering the possibility of code generation. I've been just assuming that language has enough metaprogramming to allow encoding the schema itself, though not every language has that.

@c_cube @sir Yup, that's what I was saying. Hence, BARE has tagged unions, both technically and in any other sense.

I think what you want can often be accomplished at the library level. A reasonable assumption is that the same type that was used to serialize the data can be used to deserialize the data. Thus, if the order of a Rust enum changes, then it will change during serialization and deserialization together, so everything will still work.

While I don't think programming with integer indexed enums is very self-documenting at all, it's fine for an interchange format.

@sir That looks very interesting 👍 Maybe I'll replace JSON with it some day but then I'll need a implementation in Javascript and PHP.

@sir is it me or is the publicKey optional's type not specified in the example schema ? I assume it's supposed to be optional<PublicKey> ?

@Ark error of translation to HTML, it's being interpreted as a tag. I'll fix it, thanks

Sign in to participate in the conversation

The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!