8

Often when I'm writing a set of utility functions, I find myself wanting a function that applies some logic to multiple items, as well as a function that does the same with just a single item. There are a lot of potential solutions to this, but I always find myself flipping back and forth.

  • I could write an exclusively singular version of the function (modify_item(item)) and use map, comprehension, or a foreach externally. I don't want to do this every danged time I call it with multiple items though.
  • I could write an exclusively explicitly plural version of the function (modify_items(items)) that does the iteration inside. But I don't want to call it with a list every time either. Better than always singular, but still awkward to call. This would also support bulk operations better.
  • I could write an agnostic function that checks the input's type (modify_item(item)). If it's not iterable, it'll wrap it in a list and then iterate. This seems to be the best option, but the lure of star operators always gets me...
  • I could write an agnostic function that takes a variable number of inputs (modify_item(*items)) and iterates over them. This gives me a good calling syntax and automatically packs the items into an iterable for me. The problem I always run into here is that adding subsequent arguments or keyword arguments is awkward.
  • Finally, I could just throw up my hands and write a plural function as above, and a singular one that would wrap the parameter in a list and pass it to the plural one. Then I'd have to write double the functions, which is silly.

It seems like javascript libraries usually do the type checking option (#3), and that's the one I like best. In that case, you have the question of naming conventions. I think I favor singular, but I'm not sure about that.

Examples are in python, but this question could be applied to most languages.

1

2 Answers 2

7

In these instances, I usually make two versions of the function, with the multiple version simply calling the singular version, something like this:

class Foo:
  def transform_entity(bar):
    return do_things(bar)

  def transform_entities(bars):
    return [transform_entity(b) for b in bars]

It's pretty self-explanatory, avoids any explicit wrapping, and allows you to use arguments properly without manual wrapping (unlike trying to do something terrible with varargs).

2

A friend of mine convinced me of option number three, with the addition that he uses a helper function called ensure_plural to ensure that the input is plural before continuing. This keeps it nice and declarative. The helper function could take a few different forms:

  • As a decorator, it would just modify the inputs before even getting to the main function. The problem is that it would have to assume some stuff.
  • It could just be called on the value that needs to be plural when necessary.
  • I've also come up with a version called if_plural, which would take a value and a function and return the result of applying the function directly to the value if singular, or of mapping the function over the value if plural.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.