5 ms·
But this isn't really a boolean problem - even in your example there is another mistery argument: nil And you can get the same problem with any argument type.
by account42 1y ago
But this isn't really a boolean problem - even in your example there is another mistery argument: nil
And you can get the same problem with any argument type. What do the arguments in
copy(obectA, objectB, "")
mean?
In general, you're going to need some kind of way to communicate the purpose - named parameters, IDE autocomplete, whatever - and once you have that then booleans are not worse than any other type.
- 8-prime 1y agoTrue, but I think its worth noting that inferring what a parameter could be is much easier if its something other than a boolean. You could of course store the boolean in a variable and have the variable name speak for its meaning but at that point might as well just use an enum and do it proper. For things like strings you either have a variable name - ideally a well describing one - or a string literal which still contains much more information than simply a true or false.
- nomel 1y agoIf you language doesn't support named arguments, you can always name the value, with the usual mechanism: debug_mode=True some_func(..., debug_mode)
- OskarS 1y agoYou're correct in principle, but I'm saying that "in practice", boolean arguments are usually feature flag that changes the behavior of the function in some way instead of being some pure value. And that can be really problematic, not least for testing where you now aren't testing a single function, you're testing a combinatorial explosions worth of functions with different feature flags. Basically, if you have a function takes a boolean in your API, just have two functions instead with descriptive names.
- hamburglar 1y ago> Basically, if you have a function takes a boolean in your API, just have two functions instead with descriptive names. Yeah right like I’m going to expand this function that takes 10 booleans into 1024 functions. I’m sticking with it. /s
- OrderlyTiamat 1y agoIf your function has a McCabe complexity higher than 1024, then boolean arguments are the least of your problems...
- crazygringo 1y agoNot really. Tons of well-written functions have many more potential code paths than that. And they're easy to reason about because the parameters don't interact much. Just think of plotting libraries with a ton of optional parameters for showing/hiding axes, ticks, labels, gridlines, legend, etc.
- atoav 1y agoYes but this is about the difference between: engage_turbo_encabulator(True, False, True, False, True, False, True, False) and: engage_turbo_encabulator( enable_hydrocoptic=True, allow_girdlespring=False, activate_marzelvanes=True, sync_trunnions=False, stabilize_panametric=True, lock_detractors=False, invert_logarithms=True, suppress_lunar_wane=False ) The latter is how you should use such a function if you can't change it (and if your language allows it). If this was my function I would probably make the parameters atrributes of an TurboEncabulator class and add some setter methods that can be chained, e.g. Rust-style: encabulator = ( TurboEncabulator.new() .enable_hydrocoptic(True) .allow_girdlespring(False) .enable_marzelvane_activation(True) .enable _trunnion_syncing(False) .enable_param_stabilization(True) .enable_detractor_locking(False) .enable_logarithm_inversion(True) .enable_lunar_wane_supression(False) .build() )
- crazygringo 1y ago
- atoav 1y agoWell, that just means the function might be named wrong? copy_from_to_by_key(objectA, objectB, "name") Or, much better, you use named parameters, if your language supports it: copy_value( source=objectA, target=objectB, key="name" ) Or you could make it part of object by declaring a method that could be used like this: objectB.set_value_from(objectA, key="name")