Closed Raynos closed 11 years ago
:=
symbolI'm still ambivalent about this versus just :
- it adds symbols that don't exist elsewhere in jsig or JavaScript. If no one else objects to it, however, I could be convinced.
In the earlier draft, dot notation was actually just implicit lexical symbols, rather than a feature of jsig. I support removing it from the examples in favor of clarity and the implicit lexical notation introduced elsewhere in your changes.
The distinction between foo?: T
and foo: T?
was intending to capture the difference between foo
being a property with a value of undefined and foo
not being a property at all. JavaScript is a bit warty (and casual!) that way. I was attempting to defer to the language in terms of describing semantics. This distinction matters more in describing objects than arguments, eg {}
would satisfy {foo?: String}
but not {foo: String?}
, while {foo: undefined}
would satisfy the second but not the first. The somewhat bizarre annotation of {foo?: String?}
would be satisfied by both.
Having a consistent way to express optionality is great - is it worth the cost of reduced expressivity than the underlying language? I could be convinced of this, but it wasn't my first inclination in the earlier draft.
Value
to Any
I'm good with this. Several other languages use Any
. I took Value
from the ES5 grammar, but I think Any
reads better (and has the benefit of being more concise!)
In my mind & intention, this was already supported. I appreciate the effort to clarify that :)
:+1:
:+1:
:= symbol
I use this to differentiate the PascalCase new types and the lexical symbols in the programs from labels.
Labels are there purely for human readable words and you can re-use the same label name as many times as you want. The :=
definitions have to be unique
consistent optional types
I was thinking of { foo?: X }
I'm not too sure it can be completely removed
Here I believe the disjoint union would be better, since &
implies that the preceding type is extended by the following type. So:
getOrSet := (Object, String) => T
| (Object, String, T) => void
@killdream I think of |
as meaning that getOrSet
is either function A or function B. I think of &
as meaning that getOrSet
is both function A AND function B. it's a function that complies with both signatures.
@jden
I take back "consistent optional types". You need ?
on the tag for things like
foo := (opts?: { key: String }) => Any
for types where placing a ?
on the end looks silly basically
@jden I want to break this PR into individual small features and PR & discuss them one by one.
I want to start with ones that can just be landed like:
@Raynos sounds good. I had asked @thlorenz to comment on some of these as well. I'll close this for now. I'm also going to go ahead and stick a version number on the current spec as 0.1.0, so we can go from there.
Would also love a separate PR for the grammar you started working up, maybe with a note that it is not (yet) normative
This is a discussion issue. I will list all the changes I made and then we can battle it out.
Examples folder
I added an examples folder which the majority of my type definitions so far. The examples folder does contain constructs that I have not defined in the README yet.
Grammar
I've added the start of a grammar definition which is far from complete.
name := <type>
I don't allow anonymous type declarations. I allow two types of declarations. The first one is saying
name := <type>
which generally means a lexical variablename
has the type<type>
. I also usename
to mean reference to name in npm.Example (npm name):
Example (local name):
Removal of dot notation
I think I've removed it from the README because it's not needed. You can actually define the type of a lexical variable to just be an object
consistent optional types
Optional types is now done purely through
String?
and(opts?: Object)
is invalid and should be replaced with(opts: Object?)
Introduce explicit type declarations
The second type of declaration is declaring a named type. Named types are not related to the npm namespace or the lexical variables in your program. Named types are purely defined and reference in other type signatures.
An example would be
Rename
Value
toAny
I've basically renamed the usage of
Value
to mean "any" type to usage ofAny
to mean "any" typeCompound function types
Instead of defining the same lexical variable multiple times, one for each function signature you can use a compound signature
Replacing the notion of "named paramters" with "labelled types"
Instead of saying that we can name paramters, I've changed the wording to say that you can label any type.
Example:
Introducing the enum type
Enum is like the or type but more human readable. For example
type: "create" | "update" | "delete"
can be expressed astype: Enum("create", "update", "delete")
Example: