Scheme: "expects 1 argument, given 4" odd behavior - lisp

To implement depth-first search in a grid, I wrote a function like this
(define (expand dim node visited obs)
(not-in (neighbor dim obs node) visited))
The function dfs is
(dfs dim obs visited fringe path goal)
The only appearance of expand in dfs is
(expand dim (car fringe) visited obs)
And I called dfs using
(dfs '(5 5) '((2 2) (3 2)) '((2 1)) '((1 1) (3 1)) '((2 1)) '(4 5))
dim is the dimension of the grid, obs is a list of the blocked positions in the grid.
When I call expand by hand it works perfectly. But when it's called in dfs, it says "expand: expects 1 argument, given 4: '(5 5) '(1 1) '((2 1)) '((2 2) (3 2) (3 4) (4 4) (5 4))"
However, if I change the position of arguments of expand, e.g. put obs as the second argument,
(define (expand dim obs node visited)
(not-in (neighbor dim obs node) visited))
and modify dfs and my callings correspondingly, then the error won't appear and everything works well. Then next time I launch DrRacket and paste the modified code into it, the same error reappears. If I swap obs back, it works well again...
What on earth is happening here?! Thanks!

expand is an awfully generic name that might have a definition somewhere else. Rename your funciton to dfs-expand and see if this fixes it.

It looks like this is the same problem you're having in this question. As is the case there, expand is a function that is already defined in Racket, but writing your own definition should still work fine. So like I said there, you should describe exactly what you're doing to know why you have these problems in the first place.

Related

push does not work as I would expect it - why?

