将一段Lisp代码移植到Clojure(PAIP)

时间:2010-12-31 22:48:43

标签: clojure lisp artificial-intelligence common-lisp

我正在阅读Peter Norvig撰写的人工智能编程范式(PAIP),我正在尝试用Clojure编写所有代码,而不是使用常见的Lisp。但是我仍然坚持第39页的这段代码:

(defparameter *simple-grammar*
  '((sentence -> (noun-phrase verb-phrase))
   (noun-phrase -> (Article Noun))
   (verb-phrase -> (Verb noun-phrase))
   (Article -> the a)
   (Noun -> man ball woman table)
   (Verb -> hit took saw liked))
  "A grammar for a trivial subset of English.")

 (defvar *grammar* *simple-grammar*)

如何将其翻译成Clojure? 感谢。

2 个答案:

答案 0 :(得分:12)

我是一名相对的Clojure新手,经过一段时间的精确练习。这里需要考虑的是你是否愿意尽可能地遵守Norvig的代码(比如写“Common-Lisp-flavored”Clojure),或者你是否想要写一些更接近惯用语Clojure的东西。这是我做的:

(use '[clojure.contrib.def :only [defvar]])

(defvar *simple-grammar* 
  {:sentence [[:noun-phrase :verb-phrase]]
   :noun-phrase [[:Article :Noun]]
   :verb-phrase [[:Verb :noun-phrase]]
   :Article ["the" "a"]    
   :Noun ["man" "ball" "woman" "table"]
   :Verb ["hit" "took" "saw" "liked"]}
  "A grammar for a trivial subset of English.")
defvar是糖,允许您更自然地将文档字符串添加到变量。在这种情况下,我使用地图(由{}分隔的键值对)从每个规则的LHS到RHS进行字典式查找。我也使用向量(由[]分隔)而不是列表来表示每个规则的RHS。一般来说,“惯用语”Clojure代码很少使用列表来保存顺序数据;除非你代表Clojure表格(源代码),否则首选矢量。

这些类型的更改将允许您使用该语言的更多内置功能,而不是例如必须编写小辅助函数来操作嵌套列表。

答案 1 :(得分:5)

Ken是正确的,只是对def *表单进行了一些简单的更改,以及不同的docstring样式(docstrings对于函数定义比对普通变量更简单):

(def ^{:doc "A grammar for a trivial subset of English."} 
  *simple-grammar*
  '((sentence -> (noun-phrase verb-phrase))
    (noun-phrase -> (Article Noun))
    (verb-phrase -> (Verb noun-phrase))
    (Article -> the a)
    (Noun -> man ball woman table)
    (Verb -> hit took saw liked)))

(def *grammar* *simple-grammar*)