DEV Community

Discussion on: No love for boolean parameters

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

I find that quite often flags are added to toggle code at the end or at the beginning of a subroutine. For a simple example:

function equal_strings(a, b, ignore_case)
   if ignore_case then
      a, b, = a:lower(), b:lower()
   end
   return a == b
end
Enter fullscreen mode Exit fullscreen mode

In these cases, the refactoring is quite easy: extract the common functionality into another subroutine:

function equal_strings(a, b)
   return a == b
end
function equal_strings_ignore(a, b)
   a, b, = a:lower(), b:lower()
   return equal_strings(a, b) -- EDIT: Forgot to change this line after copy-paste 😜
end
Enter fullscreen mode Exit fullscreen mode

When the code being toggled happens in the middle of the subroutine, it's often the kind of situation where passing a function as an argument is a better option:

function equal_strings(a, b, normalize)
   if normalize then
      a, b = normalize(a), normalize(b)
   end
   return a == b
end

equal_strings("foo", "Foo", string.lower)
Enter fullscreen mode Exit fullscreen mode

Cases where neither of those apply, are often a sign of over-complicated program logic, or code that shouldn't be shared at all.


Note: examples in Lua because that's what I find easy to write.

Collapse
 
patricktingen profile image
Patrick Tingen • Edited

But now you have the logic in two places, shouldn't you call one function from the other to avoid that?


function equal_strings(a, b)
   return a == b
end
function equal_strings_ignore(a, b)
   a, b, = a:lower(), b:lower()
   return equal_strings(a, b)
end
Enter fullscreen mode Exit fullscreen mode
Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Indeed, that was what I intended to do, but apparently I forgot to actually change that line after copy-pasting it. You're totally right in that this only makes sense when you actually use the subroutine with the extracted logic :D

Collapse
 
tkdodo profile image
Dominik D • Edited

yes, passing the function is what is described in the inversion of control article I linked to. Definitely worth a read, a very nice concept.

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

Calling it "inversion of control" almost seems a bit weird to me because it implies that it is the "inverted" form of how it should normally be. But the example of a select (or filter or whatever one wants to call it) function makes it very obvious how it's really just another way to write a loop. It's not "inverted"; it's just normal control-flow.