8

I started learning Python and I am wondering why empty function are needed in a programming language.

e.g. in python:

def empty_func():
    pass

Even in shell scripts empty functions are available.

My Understandings and question:

  1. Why do programming languages need empty functions? Is it for just playing around with programming language or nothing else that really matters?

  2. If this has a purpose, can anyone describe the use case or give a real example of the usage of empty functions?

  3. Or is there any tradition of programming languages allowing empty functions?

EDIT (Things I got from reading your answers):

  • For Sketching Algorithms or with Abstract Functions
  • For Submitting forms with no action needs to be performed
  • Placeholder for some mandatory operations
1
  • 1
    they can be used as STUBS if the program execution expects to find/use them, however you don't want to change anything through them. Commented Jan 14, 2015 at 10:30

4 Answers 4

4

In shell languages of the Bourne family, the : command, which does nothing at all, is typically used in two situations:

  • Placeholder for when something expects a mandatory command, e.g.

    while some_condtion
    do :
    done
    

    since do requires at least one command.

  • Discarding the arguments, but performing side effects inside the argument list, e.g.

    : ${myvar=foo}
    

I'm sure there are probably other applications that shell experts would know :)

In Python (and other languages) it's used less frequently. It can act as an argument to a higher-order function when you don't actually want to do anything. For example, say you have a function that submits a form and allows an function to be called asynchronously after submission is complete:

def submit(callback=empty_func):
    ...

This way, if the callback is not provided, the submission will still go through but no further actions will be performed. If you had used None as the default value, you'd have to explicitly check whether the callback was None, adding clutter to the code.

0

Rufflewind did a good job covering when you might use an empty function in a completed program. In my experience, it tends to be used more often in unfinished programs, so you can plan out what you're going to write and have it still compile until you get around to actually implementing it. In other words, it's usually just a placeholder.

It's necessary in python's case because it uses indentation to mark blocks, unlike C-like languages who use braces {}. This means if you didn't have pass, the parser couldn't tell if you meant to leave it empty or if you forgot. Including pass makes the parser much simpler, and gives you a convenient word to search for when you're looking for unimplemented blocks.

2
  • 1
    For unfinished code, throwing NotImplementedError is a more adequate solution since "Errors should never pass silently" and calling an unimplemented function in a live program is an error. Commented Jan 13, 2015 at 14:47
  • That depends. For code you ship, yes. But if it is code you expect to implement in an hour and you are just leaving it unimplemented while you work on the unit tests, simply leaving no implementation may be a better option. Often my workflow is 1) write stub method with pass 2) write unit test that tests return value 3) verify test fails (as method returns undefined) 4) implement method 5) verify test now passes
    – user53141
    Commented Jan 14, 2015 at 0:10
0

It depends on where you stand in the development cycle, but sometimes when sketching out an algorithm, you want to make abstraction about complex blocks without implementing them right away.

def full_algo():
  init_stuff()
  process_stuff()
  ...

You know how init_stuff will work, it's rather simple in your head but you don't really need it right away, so you declare it as an empty function. It will allow your code to compile and run without bothering about the gory details.

Another use for released applications is when using inheritance. Suppose that you have a large class that defines the behavior of platform specific code. You might end up with a logic similar to this :

init_filesystem();
access_files();
release_filesystem();

This code will work on many platforms, but some platforms might not need filesystem initialization. Then your inheritance will look like this (virtual with = 0 in C++ just means that derived classes MUST implement those methods) :

class FileSystem{
  virtual void init_filesystem() = 0;
  virtual void access_files() = 0;
  virtual void release_filesystem() = 0;
};

Then a particular implementation of this class (interface) might do nothing for some of those methods. Alternatively, the base class could declare empty methods for init/release instead of declaring them virtual.

Finally (and shamefully), sometimes you maintain a very old application. You fear that deleting methods will break things. This happens when you have complex inheritance that is not properly understood or when you have a lot of function pointers (callbacks). You just delete code inside of them so they get called anyway without breaking anything.

0

While it isn't something you'd expect to do in Python, there are times in the world of device drivers where you need to supply an empty function, to handle an event that you either (a) know won't happen or (b) don't care about even if it does.

You also see this in C with callbacks. Occasionally, you will see code that just ASSUMES you supplied a callback, and tries to call it, ignoring the risk of a null pointer. All you can do in that case is supply an empty callback routine. (Yes, I have a particular vendor in mind.)

2
  • I used pass a lot as a placeholder when writing code, particularly in classes, when I want something runnable before everything is complete. It is really python's equivalent of {}, which python can't do as it doesn't use braces. In that sense, all languages that I am aware of allow this, it is just that only a couple like python require a keyword. Even back in the assembly days we had NOP.
    – user53141
    Commented Jan 13, 2015 at 23:55
  • @StevenBurnap, usually when I do something like that, I include the local equivalent of printf(">>> routine XXX called\n"); Commented Jan 14, 2015 at 4:19

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.