15

I just found this function in the project I'm working at:

  -- Just returns the text unchanged.
  -- Note: <text> may be nil, function must return nil in that case!
  function Widget:wtr(text)
      return text
  end

Too sad, the coder does not work in the company anymore. Why would one make a function that does nothing, but returns the parameter it's called with?

Is there any use to such a function, not specified to this example, but overall in any case?

Due to

function aFunction(parameter)
    return parameter
end

Ends in

aFunction(parameter) == parameter

Why would I write something like

aFunction(parameter) == whatIWantToCheck

instead of

parameter == whatIWantToCheck

?

  • possible duplicate of Coding style for chained function calls – gnat Sep 12 '14 at 9:22
  • 13
    @gnat How on Earth is that a duplicate? – Kilian Foth Sep 12 '14 at 9:23
  • 13
    Huh? This function returns its parameter - chaining involves returning this. – Kilian Foth Sep 12 '14 at 9:28
  • 11
    @gnat The question is why someone would ever write a function that does nothing except return itself. Yes you can return certain objects or values to allow method chaining, but that's not his question. His question is why someone would ever write something like int getParam(int param) { //DO NOTHING return param; } From a method chaining perspective it's a completely redundant and unnecessary call as you can leave the OP's function out of a method chain and it would not make a single difference. – ZeroStatic Sep 12 '14 at 12:41
  • 4
    This is probably offtopic and doesn't apply to lua, but there is a valid use-case for this in PHP - in older versions, new Foo()->method(); was not valid syntax, and constructs like function with($what) { return $what; }; with(new Foo())->method(); were used as the workaround. – DCoder Sep 12 '14 at 14:27
57

Your question is sort of like asking what's the good of the number zero if whenever you add it to something you get the same value back. An identity function is like the zero for functions. Kind of useless by itself, but occasionally useful as part of an expression using higher-order functions, where you can take a function as a parameter or return it as a result. That's why most functional programming languages have an id or identity in their standard library.

Put another way, it makes a handy default function. Just like you might want to set offset = 0 as a default integer, even though that makes an offset do nothing, it might come in handy to be able to set filterFunction = identity as a default function, even though that makes the filter do nothing.

  • Shouldn't a filter function return a boolean value? In this case the "zero" filter function would be the one that returns true. – Kirill Rakhman Sep 12 '14 at 22:11
  • 1
    @cypressious A map function, then. – sapi Sep 12 '14 at 23:10
  • 6
    Or to stick it under a design concept: Null object pattern, functions edition – blgt Sep 12 '14 at 23:24
  • @cypressious, that would be for a predicate that gets passed as an argument into a filter higher-order function. A first-order filter function has the type [a] -> [a], – Karl Bielefeldt Sep 13 '14 at 1:31
  • For example in C# I often use .OrderBy(x => x) – CodesInChaos Sep 13 '14 at 12:55
27

Sure. Imagine an external API that allows you to retrieve things from somewhere that you absolutely need, but you have to specify filter criteria and output formatters for every query, even if you want all the results and want to get them exactly as stored.

Then you'd have to invent a trivial "accept everything" and a trivial "return unchanged" function to get at the data. wtr is precisely such a trivial pseudo-formatter. If you use that API a lot, it can be very useful to have this pseudo-helper function lying around rather than have to create an anonymous function whenever you query something. (You might consider calling it identity rather than wtr so that it's immediately clear it does nothing.)

  • I did not really understand the sense yet, but thats exactly the scenario. I might understand after a while, working on this project while keeping your answer in mind, I think. atm it looks useless to me,... if I got the rawdata, why would I want a function to give me the rawdata again,... – Sempie Sep 12 '14 at 9:42
  • 3
    @Sempie Again, if the API requires a formatting function, the only way to get the unaltered text is if the function does nothing to the text. – Doval Sep 12 '14 at 12:22
  • 3
    In other words: If you have a function that requires filter/format arguments to be passed, and you absolutely cannot use null as the argument, you use an empty filter function that filters with 'nothing' to make the program stop complaining. – ZeroStatic Sep 12 '14 at 12:46
  • 3
    @Sempie You've worked with SQL, right? You know how you get to either include or not include a WHERE clause? That's loosely a matter of syntactic sugar. Essentially the absence of a WHERE clause is exactly the same as if you had a WHERE clause that just goes ahead and allows everything. The fact that the designers of SQL let you not specify a WHERE clause, instead of forcing you put one down, even when it accepts everything, is more-or-less syntactic sugar, and they've just provided you that option for simple convenience... – Panzercrisis Sep 12 '14 at 12:55
  • 5
    It may be worth noting that in many cases it's faster and cleaner to have code unconditionally call a virtual method or delegate which might or might not do something useful, than to have code determine whether the call is needed and skip it if not. – supercat Sep 12 '14 at 18:29
15

Isn't that just a polymorphysm?

