12 Replies - 3596 Views - Last Post: 14 January 2012 - 05:06 PM Rate Topic: -----

#1 witchbanger  Icon User is offline

  • New D.I.C Head

Reputation: -45
  • View blog
  • Posts: 36
  • Joined: 04-December 11

Nesting functions- Why?

Posted 13 January 2012 - 10:44 PM

I received an email from a friend taking programming in school. He was telling me about what they were learning. He spoke of nesting functions. I asked him to be more clear as I haven't come across that, and said "Writing functions inside of functions".

void function1(){
... do stuff
void function2(){
... do more stuff
};
}



I am at a loss to see any advantage to this what so ever. Wouldn't this be impractical? I Googled it, and all I can find is you can declare, but not define a function in a function. Can anyone tell me WHY someone would need to do this?

This post has been edited by macosxnerd101: 13 January 2012 - 10:47 PM
Reason for edit:: Renamed title to be more descriptive


Is This A Good Question/Topic? 0
  • +

Replies To: Nesting functions- Why?

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2134
  • View blog
  • Posts: 3,271
  • Joined: 21-June 11

Re: Nesting functions- Why?

Posted 13 January 2012 - 11:24 PM

Are you asking why someone would want/need to declare a function within a function or why someone would want/need to define it (which as you said is not possible in C or C++, though it is possible in other languages (and some C compilers allow it as an extension))?

For the latter: Defining a function inside another function can be useful if you need to define a helper function which you only call from one function because it keeps the namespace clean (i.e. the function won't take up a global name because it's only accessible within the one function).

Also in most languages that have nested functions, they are closures, so they provide a more readable alternative to using anonymous functions (of course C and C++ (pre-2011) don't have anonymous functions, but they don't have nested functions either, so giving a C or C++ specific answer is kind of impossible).

This post has been edited by sepp2k: 13 January 2012 - 11:29 PM

Was This Post Helpful? 0
  • +
  • -

#3 witchbanger  Icon User is offline

  • New D.I.C Head

Reputation: -45
  • View blog
  • Posts: 36
  • Joined: 04-December 11

Re: Nesting functions- Why?

Posted 13 January 2012 - 11:33 PM

Okay. So, then much like a local variable, you are creating a local function which disappears when the parent function has ended.
This is done to keep namespace cleaner. With a lot of functions using pointers, and parameters, it sounds like that could get quite dangerous and confusing.

This post has been edited by witchbanger: 13 January 2012 - 11:44 PM

Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2134
  • View blog
  • Posts: 3,271
  • Joined: 21-June 11

Re: Nesting functions- Why?

Posted 13 January 2012 - 11:40 PM

If there was something unclear in my answer, I'd be happy to clarify. Just tell me which part isn't clear to you.
Was This Post Helpful? 0
  • +
  • -

#5 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Nesting functions- Why?

Posted 14 January 2012 - 12:26 AM

@sepp2k: can you think of any practical reason why ISO C allows declaring, but not defining, a function inside another function?

By the way, defining a function within a function is allowed by GCC as a compiler-specific extension. This program is legal in GCC:
#include <stdio.h>

int main()
{
    int mul( int x, int y ) {
        return x * y;
    }
    printf("%d\n", mul(4,5));
    return 0;
}



Was This Post Helpful? 0
  • +
  • -

#6 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2134
  • View blog
  • Posts: 3,271
  • Joined: 21-June 11

Re: Nesting functions- Why?

Posted 14 January 2012 - 12:36 AM

View Postr.stiltskin, on 14 January 2012 - 08:26 AM, said:

@sepp2k: can you think of any practical reason why ISO C allows declaring, but not defining, a function inside another function?


No, I really can't if I'm honest. Possibly you might want to access the same function using different signatures from different functions. But I can't really think of any scenario where you'd want to do that.
Was This Post Helpful? 0
  • +
  • -

#7 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 449
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: Nesting functions- Why?

Posted 14 January 2012 - 07:07 AM

Also c++11 sort of has it in the form of lambda functions. To keep with r.stiltskin's example:

#include <stdio.h>

int main()
{
    auto mul = [] ( int x, int y ) {
        return x * y;
    };
    printf("%d\n", mul(4,5));
    return 0;
}



In fact gcc seems to implement this much like nested functions as it will refer to this function as main()::mul.

Anyway, apart from keeping the namespace clean, it's also a nice way to keep the logic together.

This post has been edited by Karel-Lodewijk: 14 January 2012 - 02:12 PM

Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Nesting functions- Why?

Posted 14 January 2012 - 12:25 PM

Code is about organization.

Consider the following code:
void swap(int *a, int *b ) {
	int temp = *a;
	*a = *b;
	*b = temp;
}

int partition(int a[], int first, int last) {
	int i, index, piv;
	
	i = index = first;
	piv = a[index];
	swap(&a[index], &a[last]);
	for (; i<last; i++) {
		if (a[i]<piv) { swap(&a[index++], &a[i]);  }
	}
	swap(&a[index], &a[last]);
	return index;
}

 
void quickSort(int a[], int first, int last) {
	if(first < last) {
		int pivIndex = partition(a, first, last);
		quickSort(a,first,(pivIndex-1));
		quickSort(a,(pivIndex+1),last);
	}
}
 
