data Color = Red | BlackThat said, please consider the following:
data Color = Red | Black
data Color { Red; Black }
data Color = Red | Black | Green
data Color { Red; Black; Green }
I think the brace + semicolon-newline style actually compares pretty favorably on single-line width (it wins out on line width to an increasing degree as the line gets longer, which is important). However, it is visually more complex, which matters a lot for shorter lines. For this reason, I think that allowing both syntaxes would be ideal. The pipe-based syntax could be encouraged for single lines (newline-termination would sidestep block-end inference issues), with the curly brace based syntax being encouraged for multi-line definitions. There is a slight disadvantage in that now a user would have to know both syntaxes, of course.
edit:
Of course, since Pyret's syntax requires that ADT parameters be specified in parentheses, you can actually omit the pipes in single-line mode, too, and opt to use space-juxtaposition.
data Color: Red | Black | Green;
We did also initially discuss using = instead of : in places where we were defining things (functions, data). That's still not completely out of the question. That would get you to
data Color = Red | Green | Black;
We need a closing delimiter to avoid creating huge ambiguities in the grammar.
(a, 2a) = (1, b)
> b == 2We don't EVER use = for assignment. For us, = is binding. If you write
fun f(x):
y = x * x
y = x + 2
x - y
end
Pyret will say I'm confused: y is defined twice
and point to the two bindings.The goal here is to make the common case work fine, where you create a bunch of distinct local bindings; but when you try to mutate, you have to do it explicitly:
fun f(x):
var y = x * x
y := x + 2
x - y
where:
f(10) is -2 # the test passes
end
The first line inside f says "y is _currently_ this, but it's variable, so look out!", and subsequent mutations use := to change y. Unlike JavaScript (say), mutating a variable that hasn't previously been defined is an error, rather than quietly adding the variable to the set of defined names.- We want := to mean "change". The initial binding is not a change. This is precisely the "bindings and assignments" distinction you're talking about.
- A variable may in fact not be mutated.
- A small point is that we want to localize editing when making a change.
So, the way I read
var y = x * x
is, "y is currently bound to x * x. However, y is a variable, so this binding is not guaranteed to last. Be careful about assuming you know the value of y." If you then see y := x * z
it reads as "y's value changes to that of x * z".So: "=" means "introduced a name with this value"; "var" means "but this binding may change"; ":=" means "and yup, it really _did_ change".