Single argument doesn't capture required/optional semantics. I think a hybrid approach is best.
Also isn't discoverable, requires reading docs or source.
Usually I try to get 1 or 2 required args, then everything optional in an object. If thing requires more than 2 args then would consider single argument object. Callbacks as last param don't come into count.
Another option is fluent APIs.
E.g.
Link(target, dest) // args
Vs.
Link({from: target, to: dest}) // named args object
Vs
Link.from(target).to(dest) // fluent
> Single argument doesn't capture required/optional semantics.
I disagree. As shown here (section "Tuples and Structs")
http://gcanti.github.io/2014/09/29/javascript-types-and-sets.html
tuples and hashes are theoretically equivalent, but
I'd prefer to stick the required/optional semantic to the property:
var Person = struct({
name: Str, // required string
surname: maybe(Str), // optional string
email: maybe(Str) // optional string
});
rather than rely on an arbitrary order: `Person(name, [surname], [email])`, but it could be also `Person(name, [email], [surname])` or `Person([email], name, [surname])` ...
> I think a hybrid approach is best.
Without arguments, I'm forced to interpret it as an expression of taste, so I automatically and kindly agree with you.
> Also isn't discoverable, requires reading docs or source.
I disagree. The meta info of the `Person` type (name, surname, email)
are easily parseable (you don't even need esprima for that)
since they are expressed in vanilla JavaScript rather than opaque comments like JsDocs.
This is an example of what I'm saying:
http://gcanti.github.io/resources/tcomb-react-bootstrap/playground/playground.html
When you make a mistake I automatically display the docs.
The docs are generated on the fly analyzing a domain model written with the same style of the `Person` above.
IDE support is straightforward to obtain.
> Another option is fluent APIs.
I generally don't like fluent APIs:
- they are cumbersome for the developer designing the API
- they produce dangerous, temporary, intermediate, invalid type values during the construction
- required/optional semantic is a mess to implement since quite all properties must be temporary optional
- it's not clear when the building process can be considered terminated
Many news here are about the type "X is better than Y because Z uses it.". I like this post (and your comment above), since it teaches something about X without reference to Z (a framework). But I wrote this too fast maybe, so apologies if it was confusing.