clisp: variable x has no value - lisp

I'm receiving the error variable MAP has no value in my Common Lisp code (I am using the clisp shell in the Ubuntu terminal). My code looks like this (*map* is just an association list, so you can skip over it):
(setf *map* '((shore (stars cast reflections on the rippling sea.
it fills you with a strong but unplaceable emotion.)
(east forest))
(forest (a roof of treetops blots out the sun. something rustles
behind you.)
(west shore)
(north cliff))
(cliff (you nearly stumble into a long and fatal fall into the
sea far below you. you feel a strange urge to throw
yourself off the ledge. it would probably wisest to
leave this place.)
(south forest))))
(defun walk-direction (direction room map)
(second (assoc direction (cddr (assoc room map)))))
(defmacro defspel (&rest rest) `(defmacro ,#rest))
(defspel walk-to (direction room map)
`(walk-direction ',direction ',room map))
(walk-to east shore *map*)
(I'm following the liserpati tutorial, for those wondering about any oddities I might be committing)
If change walk-to to
(defspel walk-to (direction room)
`(walk-direction ',direction ',room *map*))
then everything goes perfectly well. However, this breaks the beautiful convention of functional programming which I would like to keep as intact as possible-- not to mention the fact that I still have no idea why my code doesn't work.

The definition of walk-to is missing a comma before map. Take a look at the output of:
(macroexpand-1 '(walk-to east shore *map*))

Let's take a look at:
(defspel walk-to (direction room map)
`(walk-direction ',direction ',room map))
Here, the symbol map is inside a backquote, and it isn't unquoted. This means that it is just a literal datum. It has no connection to the map argument of the walk-to spell.
The generated walk-direction code evaluates in an environment in which the map argument is no longer visible; it is treated as a free variable reference which expects a global variable to exist.
When you change map to *map* you fix part of the problem; the generated code then refers to the dynamic variable *map* in the global environment.
But this is still broken, because walk-to is supposed to generate code which uses the map which is passed in, which is not necessarily the global map (or else why have a parameter).
You probably want this:
(defspel walk-to (direction room map)
`(walk-direction ',direction ',room ,map))
So that, for instance, the call (walk-to north shore *map*) will generate the code (walk-direction 'north 'shore *map*). The walk-to macro quotes the direction and room symbols for you, but should not quote *map*, since that is Lisp variable which we need to evaluate to the map object it represents, and not a game symbol like north.

Related

How can I make a Racket reader macro to transform any instance of one character into two other characters?

More specifically, I need any instance of | to be transformed into \|. I tried reading the documentation on reader macros and I am extremely lost. Can somebody explain this in understandable terms, or ideally show me how to write such a macro.
You're essentially destroying the usual meaning of | in the usual syntax, so you should really do that in some uniform way to minimize surprises. Your solution doesn't do that -- it treats | differently based on whether it's the first thing or not, and that's bad. For example, xxx|xxx reads it as a character in the whole symbol which means that you get a symbol with a name of "xxx|xxx", but with an input of |xxx you get two symbols, with names of "|" and "xxx" respectively. It's therefore better to just make your syntax treat | as other characters to get a more consistent and easier-to-explain behavior.
Another possible problem with your code is your use of #f as a readtable, which means that the reader is not going to compose with a reader that is potentially modified.
And finally, you should really pay attention to the extra arguments and return a syntax object when they're given. The reason for that is obvious, and my guess is that your reason for not doing so is that you're interested in just reading such code. But you should really have one eye looking at potential extensions, and in Racket, and obvious future for such code would be to make up a proper language instead of a read+eval hack. It's true that it might seem like an overkill, but in this case there is a simple solution of using the "same as this other character" shortcut to avoid writing lengthy code.
The following addresses all of these:
(define rt (let ([c (current-readtable)]) (make-readtable c #\| #\a c)))
Figured it out! Here is the code to adjust the (read) function to change all instances of | into \|:
(define rt2 (make-readtable #f #\| 'non-terminating-macro
(lambda (c in . _)
'\|)))
(parameterize ([current-readtable rt2]
[current-namespace ns])
(eval (read)))

good style in lisp: cons vs list

Is it good style to use cons for pairs of things or would it be preferable to stick to lists?
like for instance questions and answers:
(list
(cons
"Favorite color?"
"red")
(cons
"Favorite number?"
"123")
(cons
"Favorite fruit?"
"avocado"))
I mean, some things come naturally in pairs; there is no need for something that can hold more than two, so I feel like cons would be the natural choice. However, I also feel like I should be sticking to one thing (lists).
What would be the better or more accepted style?
What you have there is an association list (alist). Alist entries are, indeed, often simple conses rather than lists (though that is a matter of preference: some people use lists for alist entries too), so what you have is fine. Though, I usually prefer to use literal syntax:
'(("Favorite color?" . "red")
("Favorite number?" . "123")
("Favorite fruit?" . "avocado"))
Alists usually use a symbol as the key, because symbols are interned, and so symbol alists can be looked up using assq instead of assoc. Here's how it might look:
'((color . "red")
(number . "123")
(fruit . "avocado"))
The default data-structure for such case should be a HASH-TABLE.
An association list of cons pairs is also a possible variant and was widely used historically. It is a valid variant, because of tradition and simplicity. But you should not use it, when the number of pairs exceeds several (probably, 10 is a good threshold), because search time is linear, while in hash-table it is constant.
Using a list for this task is also possible, but will be both ugly and inefficient.
You would need to decide for yourself based upon circumstances. There isn't a universal answer. Different tasks work differently with structures. Consider the following:
It is faster to search in a hash-table for keys, then it is in the alist.
It is easier to have an iterator and save its state, when working with alist (hash-table would need to export all of its keys as an array or a list and have a pointer into that list, while it is enough to only remember the pointer into alist to be able to restore the iterator's state and continue the iteration.
Alist vs list: they use the same amount of conses for even number of elements, given all other characters are atoms. When using lists vs alists you would have to thus make sure there isn't an odd number of elements (and you may discover it too late), which is bad.
But there are a lot more functions, including the built-in ones, which work on proper lists, and don't work on alists. For example, nth will error on alist, if it hits the cdr, which is not a list.
Some times certain macros would not function as you'd like them to with alists, for example, this:
(destructuring-bind (a b c d)
'((100 . 200) (300 . 400))
(format t "~&~{~s~^,~}" (list a b c d)))
will not work as you might've expected.
On the other hand, certain procedures may be "tricked" into doing something which they don't do for proper lists. For instance, when copying an alist with copy-list, only the conses, whose cdr is a list will be copied anew (depending upon the circumstances this may be a desired result).

Lisp symbols without package bindings

I've been working on some project. It should be able to do numerical and symbolic computing. But now I stuck on one problem and I don't really know how to resolve it. To be specific and short, let's say we are in package
(in-package #:brand-new-package)
Where we have symbol database
(defvar var-symbol-database (make-hash-table :test #'equal))
Reading and setting functions
(defun var-symbol (name)
(get-hash name var-symbol-database))
(defun set-var-symbol (name value)
(setf (get-hash name var-symbol-database) value))
(set-var-symbol 'temperature 300) ;K
(set-var-symbol 'f 200) ;Hz
(set-var-symbol 'k 1.3806504e-23) ;J K^-1
and now in another file (but same package) I will try to evaluate this equation
(eval '(+ 2 (var-symbol 'f)))
It won't work. Problem is that for some particular reason the value of key in hash table is.
brand-new-package::f
I though that I will solve the problem defining function like this
(set-var-symbol 1 '(var-symbol 'f)) ;Hz
But it is interpreted as
(brand-new-package::var-symbol brand-new-package::f)
The problem is that program can create many different symbols. It will compute electronic circuit equations. Program first inspect device objects like capacitors, resistors and so. It create circuit tablo by MNA.
During it many new symbols representing node voltages and currents could be created
(v1, v2, v3, i1, i2).
I needed some method to hold count and names of variables presented in equation. Because they will be passed to symbolic derivator ie (diff '(* (+ 40 v1) u2 ...) 'v1)) I came with an idea, maybe wrong, to make them reachable by index to define them as a list
'(v 1) '(v 2) '(v 3).
To make them evaluable I added to begining var-variable funcall. So list becomed
'(var-variable v 1) '(var-variable v 2) '(var-variable v 3)
But as I have written, system changes it to
'(brand-new-package::var-variable brand-new-package::v 1) '(brand-new-package::var-variable brand-new-package::v 2) '(brand-new-package::var-variable brand-new-package::v 3)
How to allow to users to acces these variables by typing (var-symbol 'v 1). I can imagine only one way. Instead of symbols use strings and export function (var-symbol). Then it will work this way
'(var-variable "v" 1)
But it is a little bit confusing.
You are duplicating what Lisp already does. Symbols are already managed in tables, called packages. A symbol can have a value. Putting it into a package is INTERN. Finding it is FIND-SYMBOL or just using the Lisp READer.
If you want your own symbol index tables, hash tables are fine. If you don't want to deal with packages of those symbols, then just use keyword symbols. They have a single colon in front. :temperature would be an example. Keyword symbols are automagically in the package KEYWORD and they evaluate to themselves.
What you state to be a "problem" is as expected. The Common Lisp notation brand-new-package::var-symbol signifies that the symbol var-symbol is in the package brand-new-package, which was the current package at the time the symbol was read by the lisp.

Strange Lisp Quoting scenario - Graham's On Lisp, page 37

I'm working my way through Graham's book "On Lisp" and can't understand the following example at page 37:
If we define exclaim so that its return value
incorporates a quoted list,
(defun exclaim (expression)
(append expression ’(oh my)))
> (exclaim ’(lions and tigers and bears))
(LIONS AND TIGERS AND BEARS OH MY)
> (nconc * ’(goodness))
(LIONS AND TIGERS AND BEARS OH MY GOODNESS)
could alter the list within the function:
> (exclaim ’(fixnums and bignums and floats))
(FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)
To make exclaim proof against such problems, it should be written:
(defun exclaim (expression)
(append expression (list ’oh ’my)))
Does anyone understand what's going on here? This is seriously screwing with my mental model of what quoting does.
nconc is a destructive operation that alters its first argument by changing its tail. In this case, it means that the constant list '(oh my) gets a new tail.
To hopefully make this clearer. It's a bit like this:
; Hidden variable inside exclaim
oh_my = oh → my → nil
(exclaim '(lions and tigers and bears)) =
lions → and → tigers → and → bears → oh_my
(nconc * '(goodness)) destructively appends goodness to the last result:
lions → and → tigers → and → bears → oh → my → goodness → nil
so now, oh_my = oh → my → goodness → nil
Replacing '(oh my) with (list 'oh 'my) fixes this because there is no longer a constant being shared by all and sundry. Each call to exclaim generates a new list (the list function's purpose in life is to create brand new lists).
The observation that your mental model of quoting may be flawed is an excellent one—although it may or may not apply depending on what that mental model is.
First, remember that there are various stages to program execution. A Lisp environment must first read the program text into data structures (lists, symbols, and various literal data such as strings and numbers). Next, it may or may not compile those data structures into machine code or some sort of intermediary format. Finally, the resulting code is evaluated (in the case of machine code, of course, this may simply mean jumping to the appropriate address).
Let's put the issue of compilation aside for now and focus on the reading and evaluation stages, assuming (for simplicity) that the evaluator's input is the list of data structures read by the reader.
Consider a form (QUOTE x) where x is some textual representation of an object. This may be symbol literal as in (QUOTE ABC), a list literal as in (QUOTE (A B C)), a string literal as in (QUOTE "abc"), or any other kind of literal. In the reading stage, the reader will read the form as a list (call it form1) whose first element is the symbol QUOTE and whose second element is the object x' whose textual representation is x. Note that I'm specifically saying that the object x' is stored within the list that represents the expression, i.e. in a sense, it's stored as a part of the code itself.
Now it's the evaluator's turn. The evaluator's input is form1, which is a list. So it looks at the first element of form1, and, having determined that it is the symbol QUOTE, it returns as the result of the evaluation the second element of the list. This is the crucial point. The evaluator returns the second element of the list to be evaluated, which is what the reader read in in the first execution stage (prior to compilation!). That's all it does. There's no magic to it, it's very simple, and significantly, no new objects are created and no existing ones are copied.
Therefore, whenever you modify a “quoted list”, you're modifying the code itself. Self-modifying code is a very confusing thing, and in this case, the behaviour is actually undefined (because ANSI Common Lisp permits implementations to put code in read-only memory).
Of course, the above is merely a mental model. Implementations are free to implement the model in various ways, and in fact, I know of no implementation of Common Lisp that, like my explanation, does no compilation at all. Still, this is the basic idea.
In Common Lisp.
Remember:
'(1 2 3 4)
Above is a literal list. Constant data.
(list 1 2 3 4)
LIST is a function that when call returns a fresh new list with its arguments as list elements.
Avoid modifying literal lists. The effects are not standardized. Imagine a Lisp that compiles all constant data into a read only memory area. Imagine a Lisp that takes constant lists and shares them across functions.
(defun a () '(1 2 3)
(defun b () '(1 2 3))
A Lisp compiler may create one list that is shared by both functions.
If you modify the list returned by function a
it might not be changed
it might be changed
it might be an error
it might also change the list returned by function b
Implementations have the freedom to do what they like. This leaves room for optimizations.

What does "my other car is a cdr" mean?

Can anyone well versed in lisp explain this joke to me?
I've done some reading on functional programming languages and know that CAR/CDR mean Contents of Address/Decrement Register but I still don't really understand the humour.
In Lisp, a linked list element is called a CONS. It is a data structure with two elements, called the CAR and the CDR for historical reasons. (Some Common Lisp programmers prefer to refer to them using the FIRST and REST functions, while others like CAR and CDR because they fit well with the precomposed versions such as (CADR x) ≡ (CAR (CDR x)).
The joke is a parody of the bumper stickers you sometimes see on beat-up old cars saying "My other car is a Porsche/BMW/etc."
My response to this joke has always been "My other CAR is a CADR. CDR isn't a CAR at all."
Yes, definitely a geek joke.
The names come from the IBM 704, but that's not the joke.
The joke is (bad) pun on "my other car is a ___." But the in-joke is about recursion.
When you loop/manipulate/select/invoke/more in lisp you use a combination of car (the first element in the list) and cdr (the rest of the list) to juggle functions.
So you've got a car, but your other car is your cdr because you can always get a car from a cdr since the cdr is always (in recursion) more elements. Get it? Laugh yet?
You'll probably have to learn lisp to actually chuckle a bit, or not. Of course, by then, you'll probably find yourself chuckling randomly for no apparent reason because:
Lisp makes you loopy.
//Coming from Scheme
Scheme has very few data structures, one of them is a tuple: '(first . second). In this case, car is the first element, and cdr is the second. This construct can be extended to create lists, trees, and other structures.
The joke isn't very funny.