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-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*)
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*)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With