Syntax for union types
On 27/10/2007, James Clark <jjc at jclark.com> wrote:
(int, string) doesn't seem to me to be a syntax that the average JS programmer will guess means union. I would have thought a better choice would be (int | string) (especially given that regexps use |) or a keyword.
Honestly, there's very little in the type system that I think will come entirely natural for ES3 users. Annoted object types look like object initialisers with name-value pairs, annoted array types look like array initialisers, the constructor syntax looks entirely weird, parametric types don't look like anything else in the language etc. And other parts too - destructuring assignment, array comprehensions etc, all look slightly foreign.
I really don't think this syntax is that very foreign (it's a quite natural way to list different types something can be after all), and with all the new syntax related to typing, as well as other syntax additions, it's going to be one tiny part of an entire new domain to learn.
On Oct 26, 2007 6:35 PM, James Clark <jjc at jclark.com> wrote:
(int, string) doesn't seem to me to be a syntax that the average JS programmer will guess means union. I would have thought a better choice would be (int | string) (especially given that regexps use |) or a keyword.
Yep. I read (int, string) as a tuple type every time. ML, Haskell, Python 3.0... I'm not sure what we gain by going against the grain here.
So it's not a big deal, but switching to (t1 | t2) seems all upside to me. It's a shallow change. +1.
Is there any reason why this proposal isn't being considered?
Not only is (int | string) more intuitive than (int, string), the (int, string) syntax can be reserved for another yet-unknown purpose.
Along the same lines, I find the syntax for constraining list types to be unintuitive. [int] is very different from [int, string], and [int, string] is very different from (int, string). Perhaps that (int, string) can describe the tuple type. And [int | string] could be syntactic sugar for [(int | string)]. The usage of "|" improves readability in that there's no way to confuse a union type with a tuple type.
-Yuh-Ruey Chen
-----Original Message----- From: es4-discuss-bounces at mozilla.org [mailto:es4-discuss-bounces at mozilla.org] On Behalf Of Yuh-Ruey Chen Sent: 9. november 2007 01:06 To: Jason Orendorff Cc: es4-discuss at mozilla.org Subject: Re: Syntax for union types
Is there any reason why this proposal isn't being considered?
Yes. The current syntax has been accepted by the working group. We have made use of it in various contexts, (builtins, ESC). Speaking for myself I don't see the problem with what we have.
Not only is (int | string) more intuitive than (int, string), the (int, string) syntax can be reserved for another yet-unknown
purpose.
Intuition tends to be personal, and the other argument can be turned on its head (why wouldn't I want to use "int | string" for something else in the future?). Since "|" is bitwise or, "||" would have been better, but that has yet other connotations.
Along the same lines, I find the syntax for constraining list types to be unintuitive. [int] is very different from [int, string], and [int, string] is very different from (int, string). Perhaps that (int, string) can describe the tuple type. And [int | string] could be syntactic sugar for [(int | string)]. The usage of "|" improves readability in that there's no way to confuse a union type with a tuple type.
This has been discussed at considerable length, and we've concluded that the current solution represents a workable compromise.
Syntax discussions are not fruitless, but the decisions for the things you mention above were not arbitrary, and there is, to my knowledge, no inclination inside the group to revisit the choices.
(More interesting open questions about the language are whether generic functions ought to be available on instances or discriminating on structural types, or whether packages ought to be sealable for security, or whether ES4 precludes the use of current ES3 AOP patterns and how that might be solved. Among other things.)
On Nov 9, 2007 4:31 PM, Lars Hansen <lhansen at adobe.com> wrote: [snip]
(More interesting open questions about the language are whether generic functions ought to be available on instances or discriminating on structural types, or whether packages ought to be sealable for security, or whether ES4 precludes the use of current ES3 AOP patterns and how that might be solved. Among other things.)
the option to have sealed package would be indeed an interesting feature in ES4, is this is discussed somewhere in the wiki ?
-----Original Message----- From: zwetan [mailto:zwetan at gmail.com] Sent: 9. november 2007 07:49 To: Lars Hansen; es4-discuss Subject: Re: Syntax for union types
On Nov 9, 2007 4:31 PM, Lars Hansen <lhansen at adobe.com> wrote: [snip]
(More interesting open questions about the language are whether generic functions ought to be available on instances or discriminating on structural types, or whether packages ought to be sealable for security, or whether ES4 precludes the use of current ES3 AOP patterns and how that might be solved. Among other things.)
the option to have sealed package would be indeed an interesting feature in ES4, is this is discussed somewhere in the wiki ?
Not to my knowledge, and we've in any case not incorporated anything like this.
A couple of obvious solutions would be to have package fragments designated "final" be the only package fragment for the package, or to have a "final"-designated package fragment provide the last fragment of the package, preventing the loading of subsequent fragments.
Whether this is a good idea or not depends in part on whether you think packages and namespaces are for secrecy/integrity, as implied by the use of eg "private" in a class ("private" is just a namespace), or if namespaces are just for collision avoidance.
On Nov 9, 2007 5:13 PM, Lars Hansen <lhansen at adobe.com> wrote:
the option to have sealed package would be indeed an interesting feature in ES4, is this is discussed somewhere in the wiki ?
Not to my knowledge, and we've in any case not incorporated anything like this.
ok I thougth that what you mentioned was already discussed by TG1.
A couple of obvious solutions would be to have package fragments designated "final" be the only package fragment for the package, or to have a "final"-designated package fragment provide the last fragment of the package, preventing the loading of subsequent fragments.
Whether this is a good idea or not depends in part on whether you think packages and namespaces are for secrecy/integrity, as implied by the use of eg "private" in a class ("private" is just a namespace), or if namespaces are just for collision avoidance.
well it depends on the context, for security it could be good to have final package, if I remember well inside the spec there were a namespace exemple showing how to "secure" the access to a class using namespaces, but apparently we don't have access to the spec pages anymore (?).
zwetan
On Nov 9, 2007, at 8:53 AM, zwetan wrote:
but apparently we don't have access to the spec pages anymore (?).
The spec: section was badly out of date, hidden from view, then
inadvertently exposed again (making for new confusion), now hidden
again. It's based too much on AS3 and not being updated, so better to
let it alone.
As Lars suggested, we have bigger fish to fry, but we settled on
union syntax quickly and were content to stay there. I'm not against
| instead of , and if enough people think it's the right user
interface, we could consider it again. I'm not saying it's a good use
of time to fuss over this, but it's "fixable" if (T, U, ...) is not
as good as (T | U | ...).
Recall that ES4 and indeed JavaScript do not have tuples, so we want
to use [T, U] for the array structural type describing a tuple of at
least index 0 of type T and index 1 of type U. If we ever did add
tuples, then Yuh-Ruey has a point I think: we might rather use (T |
U) for union of T and U, and (T, U) -- or possibly (T, U,) to match
expression syntax (which would have to be (e1, e2,) to avoid
ambiguity with comma expression) for tuple type.
Lars Hansen wrote:
Not only is (int | string) more intuitive than (int, string), the (int, string) syntax can be reserved for another yet-unknown purpose.
Intuition tends to be personal, and the other argument can be turned on its head (why wouldn't I want to use "int | string" for something else in the future?). Since "|" is bitwise or, "||" would have been better, but that has yet other connotations.
Well, I didn't draw that intuitiveness primarily from ES3 operators. It comes from regexes (which are already in the langauge) and common grammar notation (which are well-known to CS majors), which all tend to use "|" as the "or" operator.
Along the same lines, I find the syntax for constraining list types to be unintuitive. [int] is very different from [int, string], and [int, string] is very different from (int, string). Perhaps that (int, string) can describe the tuple type. And [int | string] could be syntactic sugar for [(int | string)]. The usage of "|" improves readability in that there's no way to confuse a union type with a tuple type.
This has been discussed at considerable length, and we've concluded that the current solution represents a workable compromise.
A compromise between what? I'm not aware of any existing implementation (besides the RI) that uses union types. I'm also unaware of any published discussion concerning the syntax of union types (didn't find any in the wiki).
(More interesting open questions about the language are whether generic functions ought to be available on instances or discriminating on structural types, or whether packages ought to be sealable for security, or whether ES4 precludes the use of current ES3 AOP patterns and how that might be solved. Among other things.)
--lars
By "generic functions ought to be available on instances", do you mean non-global generic methods? TBH, I consider generic functions a bit of an odd fuck in ES4, because of its many restrictions compared to normal functions (see the "non-features, future directions, etc." section on the generic functions proposal).
-Yuh-Ruey Chen
Yuh-Ruey Chen wrote:
By "generic functions ought to be available on instances", do you mean non-global generic methods? TBH, I consider generic functions a bit of an odd fuck in ES4, because of its many restrictions compared to normal functions (see the "non-features, future directions, etc." section on the generic functions proposal).
-Yuh-Ruey Chen
odd duck sigh
+1 for |
Thanks. I filed:
bugs.ecmascript.org/ticket/300
asking for this change. As I wrote there, this kind of fine-tuning of
syntax (the UI to the language) should not be cut off by the new
proposals cutoff, any more than fiddling over JSON APIs should be cut
off or frozen prematurely. So I'll advocate for this change in the
group.
(int, string) doesn't seem to me to be a syntax that the average JS programmer will guess means union. I would have thought a better choice would be (int | string) (especially given that regexps use |) or a keyword.
James