1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/docs/inlining.txt Fri Jun 28 17:18:03 2013 +0200
1.3 @@ -0,0 +1,45 @@
1.4 +Inlining can be considered similar to grammar productions. The path of
1.5 +execution in Python is somewhat indirect due to the need to branch
1.6 +continuously in order to perform work. Consider the following function calls:
1.7 +
1.8 +x(n)
1.9 +y(n)
1.10 +z(n)
1.11 +
1.12 +Where x, y and z are identifiable in advance and are stable, one can consider
1.13 +the contents of these functions together. We can write the executed code using
1.14 +the following abstract representation:
1.15 +
1.16 +XYZ
1.17 +
1.18 +However, it is rather likely that one instead sees things like this:
1.19 +
1.20 +a.x(n)
1.21 +b.y(n)
1.22 +c.z(n)
1.23 +
1.24 +Here, the functions called depend on what a, b and c are. This might be
1.25 +written as follows using the abstract representation, borrowing from regular
1.26 +expression notation:
1.27 +
1.28 +(X|P)(Y|Q)(Z|R)
1.29 +
1.30 +Here, P, Q and R are alternatives for X, Y and Z respectively. Within each of
1.31 +these functions, other code is executed, and we might want to expand the
1.32 +top-level "productions" to show the actual operations performed inside those
1.33 +functions. Consider Y and Q being defined as follows:
1.34 +
1.35 +def Y(n):
1.36 + return n
1.37 +
1.38 +def Q(n):
1.39 + return n and Q(f(n))
1.40 +
1.41 +This might change the abstract representation as follows:
1.42 +
1.43 +(X|P)(Y|F*)(Z|R)
1.44 +
1.45 +Here, Q evaluates n and either returns n immediately or calls itself with the
1.46 +result of f (which we will consider as identical to F). Where Q does not have
1.47 +a value of n that causes it to return immediately, F is invoked, and so F is
1.48 +invoked repeatedly until a final invocation of Q that returns immediately.