void callQuickSort(int *list, int size) { 
	quickSort(list,0, size-1);
}



Note the need for either a callQuickSort or fundamental knowledge of how quickSort must be called. We break down a couple of steps for clarity, but it's really only quickSort that needs them.

Now, a nested version:
void sort(int *a, int size) {
	void quickSort(int first, int last) {
		void swap(int p1, int p2) {
			int temp = a[p1];
			a[p1] = a[p2];
			a[p2] = temp;
		}

		int partition() {
			int i, index, piv;
			
			i = index = first;
			piv = a[index];
			swap(index, last);
			for (; i<last; i++) {
				if (a[i]<piv) { swap(index++, i);  }
			}
			swap(index, last);
			return index;
		}
		
		
		if(first < last) {
			int pivIndex = partition();
			quickSort(first,(pivIndex-1));
			quickSort((pivIndex+1),last);
		}
	}
	quickSort(0, size-1);
} 



Look at all the clever tricks we can do with shared scope. Less parameter passing. Clarity of what belongs to what. Actual private code in C...

This may no be your cup of tea. In C++ it's silly, because you have all that wonderful namespace and class object stuff. But in C, this kind of program might have a certain appeal, depending on what you're doing.
Was This Post Helpful? 0
  • +
  • -

#9 witchbanger  Icon User is offline

  • New D.I.C Head

Reputation: -45
  • View blog
  • Posts: 36
  • Joined: 04-December 11

Re: Nesting functions- Why?

Posted 14 January 2012 - 01:36 PM

View Postbaavgai, on 14 January 2012 - 07:25 PM, said:

Code is about organization. ... In C++ it's silly, because you have all that wonderful namespace and class object stuff.


Thank you all for clearing it up for me. I see exploring this would be a waste of time. :tup:
Was This Post Helpful? 0
  • +
  • -

#10 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Nesting functions- Why?

Posted 14 January 2012 - 02:01 PM

@Baavgai: I guess this is a consequence of my lack of IT industry experience, but I still don't see the point. Suppose we take your first example, rename callQuickSort to sort, save it all in sorting.c, and declare sort in sorting.h. And suppose we take your second example, save it in sorting.c, and declare sort in sorting.h. Granted, inside the file sorting.c there's a difference in that quicksort and swap are hidden from any other function outside of sort. But viewed from the rest of the project, all we have is sort.

So from a practical point of view, say, from any project point of view, what's the difference? Obviously ISO doesn't consider it particularly important. Can you think of a "real" instance where it would matter to you?

edit: ah, I realize that in the first version, swap and quicksort could be called from elsewhere in the project, so is that what you had in mind? Some rebel coder on the project using "unauthorized" functions?

This post has been edited by r.stiltskin: 14 January 2012 - 02:38 PM

Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Nesting functions- Why?

Posted 14 January 2012 - 03:06 PM

@r.stiltskin: You're right. In plain old C, code organization is mostly achieved through files and headers. Only put the stuff in the header you want to share and be sure to make the functions in the file static that aren't being shared and you're basically doing code isolation C style.

Do you need a nested function? Not really. Though I guess you'd have an easier time doing some un C like things like closures...

Do you actually need enum? It's kind of sloppy in C, anyway. Or const? Really? There is no sane reason for switch ( I hate them ), but some people find every excuse to use them.

If I was coming to C right off, say, a lot of Javascript or something seriously functional, I might be into nested functions. I might find I just like them and go from there. No reason, just inclination.

A nested function is just an option, and a style, and that's about it. It's compiler specific, so I generally wouldn't recommend it. I've always suspected some gcc guy had a thing for them.

Just for fun, here's a little bubble that supports both directions, using nested functions:
void sort(int *a, int size, int asc) {
	void swap(int p1, int p2) { int temp = a[p1]; a[p1] = a[p2]; a[p2] = temp; }
	int cmpAscending(int p1, int p2) { return a[p1] - a[p2]; }
	int cmpDescending(int p1, int p2) { return a[p2] - a[p1]; }
	
	int (*cmp)(int,int) = asc ? cmpAscending : cmpDescending;
	int flag = 1;
	while(flag) {
		int i;
		flag = 0;
		for(i=0; i<size-1; i++) {
			if(cmp(i, i+1)>0) { swap(i, i+1); flag=1; }
		}
	}
} 



Sure, you don't need it. But some programmer might like it.
Was This Post Helpful? 2
  • +
  • -

#12 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Nesting functions- Why?

Posted 14 January 2012 - 03:13 PM

You're surely the only certifiable bubble-sort-fetishist I've ever encountered. :P
Was This Post Helpful? 0
  • +
  • -

#13 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 449
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: Nesting functions- Why?

Posted 14 January 2012 - 05:06 PM

Also baavgai's example also demonstrates the poluting namespace problem very well. Suppose I was to copy paste his code into a c++ context import the right headers and put a using namespace std; in there. Then I have the possibilty of people confusing sort/std::sort, partition/std::partition, swap/std::swap. For the last one the function signature would even fit std::swap allthough not as much as to cause ambiguity.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1