4 ms·
Nice try blanco niño, but the following program runs fine. This doesn't detract from your overall point, but if you're trying to win over people who think the
by jfm3 16y ago
Nice try blanco niño, but the following program runs fine. This doesn't detract from your overall point, but if you're trying to win over people who think the Boost macros are super awesome, this argument won't do it.
#include <stdio.h>
#define LOOP(n) \
int i; \
for (i = 0; i < n; i++)
#define LOOP10 \
LOOP(10) printf("%d\n", i)
int main(int argc, char *argv[])
{
LOOP10;
}
- mahmud 16y agoYesterday I was writing code that kept messing my Lisp's signal handling, so I wrote a FOR-DURATION macro that arms a timeout and makes sure whatever that runs in its body gets killed after N seconds. Here it is: (defmacro for-duration ((seconds) &body body) `(handler-case (bt:with-timeout (,seconds) ,@body) (bt:timeout () nil))) Five lines to alter the evaluation model of your language. Not bad. Use as: (for-duration (10) (loop (print "Infinite loop! where is your Godel now?"))) "bt" is the bordeaux-threads package, a portable Lisp library for thread programming.
- GregBuchholz 16y ago(defun for-duration (seconds body) (handler-case (bt:with-timeout seconds (body)) (bt:timeout () nil))) (for-duration 10 (lambda () (loop (print "Infinite loop! where is your Godel now?"))))
- makmanalp 16y agoI think Greg is trying to say "why the hell do we even need macros for this"?
- mahmud 16y agoWith functions you have to make a conscious effort to quote arguments, otherwise the strict evaluation will evaluate its arguments before the function. Also, with macros you can introduce you new "implicit" control and structure semantics; it's very common for forms to have an "implicit progn", or a block named NIL or similar.
- funptr 16y agoC99 + GCC extensions + POSIX: #define for_duration(seconds, body) \ { \ pthread_t tid_task, tid_watcher; \ \ void* task(void* arg) { \ body ; \ pthread_cancel(tid_watcher); \ return NULL; \ } \ \ void* watcher(void* arg) { \ sleep((seconds)); \ pthread_cancel(tid_task); \ return NULL; \ } \ \ pthread_create(&tid_task, NULL, &task, NULL); \ pthread_create(&tid_watcher, NULL, &watcher, NULL); \ pthread_join(tid_task, NULL); \ } Use as: for_duration(10, { while (true) { printf("Infinite loop! where is your Godel now?\n"); } }); Or with single brace-less statements: for_duration(10, while (true) printf("something\n") ); Lexical scope is sane: int i = 0; for_duration(10, { while (true) { printf("%d\n", i++); } }); My comparison isn't quite fair, because your threading library provides 'with-timeout', while pthreads doesn't. If you factored this out, say with a signature like: void with_timeout(unsigned int seconds, void (*func)(void)); (in analogy to the common lisp function), then the macro part becomes just four lines: #define for_duration(seconds, body) { \ void func() { body ; } \ with_timeout((seconds), &func); \ } I acknowledge that the lisp solution is rather more elegant. Also, my C macro is potentially dangerous because it is unhygenic. (It shadows outer declarations of 'task()', 'watcher()', 'tid_task', 'tid_watcher', and 'arg', in the body of 'body'.)
- chc 16y agoI don't believe nested functions like you're using there are valid C. They're a nonstandard extension that some compilers implement because they're so handy. So this basically illustrates that C gets closer Lisp's usability when you add Lispy features to it.