I am experiencing a behavior of the push function that I don't get. Maybe someone could explain to me why Lisp behaves this way.
Supposed I define a list as a global variable, and then try to push a new value to it using the following code:
(defparameter *primes* '(3 5 7 11))
(push 2 *primes*)
Then *primes* is now (2 3 5 7 11). So far, so good.
Now I try to do the same thing, but without the *primes* variable, i.e.:
(push 2 '(3 5 7 11))
The result is an error message:
EVAL: 3 is not a function name; try using a symbol instead
Now I have two questions:
Why does this not work? I would expect that push returns the list (2 3 5 7 11), why does this not happen? Where am I wrong?
Apart from that, I don't get the error message. What is Lisp trying to tell me with 3 is not a function name? Of course, 3 is not a function name, but I don't try to call a function named 3 anywhere, do I?
Any help is appreciated :-)
If you read the CL Hyperspec for PUSH, you will read that push expects a place.
A place is something like a variable, a structure slot, a class slot, an array access, or similar. Since Lisp uses linked cons cells for lists, it does not make sense to push something in front of a cons cell, without a reference for that.
So above is simple: we can't push to a direct list.
Why this error message?
This gets a bit complicated...
(push 2 '(3 5 7 11))
Is actually:
(push 2 (quote (3 5 7 11))
A function can be a place, it then needs a corresponding setter function. Here the setter is thought to be (setf quote) - that's right, Common Lisp can sometimes have lists as function names, not only symbols.
If we look at the macroexpansion of above:
? (pprint (macroexpand '(push 2 (quote (3 5 7 11)))))
(LET* ((#:G328 2) (#:G327 (3 5 7 11)) (#:G326 (CONS #:G328 '#:G327)))
#:G327
#:G326
(FUNCALL #'(SETF QUOTE) #:G326 #:G327))
You can see that it tries to call the setter. But it also thinks that (3 5 7 11) is a Lisp form.
I give you an example, where it actually works, but we don't use quote, but a real accessor function:
CL-USER 40 > (let ((v (vector (list (list 'a 'b 'c) (list 'd 'e 'f))
(list (list 1 2 3) (list 4 5 6)))))
(print v)
(push 42 (first (aref v 1)))
(print v)
(values))
#(((A B C) (D E F)) ((1 2 3) (4 5 6)))
#(((A B C) (D E F)) ((42 1 2 3) (4 5 6)))
In above first is the getter and CL knows the corresponding setter. The form (aref v 1) is the call and returns the index 1 element of the vector. We are then pushing to the first list of the element.
Your call has a similar structure and (3 5 7 11) is at a similar position as (aref v 1). The Lisp system says that in (3 4 7 11) then number 3 is not a valid function. Which is correct. But the real error was about the push operation. Since the macro could not detect the error, the error gets later detected in the macro expanded code.
I have found only the emacs lisp manual push, but I guess it behaves similar for Common Lisp
— Macro: push element listname
This macro creates a new list whose car is element and whose cdr is the list specified by listname, and saves that list in listname.
So it seems push is modifying its argument listname, which isn't possible with a literal list. To do what you have in mind, one would use cons instead.
To the second part 3 is not a function name, I would say push, or some function inside it, tries to evaluate the literal list. Evaluating (3 5 7 11) means, call the function 3 with arguments 5 7 11. Hence the error message.
Again from emacs, Ctrl-h f push
push is a Lisp macro in `cl.el'.
(push X PLACE)
Insert X at the head of the list stored in PLACE.
Analogous to (setf PLACE (cons X PLACE)), though more careful about
evaluating each argument only once and in the right order. PLACE may
be a symbol, or any generalized variable allowed by `setf'.
setf in turn allows place to be a
symbolic references such as (car x) or (aref x i)
which explains, why push evaluates the second argument.
I think you need CONS in second case:
(cons 2 '(3 5 7 11)) => (2 3 5 7 11)

Can I make a macro that expands into more than one value?

Is there a way to define a racket macro foo so that
(list 1 (foo 2 3) 4)
expands into
(list 1 2 3 4)
?
It's currently not possible (and seems unlikely to change in the near future).
Here's one thread discussing this. See in particular the answer by Matthew Flatt:
allowing splicing of results in function-call
subexpressions would break equivalences that are currently exploited by
macros and the compiler.
As other answers have mentioned, you cannot have a macro expand into more than one value, and have that spliced into the calling context. But you can do something similar using quasiquotation.
Assuming your macro is adapted to return a list instead, you can do this (for your given example):
`(1 ,#(foo 2 3) 4)
Example (tested in Racket):
> `(1 ,#(map sqrt '(2 3)) 4)
'(1 1.4142135623730951 1.7320508075688772 4)

Using Paredit to wrap existing expression

I'm using Emacs in Paredit mode for Lisp code.
I'm trying to wrap a function call in println:
(square 5)
(println (square 5))
What ends up happening in paredit is this:
(square 5)
(println) (square 5)
There is no way i can delete closing paren of println and move it to the end.
The way i'm doing it now is to:
1. delete function call and yank it within println
2. write println without paren, visually select code and enclose in parens
(square 5)
println (square 5)
=> select block of code and type (
(println (square 5))
Both of these approaches are tedious. This seems to be a common problem anytime i write code inside out in Paredit. Any help would be appreciated
paredit-wrap-round command may help (bound to M-( in the paredit version I use).
In contrast to the other answers, I tend to use Ctrl-Right for this: after you get
(println|) (square 5)
(where | is where the cursor is), I simply press Ctrl-Right to get the correct result.
M-(
You can call paredit-insert-html-examples to generate a HTML webpage cheatsheet. One version is here.
Three ways to wrap a print form around a square form, in step-by-step progressions. (two ways of the three are already mentioned in other answers)
(1) Cut & type & paste
(+ (square 3) 4)
;;; make sure cursor is at right place (| is cursor)
(+ |(square 3) 4)
;;; mark-sexp and kill-region
(+ | 4)
;;; type the print form and make sure cursor is at right place
(+ (print |) 4)
;;; paste
(+ (print (square 3)) 4)
(2) type & slurf
(+ (square 3) 4)
;;; make sure cursor is at right place (| is cursor)
(+ |(square 3) 4)
;;; type the print form and make sure cursor is at right place
(+ (print|) (square 3) 4)
;;; paredit-forward-slurp-sexp
(+ (print (square 3)) 4)
(3) wrap & type
(+ (square 3) 4)
;;; make sure cursor is at right place (| is cursor)
(+ |(square 3) 4)
;;; paredit-wrap-round
(+ (|(square 3)) 4)
;;; type print
(+ (print (square 3)) 4)
Cut & type & paste is the most tedious. It doesn't depend on paredit and is the easiest to generalize to the case of wrapping a complex outer form around more than one inner forms which may be in multiline format, for example, turning
(let ((x 1))
(moo)
(oink)
(oink))
into
(let ((x 1))
(moo)
(mapc (lambda (x)
(oink)
(oink))
(list 1 2 3)))
by wrapping a mapc-over-lambda form around two oinks.
Type & slurf seems to be the most known. It can be generalized to the mapc-over-lambda case as well.
Wrap & type is the most easiest to type. When you generalize this to the map-over-lambda case, you select two oinks, and press ( to wrap it, and finish writing the lambda form, and select the lambda form, press ( to wrap it, type mapc, and you can use C-M-f to cross over the lambda form and type (list 1 2 3).
In your case the solution is M-2 M-( or M-( C-).
There are several ways of doing this. The way that I normally do this is type
"("
which gets you
()println
and then C-S-) which gets you
(println)
The best way to use paredit to start is to have the paredit cheatsheet on a piece of paper stuck to the side of your monitor. Or, you could also install paredit-menu which adds a menu item with tooltips showing the same examples the cheetsheet does.
I use M-C-(, which will immediately wrap the following sexp in parens.

Lisp initialize variable with list

I'm learning Lisp. I'm implementing solution to some relatively simple problem. I'm thinking of list that represents initial state of problem like this
((0 1) (2 3) (5 4))
I want to create variable and assign that list to it. I've tried
(let ((initial-state ((0 1) (2 3) (5 4)))))
but this won't compile. After that I've tried
(let ((initial-state list (list 0 1) (list 2 3) (list 5 4))))
this works, but it's too long. Is there better way to do this?
(let ((initial-state '((0 1) (2 3) (4 5))))
...)
The ' expands to (quote ...) which basically means "don't evaluate this, just return it to me as a list". It's used to separate data from code (which in lisp are related concepts).
Do you mean this?
(let ((initial-state '((0 1) (2 3) (5 4)))) ...)
That single quote is a quote. :)
More about quoting here:
When to use 'quote in Lisp
Wikipedia article on Lisp

Assigning the result of an expression to a variable

Working with DrScheme (language-- Pretty Big). Trying to pass the result of an expression to a variable that can later be used in another expression. Here is a simplified version of the problem:
Definitions window:
(define (tot a b c) (+ a b c))
(define (tot2) (+ (tot a b c) 1))
Interpreter window
> (tot 5 6 7)
18
> (tot2)
. . reference to undefined identifier: a
The result I want, of course, is 19. It would be easy to have DrScheme do all the algebra at once, but I need to have it solve the first expression, then solve the second expression based on the result of the first.
Is this what you are looking for?
(define (tot a b c) (+ a b c))
(define (tot2 a b c) (+ (tot a b c) 1))
Then
(tot2 5 6 7)
should result in 19.
If you want tot2 assigned to the integer value rather than to a function,
(define (tot a b c) (+ a b c))
(define tot2 (+ (tot 5 6 7) 1))
assigns the result of the expression (+ (tot 5 6 7) 1) to the name tot2
Scheme is lexically scoped: so a, b, and c will only exist for the dynamic extent of tot.
The dynamic extent of a procedure call is the period between when the call is initiated and when it returns (via gnu).
You're imagining a "persistence" that isn't there, though it's probably plausible, given prior experience with math.
That is: if I'm solving a math problem, and I say that x equals 5, well then x should stay equal to five for the remainder of the problem; until I erase the board, for instance.
So, can you write a programming language like this? Yes! In fact, I could write a small macro in DrScheme for you that produced exactly the behavior you appear to be looking for: it would set up a global table of variables so that every variable binding caused an update to this single table of variables.
BUT! All of the programmers I surveyed (one) (okay, it was me) agreed that this would be a very bad idea.
To see why, imagine that I have a large program that contains several variables called 'a'. Then, any time someone in part A of the program calls a function with a variable named 'a', then part B of the program will suddenly change its behavior. This will make it nearly impossible to reason about the behavior of larger programs.
More generally, this is the problem with "state" and "mutation".
For this reason, you cannot refer to variables other than the ones that are "in scope". That is, those variables whose binding form (in this case a 'define') encloses the reference.
Based on your comments on John's answer, I think what you want is just to assign the result of each function call to a variable (either one variable for each or stick them all in a list) and then add those results together.
After reading through everyone's comments, I realized that I was confusing two issues: having the interpreter evaluate an expression with variables, and actually supplying values for those variables. Because of this confusion, the questions I asked did not make sense. Here's a simplified version of the solution. As you can see, it is embarrassingly simple-- I just used "read" to have the user enter the values.
(define a (read))
(define b (read))
(define c (read))
(define d (read))
(define ee (read))
(define f (read))
(define tot (+ a b c))
(define tot2 (+ d ee f))
(define grandtotal (+ tot tot2))
(display grandtotal)
I used this approach with the actual program and now have a nice little application that totals my hours worked for the week. Thanks everyone for your patient assistance.