9

它改变

(a b c d (1 2 |3 4) ha ha ha)

进入

|(1 2 (a b c d 3 4 ha ha ha))

这种转变有什么用?

4

4 回答 4

17

也只是关于实际使用的快速补充,您可能想查看本教程的 1:40 分钟:http: //emacsrocks.com/e14.html

打电话给M-?将光标放在 do-something 的开头扩大了 let 的范围,由此:

(defun my-other-command ()
  (when (and (this-predicate)
             (that-predicate))
    (let ((v (calculate-v))
          (x (calculate-x)))
      (do-something)
      (do-some-more)
      (do-a-third-thing))))

直接到这个:

(defun my-other-command ()
  (let ((v (calculate-v))
        (x (calculate-x)))
    (when (and (this-predicate)
               (that-predicate))
      (do-something)
      (do-some-more)
      (do-a-third-thing))))

干杯!安德烈斯

于 2015-01-30T15:22:56.607 回答
7

严格来说,它用于反转内部表达式的嵌套。

举个例子:

(let [foo bar] (if a b| c))

变成

(if a b (let [foo bar]| c))

至于用例,我从来没有专门使用它,但它是更大宏的一个很好的构建块

于 2013-08-12T16:30:57.373 回答
3

添加到尼尔克的答案

对于 smartparens 用户,M-x sp-prefix-save-excursion M-x sp-convolute-sexp更改

(let [foo bar] (if a b| c))

(let [foo bar] (if a b |c))

进入

(if a b (let [foo bar] |c))

对于 paredit 用户,M-x paredit-convolute-sexp更改

(let [foo bar] (if a b| c))

(let [foo bar] (if a b |c))

进入

|(if a b(let [foo bar]  c))

|(if a b (let [foo bar] c))

对于那些都不使用的人,如果您包含,您仍然可以使用卷积命令

(require 'paredit)
(require 'smartparens)

在 init 文件中,仅这两行就不会将您的 Emacs 设置为使用 paredit 模式或 smartparens 模式,所以一切都很好。如果您从包存档安装 paredit 包,则自动加载文件可能会或可能不会将 Emacs 设置为使用 paredit 模式,并且 paredit 没有自定义界面。如果您安装 smartparens 包,无论 autoloads 文件做什么,您都可以使用自定义界面将 smartparens-global-mode 设置为 nil,如果它的默认值不是 nil(虽然现在默认是 nil)。

于 2013-08-13T00:48:48.603 回答
2

let大多数示例都显示范围缩小,但如果您意识到您在 an 中有一个表单if并且意识到您在表单的另一个分支中也需要这些绑定,我希望您很可能会使用它if

假设你是一个巨魔,你找到了一个看起来很美味的小偷。

(defn eat-hobbit [hobbit]
  (if (is-cooked? hobbit)
    (eat! hobbit)
    (let [is-fat (< too-greasy (:fat-content hobbit))]
      (if is-fat
        (eat! (deep-fry hobbit))
        (eat! (saute hobbit))))))

你意识到你可能应该做出更好的健康选择,而不是只吃你遇到的每一个霍比特人,无论是否煮熟,所以你决定首先根据它的脂肪程度决定是否吃霍比特人。is-fat在决定吃之前你需要知道!所以,你想提升它let。将光标放在绑定向量之后的(let [is-fat ...]and M-?(并用 清理空格M-j M-q):

(defn eat-hobbit [hobbit]
  (let [is-fat (< too-greasy (:fat-content hobbit))]
    (if (is-cooked? hobbit)
      (eat! hobbit)
      (if is-fat
        (eat! (deep-fry hobbit))
        (eat! (saute hobbit))))))

你还没有做出更好的食物选择,但现在绑定在正确的范围内,可以做出更好的决定。

让我们再试一次。我们真的应该先问霍比特人是否胖,所以将光标放在(if is-fatand之后M-?(并M-j M-q再次清理):

(defn eat-hobbit [hobbit]
  (let [is-fat (< too-greasy (:fat-content hobbit))]
    (if is-fat
      (if (is-cooked? hobbit)
        (eat! hobbit)

        (eat! (deep-fry hobbit))
        (eat! (saute hobbit))))))

唔。这还不是很有效——其中有一个额外的形式if——但它非常接近我们想要的位置。在这一点上,我们可以轻松地使用更常见的 paredit 绑定来 barf、转置和/或杀死 中的额外形式if,这取决于我们对健康饮食的意图有多真诚。为简洁起见,我们还可以将这两种if形式拼接在一起。

于 2018-10-02T00:34:47.750 回答