【问题标题】:pretty printing and expansion漂亮的打印和扩展
【发布时间】:2012-05-11 19:41:11
【问题描述】:

编辑我不只是询问“缩进”每一行代码,而是询问“漂亮的打印”和/或更广泛的“缩进”定义,其中行将是根据它们包含的内容进行分组/拆分。

这是一个函数(我写它是为了解决欧拉问题,但这不是重点:我可以用不同的方式编写它),我正在尝试打印它:

版本手动缩进:

(apply max
       (flatten
        (for [x (range 100 1000)]
          (map
           #(if (= (str (* x %)) (apply str (reverse (str (* x %)))))
              (* x %)
              0)
           (range x 1000)))))

显然,这不是一种真正的 Lisp 缩进/打印样式,而且我想从一开始就养成良好的习惯,所以我尝试“漂亮地打印”它,从 Emacs 的 slime 中执行以下操作-repl clojure REPL:

user> (doc pprint)      ;; just to show which version of pprint I'm using
clojure.pprint/pprint
...

所以我尝试这样做:

user> (pprint '(apply max
       (flatten
        (for [x (range 100 1000)]
          (map
           #(if (= (str (* x %)) (apply str (reverse (str (* x %)))))
              (* x %)
              0)
           (range x 1000))))))

我得到了以下信息:

(apply
 max
 (flatten
  (for
   [x (range 100 1000)]
   (map
    (fn*
     [p1__13958#]
     (if
      (=
       (str (* x p1__13958#))
       (apply str (reverse (str (* x p1__13958#)))))
      (* x p1__13958#)
      0))
    (range x 1000)))))

据我了解,lambda 的 #(...) 符号是“阅读器宏”。那么如何在不触发宏扩展的情况下进行漂亮的打印呢?更一般地说:我怎样才能漂亮地打印“我在文本编辑器中看到的内容”?

另外,几乎所有事情都在一个新的线路上进行是正常的吗?例如:

(apply
 max
 (flatten
  (for
   [x (range 100 1000)]
   (map
    ...

似乎浪费了相当多的垂直屏幕空间。这是 Lisp 代码应该缩进的方式吗?

还有一个相关的问题:Emacs 能否配置为“漂亮打印”选定区域或整个 .clj 缓冲区?

【问题讨论】:

    标签: emacs macros clojure read-eval-print-loop pretty-print


    【解决方案1】:

    没有“官方”缩进 lisp 代码的方式,但我喜欢 clojure-mode 缩进 clojure 代码的方式(见下文)。

    我不知道为什么 pprint 会以这种方式打印代码,但根据this 页面,它是一个早期版本,功能还不完整。

    对于 emacs 缩进部分,你可能想看看clojure-mode

    【讨论】:

    • “没有“官方”的方式来缩进 lisp 代码没有“官方”的方式来缩进 Lisp 代码”...啊...我以为有一个。或者至少是一种“文化上”接受的方式。例如,人们普遍认为永远不应该将右括号放在换行符上:没有一个“漂亮的打印机”会这样做,而且知识渊博的 Lisp 程序员编写的 Lisp 代码也几乎不会这样做。如果没有“官方”标准,那么我将采用“最常见”的方式来格式化 Lisp 代码; )
    • Clojure-mode 的缩进可能与此接近。它或多或少与 clojure.org 和许多库中使用的缩进相同。
    【解决方案2】:

    我所见过的最接近共识的是“像 Emacs 一样缩进”,我想在政治上是正确的,我应该包括推论“像 vim 一样缩进”。 eclipse+CCW 等其他编辑器似乎与此相当接近。尽管默认的漂亮打印机添加了更多换行符。

    【讨论】:

    • 我 +1 了但仍然...为什么 pprint 扩展 lambda?这是它应该如何工作的?
    【解决方案3】:

    这是我目前正在做的事情:

    (defn pprint-code [code]
      (with-pprint-dispatch code-dispatch
        (binding [*print-suppress-namespaces* true]
          (pprint code))))
    

    注意:查看 clojure.pprint 以解析免费变量。

    这当然是一种改进。我仍然不知道如何调整*print-miser-width* 和/或*print-right-margin* 以获得更好的输出。 YMMV。我目前的牛肉是(自动)gensyms - 我希望在某些情况下打印时将它们解开。

    理想情况下,表单/函数可以定义自己的格式规则,例如let-bindings 应该总是在不同的行上。我不知道能否使用 clojure.core 做到这一点。

    有关参考,请参阅此overview

    【讨论】:

      猜你喜欢
      • 2011-03-20
      • 2013-02-07
      • 2021-06-22
      • 1970-01-01
      • 2016-07-07
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      相关资源
      最近更新 更多