我正在阅读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? 感谢。
答案 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*)