jsigbiz / spec

JavaScript signature notation
131 stars 6 forks source link

Closed or open #45

Open Raynos opened 9 years ago

Raynos commented 9 years ago

Here is an idea to express closed and open objects:

This is a closed object

foo : { foo: String  }

This is an open object

foo : Object & { foo: String }

This requires no new syntax to express open and closed. It also has closed semantics by default.

Closed vs Open

A quick definition of open and closed.

A closed object is an object who has at MOST these fields. This means that the following do not type check.

// foo : ({ foo: String }) => void
foo({ foo: 'bar', baz: 'bob' })

Closed semantics are really useful for strict ness and future proofing of an interface. They are also useful to express that you will only return these fields

An open object is an object who has AT LEAST these fields.

Open objects are useful for communicating that that an object can have extra random fields.

cc @jden @Matt-Esch

junosuarez commented 9 years ago

A closed object is an object who has at MOST these fields. This means that the following do not type check.

Shouldn't it be an object which has exactly those properties (except the ? operator)?

As for the idea of open/closed objects, it reminds me of the final keyword in Java. In my experience this only hurt the evolvability and maintainability of codebases and led to hacky workarounds and wrapper classes. YMMV. Conceptually, types in jsig are different from types in Java; most relevantly, they are structural and not inheritance based. jsig types are extended and combined with set-style operators (related: issue for the "without" operator #46)

I'm interested in hearing more about the use case for being able to express a closed object.

I'm also against making closed the default. This runs counter to the dynamic nature of JavaScript objects. Some JavaScript programming styles apply additional constraints to JavaScript's own semantics, e.g. treating objects as immutable, but jsig should be flexible enough to cover a broad range of JavaScript styles.

Raynos commented 9 years ago

closed shouldn't suffer the painpoints of final. You can still extend these objects.

Closed objects allow you to reason about your program at the edges. It allows you to make assumptions about input and output.

With open objects you cannot make any assumptions about input or output and have to do defensive programming.

Being able to reason about closed and open is only really important for a type checker or a correctness tool.