Why Can't I Define a Function Inside Another Function

Why can't I define a function inside another function?

It is not obvious why one is not allowed; nested functions were proposed a long time ago in N0295 which says:

We discuss the introduction of nested functions into C++. Nested
functions are well understood and their introduction requires little
effort from either compiler vendors, programmers, or the committee.
Nested functions offer significant advantages, [...]

Obviously this proposal was rejected, but since we don't have meeting minutes available online for 1993 we don't have a possible source for the rationale for this rejection.

In fact this proposal is noted in Lambda expressions and closures for C
++
as a possible alternative:

One article [Bre88] and proposal N0295 to the C
++ committee [SH93] suggest adding nested functions to C
++ . Nested functions are similar to lambda expressions, but are defined as statements within a function body, and the resulting
closure cannot be used unless that function is active. These proposals
also do not include adding a new type for each lambda expression, but
instead implementing them more like normal functions, including
allowing a special kind of function pointer to refer to them. Both of
these proposals predate the addition of templates to C
++ , and so do not mention the use of nested functions in combination with generic algorithms. Also, these proposals have no way to copy
local variables into a closure, and so the nested functions they
produce are completely unusable outside their enclosing function

Considering we do now have lambdas we are unlikely to see nested functions since, as the paper outlines, they are alternatives for the same problem and nested functions have several limitations relative to lambdas.

As for this part of your question:

// This is legal, but why would I want this?
int two(int bar);

There are cases where this would be a useful way to call the function you want. The draft C++ standard section 3.4.1 [basic.lookup.unqual] gives us one interesting example:

namespace NS {
class T { };
void f(T);
void g(T, int);
}

NS::T parm;
void g(NS::T, float);

int main() {
f(parm); // OK: calls NS::f
extern void g(NS::T, float);
g(parm, 1); // OK: calls g(NS::T, float)
}

Why can't we define function inside the main function?

m is defined inside of main. In standard C, that's not allowed (you can't define a function within another function).

Some compilers (e.g. gcc) allow it as an extension. But then the function is local, i.e. m only exists within main and can't be seen from the outside. Similarly, variables defined within a function are local to that function and can't be seen from the outside.

Your void m(); declaration at the top claims that a (global) function called m exists, but it doesn't. That's why you get the linker error.

call a nested function (function inside another function)

THIS IS NOT SOMETHING YOU SHOULD DO, but you could create a nested function attribute like so:

def foo():
# for closures or strictly local function
# then this is useful!
# ugly hack other wise to try and create methods.
def bar():
print('bar')

# if there are multiple function, return a container...
return bar

Then:

foo.bar=foo()
foo.bar()
# prints 'bar'

BUT, this is far easier with a class:

class Foo:
# class can hold related methods, setters and getters,
# protected variables, etc.
# Python is DESIGNED to do this.
def bar(self):
print('bar')

Then:

f=Foo()
f.bar()
# prints 'bar'

Why is it easier?

  1. Because Python is designed to use the second example, a class, but the first example is a hack. The ways to use classes are well documented and tested.
  2. It does not scale well. Each function attribute needs to be added from the OUTSIDE of the function.
  3. You will run into local vs global namespace issues if you try and change variables. Classes gracefully support both instance and class data.

It is horrible -- don't do it. Use a class or a module to hold methods.


After a morning coffee, you can potentially do something like this if you really want to add function attributes -- Use a decorator to monkey patch a function:

def add_func_to(function):
# decorator to add function attributes
def attr_f(new_func):
setattr(function, new_func.__name__, new_func)
return new_func
return attr_f

# some function to add an attribute function to:
def foo():
pass

@add_func_to(foo)
# added attribute function below
def attr_f(string):
print(string)

Test it:

>>> foo.attr_f('test')
test

This is still limited vs a class or module since you will be limited to using global or passed variables. It is more applicable if you just want to add a function attribute to an existing function and be done with it...

Can't call a function inside another function

In Javascript, this in a function, is the context in which the function is called. In other words, the object which is invoking the function.

In your case, when you do myFunction(), you are essentially calling window.myFunction(). So the this becomes window.

So your function will print the console - Something.
It will add somethingElse in your window.
So if you try to access myFunction().somethingElse is wrong, Because somethingElse is not part of your function.

