7

我有许多方便的函数可以在当前单词或区域上运行,并且由于懒惰等原因。我已经用模板构建了它们......

例如

(defun lower-camelcase-at-point-or-region ()
  "lowerCamelCaseTheCurrent dashed or snake_case word or any words in text selection."
  (interactive)
  (let (pos1 pos2 meat)
    (if (and transient-mark-mode mark-active)
        (setq pos1 (region-beginning)
              pos2 (region-end))
      (setq pos1 (car (bounds-of-thing-at-point 'symbol))
            pos2 (cdr (bounds-of-thing-at-point 'symbol))))
    (setq meat (s-lower-camel-case (buffer-substring-no-properties pos1 pos2)))
    (delete-region pos1 pos2)
    (insert  meat)    
    )
  )

实际上,这都是样板,除了这条线......

(setq meat (s-lower-camel-case (buffer-substring-no-properties pos1 pos2)))

我在哪里调用s-lower-camel-case缓冲区子字符串。我想重用 at point 或 region 的东西,但不要在任何地方复制它,(因为这很愚蠢,而且维护起来很头疼。)

所以我真正想知道的是,我可以在 Emacs Lisp 中 curry 函数吗?

当我尝试这个...

(defun do-stuff-on-point-or-region ()
  "Do stuff."
  (interactive)
  (operate-on-point-or-region 's-lower-camel-case)
)

定义operate-on-point-or-region为...:

(defun operate-on-point-or-region (fn)
  "Pick the substring at point, or region 
   and replace it with the output of fn"
  (let (pos1 pos2 meat)
    (if (and transient-mark-mode mark-active)
        (setq pos1 (region-beginning)
              pos2 (region-end))
      (setq pos1 (car (bounds-of-thing-at-point 'symbol))
            pos2 (cdr (bounds-of-thing-at-point 'symbol))))
    (setq meat (fn (buffer-substring-no-properties pos1 pos2)))
    (delete-region pos1 pos2)
    (insert  meat)    
    )
)

我得到:Symbol's function definition is void: fn

我是否愚蠢地假设在 Emacs Lisp 中可以进行柯里化!?还是我只是做错了?

4

2 回答 2

8

I wish to add that in Emacs lisp currying is not possible -- function application is not currying, because it does not follow the curry's formula.

Currying means to apply a function to partial arguments, and return another function. This is not possible in Elisp, due to the dynamic scope.

EDIT: UPDATE

Now emacs-gnu has closures.

于 2013-01-30T08:47:38.370 回答
5

首先,emacs-lisp 是一个 2-lisp,有点,排序,所以以下是无效的:

(defun foo (fn)
  (fn 3)) ;; DOES NOT WORK!

相反,您必须执行以下操作:

(defun foo (fn)
  (funcall fn 3))

所以如果你(setq meat (fn(setq meat (funcall fn代码替换应该可以工作。

于 2013-01-30T08:12:48.370 回答