I just started learning Lisp and I don't seem to understand the following piece of code:
(setf y (loop for x in y
for z = (something)
unless (condition for z)
append z))
Where is z appended?
It is appended to an unnamed list to be returned when the loop terminates. As first approximation, you may think of it as a shorthand for
(loop ... append z into result finally (return result))
The append here is a loop keyword; it's not related to the append function, except for sharing the same name --- so it's the loop macro that decides how it works, instead of the append function.
Related
I'm a beginner at lisp. I'm grateful that stackoverflow helped me a lot.
First, I want to express the recursive function using the lisp function.
There is no compilation error, but I want to check if the code I wrote is grammatically correct.
Below is the C code I wrote.
void queens(int i)
{
int j;
if (promising(i))
{
if (i == n)
{
//print all col list
return
}
else
{
for (j = 1; j <= n; j++)
{
col[i + 1] = j;
queens(i + 1);
}
}
}
}
Below is the lisp code.
(defvar n 4)
(defvar col (list 0 0 0 0 0 ))
(defun queens(i)
(let ((j 1))
(if (promising i)
(if (= i n) (print col)
(loop while (<= j n) do (setf (nth (+ 1 i ) col) j)
( queens (+ 1 i ) )
(incf j)))
)
))
First, you (still) need to fix the indentation, alignment, and general style. This is not merely to annoy you, but because it actually makes things clearer, and easier to debug. For example, if you do not indent properly, it becomes hard to see where each expression ends, and this is even worse when using complex macros such as loop. Your code, properly formatted but without any other modification, should be:
(defun queens (i)
(let ((j 1))
(if (promising i)
(if (= i n)
(print col)
(loop while (<= j n)
do (setf (nth (+ 1 i) col) j)
(queens (+ 1 i))
(incf j))))))
The closing parenthesis is placed right after the last form of the expression, without line break, without whitespace.
The opening parenthesis is also right before the first element of the form, without whitespace, but should be detached from what comes before, unless it is another parenthesis (so (defun queen (i) ...) is correct, while ( defun queens(i)) breaks two of the rules).
When using an if construct, either you write it all on a single line (the condition, the "then" form and the "else" form), or you have to insert line breaks after each of them. Otherwise, it is unclear when the "then" form ends and when the "else" starts.
When defining special variables with defvar, name them with '*' around their names, as in (defvar *n* 4) and (defvar *col* (list ...)).
Another style considerations, which helps with problems related to nesting: use when and unless instead of if if you are only interested in one of the two branches. This makes intent clear, and can also simplify the syntax in case of complex branches.
Now, for the code:
If you want to use loop, use the basic for constructs. Instead of writing
(loop while (< j n) do ... (incf j))
use
(loop for j from <start> to <end> do ...)
You can also use upto, below ... if you want subtly different termination conditions.
When you do this, you do not need to introduce a binding for j using let, it will be introduced by the loop.
If you want to modify a list, use a vector instead. Instead of defining col as (list ...), simply use (vector ...) or the make-array function. Afterwards, use elt or aref to access individual elements instead of nth which only works for lists. A version of the code which assumes that all the previous remarks have been taken into account:
(defun queens (i)
(when (promising i)
(if (= i n)
(print *col*)
(loop for j from 1 to *n*
do (setf (aref *col* (1+ i)) j)
(queens (1+ i))))))
Without knowing what promising does and what queens is supposed to do, it is hard to give more insight, but the algorithm is weird nonetheless. For example, in a given call to (queens i), the lexically apparent setf will only ever modify the i+1-th cell of col, setting it to a new j at each iteration. As far as I can tell, this simply results in (aref col (1+ i)) being set to n at the end of the loop. It also seems that you do not use the value recursively returned by queens (which is to be expected: your C function returns nothing !), and that you do not really do any check involving col, so a recursive solution seems weird, there is (seemingly) no relation between (queens i) and the (queens (1+ i)) that it calls n times in a loop !
If the above paragraph is irrelevant because promising also heavily modifies col: stop doing C-in-Lisp and stop modifying things all around the place. Don't rely on state, mutation, global variables & the like, when you can avoid it. It is easy to define recursive solution, to pass lists as arguments, to return several values ... and so it is generally unnecessary to use multiple functions, each of them calling the other ones, recursively modifying the shared global state. That's a mess and can't be debugged.
I want to make user-program which extract elements a which have element b (given by parameter) as pair in list.
Like, if I give c as parameter and list ((c a) (c b) (d f) (d g)),
result should be 'a' 'b';
So I define a function as below,
(defun myr (b a) (if (= CAAR(a) b) CDAR(a) 'nope myr(b CDR(a))));
and call like this
myr(b ((b a) (b c) (a d) (a f)))
But result is like variable myr has no value
Its my first time in Lisp, So just tell me what keyword should I search for will be great help for me.
Thank you for reading.
You really need to start with a good lisp book, e.g., PCL or ACL.
You will save yourself a lot of time.
Lisp syntax is different from C.
In C, you call a function f with arguments х and y like this: f(x,y).
In Lisp, you do it like this: (f x y).
When you invoke your function myr(...), you put the symbol myr in the variable position, not function position, which causes the error you reported.
You also need to use quote as appropriate.
So I'm slightly confused on an introduction to Racket.
I need to write a function called "extend" that takes an element and a predicate, and "extends" the predicate to include the element. For example:
((extend 1 even?) 1)
#t
((extend 3 even?) 3)
#f
I'm fairly new to the language but I don't understand how to get a function to be used or return as a predicate. Not sure if I'm overthinking it or what.
A function is just a value and extend is just a variable like + and cons that evaluate to a function value. functions can be passed as arguments and you just use whatever name you have given it as if it's a function, by using parentheses, and it just works.
A function returns the value the last expression evaluate to. To get it to be a function it either needs to be a variable that evaluate to a function or a lambda that also evaluate to a function.
(define (double-up fn)
(lambda (value)
(fn (fn value)))) ; see. Just use fn as if it is a procedure
((double-up add1) 4) ; ==> 6
(define add2 (double-up add1))
(add2 4) ; ==> 6
(define error-use (double-up 5)) ; works like a charm
(error-use 4)
; Signals "application: not a procedure"
; since `5` isn't a procedure.
Here is another example which is more similar to your assignment. It takes a number, then returns a function that takes another number and then adds them together. Here I choose to define it locally and then leave it as the last expession so that it becomes the result.
(define (make-add initial-value)
(define (adder new-value)
(+ initial-value new-value))
adder) ; this is the result
((make-add 5) 7) ; ==> 12
A predicate is what we call functions often called in predicate position in conditionals (like if and cond). Thus just a function that either return #t or #f and often bound to variables ending with question mark as a naming convention.
Problem: How to handle a catch-all parameter after & in a macro, when the arguments to be passed are sequences, and the catch-all variable needs to be dealt with as a sequence of sequences? What gets listed in the catch-all variable are literal expressions.
This is a macro that's intended to behave roughly Common Lisp's mapc, i.e. to do what Clojure's map does, but only for side-effects, and without laziness:
(defmacro domap [f & colls]
`(dotimes [i# (apply min (map count '(~#colls)))]
(apply ~f (map #(nth % i#) '(~#colls)))))
I've come to realize that this is not a good way to write domap--I got good advice about that in this question. However, I'm still wondering about the tricky macro problem that I encountered along the way.
This works if the collection is passed as a literal:
user=> (domap println [0 1 2])
0
1
2
nil
But doesn't work in other situations like this one:
user=> (domap println (range 3))
range
3
nil
Or this one:
user=> (def nums [0 1 2])
#'user/nums
user=> (domap println nums)
UnsupportedOperationException count not supported on this type: Symbol clojure.lang.RT.countFro (RT.java:556)
The problem is that it's literal expressions that are inside colls. This is why the macro domap works when passed a sequence of integers, but not in other situations. Notice the instances of '(nums):
user=> (pprint (macroexpand-1 '(domap println nums)))
(clojure.core/dotimes
[i__199__auto__
(clojure.core/apply
clojure.core/min
(clojure.core/map clojure.core/count '(nums)))]
(clojure.core/apply
println
(clojure.core/map
(fn*
[p1__198__200__auto__]
(clojure.core/nth p1__198__200__auto__ i__199__auto__))
'(nums))))
I've tried various combinations of ~, ~#, ', let with var#, etc. Nothing's worked. Maybe it's a mistake to try to write this as a macro, but I'd still be curious how to write a variadic macro that takes complex arguments like these.
Here is why your macro does not work:
'(~#colls) This expression creates a quoted list of all colls. E. g. if you pass it (range 3), this expression becomes '((range 3)), so the literal argument will be one of your colls, preventing evaluation of (range 3) certainly not what you want here.
Now if you would not quote (~#colls) inside the macro, of course they would become a literal function invocation like ((range 3)), which makes the compiler throw after macroexpansion time (it will try to eval ((0 1 2))).
You can use list to avoid this problem:
(defmacro domap [f & colls]
`(dotimes [i# (apply min (map count (list ~#colls)))]
(apply ~f (map #(nth % i#) (list ~#colls)))))
=> (domap println (range 3))
0
1
2
However one thing here is terrible: Inside the macro, the entire list is created twice. Here is how we could avoid that:
(defmacro domap [f & colls]
`(let [colls# (list ~#colls)]
(dotimes [i# (apply min (map count colls#))]
(apply ~f (map #(nth % i#) colls#)))))
The colls are not the only thing that we need to prevent from being evaluated multiple times. If the user passes something like (fn [& args] ...) as f, that lambda would also be compiled in every step.
Now this is the exactly the scenario where you should ask yourself why you are writing a macro. Essentially, your macro has to make sure all arguments are eval'd without transforming them in any way before. Evaluation comes gratis with functions, so let's write it as a function instead:
(defn domap [f & colls]
(dotimes [i (apply min (map count colls))]
(apply f (map #(nth % i) colls))))
Given what you want to achieve, notice there is a function to solve that already, dorun which simply realizes a seq but does not retain the head. E. g.:
`(dorun (map println (range 3)))
would do the trick as well.
Now that you have dorun and map, you can simply compose them using comp to achieve your goal:
(def domap (comp dorun map))
=> (domap println (range 3) (range 10) (range 3))
0 0 0
1 1 1
2 2 2
I'm working with clojure and while I've dabbled with lisps before, I'm having trouble finding a clean way to nest let statements in cond statements. For example, consider the following function:
(defn operate-on-list [xs]
(let [[unpack vector] (first xs)]
(cond
[(empty? xs) 'empty
unpack vector
:else (operate-on-list (rest xs))])))
It's a pretty standard recursive operation on a list, but it needs to do some work on the first element in the list before it works with the contents. The issue, of course, is that the list may be empty.
In this example, it wouldn't be hard to change unpack to ((first xs) 0) and vector to ((first xs) 1), but this quickly gets ugly if more work needs to be done on (first xs).
Is there any way to effectively use a let statement part-way through a cond?
Thanks.
-Nate
In cases like these, you're best off using if-let:
(defn operate-on-list [xs]
(if-let [[unpack v] (first xs)]
(cond
unpack v
:else (operate-on-list (rest xs)))))
This code walks the given list seq-able (list, vector, array...) of vectors and returns the second element of the first vector whose first element is true (meaning not false or nil). nil is returned if no such vector is found.
Note that vector is a built-in function, so I've chosen v as the variable name, just in case the need to use the function in the body arises in the future. More importantly, you're using too many brackets in your cond syntax; fixed in this version.
UPDATE: Two additional things worth noting about if-let:
The way if-let works, if (first xs) happens to be nil (false would be the same), the destructuring binding never takes place, so Clojure won't complain about not being able to bind nil to [unpack v].
Also, if-let accepts an else clause (in which you can't refer to the variables bound in if-let bindings vector -- though if you're in the else clause, you know they where false or nil anyway).
;use conditional let: http://richhickey.github.com/clojure-contrib/cond-api.html
(use 'clojure.contrib.cond)
(cond-let [b]
nil b
12 (prn (+ b 1))
:else 17 )
;==> 13
Another good example can be found here http://www.mail-archive.com/clojure#googlegroups.com/msg03684.html
Sort of like this, with a let inside the scope of the cond?
(defn operate-on-list [list]
(let [ el_first (first list) ]
(cond
(nil? el_first) (println "Finished")
:else (do
(let [ list_rest (rest list) ]
(println el_first)
(operate-on-list list_rest))))))
(operate-on-list '(1 2 3))
The output is:
1
2
3
Finished