Open lucaswerkmeister opened 8 years ago
@lucaswerkmeister Do you always have a type
declaration whenever you have a function overloaded by string types?
@gavinking no, for the overloading usecase I haven’t seen that at all. I don’t see how it would make sense, either – where would you use that declaration? Each overloaded definition only uses one of the string types, not the union.
And by the way, here’s an example where string types are used as a sort of “enum”, but without a type alias:
interface String {
normalize(form: "NFC" | "NFD" | "NFKC" | "NFKD"): string;
// ...
}
Oh, I see, I misread.
FTR, I would not be totally implacably against adding symbols and symbol types to the language, that is, something like the following:
alias ScrollBehavior = $Auto | $Instant | $Smooth;
ScrollBehavior scrollBehavior = $auto;
And:
HTMLAnchorElement createElement($A tagName);
HTMLAppletElement createElement($Applet tagName);
HTMLAnchorElement a = createElement($a);
Or something like that.
Reminds me of SmallTalk :-)
I don’t know, I don’t feel like string types are very useful outside of modeling pre-existing APIs. I don’t think we need to add these symbols to Ceylon.
TypeScript has “string types”:
"foo"
is a perfectly ordinary type, and so is"foo" | "bar" | number
.Their two main uses seem to be:
Union of string types as “enum”:
Overloads:
The first case could be converted to the equivalent of:
Where the backend would erase
ScrollBehavior.auto
to"auto"
, anddre$$
would know that the typeScrollBehavior
is really justString
. (Note: these “enums” don’t always get a type alias; we might for example have to take the name from the parameter whose type they are, i. e.scrollBehavior: "auto" | "instant" | "smooth"
.)But for the second case, we need them to be actual types. So I would propose this instead:
And the overloads would map to:
The backend would still make sure that all of these objects are erased to their string literal, and
dre$$
would know that this string value is the only allowed value for that type.Of course, we would have to make sure that these names do not collide with any pre-existing module members; where necessary, we would disambiguate them with
aString
,aStringType
, or something similar. (However, it’s no problem if a string type appears multiple times: just reuse the object.)For string types that don’t happen to be valid identifiers, we would need to either escape the name or just invent one (
stringType1
). To make sure that this isn’t necessary too often, we should check type aliases first: the user could then add the “helper alias”and we would map that string type in
createElementNS
toSvgNamespace
instead of a made-up name. (This is also how we’ll make structural types not suck: give them names with aliases.)Any comments or suggestions?