Bart <b...@freeuk.com>:
> If you did need one of those others to be variable, then you just assign
> it to a variable the rare times you need to do that. For example:
>
>   def fn1(): pass
>   def fn2(): pass
>
>   fn = fn1 if cond else fn2
>
> fn1, fn2 will always be functions. fn will always be a variable, but one
> that can change between referring to fn1, fn2 or anything else.

In high-level programming languages, functions are ordinary values. You
can perform similar operations on functions as on integers or strings.
You can give me two functions, and I can use those two to create a
third function:

   def compose(f1, f2):
       def composition(x):
           return f1(f2(x))
       return composition

Here "compose", "composition", "f1" and "f2" are variables:

 * "compose" gets assigned when the first, outer "def" statement is
   executed,

 * "f1" and "f2" get assigned when the function held by "compose" is
   called,

 * "composition" gets assigned when the inner "def" statement is
   executed.


While FORTRAN or C couldn't operate on functions like this, an assembly
language program could easily. Simply compose a CPU instruction sequence
on the fly, mark it executable and use the "CALL" opcode to transfer
control to your constructed function.

In the same vein, you could understand the "def" statement as a runtime
compiler that takes the function body, compiles it into machine language
and assigns the start address to the given variable. In fact, that would
be a perfectly working way to implement "def." Whether it would be a
smart thing to do is a different question. Key is, though, that "def"
always creates a new *data* object that can be called as *executable
code*.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to