Hi Sean,

Thanks for getting this started, sorry it took me a bit to put a response 
together. I initially wrote way too much, and  I'll probably spin out several 
other threads soon. This continues to be something that I think would be very 
helpful in the language, and I think the core you have proposed is great.

> In rust, the field names here need to match the definition;  e.g. `when 
> Circle{r} do` would be an error.  We could do the same, or we could match 
> based on position, and allow _ for ignored fields, e.g. `when Rectangle{len, 
> _} do`. I prefer the former, to avoid bugs if the enum definition changes.

I'd say matching names field names would be preferred as well. We already allow 
`_` to be used in tuple unpacking to ignore a value, so that does seem like a 
natural fit.

> Aside: I also like this syntax for record initialization it feels more 
> in-tune with the value semantics.

For now lets stick to the normal parens, and address this as a separate issue.


With the Maybe example, one bit of syntax doesn't quite make sense:

`Maybe(int)` - what is `int` describing here? What happens if the enum has a 
generic Left and Right? I think doing something along the lines of:

    enum Or(type U, type V) {
        Left { var value: T; },
        Right { var value: V; }
    }

could work here.


Some open questions I see in this related to this topic:

1. Reference vs Value semantics for enums? Some situations want one or the 
other.

2. Do we allow anonymous product types?
    enum Or(type U, type V) {
        Left( U ),
        Right( V, V )
    }

To address the issue raised in your second email:

> It should be easy enough to implement that special case efficiently (and 
> document the fact that it's efficient so users can depend on it). That seems 
> cleaner to me than saying that `enum {A,B}` is semantically identical to 
> `union {A,B}` but might be implemented differently.

I'll throw out my support for using `enum` over `union` to describe sum types 
in Chapel. Mostly because I think that union types could also have an 
interesting place in Chapel, but that is another email.

-Kyle

From: Sean Billig <[email protected]<mailto:[email protected]>>
Date: Tuesday, January 13, 2015 at 11:05 PM
To: Chapel Sourceforge Developers List 
<[email protected]<mailto:[email protected]>>
Subject: [Chapel-developers] Tagged unions

In the "type select on unions" thread, Kyle said:

Longer term I think it could be valuable in looking at changing unions to
a ML/Haskell/rust style tagged union. Going down this route could help
with the syntax questions as well. But that is probably a topic for
another thread.

I'd like to kick this discussion off, because I think it's a great idea. I'll 
toss out some thoughts on what this might look like in chapel, in the form of 
commented code. This is heavily inspired by rust's enum.

// Simple enumerated type
enum Color { Red, Green, Blue }

// (Contrived) sum-of-products type
enum Shape {
  Circle { var radius: real; },
  Rectangle { var length, width: real; },
  Point
}

proc area(s: Shape) {
  select s {
    when Shape.Circle{radius} do return pi * radius**2;
    when Shape.Rectangle{length, width} do return length * width;
    when Shape.Point do return 0;
  }
  // In rust, the field names here need to match the definition;
  // e.g. `when Circle{r} do` would be an error.
  // We could do the same, or we could match based on position,
  // and allow _ for ignored fields, e.g. `when Rectangle{len, _} do`.
  // I prefer the former, to avoid bugs if the enum definition changes.
}

var s = Shape.Rectangle{length:4, width:5};
writeln(area(s));
// Aside: I also like this syntax for record initialization;
// it feels more in-tune with the value semantics.

// Haskell's Maybe type (generic)
enum Maybe {
  Just { var value; },
  Nothing
}
var i: Maybe(int) = parseInt(readString());
select i {
  when Just{value} do writeln("success: ", value);
  when Nothing do writeln("parsing failed");
}

enum Expected {
  Good { var value; },
  Bad { var error: string; }
}
var x: Expected(real) = fallibleComputation();
select x {
  when Good{value} do writeln("success: ", value);
  when Bad{error} do writeln("failed: ", error);
}


Thoughts?

- Sean

------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
Chapel-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-developers

Reply via email to