Changes between Version 29 and Version 30 of ExplicitCallStack
- Timestamp:
- 01/29/07 09:22:26 (6 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
ExplicitCallStack
v29 v30 163 163 An advantage of this transformation style is that it handles combinations of transformed and untransformed functions easily. When variable expressions are transformed we simply check to see if the variable corresponds to a transformed function. If it does, we pass it the current stack value as an argument, otherwise we don't. 164 164 165 A problem with this transformation style is that it is sensitive to program transformations that might happen in the compiler. For example consider this code:165 A problem with this transformation style is that it is sensitive to program transformations that might happen in the compiler. For example, it transforms these two functions differently, even though they are semantically equivalent: 166 166 167 167 {{{ 168 f = let x = EXP in (\y -> head (foo x)) 168 f1 = let x = EXP in (\y -> head (foo x)) 169 170 f2 = \y -> head (foo (let x = EXP in x)) 169 171 }}} 170 172 171 where EXP is some arbitrary expression. Suppose that head is transformed to accept a stack argument, and foo is not. After transformation the code will become:173 Here is the output of the two different transformations: 172 174 173 175 {{{ 174 f = let x = EXP in (\y -> head ["f"] (foo x)) 176 f1 = let x = EXP in (\y -> head ["f1"] (foo ["f1" x)) 177 178 f2 = \t y -> head ("f2":t) (foo ("f2":t) (let x = EXP in x)) 175 179 }}} 176 177 If we get an excpetion in head, the stack trace will tell us that head was called inside f, and f will be the root of the call stack.
