Re: APIs that overload numbers and strings

On 4/13/13 7:39 PM, Allen Wirfs-Brock wrote:
> I think "overload" is the wrong way to think about these particular
> use cases and in general is not a good way to be thinking about JS
> functions. "Overload" to many developers implies multiple distinct
> functions that share a common name but where each function has it own
> distinct definition and behavior.  Static analysis of argument types
> determines which function is actually called at each call site.

Sure.

> That's not how JS works or how a JS programmer would think about the
>  equivalant situation.  In JS there is one function with a single
> definition that may include logic that dynamic selects distinct
> behaviors based upon analysis of  the actual parameter values.  In
> the JS case, internally dispatching upon an parameter value's type is
> really not much different from dispatching on the numeric value of a
> control parameter, or based upon the properties of an option object.

While true, the end result is that you end up with having different
behaviors depending on the parameter value type.  Whether that's handled
by an if/else or by separate functions is sort of an implementation
detail...

I'm happy with changing the terminology here as needed if that would
help, since in practice what happens right now is that the callee
introspects the arguments (and then possibly calls actual separate
functions in the implementation).

> This is interesting from an legacy compatibility perspective. If
> numeric strings and equivalent numbers always mean the same thing

Well, that's a question.  ;)

The old audio API had numeric named constants:
SomeInterface.SOME_BEHAVIOR_CONSTANT, etc.

The new audio API just takes strings like "somebehavior" that determine
the behavior.

> If most of the legacy values correspond to named constant attributes
>  you may be able to respecify those constants as string values

We'd still need to handle numeric values passed in somehow, since I
doubt consumers are consistently using the named constants....

> Note that in  JS someArray[5] also implies an implicit number to
> string conversion.

Quite, but engine's special-case very carefully to avoid such
conversions.  So it's quite a different situation.

> Idiomatic JS code that needs to distinguish numbers and strings would
> just say typeof foo === "number" or typeof foo === "string"

As long as they ignore Number and String objects, yep.

> However, the test may no be needed at all, if the value is just going to be
> passed on to some lower level interface that is doing its own type
> discrimination.

We've had this discussion before; in practice type sanitization needs to 
happen at some trust boundary, wherever you draw that.

> I won't worry about doing something special for String or Number
> wrapper objects.  They're really just an unfortunately exposed
> implementation artifact that JS programs seldom have to explicitly
> deal with.

OK, great.

> Going back to the beginning, it isn't that they want overloading, its
> that they may want to do distinct things for certain kinds of values.

Yes.

> Distinguishing numbers and strings is one possible discrimination, so
> is distinguishing positive and negative numbers, and objects that
> have a foo property from those that don't.  I don't think you can
> generalize very much here as the "right think" to do is highly
> situational.

Well, sure.

Let me try to be a bit more specific about the state of things.

What WebIDL gives you right now are tools to declare that you want your 
arguments checked and/or coerced in certain ways.   This includes some 
"type" coercions (ToString, ToNumber, etc), certain type checks 
(instance of a particular interface), some numeric range checks and some 
numeric range coercions.  If you don't want any of that jazz, then you 
can just use "any" and do whatever the heck you want with it (as 
IndexedDB does).

What WebIDL does NOT give you is a simple way to declare that your 
function should have as one of its initial steps "check that the input 
is a primitive string or primitive number, without doing any coercions".

_Should_ WebIDL provide some facility that allows the above?  If so, 
should it be restricted to primitives or should it do something with 
random objects (e.g. valueOf or whatnot)?

Again, this isn't about what range of behaviors are allowed.  All 
behaviors are always allowed with "any".  The question is what behaviors 
are _encouraged_ when API designers who don't care all that much about 
any of the edge cases consider an API where they want to differentiate 
between numbers and strings.

Does that make sense?

-Boris

Received on Sunday, 14 April 2013 00:44:39 UTC