开发者

Porting a piece of Lisp code to Clojure (PAIP)

I'm reading Paradigms of Artificial Intelligence Programming (PAIP) by Peter Norvig and I'm trying to write all the code in Clojure rather than common Lisp. However I'm stuck on this piece of code on page 39:

(defparameter *simple-grammar*
  '((sentence -> (noun-ph开发者_开发问答rase 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*)

How can I translate this into Clojure? Thanks.


I'm a relative Clojure newbie that went through this exact exercise a while back. Something to consider here is whether you'd like to adhere as closely as possible to Norvig's code (like writing "Common-Lisp-flavored" Clojure) or if you'd like to write something closer to idiomatic Clojure. Here's what I did:

(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 is sugar that allows you to add docstrings to vars more naturally. In this case I'm using a map (key value pairs delimited by {}) to get dictionary-style lookup from the LHS of each rule to the RHS. I'm also using vectors (delimited by []) instead of lists to represent the RHS of each rule. Generally speaking, "idiomatic" Clojure code rarely uses lists to hold sequential data; vectors are preferred unless you're representing Clojure forms (source code).

These kinds of changes will allow you to use more of the built-in power of the language instead of e.g., having to write little helper functions to manipulate nested lists.


Ken's right, just a simple few changes to the def* forms, and a different style of docstring (docstrings are a bit simpler for function definitions than for normal vars):

(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*)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