From my experience with Qt tr() and wtr() methods are supposed to be used (there, in Qt) in localization of Widget's text.

So, by returning unchanged text this method just says: Widget does no localization (translation of the text) by default. Override this function to enable your own logic.

  • 1
    didn't realize this was a QT thing - this is obviously the answer. – Corley Brigman Sep 15 '14 at 14:34
8

A very common case for this is 'later added functionality'. So the programmer thought that there could be some change to that function later. Since you access it as a function and not as the parameter itself, you can easily globally change this. Lets say you have an index with:

function getIndex(index)
    return index
end

and since your index starts at 0 this is all fine. You later change a component somewhere else, this component needs you to translate your index to start at 1. You would have to add hundreds of index+1 everywhere in your code. But with a method like this, simply say:

 function getIndex(index)
    return index+1
end

and you are fine. Functions like this can quickly lead to over-engineering but at some points they make a lot of sense!

  • 2
    Yes, though it's worth noting that the doctstring of the function posted by the OP does not suggest that this is the purpose of the function in his case. – Mark Amery Sep 13 '14 at 8:53
6

Stub functions like this are common in type-inheritance situations. The base class might do nothing useful, but derived classes might do various things with the inputs. Declaring the stub function in the base class allows all derived classes to have a function of that name, and individual derived classes to override it with something more elaborate and useful.

5

One additional scenario is similar to the use in python and C# of properties, but in languages that don't have the feature.

In general, you can declare something as just a member of the class; let's say, 'name' as a string. This means that you access it like this:

someobject.name

Later, you decide that the name really needs to be dependent on what's in the object. So it should really be a function. Oops! Even with no arguments, that means all code that accesses it now has to be changed to

someobject.name()

But if you have a lot of instances of this call, the chances of nothing going wrong with that is pretty low - somewhere this change won't be made, the program will crash when you get to that point, etc.

Properties in C#/Python allow you to substitute a function in for what used to be an attribute, while still allowing it to be accessed like an attribute i.e. with no change. You don't even have to have planned ahead.

If your language doesn't have that, you have to plan ahead, but you can still sort of support it the way people did before by making it a function from the beginning that doesn't do anything. In the beginning, it won't do anything interesting, and look like it should be removed, and many functions of this type are never changed. But later, if you realize that really whenever you call Widget.wtr you need to strip some special characters out, it's no big deal - it's already a function, you just add that in and you're done.

TL;DR This could just be a wise programmer planning ahead for future changes.

  • 3
    That would make sense if this method depended on anything else, but it doesn't. It's not a property, getter/setter or a field. It's a method that doesn't currently do anything. Only way he's planning for future changes is if the logic of this method is going to have to change. – Matthew Steeples Sep 12 '14 at 18:24
  • 1
    It doesn't have to... it means that right now, i don't process this data, but later on, if I want to process it, every user of that data gets the processed data for free. Stupid example: Let's say you print strings to the screen, and you usually do print data. Then later, you realize all the strings have to be upper case - you'd have to go find every print in your program and change to print data.upper(). But if you have def cdata(data): return data and everywhere says print cdata(data), then you just change to def cdata(data): return data.upper() and it's the only change. – Corley Brigman Sep 15 '14 at 13:41
  • I see what you mean there. That makes more sense – Matthew Steeples Sep 15 '14 at 14:03
2

It's not useless, actually it can be extremely useful, because it makes your code more uniform and flexible.

Say, for example, that you have a listing of people and a dropdown for the user to select if we wants to see "all" or just those that are "male" or "female".

You can either handle "all" as a special case, in which case you'll need an extra if and to check for this case explicitly, or you can have a filter function that just returns its parameter (e.g allows everything to pass), assigned to be used for the "all" case.

  • 4
    That does not fit the scenario. I meant a function that returns his parameters and, in no case, don't do anything else. – Sempie Sep 12 '14 at 13:43
  • @Sempie: That's what he's saying. If you have a Filter class or interface with MaleFilter and FemaleFilter subclasses, and your code requires some filter, a filter which does nothing (returns its parameter unchanged) is how you handle All. The function never does anything, but can be substituted for one which does. – Magus Sep 12 '14 at 21:57
  • @Magus, but in your scenario the function is some kind of placeholder wich either, will be replaced later, or just exists because the old function got obsolete but the programm needs this passthrough. Anyway, it's not an handover. The function doesn't give the unchanged parameter to another function, as a filter would might do, but returns it to the calling function. – Sempie Oct 1 '14 at 11:26
  • @Sempie No, it's neither a placeholer not it's use as a temporary passthrough. It's a useful coding (and mathematical) notion, the "identity" function. And, yes, it is still a handover, whether it returns it to "another function" or to the calling function.The key is that the "identity" function can be one of many possible functions called by the calling function, and is used to avoids if and special-casing when the called function doesn't need to do anything. – Hejazzman Feb 10 '17 at 19:22

protected by gnat Sep 19 '14 at 14:35

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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