Thanks to visit codestin.com
Credit goes to github.com

Skip to content

enum (aka sum type) limitations #9

@warpfork

Description

@warpfork

Preface: this is an amazing project. Just wow. So many delightful things here.

I'm poking around the enums feature. It's a little underdiscussed in the readme right now (only shows up under the "destructuring" heading!) but it looks like it's full sum types, which is delightful.

So I'm dottering around in the playground (again, nice work) on the enums example, and I'm tweaking it to this, to see what happens:

type IpAddr enum {
    V4(u8, u8, u8, u8)
    V6(string)
    Wot(Spicy)
}

type Spicy struct {
    Voop string
}

And something goes correctly wrong: "match expression is not exhaustive". Nice. NICE. It's even got the line and column numbers! NICE!!!

Alright, so I go down to the match expression in question. Indeed, it's missing an arm.

Okay. Issue 1: (just a quick tangent) adding a default branch causes a nil panic. ... but I can't say that's often what I want, so, moving on.

Adding a branch:

    case IpAddr.Wot:
        return false

Alright, that works. Excellent.

But what if I want the value? Okay, let's try parens destructuring, like the others:

    case IpAddr.Wot(x):
        return false

Hm. Issue 2: "undefined identifier x". That... doesn't seem like anything I'd expect. My mental parse here is: "IpAddr" contains a member "Wot", which is a 1-tuple containing a value of type "Spicy" (which is a struct containing a string called "Voop"). And I'm asking it to destructure out a value called "x" and it should be a copy of the "Spicy"-type struct.

I tried a couple other things like case IpAddr.Wot{x}: and case IpAddr.Wot({x}): (not particularly expecting that one to work, but, why not), and get various panics about ast expectation mismatches. (My heart goes out to you, by the way. I've written code using those packages before. They're a stellar example of the reason I want sum types in golang so very badly. The irony!)

I also kicked around to see if I could access things in a property-like way after matching on which member is inhabited: case IpAddr.Wot: return ip.(IpAddr.Spicy).Voop == "". I don't think I really expect this to work either (it would be kind of alarming if it did!), but the error messages also weren't great: this one just emitted panic: IpAddr types.EnumType, at the moment.

Overall, I couldn't find a way to successfully extract a value from an enum member that's another complex type.


On a slightly different vein of approach: I also tried a couple different variations of the enum declaration itself:

type IpAddr enum {
    V4(u8, u8, u8, u8)
    V6(string)
    Wot
}

^ This seems to get parsed roughly as if "Wot" is a 0-tuple. Alright, fine.

type IpAddr enum {
    V4(u8, u8, u8, u8)
    V6(string)
    Spicy
}

type Spicy struct { //...

^ This... is probably also parsed as if IpAddr.Spicy is a 0-tuple. But I wanted to mention it as potentially kind of interesting, because a Golang-shaped-brain (and some other languages, too, I reckon) might expect that to be a shorthand for Spicy(Spicy) -- in other words, an enum member that is a transparent/1-tuple of the struct type already named Spicy. I don't know if that's worth special handling; just mentioning the consideration, since I'm poking everything and this is one of the bits that sometimes contains surprises.


I hope any of this noodling report is of use to you! If nothing else, please know that someone's trying your work out and thinks it's pretty awesome! :D

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions