The docs say:

Code: Select all

` _.sample(list, [n]) `

I can't fit the answer in this post because there are too many cases.

e.g.,

Code: Select all

`_.sample(a, 1)`

Code: Select all

`_.sample(a)`

Next: Allocations?Again, depends on how it's called. For

Code: Select all

`n != undefined`

What are the error conditions?

Code: Select all

`_.sample({ height: "10", width: "10", length: "10" }) is "10"`

Code: Select all

`_.sample({ height: 10, width: 10, length: 10 })`

Code: Select all

`_.sample({ height: 10, width: 10, length: 10 }, 1)`

More edge cases?

Code: Select all

`_.sample(2, [3, 4]) returns []`

Code: Select all

`_.sample(2)`

Code: Select all

`[1, 2, 3].map(_.sample.bind(_, [3, 4, 5])`

Code: Select all

`[[5], 3, 4]`

Code: Select all

`_.sample("abcdef")`

Code: Select all

`_.sample("abcdef", 3)`

Code: Select all

`_.sample("abc", "abc")`

So this function doesn't even always return an array, even for 'n' > 1

Underscore was built for size, not speed/predictability, but it's still *incredibly* hard just to describe the behavior of this function. I only tweet about TypeScript, though, so what's the connection?DefinitelyTyped's job is, in part, to:

1) Figure out all the rules the docs don't explain

2) Get people to agree on which of those behaviors constitute "errors"

3) Explain that behavior to a computer using a general-purpose DSL

So sometimes I hear "Type definitions are too complex" and really my response is that it isn't the definitions that are too complex, it's the library behavior. The *true* documentation for "sample" alone would span several written pages.

If you come across some code that is heavily indirected and just says

Code: Select all

`_.sample(obj, arg)`

In a reasonable world, 'sample' throws on non-array inputs, does the right thing on strings instead of nonsense, and you call sampleKeys or sampleValues to sample from objects.This isn't me dynamic-shaming you, it's that a function should do one predictable job, not guesstimate your intent. You can write dynamic code without having five layers of "Does X if Y is Z, otherwise does Q to M when A is present"

My hope is that long-term, people write functions whose behavior is *easy* to describe, both to a human and to a machine.