HNHacker News
TopNewBestAskShowJobs

funptr

16 karma · joined January 26, 2011

submissionscomments
funptr··on Mastering Key Bindings in Emacs
Not offhand, but I looked it up and I think what you want is `key-description'. It prints key sequences, so e.g. (key-description "\370") evals to "M-x".
funptr··on Mastering Key Bindings in Emacs
That seems to work also, what's the problem?
funptr··on Mastering Key Bindings in Emacs
It's not part of emacs, I just wrote it as an example.
funptr··on Mastering Key Bindings in Emacs
This one prompts you to type a literal key sequence (exactly like with `describe-key', C-h k) and inserts it at the point in a representation that the *-set-key functions can use. As written it's bound to to C-c k, and only in the scope of elisp buffers.

    (defun insert-key-sequence (key-repr)
      "Reads a literal key sequence from the user
    and inserts a representation of it at point,
    suitable for `global-set-key' or `local-set-key'."
      (interactive "KKey sequence? ")
      (prin1 key-repr (current-buffer))
      (insert " "))
    
    (add-hook 'emacs-lisp-mode-hook 
              #'(lambda () 
                  (local-set-key "\C-ck" #'insert-key-sequence)))
    
    (run-hooks 'emacs-lisp-mode-hook)
Unfortunately it doesn't seem to work for mouse chords.
funptr··on How Lisp macros differ from static code-generation and metaprogramming
>Is there a C macro that can do this?

No, of course. C macros only see strings; you need to parse a syntax tree to do your reverse example (like lisp macros).

No argument from me.

>Lisp's macro system allows you to create new syntax, including changes in flow control.

Well, C macros seem to be able to manipulate control flow. You can't break up an expression to do that (not smart enough to parse), but you can rearrange expressions that are given whole.

funptr··on How Lisp macros differ from static code-generation and metaprogramming
You're right, it's not even valid C99. My mistake.
funptr··on How Lisp macros differ from static code-generation and metaprogramming
C99 + 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'.)