Closures/Value capture: Difference between revisions

Content added Content deleted
(→‎{{header|C}}: it's a lot worse than that)
(→‎{{header|C}}: Another aproach: closures and funcall in C with some type-tagged dynamic objects.)
Line 5: Line 5:


=={{header|C}}==
=={{header|C}}==

===Function image copying approach===

Non-portable. Copying a function body depends on implementation-specific semantics of volatile, if the replacement target still exists afte optimization, if the dest memory is suitably aligned, if the memory is executable, if it makes any function calls to a relative offset, if it refers to any memory location with an absolute address, etc. It only very occasionally works.
Non-portable. Copying a function body depends on implementation-specific semantics of volatile, if the replacement target still exists afte optimization, if the dest memory is suitably aligned, if the memory is executable, if it makes any function calls to a relative offset, if it refers to any memory location with an absolute address, etc. It only very occasionally works.


Line 49: Line 52:
func[7]: 49
func[7]: 49
func[8]: 64</lang>
func[8]: 64</lang>

===Greenspunned mini Lisp dialect===

See [[Closures/Variable_capture/C]] for complete code. The relevant excerpt is:

<lang c>void init(void)
{
t = intern(lit("t"));
x = intern(lit("x"));
}

val square(val env)
{
val xbind = assoc(env, x); /* look up binding of variable x in env */
val xval = cdr(xbind); /* value is the cdr of the binding cell */
return num(cnum(xval) * cnum(xval));
}

int main(void)
{
int i;
val funlist = nil, iter;

init();

for (i = 0; i < 10; i++) {
val closure_env = cons(cons(x, num(i)), nil);
funlist = cons(func_f0(closure_env, square), funlist);
}

for (iter = funlist; iter != nil; iter = cdr(iter)) {
val fun = car(iter);
val square = funcall(fun, nao);

printf("%d\n", cnum(square));
}
return 0;
}</lang>

Here, we create an environment explicitly as an association list which we can search with the <code>assoc</code> function. The environment contains a binding for the symbol <code>x</code>. The <code>square</code> function retrieves the value and returns its square.

Output:

<pre>$ ./a.out
81
64
49
36
25
16
9
4
1
0
</pre>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==