>>3
Ignoring the "static" solution (not a real one), you could write this in 2 main ways:
1) Unportable: malloc a buffer, and write the function code to it, insert n's value in the function code. Not hard to do, but not portable.
2) Portable: make a FUNCALL-like macro, which calls a function with a context struct or value cell array, and have the function use the values in the struct (in this case, the value of n).
In the case 2, a function is either a piece of code or a structure which contains the address of a real function and an array or structure of values closed over (or pointers to them). A funcall function or macro can call the real function or the encapsulated structure (containing the real function and closed over values). This is how most Lisps do it, but it's done behind the scenes, so you don't really need to know how closures are implemented.
>>3 int (*foo(int n))(int)
{ int f(int i)
{ return n + i; }
return f; }
Name:
Anonymous2010-07-16 19:28
And here's the old C++ way to do it using templates and compile-time functors, although it's not exactly the same thing as actual lambdas and closures that are in C++0x.
template< int N >
struct foo
{
int operator()(int i) {
return i + N;
}
};
>>11
It looks like it just creates a closure on the stack to capture the value of 'n' that gets passed in when calling the the returned pointer to 'f' (the compiler already knows it's on the stack after the call to foo, so it optimizes it out).
So it looks to be pretty efficient. Not sure yet what would happen across optimization boundaries.
Name:
Anonymous2010-07-16 20:11
DISCLAIMER: THIS IS A TOY! I DO NOT ACTUALLY CODE LIKE THIS
Should run under ikarus with the iksqlite lib
(import (rnrs) (zeptodyne iksqlite))
(define make-counter
(letrec* ((db (sqlite-open "/tmp/test.db"))
(n 0)
(make-name
(lambda ()
(set! n (+ n 1))
(string-append "counter"
(number->string n)))))
(sqlite-exec db "create table retarded_counter (k string, v integer)")
(lambda (x)
(let ((name (make-name)))
(sqlite-exec db (format "insert into retarded_counter values (~s,~s)" name x))
(lambda ()
(let ((ans (string->number
(vector-ref
(car (sqlite-exec db (format "select v from retarded_counter where k = ~s" name))) 0))))
(sqlite-exec db (format "update retarded_counter set v = ~s where k = ~s"
(+ ans 1) name))
ans))))))
Name:
Anonymous2010-07-16 20:15
>>17
If this were real code, it would be a candidate submission for thedailywtf.com.
(defun foo (n) (curry #'+ n))
Should also work, where you should write or import your currying function (a simple 3-4 line version is easy to write, if you don't have it in a library).
>>35 >>36
>clang does not support nested functions; this is a complex feature which is infrequently used, so it is unlikely to be implemented anytime soon.
>>40
No. Supporting nested functions does not necessitate supporting closures.
Name:
Anonymous2010-07-17 0:24
>>41
The GCC nested functions extension support closures, which is what we're talking about.
Name:
Anonymous2010-07-17 0:27
>>42
Well, arguably clang could support closures without supporting nested functions but I don't know how much use that would be.
Name:
Anonymous2010-07-17 0:30
>>43
Oddly enough, Clang supports both Objective-C style blocks (lambda functions and closures) and C++0x lambda functions with closures, but both are implemented through different mechanisms, and both aren't language extensions.
Name:
Anonymous2010-07-17 0:43
>Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.
a=parseInt(prompt("Enter a number",0));;
eval("function newf(i){return a+i}")
newf(10);
>>45 function foo(n){return function(i){return n+i}}
foo(pareInt(prompt('Enter a number', 0)))(10);
Name:
Anonymous2010-07-17 1:35
>>46
You can't reuse that function without declaring it with a name outside function scope. Observe:
function check(){
a=parseInt(prompt("Enter a number",0));;
eval("function newf(i){return a+i}")}
check()
newf(10);//Error: newf is not defined
>>52
Why would you do that?
OOP and closures are somewhat equivalent.
A class with a (possibly private) member called i, a constructor which takes i, and an add method which takes n is enough.
Usage would be like:
Adder adder = new Adder(i);
int newValue = adder.Add(n,i);
It's not exactly what OP requested for, but the concepts are somewhat equivalent. It's easier to implement OO systems if you already have closures and macros, but it's harder to implement closures if you only have classes, but aside from that the functionality they present is somewhat equivalent.
>>53
I was trying to go for a "nested functions" feel and this was the only way I could think of achieving that.
I suppose I could the Java Method class in some way too but that would be a ridiculous amount of work compared to the simplicity of the request.
Name:
Anonymous2010-07-17 4:08
Any solution which manipulates function pointers is very messy.
(return *func_pointer)(execute_from) vs setting global variable x=n; and using standard function calls
#include <stdio.h>
#include <stdlib.h>
int n=0;
int getn(i){return n+i;}
int main(int agrc,char**argv){
n=10;printf("%i",getn(6));
return 0;
}
>>55
Any solution involving globals isn't a real solution as you can't just "make as many functions/closures" as you'd like. You can only "generate" one such function. "Making" another invalidates the previous one.
Name:
Anonymous2010-07-17 5:05
JESUS FUCK PEOPLE WHAT THE FUCK IS WRONG WITH THIS THREAD
>>4
1) would work, except it's more complicated than you make it seem; for instance malloc'd memory is execution-protected on modern operating systems. Honestly to make it portable, your best bet is probably to compile it with llvm. You still have to manage the memory containing the closure though, so it's still not like a closure in a typical HLL.
2) does not work because your funcall macro can't be passed around as a function pointer. there's no real way to do it other than return a struct (the closing environment) and pass in that struct in the function call.
In other words it's certainly not possible in standard C, but possible with runtime code generation or compiler extensions.
>>76
You wouldn't need any semicolons for that in Perl but you'd use them anyway.
For some reason I find keeping it on a single line helps me remember the semicolon after curlies. It's also the only excuse I sympathize with for instancing typedefs with their definitions.
Name:
Anonymous2010-07-18 5:32
perl: sub foo{eval"sub{@_+pop}"}
javascript (1.8+): foo = function(n) function(i) n + i;
>>81
I would think best practices would have it covered. If you don't think so too you're fired.
Name:
2,42010-07-18 19:09
1) would work, except it's more complicated than you make it seem; for instance malloc'd memory is execution-protected on modern operating systems. Honestly to make it portable, your best bet is probably to compile it with llvm. You still have to manage the memory containing the closure though, so it's still not like a closure in a typical HLL.
If malloc isn't enough, you can always use the system's page memory allocator (for example VirtualAlloc on Win32), and if the system respects the no-execute bit or allows read/write/execute memory protection on pages, just make a call to change the memory protection (for example VirtualProtect on Win32). Of course, there are plenty other ways to do this, but on the lower level, it will always involve allocing a piece of memory which can contain executable code. The real problem here is generating the right code which points to the right (closure data) offsets (apply relocations if needed or generate base indepdent code).
2) does not work because your funcall macro can't be passed around as a function pointer. there's no real way to do it other than return a struct (the closing environment) and pass in that struct in the function call.
You'd pass a "function object"(encapsulates a function and the closure object) to the funcall macro. The macro itself calls the function field of the structure with the closure object and the rest of the arguments passed. It can also be done as a function. While this means that you're passing structs around instead of function pointers, and the syntax is a bit different, the functionality is achieved, except it's not nearly as comfortable to use as normal functions.
Closures are probably a pain to use in languages which don't support them natively, maybe to the point you might not want to bother with them.
>>83
How do we know when the closure object will be freed? Most code is usually freed by the OS when the application exits, however that's probably not a good idea for closures as they can grow in number. Given C's approach of manual memory management, you'd probably make some closure_free function which performs the cleanup and call it whenever you don't need the closure anymore.
Name:
Anonymous2010-07-18 20:05
Object pascal:
type
TNumFunc = function(i: PtrInt): PtrInt of object;
TNumHax = class
function NumFunk(i: PtrInt): PtrInt;
end;
function TNumHax.NumFunk(i: PtrInt): PtrInt;
begin
result := PtrInt(self)+i;
end;
function foo(n: PtrInt): TNumFunc;
begin
TMethod(result).Code := @TNumHax.NumFunk;
TMethod(result).Data := Pointer(n);
end;
I have to say, I'm disappointed at the severe lack of ridiculous implementations.
Name:
Anonymous2010-07-18 21:36
>>85
Yes but your macro can't be used as a function pointer, that's the whole point. You can't pass it around as an int(*)(int). You're not calling the return value of the generator as a function; you're calling some other macro, passing in the return value of the generator.
This is why you can almost accomplish this in C++ by creating an object containing the closure values and overriding operator(). You can't store it in a regular function pointer, but you can still call it as a regular function.
>>89 You can't store it in a regular function pointer, but you can still call it as a regular function.
That's similar to >>21 in that you have to call() the returned block, you can't just invoke it like a method.
>>90
Actually, it should be possible to generate a small function which calls a specific closure, and you only have to specify the closure params to it. Easy with a bit of asm, but not very portable. That's the problem with languages which can't generate code at runtime and can't assign symbols with code at runtime. Much easier done in Lisp.
>>90
Actually, it should be possible to generate a small function which calls a specific closure, and you only have to specify the closure params to it. Easy with a bit of asm, but not very portable. That's the problem with languages which can't generate code at runtime and can't assign symbols with code at runtime. Much easier done in Lisp.
>>92 >>21 could be 'fixed', but it wouldn't normally be worth the extra code. Sending a call message is not a serious problem. Fixing the C++ example is certainly not worth it, and any attempts to do so trade on the purity of the concept anyway.
Name:
Anonymous2010-07-18 23:37
I use closures in C all the time. Also, typedefs are for pussies.
I have NX bit turned by default and immutable.
Any "clever" program trying to write/execute to memory(like some Opera versions) gets uninstalled immediately.
Such hacks have no place in modern enterprise environment.
Name:
Anonymous2010-07-19 3:25
>>102
Java and any JIT/VM/Intepreter engines requires executing memory. Are you saying your enterprise doesn't work with Java EE?
I'm going to go ahead and agree with #103, even for non-JIT interpreted environments. The only difference is that non-JIT interpreted environments aren't affected by the NX bit, because the NX bit can only stop regions of memory from being executed by the processor itself. The same types of attacks that work on buffer overflows in native code foiled by the NX bit would succeed against the same flaws in interpreted environments.
So that means that #102 should, by their own admission, remove any copies of Perl / Python / Ruby / Java / Javascript / Lisp / Scheme / Haskell / Bash / Sh / Zsh / Ksh / Apple BASIC from their systems right now. Doubly so for Java / Python "Unladen Swallow" / Lua-JIT / half of Lisp implementations ever.
It's not "clever", it's the whole point of the Von Neumann architecture. If people thought we didn't need to execute main memory, we'd switch to Harvard architecture in a heartbeat -- processor performance certainly increases. But no, people only use Harvard architecture for dumb, fast things like DSP microcontrollers.
Enforcing the NX bit on all your programs' heaps is like trying to reduce home burglaries by nailing everyone's windows shut.
Name:
Anonymous2010-07-19 3:52
Program A creates binary file B and saves it to disk/ram
B executes/spawns as new thread/process/dll.
NX bit just stands there being useless.
Where is your Neumann now?
>>102
That's silly and there are countless ways to bypass it. It's also harmful because it disallows dynamic code generation done by a lot of modern language implementations.
Also what >>106 said: So that means that #102 should, by their own admission, remove any copies of Perl / Python / Ruby / Java / Javascript / Lisp / Scheme / Haskell / Bash / Sh / Zsh / Ksh / Apple BASIC from their systems right now. Doubly so for Java / Python "Unladen Swallow" / Lua-JIT / half of Lisp implementations ever.
Enjoy your C-only setup >>102.
Did I also mention that on some platforms, executable packers/protections are prevalent and a lot of applications write code then execute it. Are you telling me you refuse to run UPX'ed apps?
Name:
Anonymous2010-07-19 4:17
<?php
// 5.3 -->
function foo_closure($n)
{
return function($i) use ($n) {
return $n + $i;
};
}
On that note, here's a helpful comment from the manual. Topmost entry. Luckily I happened to glance across it.
To avoid memory problems, when creating a dynamic function within loops, register it as a global variable, and check if it has already been set;
<?php
global $my_func;
if (!isset($my_func))
{
$my_func = create_function($args, $code);
}
$my_func();
?>
That way you don't end up creating the same function twice (or a couple of million of times, as it happened to me...)
Name:
Anonymous2010-07-19 4:48
Here's an "improved" C version, guaranteed to be portable across different Linux architectures. It's also very easy to change the function to perform arbitrary computations. With minimal modification it can also run on OS X. No worries about the NX bit, either. It does leak memory, though... like all good C programs should.
* A new warning has been added to GCC: "-Wtrampolines". This issues a warning message whenever gcc generates a trampoline, which is a small piece of code that is needed whenever the address of a nested function is taken. Since this piece of code is created at run time on the stack, it requires an executable stack in order work. This might be a problem for the target execution environment.
While I'm sure most of us love entertaining dynamic code generation, in reality, very few language implementations recompile the whole function to generate a closure (I haven't actually see any that do), instead, what they do is compile the closed over functions, and the closure state is referenced either through the stack(arguments) or through some other hidden way to pass arguments. It's also quite common to pass a reference instead of the literate value, this allows sharing the value between functions/closures. Closure objects themselves are very lightweight and only contain: tag bits (or some other way to identify them), a reference(pointer) to the function object (usually tagged as well), the closure data(array or structure(which are not that different from arrays)). Closures themselves are callable objects, just like functions (those functions objects) or other data types which can be callable (for example, funcallable instances(of classes) exist in CL implementations with MOP support, they're functionally equivalent to closures, but allow more fine-grained control)). Calling such an object would lead to either have the compiler generate the needed calling code by itself (if it's possible to determine at compile time), or call a dispatcher which performs the call at runtime depending on the type.
It should also be noticed that some of the closure implementations in this thread use literals, so they do not allow sharing state, here's a simple example which illustrates this as well as shows how the closure internals work:
#<FUNCTION {24DE7C3D}>
--------------------
FUNCTION: #<FUNCTION SET-A {24DE7E3D}>
Closed over values:
0: #<value cell 100 {24DE7C4F}> <-- same pointer!
the value cell a:
#<SB-KERNEL::RANDOM-CLASS {24DE7C4F}>
--------------------
VALUE: 100
(In this case, the compiler actually compiles both functions at once, so they actually point to different offsets within the same code block, but that'd be too much detail to show here...)
Also keep in mind that while this used functions, closures can be generated at runtime quite easily and cheaply (just return a lambda), so whatever closure implementation your language supports needs to allow this as well (without the previous requirement, you can just use globals to achieve the same).
So the points I'm trying to make is that real closures:
1) Allow their value to be shared by other closures or pieces of code. They can close over anything in the lexical scope. Sharing values also means that if the language allows mutation of variables, this should also be supported.
2) Can be implemented fairly cheaply(in terms of speed and space cost) without the need of runtime code generation.
Sadly, I don't see how you can achieve these goals in ANSI C portably without adding your own function call macro, which would make everything quite clunky, also memory management would be a pain.
Most of the people who would do this kind of thing in C are people who are implementing runtime libraries for higher level languages, and they don't care about portability because they'd need to rewrite the code generator if they switched architectures anyway.
To summarize the reasonable options presented in #115, implementors have three reasonable options for supporting closures:
1. Use globals and only allow one instance of a given closure to be active at any given time. This works surprisingly well on the smallest of embedded systems. Some environments for small embedded systems don't support recursive functions. By "small", I mean no more than 1K RAM.
2. Change the calling convention for functions, add a "hidden" parameter.
3. Dynamically generate a piece of code to add a hidden parameter to the function call and then jump to the main function.
I'm making a case for #3 as being pretty reasonable. Runtime code generation sounds like a beast, but on most architectures you can write one piece of glue code that works for all closures. It would only require twenty bytes or so, and for most runtimes you'd need to make an allocation for technique #2 anyway so an extra twenty bytes is pretty cheap. In many cases a sophisticated complier would inline the glue code (if its value is known) which effectively turns it into case #2. (This glue code is what GCC calls a "trampoline".) The performance question boils down to which you do more often: pass around closures or ordinary function pointers. My guess is that:
; Assuming mapcar isn't inlined. This assumption is almost certainly wrong.
(mapcar #'car my-list) ; faster with option #3, probably
(mapcar #'(lambda (x) (* x n)) my-list) ; faster with option #2, probably
; Do you even know which of the above two cases is more common for non-inlined
; higher order functions in your code base? I bet you have no clue.
; So the performance argument is kinda pointless.
As for C, these days you can use blocks if you're okay with targeting clang. That's not unreasonable, people writing Lisp code are fairly cavalier about portability and most Haskellers you meet don't care about any compiler other than GHC.
Name:
Anonymous2010-07-19 9:08
>>111
To optimize speed just write it to a RAM drive.