Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Whew. All right, here we go!</p> <p>First, you have a function, any function. In your case, that's <code>fib()</code>. Now, in python, functions are also objects, and they can be created in runtime, so we can actually do this:</p> <pre><code>def give_me_a_function(): def f(x): return x return f </code></pre> <p>(Warning: horrible repetition of the word 'function' for the rest of this answer).</p> <p>Well, we defined a function that takes no arguments and returns,... another function? That's right! Functions are objects! You can create them in runtime! So we defined a second function inside our original one, and returned it, as we would any other object.</p> <p>Now, let's do something a tad more complicated:</p> <pre><code>def alter(other_function): def altered(x): return other_function(x) + 1 return altered </code></pre> <p>What the hell was that? </p> <p>Well, we defined a function, <code>alter()</code>. Just as in the example above, it creates a function in run-time and returns it, as the object it is. That much we already covered.</p> <p>Now, if functions are objects, and can be created and returned, why wouldn't you be able to pass one as argument? And call it, while it you're at it! That's right: <code>alter()</code> takes a function as argument(*), and uses it.</p> <p>All it takes to have <code>alter()</code> is combining the above magic with this new magic: we receive a function as an argument, create another one on the fly that makes use of it, and return this new function-object!</p> <p>Let's try it.</p> <pre><code>&gt;&gt;&gt; def f(x): ... return 2*x &gt;&gt;&gt; new_function = alter(f) &gt;&gt;&gt; f(2) 4 &gt;&gt;&gt; new_function(2) 5 </code></pre> <p>There it goes! <code>alter()</code> takes my <code>f()</code>, creates a new function that will return <code>f() + 1</code>, and gives that to me as a return value. I assign it to <code>new_function</code>, and I have a new, home-brewed, run-time created function.</p> <p>(I did warn you about the use of the word 'function', did I not?)</p> <p>Now, to your piece of code. You're doing something more complicated than just <code>f() + 1</code>. Or not? Well, you're creating a new function that takes the original one, calls it, and prints some data. That's not much more magical than what we just did. Where's the big difference?</p> <p>Well, there is one detail: fib() is recursive, so it calls itself, right? Nope! Not <strong>itself</strong>. It calls <code>fib()</code>, and you happened to do this:</p> <pre><code>fib = trace(fib) </code></pre> <p><strong>WHAM. <code>fib()</code> is not itself anymore!</strong> Now <code>fib()</code> is <code>trace(fib)</code>! So when <code>fib()</code> goes into recursion, it's not calling itself, it's calling the wrapped version of itself we created.</p> <p>That's why the indentation is handled like that. Look at <code>trace()</code> again, now knowing it's actually recursively indenting, and it makes sense, doesn't it? You want to have one indentation per level of recursion, so increment it, call <code>fib()</code> (which, remember, is now <code>trace(fib)</code>), and then when we're back (so the recursion went and came, and we're about to return to a previous step in the calling chain) we decrement it.</p> <p>If you still don't see it, try moving all the functionality to fib(). Forget about the decorating function, that's plain confusing.</p> <p>Ah. I really hope this helps, and that the 2.000 guys that beat me to the answer didn't already make this question obsolete.</p> <p>Cheers!</p> <p>(*) Yeah yeah duck typing yadda yadda callable objects bla bla irrelevant.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload