在emacs lisp中调整函数

oco*_*odo 7 elisp emacs24

我有很多方便的功能,可以在当前的单词或区域上运行,并且由于懒惰等等,我用模板构建它们......

例如

(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)    
    )
  )
Run Code Online (Sandbox Code Playgroud)

实际上这是所有锅炉板,除了这条线......

(setq meat (s-lower-camel-case (buffer-substring-no-properties pos1 pos2)))
Run Code Online (Sandbox Code Playgroud)

我调用s-lower-camel-case缓冲区子串的地方.我想重用at点或区域的东西,但是没有在任何地方重复它(因为那是愚蠢的,并且很难维护.)

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

当我试着这个......

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

随着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)    
    )
)
Run Code Online (Sandbox Code Playgroud)

我明白了: Symbol's function definition is void: fn

我愚蠢地假设在Emacs Lisp中可以使用currying!?或者我只是做错了?

ali*_*oar 8

我想补充一点,在 Emacs lisp 中咖喱是不可能的——函数应用程序不是咖喱,因为它不遵循咖喱公式。

柯里化意味着将函数应用于部分参数,并返回另一个函数。由于动态范围,这在 Elisp 中是不可能的。

编辑:更新

现在 emacs-gnu 有闭包了。


Vat*_*ine 5

首先,emacs-lisp有点儿是2-lisp,因此以下内容无效:

(defun foo (fn)
  (fn 3)) ;; DOES NOT WORK!
Run Code Online (Sandbox Code Playgroud)

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

(defun foo (fn)
  (funcall fn 3))
Run Code Online (Sandbox Code Playgroud)

所以,如果你更换(setq meat (fn(setq meat (funcall fn的代码应该工作。