But if you try to execute myFunction() and then somethingElse, it will print in the console - Something else.

function myFunction() {

console.log("Something")

this.somethingElse = event => console.log("Something else")

}

myFunction();

somethingElse()

C++: declaration of a function inside another function is not a compiler error so... what is it?

I was curious what the compiler was thinking.

Its thinking that you declared a function by the name y that returns void and has an empty argument list. void y(); is a function declaration.

Did the compiler(s) consider this a declaration?

Yes.

if so, how this could be further used when nested functions are not allowed in C++?

You can use a function declaration for example to call it, or to take its address. Like so:

void x()
{
void y(); // a function declaration

// now that y has been declared, it can be called:
y(); // a function call

// also, it is now possible to take the address:
void (*fun_ptr)() = y;
}

Calling function inside function is not defined

Your code has an object users which when initialized, runs a function which in turn returns an object with methods as its properties.

The users object is globally available, i.e, you can use users.something anywhere as long as its initialized.

the functions that return from the user object have scopes limited to the return function where they're defined. They can only be accessible outside the scope using user.functionName in your case user.init() or user.validation() etc.,

but once you go a level inside the code to where the functions are defined, you are entering into the scope of the function which was used to create the user object. At this level, you do not have access to other functions as earlier, but only the methods or variables which are defined within the scope of the function you are in.

For example: I've added a function consoleStatement() below. and it will print out some console logs, if you run the code, you will observe that the console log for year will output different year the second time when you defined the year as 2019.

var users = (function($) {
"use strict";

return {
init: function() {
this.validation();
},
validation: function() {
$('#form input').on('blur', function(){

// This will NOT work because there is no ajaxcheck defined here
ajaxcheck();

// This will work because the "this" keyword uses the object (this)
this.ajaxcheck();

// This will definitely work because the function is available globally
checkMyAjax();
});
},
ajaxcheck: function() {
console.log('ajax call');
},
consoleStatement: function() {
var name = "Marco";
var year = 2020;
console.log('Name is: '+name);
console.log('Year is: '+year);
},
}
})( jQuery );

function checkMyAjax () {
console.log('ajax call again');
}

jQuery(document).ready(function() {
var year = 2019;
users.init();
console.log('Year is: '+year);
users.consoleStatement();
});

Scope of a function lies with in the block it is defined, for example function myFunction () {} so in order to access variables and functions, they either must be in the scope of the function or must be available globally. I.e, outside all functions.

Here is a gist I've created with line numbers for you to understand clearly: https://gist.github.com/ypk/303659beb2e74429858903052e0c2557

Why can't I put a function in another function without getting an error?

This is a scope issue. When you define a function inside a class, it's not accessible by its name from other functions defined within the class. Rather, you need to access it via the class name (or an instance of the class) and get the function as an attribute.

Changing your calls to within_y to Coords.within_y should work. But I'm not sure that easy fix is really the best fix.

When you define a function in a class, usually it's intended to be a method, called on an instance of the class. For instance:

class Foo():
def bar(self):
print("bar")

def quux(self):
print("quux")
self.bar()
print("quuux")

f = Foo()
f.bar() # prints bar
f.quux() # prints quux, then bar, then quuux, each on its own line

Since your within_y and various collided_X functions look like they take a Coords instance as their first argument, you can already use them as methods. So rather than Coords.within_y(co1, co2), you could call co1.within_y(co2). So that's an alternative way to fix your code, with minimal changes.

However, it would be a bit more natural looking (for Python code) if you changed the parameter names so that co1 was self and co2 was something else (like other, perhaps). Naming the first argument of a method self is a convention, so you don't always need to follow it, but doing so will make your code much easier to understand for anyone else who reads it. Anyone who sees def foo(self) will know right away that they're reading a method, and self is the instance the method is being called on.

Why this code is not able call function inside another function in python

The value_n_from_end does not return anything. You should write:

return self.value_at(self.n)

Indeed, self.value_at(self.n) returns what you want in the function value_n_from_end but then you have to get it back to you by using a return statement. Otherwise it is bound to the function namespace.

Nested function in C

You cannot define a function within another function in standard C.

You can declare a function inside of a function, but it's not a nested function.

gcc has a language extension that allows nested functions. They are nonstandard, and as such are entirely compiler-dependent.



Related Topics



Leave a reply



Submit