Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

PROGRAMMING CHALLENGE

Name: Anonymous 2010-07-16 18:57


This one should be difficult enough for you guys,

Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.


My submission, in Scheme


(define (foo num)
  (lambda (x) (+ x num)))

Name: 2,4 2010-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.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List