| ... | ... | @@ -19,69 +19,58 @@ Reallow punning, Foo {x,y,z} would be interpreted as Foo {x = x, y = y, z = z} i | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Update syntax should not bottom out when fields are undefined. as in
 | 
| 
 | 
 | 
Update syntax should not bottom out when fields are undefined, e.g.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
data Foo = Foo { x :: String, y :: Int } | Bar { x :: String }
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
foo = Bar { x = "hello }
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
baz = foo { y = 3 }
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
should not result in an error, but rather pass foo 
 | 
| 
 | 
 | 
through unchanged. update should update the record 
 | 
| 
 | 
 | 
if it exists, but pass the type through otherwise.
 | 
| 
 | 
 | 
This would make the update syntax actually useful
 | 
| 
 | 
 | 
This would make the update syntax actually useful.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## Label-based pattern-matching
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> the function:
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> ```wiki
 | 
| 
 | 
 | 
>   f val { x = "foo" } = 4
 | 
| 
 | 
 | 
> ```
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> should match if passed a Foo or a Bar with x being equal to "foo" and val would be bound to its argument (like an @
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
The function:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
f val { x = "foo" } = 4
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
should match if passed a Foo or a Bar with x being equal to "foo" and val would be bound to its argument (like an @
 | 
| 
 | 
 | 
pattern)
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
 g _ { y = 3 } = 4
 | 
| 
 | 
 | 
g _ { y = 3 } = 4
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> would match only the Bar constructor since it is the only one with a  y field.
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> This would mitigate the problems caused by accessors being partial functions since you can use a simple case statement to get the effect of an accesor that returns its result in a Maybe.
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> Note from Simon.  I hate that the above defn of 'f' has just one argument (val {x="foo")), 
 | 
| 
 | 
 | 
> whereas it looks as if it has two.  (This is a problem with existing Haskell.)  It looks
 | 
| 
 | 
 | 
> like 'f' has an argument 'val' and another arguement that is a free-standing record, 
 | 
| 
 | 
 | 
> something we really want in the end anyhow.  Not sure how to fix this.  val@{x="foo")?
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
would match only the Bar constructor since it is the only one with a  y field.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
This would mitigate the problems caused by accessors being partial functions since you can use a simple case statement to get the effect of an accesor that returns its result in a Maybe.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Note from Simon.  I hate that the above defn of 'f' has just one argument (val {x="foo")), 
 | 
| 
 | 
 | 
whereas it looks as if it has two.  (This is a problem with existing Haskell.)  It looks
 | 
| 
 | 
 | 
like 'f' has an argument 'val' and another arguement that is a free-standing record, 
 | 
| 
 | 
 | 
something we really want in the end anyhow.  Not sure how to fix this.  `val@{x="foo")`?
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## First-class syntax
 | 
| 
 | 
 | 
 | 
| ... | ... | @@ -92,73 +81,79 @@ A syntax for updating and setting fields should be allowed.  Some possibilites a | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
foo { x = }
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
would be equivalent to `(\v -> foo { x = v })`
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
would be equivalent to (\v -> foo { x = v })
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
foo { x \ }
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
would be equivalent to 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
(\f -> foo { x = case foo of _ {x} -> foo { x = f x }; _ -> foo }) 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
(\f -> foo { x = case foo of _ {x} -> foo { x = f x }; _ -> foo })
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## Polymorphic record update
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> Given a record like:
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> ```wiki
 | 
| 
 | 
 | 
> data Foo a = Foo { bar :: a }
 | 
| 
 | 
 | 
> ```
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> it would be nice to be able to update it like:
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> ```wiki
 | 
| 
 | 
 | 
> f = Foo { bar = 'a' }
 | 
| 
 | 
 | 
> g = f { bar = False }
 | 
| 
 | 
 | 
> ```
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
> Note the change in the type of the stored field.  At the moment, such a record update must be written using the
 | 
| 
 | 
 | 
> data constructor, not the update syntax.
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
>
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 'Open' statement
 | 
| 
 | 
 | 
Given a record like:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
data Foo a = Foo { bar :: a }
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
having the ability to 'open' a record bringing all its values into scope would be useful for techniques such as first class modules when combined with [PolymorphicComponents](polymorphic-components). a proposal is
 | 
| 
 | 
 | 
it would be nice to be able to update it like:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
f = Foo { bar = 'a' }
 | 
| 
 | 
 | 
g = f { bar = False }
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Note the change in the type of the stored field.
 | 
| 
 | 
 | 
At the moment, such a record update must be written using the data constructor, not the update syntax.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 'Open' statement
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Having the ability to 'open' a record bringing all its values into scope would be useful for techniques such as first class modules when combined with [PolymorphicComponents](polymorphic-components). a proposal is
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
data Record = Record { foo :: Int, bar :: String }
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
f :: Record -> Int
 | 
| 
 | 
 | 
f x = ... where
 | 
| 
 | 
 | 
   open x
 | 
| 
 | 
 | 
   ans = ...
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
will desugar to
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```wiki
 | 
| 
 | 
 | 
f x = ... where
 | 
| 
 | 
 | 
   Record { foo = foo } = x 
 | 
| 
 | 
 | 
   Record { bar = bar } = x 
 | 
| 
 | 
 | 
   ans = ...
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
open x would be allowed at the top level, in a let binding, or in a where binding.
 | 
| 
 | 
 | 
`open x` would be allowed at the top level, in a let binding, or in a where binding.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## Abstraction
 | 
| ... | ... |  |