# Differences

This shows you the differences between the selected revision and the current version of the page.

at:tutorial:metaprogramming 2009/11/21 07:42 at:tutorial:metaprogramming 2009/11/21 07:44 current
Line 212: Line 212:
==== Multi-stage (Generative) Programming ==== ==== Multi-stage (Generative) Programming ====
-Here's a small example of "compile-time" metaprogramming or "multi-stage programming" inspired by the same example from the E language on [http://www.erights.org/elang/examples/multi-stage.html|Multi-stage programming in E]:+Here's a small example of "compile-time" metaprogramming or "multi-stage programming" inspired by the same example from the E language on [[http://www.erights.org/elang/examples/multi-stage.html|Multi-stage programming in E]]:
Below is a regular power function. Given two numbers 'x' and 'n', it returns 'x^n': Below is a regular power function. Given two numbers 'x' and 'n', it returns 'x^n':
-<code>+<code javascript>
def pow(x, n) { def pow(x, n) {
if: (n == 0) then: {   if: (n == 0) then: {
Line 227: Line 227:
Let's see whether it works: Let's see whether it works:
-<code>+<code javascript>
system.println(pow(2,5)); // prints 32 system.println(pow(2,5)); // prints 32
</code> </code>
Line 233: Line 233:
Now, consider the following 'expandPow' function that is very similar to the above function, but which, instead of //calculating the value// of the power function will //build an expression// that, when evaluated, yields the value of the power function. Note that this function is parameterized with the name of the variable that is used to calculate the power value: Now, consider the following 'expandPow' function that is very similar to the above function, but which, instead of //calculating the value// of the power function will //build an expression// that, when evaluated, yields the value of the power function. Note that this function is parameterized with the name of the variable that is used to calculate the power value:
-<code>+<code javascript>
def expandPow(var, n) { def expandPow(var, n) {
if: (n == 0) then: {   if: (n == 0) then: {
Line 251: Line 251:
To be able to use the expression generated by the above function, let's define a small helper function that will embed this expression in a first-class function: To be able to use the expression generated by the above function, let's define a small helper function that will embed this expression in a first-class function:
-<code>+<code javascript>
def powMaker(n) { def powMaker(n) {
def ast := expandPow(`x, n);   def ast := expandPow(`x, n);
Line 263: Line 263:
Now we can generate power functions that are fixed in their second argument, but that are more efficient to execute: Now we can generate power functions that are fixed in their second argument, but that are more efficient to execute:
-<code>+<code javascript>
// pow5 is now bound to a function { |x| x*x*x*x*x*1 } // pow5 is now bound to a function { |x| x*x*x*x*x*1 }
def pow5 := powMaker(5); def pow5 := powMaker(5);
Line 272: Line 272:
You can measure the performance difference by timing the evaluation of both functions: You can measure the performance difference by timing the evaluation of both functions:
-<code>+<code javascript>
import /.at.support.timer import /.at.support.timer
system.println("pow(2,5) takes " + (time: { pow(2,5) }) +"ms"); system.println("pow(2,5) takes " + (time: { pow(2,5) }) +"ms");        