7 ms·
I don't think this is a naming issue at all. In the provided example, 'Accuracy' is the correct name for the parameter, as that's what the parameter represents,
by Sandman 6y ago
I don't think this is a naming issue at all. In the provided example, 'Accuracy' is the correct name for the parameter, as that's what the parameter represents, accuracy. The fact that accuracy should be given as a value in an interval from 0 to 1 should be a property of parameter type. In other words, the parameter should not be a float, but a more constrained type that allows floats only in [0,1].
EDIT: Some of you asked what about languages that don't support such more constrained types, so to answer all of you here: different languages have different capabilities, of course, so while some may make what I proposed trivial, in others it would be almost or literally impossible. However, I believe most of the more popular languages support creation of custom data types?
So the idea (for those languages at least) is quite simple - hold the value as a float, but wrap it in a custom data type that makes sure the value stays within bounds through accessor methods.
- firstbabylonian 6y agoyeah, right, so what do you call such a type? I believe that is the actual question.
- StavrosK 6y agoThe question was about the parameter name, though. The correct answer seems to be: function FuncName(UnitInterval accuracy)
- elcomet 6y agoUnitInterval seems to contains an interval, not a single float. I don't think it's a very good name. UnitIntervalNumber would be better, but it's too long. Something like UnitNumber or UnitFloat could maybe work.
- peterhil 6y agoAfter reading this reply twice, I realised you are right and UnitInterval type indicates an interval object instead of a single scalar number. I have actually used intervals, and should have realised this sooner. But I just had my first cup of coffee...
- dmurray 6y agoYes, UnitInterval is a really bad name for a single number. Astonishingly, it has 30 upvotes on SO.
- ajuc 6y agofunction FuncName(NormalizedFloat accuracy) In languages with operator overloading you can make NormalizedFloat a proper class with asserts in debug version and change it to an alias of float in release version. Similarly I wonder why gemoetry libraries don't define separate Point class and Vector class, they almost always use Vector class for vectors and points. I understand math checks out, and sometimes you want to add or multiply points, for example: Pmid = (P0 + P1) / 2 But you could cast in such instances: Pmid = (P0 + (Vector)P1)/ 2 And the distinction would surely catch some errors. Point - Point = Vector Point + Point = ERROR Vector +/- Vector = Vector Point +/- Vector = Point Point * scalar = ERROR Vector * scalar = Vector Point */x Point = ERROR Vector * Vector = scalar Vector x Vector = Vector
- cloogshicer 6y agoI think this is the best answer. This got me thinking: What about a situation where the accuracy is given in a real-life unit. For example, the accuracy of a GPS measurement, given in meters. I've sometimes used names like 'accuracyInMeters' to represent this, but it felt a bit cumbersome. Edit: Thinking more about it, I guess you could typealias Float to Meters, or something like that, but also feels weird to me.
- eru 6y agoSome languages provide more than just an alias. Eg Haskell lets you wrap your Float in a 'newtype' like 'GpsInMeters'. The newtype wrapper doesn't show up at runtime, only at compile time. It can be set up in such a way that the compiler complains about adding GpsInMeters to GpsInMiles naively.
- clusterfish 6y agoThat's what unboxed tagged types are for. Floats (e.g.) at runtime, but with compile time restrictions.
- sriku 6y agoI've used "fraction" for this purpose .. but that isn't general enough. In fact a convention I've used for nearly 2 decades has been varName_unit .. where the part after the underscore (with the preceding part being camel case) indicates the unit of the value. So (x_frac, y_frac) are normalized screen coordinates whereas (x_px, y_px) would be pixel unit coordinates. Others are like freq_hz, duration_secs and so on.
- andrewaylett 6y agoMore complex type systems absolutely support asserting the units of a value in the type system. For example, here's an implementation of SI types in C++: https://github.com/bernedom/SI https://github.com/bernedom/SI
- GuB-42 6y agoI usually do the "inMeters" thing. Another thing you can do is define a "METER" constant equal to 1. You can then call your function like this: func(1.5 * METER), and when you need a number of meters, you can do "accuracy / METER". The multiplication and division should be optimized away. Good thing about that is that you can specify the units you want, for example you can set FOOT to 0.3048 and do "5. * FOOT" and get back your result in centimeters by doing "accuracy / CENTIMETER". The last conversion is not free if the internal representation is in meter but at least, you can do it and it is readable. If you are going to use such distances a lot, at least in C++, you can get a bit of help from the type system. Define a "distance" class operator overloads, constants and convenience functions to enforce consistent units. Again, the optimizer should make it not more costly than using raw floats if that's what you decide to use as an internal representation.
- singularity2001 6y agoThat's a very good observation. We still could need a (new) term for this common type. Maybe floatbit, softbit, qubit(sic), pot, unitfloat, unit01 or just unitinterval as suggested? This begs an interesting tangential question: Which programming languages allow such resticted intervals as types? type percentage:=int[0,100] type hexdigit:=int[0,15] … since this might be overkill, sane programming languages might encourage assert statements inside the functions.
- m12k 6y agofloatbit is good starting idea, but maybe too long to be catchy. How about a flit?
- shawnz 6y agoBut what do you name the variable in the languages that don't support such a constrained type feature (the majority of them)?
- SideburnsOfDoom 6y agoObject-oriented languages have equivalent constructs, so I would say that this is doable in the vast majority of languages in common use: https://news.ycombinator.com/item?id=24374372 https://news.ycombinator.com/item?id=24374372 http://wiki.c2.com/?ValueObject http://wiki.c2.com/?ValueObject
- singularity2001 6y agoI'm envisioning a programming language in which variable names and type names can become one. So instead of func call(Person person){} you just have func call(person){} where person is a known type AND the variable name. In that scenario 'accuracy' would be a type with known value between 0 and 1.
- elcomet 6y agowhat if you have to deal with two persons?
- singularity2001 6y agoIn that case you could have the signature func call(person#1 person#2){}
- ajuc 6y agoWouldn't it be better if we could give meaningful names instead of 1 and 2? function call(person#sender person#receiver) And at that point we're back to the square one, just remove the # :)
- quickthrower2 6y agoCombine with the JS/TS syntax sugar for objects and {person} Is an object person with key person and value person of type Person
- hellofunk 6y agoWhile true, if your language doesn’t support such a type, then the burden for such a name goes to the parameter, does it not?
- metafunctor 6y agoUsually that would go to the documentation of the parameter, plus a run-time assertion to check that received values are valid.
- hellofunk 6y agoBut the best documentation is the code itself that is documentation. I mean, well that’s kind of a cliché, but names can carry a lot of meaning.
- afarrell 6y agoJoel, on the original purpose of Hungarian notation: https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/ https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...
- deleted 6y ago[deleted]
- FabHK 6y agoVery insightful article. I wasn't aware of "Apps Hungarian", which indeed seems like a much better idea of the redundant "System Hungarian".
- SideburnsOfDoom 6y ago> While true, if your language doesn’t support such a type You'd be surprised where the support is. In C#, you would declare a struct type with one read only field of type double, and range validation (x <= x <= 1) in the constructor. this is the "value object" pattern. http://wiki.c2.com/?ValueObject http://wiki.c2.com/?ValueObject Yes there's a bit of boilerplate - especially since you might want to override equality, cast operators etc. But there is support. And with a struct, not much overhead to it.
- codesections 6y agoUnfortunately, creating a constrained type like this isn't easy (or even doable) in all programming languages. Fortunately, my preferred programming language, Raku, makes creating this sort of subset trivially easy[0]: subset UnitInterval of Real where 0 ≤ * ≤ 1 [0]: https://docs.raku.org/language/typesystem#index-entry-subset-subset https://docs.raku.org/language/typesystem#index-entry-subset...
- johnsolo1701 6y agoIs there a difference between ≤ and <= in Raku? Curious why you used ≤ in your example.
- winthrowe 6y agoThey're equivalent, Raku defines both Ascii compatible and Unicode names for typical operators. I expect they used ≤ because it looks nicer.
- codesections 6y agoYep, correct on both counts
- tzs 6y agoIn C, I wonder if you could do something with functions and macros? Say you need to represent velocity in a transportation simulation. You could have a function, velocity, that looks like this: double velocity(double v, char * of_what) You use it to wrap constrained values. E.g., double v_jogger = velocity(8.0, "human"); double v_car = velocity(65.0, "city car"); velocity() simply returns the first argument, after doing validity checking based on the second argument. You probably couldn't reasonably use this everywhere that you would use actual constrained types in a language that has them, but you could probably catch a lot of errors just using them in initializers.
- saagarjha 6y agoThe problem you'd have is that doing any operations on such a value could take it outside the bounds of the "type".
- akaryocyte 6y agoStan, a probabilistic programming language where this thing comes up a lot, makes it easy to declare such constrained parameters: real<lower = 0, upper = 1> accuracy;
- deleted 6y ago[deleted]
- rocqua 6y agoGreat that you like typed languages, and ones that allow for such constrained/dependent typing as well. It seems disingenuous to me to suggest that anyone using other languages do not have this problem. And really, there are quite a few languages to not have this form of typing, and even some reasons for a language to not want this form of typing. So please, don't answer a question by saying "your questions is wrong" it is condescending and unhelpful.
- afarrell 6y ago"your question is wrong" is indeed unhelpful, especially as a direct response to someone asking a question. "here is what seems like a better question" is helpful, especially in a discussion forum separate from the original Q/A. But if "here is what seems like a better question" is the _only_ response or drowns out direct responses, then thats still frustrating. > condescending As a man who sometimes lacks knowledge about things, when I ask a question, please please please err on the side of condescending to me rather than staying silent. (No, I don't know how you should remember my preferences separately from the preferences of any other human)
- Sandman 6y agoI'm genuinely sorry if I came across as condescending, that was not my intention at all. I merely wanted to point out that, in my opinion, this property should be reflected in parameter type, rather than the name. Just like, if we wanted a parameter that should only be a whole number, we wouldn't declare it as a float and name it "MyVariableInteger" and hope that the callers would only send integers. You mentioned that there are quite a few languages that do not permit what I proposed, would you mind specifying which ones exactly? The only one that comes to my mind is assembly?
- FabHK 6y agoSo, then the user calling the library with foo(3.5) will get a runtime error (or, ok, maybe even a compile time error). To avoid that, you need to document that the value should be between 0 and 1, and you could do that with a comment line (which the OP wanted to avoid), or by naming the variable or type appropriately: And that takes us back to the original question. (Whether the concept is expressed in the parameter name or parameter type (and its name) is secondary.)
- coldtea 6y ago>However, I believe most of the more popular languages support creation of custom data types? No, most don't, except if you go into building custom classes.
- dragonwriter 6y agoSo, most don't support custom types unless you...use the mechanism they have for defining a custom type? That seems a very elaborate way to say “No" when the answer is really “Yes”.
- coldtea 6y agoIt's a succint way to say "No, not types that will automatically work as primitive types (which normally the variable passed for 0 to 1 would be), and that will work with numeric operators". Or in other words, a succint way to say "Technically yes, but practically useless, so no".
- rco8786 6y agoIs there an example, in any language, showing how you would represent this at the type level? I can’t see how you would do it.
- lexicality 6y agoTypescript: type NormalisedFloat = number Admittedly it doesn't add any actual value checking, but it does convey the information when you look at the parameter definition.
- savanaly 6y agoIn Elm (and many other languages, I assume, I'm just most familiar with Elm) there's a pattern called "opaque data type". [0] You make a file that contains the type and its constructor but you don't export the constructor. You only export the getter and setter methods. This ensures that if you properly police the methods of that one short file, everywhere else in your program that the type is used is guaranteed by the type system to have a number between zero and one. -- BetweenZeroAndOne.elm module BetweenZeroAndOne exposing (get, set) type BetweenZeroAndOne = BetweenZeroAndOne Float set : Float -> BetweenZeroAndOne set value = BetweenZeroAndOne (Basics.clamp 0.0 1.0 value) get : BetweenZeroAndOne -> Float get (BetweenZeroAndOne value) = value [0] https://en.wikipedia.org/wiki/Opaque_data_type#:~:text=In%20computer%20science%2C%20an%20opaque,access%20to%20the%20missing%20information https://en.wikipedia.org/wiki/Opaque_data_type#:~:text=In%20....
- hombre_fatal 6y agoYou would just make the constructor return a possible error if it's not in range, or maybe some specialty constructors that may clamp it into range for you so they always succeed. It's the same question of, how can you convert a string to a Regexp type if not all strings are valid Regexps?
- rco8786 6y agoRight, so there's no way to do this: > In other words, the parameter should not be a float, but a more constrained type that allows floats only in [0,1] It's a value check, not a type check.
- pbhjpbhj 6y agoI agree that it's a question of type: what would you call that type though? I propose "pun" - proportion of unity, or "p(er) un".
- quickthrower2 6y agoBetween0And1Inclusive I like verbosity! Or use a dependent type language. Maybe Idris? Then something like Between(0,1) I guess.
- hombre_fatal 6y agoNothing wrong with the name ZeroToOneInclusive. Seems like a great type to have around, and a great name for it. UnitFloat or UnitIntervalFloat or other ideas ITT are cuter but not much clearer.
- jberryman 6y agoI think this is right, but it's still IMO basically a natural language semantics issue. For instance in haskell (which has a pretty advanced static type system), I would still probably be satisfied with: -- A float between 0 and 1, inclusive. type UnitInterval = Float foo :: UnitInterval -> SomeResultPresumably foo accuracy = ... i.e. I think the essential problem in the SO question is solved, even though we have no additional type safety. A language without type synonyms could do just as well with CPP defines
- theptip 6y agoLooks like it’s actually possible to string something like this together in Python; custom types are of course supported, and you can write a generic validation function that looks for your function’s type signature and then asserts that every UnitInterval variable is within the specified bounds. You’d have to decorate/call manually in your functions so it’s not watertight, but at least it’s DRY.
- LudwigNagasena 6y agoI would simply put this in the description of the parameter. That’s what it is for; after all, not every constraint is computable or easy to check.
- jameshart 6y agoI don’t understand why having the ability to describe such a type removes the need to be able to name it.
- alecbz 6y agoEven if you could created constrained types like this, don't you still need to worry about what to call it?
- Bekwnn 6y agoI work in games where these values are extremely common and 'accuracy' wouldn't be very descriptive in a lot of circumstances: explosion radius falloff damage, water flow strength, positional/rotational lerps or easing, and more. I wish I were commenting here with an answer, but I don't have one. "brightness01" is a common naming convention for values of this type in computer graphics programming, but niche enough that it got raised in review comments by another gameplay programmer.