jsigbiz / spec

JavaScript signature notation
130 stars 6 forks source link

without operator #36

Open Raynos opened 10 years ago

Raynos commented 10 years ago

The without operator / does not currently exist in jsig.

This a proposal for it.

The / operator is basically the set complement operator ( http://en.wikipedia.org/wiki/Complement_(set_theory) ).

The way it works is you can define a type T : A \ B and a value is of type T if the value is of type A AND not of type B

My use case is:

type ActionKey : "read" | "update" | "create" | "destroy"
type RestResource : (String \ ActionKey) \ "rpc"

type RestSpec :
    Object<ActionKey, Action> &
    Object<"rpc", Object<RpcMethodName, RestOperation>> &
    Object<RestResource, RestSpec>

I have an object that looks like

{
  read: myAction,
  rpc: { rpcMethodName: myOperation },
  'nestedResourceA': { read: otherAction },
  'nestedResourceB': { read: otherAction }
}

I want to use jsig to say that the object has a whitelist of keys that have special semantics and that all additional properties look like a nested thing.

Currently today I could express this as

{
  read: myAction,
  rpc: { rpcMethodName: myOperation },
  resources: {
    'nestedResourceA': { read: otherAction },
    'nestedResourceB': { read: otherAction }
  }
}

This would have a jsig type of

type RestResource : String

type RestSpec : {
  read: Action,
  rpc: Object<RpcMethodName, RestOperation>,
  resources: Object<RestResource, RestSpec>
}

I don't want to be forced to use nested properties for homogenous maps / dictionaries.

I want a way to express that an object is a homogenous dictionary but it has this whitelist of properties that have different types.

junosuarez commented 10 years ago

This is a sensible use case. I can think of other examples in popular libraries which use this, for example Model objects in Backbone and Ampersand.

A paraphrase is that you'd like the ability to specify an object which has certain specific properties and arbitrary other properties.

By essentially reserving certain property names, you're saying that any other property name could come from the complementary set of all property names which aren't a reserved name. Thinking ahead to Sets, Maps, and WeakMaps, this would also apply, but to a domain of objects not just strings.

+1 to including a "without" operator.

I am neutral on the syntax. One of the early design principles of jsig was to have syntax be as familiar as possible to JavaScript programmers, meaning borrowing from existing JavaScript syntax wherever possible. \ is used to escape certain characters in strings. How about ^ as used in RegExps?

Raynos commented 10 years ago

As for the syntax I wanted to use \ as its the set complement operator.

The way ^ is used in regular expressions is the NOT operator, it is not these things, ^ A is like Any / A, which is a subset of the \ functionality.

junosuarez commented 10 years ago

You could get the same expressivity with a NOT operator and rewrite

The way it works is you can define a type T : A \ B and a value is of type T if the value is of type A AND not of type B

as

type T : A & ^B

.

For reference (which I had forgotten from school, since I spend little of my day around mathematical notation), the complement operator notation being proposed here is from standard set notation.

Raynos commented 10 years ago

I would like to look up other typed languages that had one of:

To see what is the wiser way of addressing this use case.