> Or, to put it another way, how do you decide a given method should have "small types" used for parameters?
I think a good rule of thumb is to ask yourself what the "dimension" or "unit" the parameter has. (See also: Dimensional Analysis.) You never want to pass 4.33f radians into a function expecting 4.33f newtons!
A few more examples:
Distance in meters, Distance in feet, Speed in m/s, speed in yards/minute, Acceleration in m/s^2, Acceleration in cm/s^2, Mass in grams, Weight in pounds, Force in newtons, Force in dynes, Temperature in Celsius, Temperature in Fahrenheit, Angles in radians, Angles in degrees....
"But I don't do physics programming!", you say? Well, there's plenty more:
Time in seconds, Time in milliseconds, Distance in pixels, Distance in inches, Numeric ID of a Foo, Numeric ID of a Bar, Bytes in UTF8, Bytes in ASCII, US currency in dollars, US currency in cents, Euros, interest rate (yearly), interest rate (monthly)...
And that's not even getting into industry-specific dimensions that might exist.
That brings up an interesting issue -- is the "right way" to do that to have different types for these, or one type for distance with different factory function/methods for different units. E.g.: should "meters" and "feet" be different types, or should the "measurement" module have both a "meters" and "feet" method that return the same ("distance") type.
It seems to me the latter is more conceptually clean.
OTOH, math might be easier to express with the former (particularly in a language that allows you to define implicit type conversions, so that if you pass an "inch" value to a function expecting a "cm" parameter, it gets automatically converted to the appropriate "cm" value.)
Well, there are really three different kinds of information involved. For example, the variable "target_resist" might have: Computational type (float), Dimension (resistance), and Unit (milliohms).
Most built-in type-systems (sensibly!) only try to tackle the broadly-applicable computational-type, since the rest is context-specific.
However, in a contractual sense, all of those are important, if any are not as expected, you'll get bugs.
Ok, I can understand that logic but then you might end up with dozens and dozens of "small types" so, as far as I understand, those who try to follow that paradigm have no problem whatsoever with the potentially high number of these types, is it so?
(Again, asked another way, is it ever a problem to create a "small type" if it follows that rule? For some codebases it might mean having a "small type" per unique parameter on signatures.)
> Again, asked another way, is it ever a problem to create a "small type" if it follows that rule?
IMO the biggest problem isn't having too many distinct types, because they represent information you'd need to track manually anyway, like knowing that $time is seconds rather than milliseconds. I'd be more worried about:
1. The risk of conflicts between different groups of people who both defined their own type called called "Newtons" and want their libraries to work together.
2. The sliding-scale of inconvenience if your implementation gets in the way of the mathematics, like having to call `foo.asFloat() * 2` rather than `foo * 2`. (You can relax things a bit by relying on best-effort annotations.)
I think a good rule of thumb is to ask yourself what the "dimension" or "unit" the parameter has. (See also: Dimensional Analysis.) You never want to pass 4.33f radians into a function expecting 4.33f newtons!
A few more examples:
Distance in meters, Distance in feet, Speed in m/s, speed in yards/minute, Acceleration in m/s^2, Acceleration in cm/s^2, Mass in grams, Weight in pounds, Force in newtons, Force in dynes, Temperature in Celsius, Temperature in Fahrenheit, Angles in radians, Angles in degrees....
"But I don't do physics programming!", you say? Well, there's plenty more:
Time in seconds, Time in milliseconds, Distance in pixels, Distance in inches, Numeric ID of a Foo, Numeric ID of a Bar, Bytes in UTF8, Bytes in ASCII, US currency in dollars, US currency in cents, Euros, interest rate (yearly), interest rate (monthly)...
And that's not even getting into industry-specific dimensions that might exist.