[Tutor] Newbie problems

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Tue, 5 Mar 2002 14:49:16 -0800 (PST)


On Tue, 5 Mar 2002, Kirby Urner wrote:

> 
> def mainmenu():
>          switch = [f1,f2,f3,f4,f5]
>          while 1:
>            print """

[some code cut]

> The "subprograms" (non-Python terminology) are all
> top-level functions, and must already be defined for the
> above to work.  I've used simple stub functions:
> 
> def f1(): print "Menu option 1"
> def f2(): print "Menu option 2"
> def f3(): print "Menu option 3"
> def f4(): print "Menu option 4"
> def f5(): print "Menu option 5"


Just to clarify: those functions should exist by the time we actually
execute "mainmenu()" function.  However, before we execute the function,
those f1() through f5() functions don't have to exist yet.  Python is
considered very "dynamic" because of this.


When we're declaring a function, Python actually won't even look too
closely at the body of the function; it'll look up the values of things
when we actually run the function.


This allows us do do wacky stuff like this:

###
>>> def isEven(n):
...     if n == 0:       
...         return 1
...     else:
...         return isOdd(n-1)
... 
>>> def isOdd(n):
...     if n == 0:
...         return 0
...     else:
...         return isEven(n-1)
... 
>>> isEven(1)
0
>>> isOdd(42)
0
>>> isOdd(43)
1
###

Notice that there's no real way of putting one function in "front" of the
other: they're knotted together very tightly.  We can resolve the conflict
when we see that Python won't look at function bodies until we actually
run those functions.

The above is an artificial example, of course, but there are actual cases
when we need "mutually recursive" functions that call each other, and it's
useful to know how Python handles this.





[Aside: skip this if you haven't seen C before]

This situation is very different from static languages like C or ML, where
all function names need to be known immediately.  In fact, we can't really
write isEven() and isOdd() C without contorting ourselves with function
prototypes:

/***/
/** Function prototypes */
int isEven(int n);
int isOdd(int n);

int isEven(int n) {
    if (n == 0) return 1;
    else return isOdd(n-1);
}

int isOdd(int n) {
    if (n == 0) return 0;
    else return isEven(n-1);
}
/***/

Without the function prototypes at the top, C gets totally confused and
hollers that we have no idea what we're doing.  *grin*.  This is a strong
reason why C uses function prototypes, so that C knows up front what
functions will be available.




Hope this helps!