Lisp Recreating a Temporary Variable - lisp

I'm having a bit of trouble with Lisp. What i'm attempting to do, is keep track of the amount of times a number appears in x number of lists. However, running this over and over again, lisp isn't recreating the variable, but using the ending value from the last time I called the function. So I'm wondering how can I get past the 'binding' powers of let?
So, I've got some list like this
(((8 7) (3)) ((8 3) (2)) ((7 3) (6)) ((7 2) (8)) ((6 7) (4 1))
((6 6) (4 1)) ((6 2) (2)) ((5 6) (3)) ((5 3) (8 3)) ((4 6) (4))
((4 4) (6)) ((4 1) (7)) ((3 7) (5 3)) ((3 4) (1)) ((3 3) (3)) ((3 1) (9))
((2 7) (7)) ((2 5) (2)) ((2 2) (5 2)) ((1 7) (1)) ((1 6) (6 1))
((1 1) (2 1)) ((1 0) (3)) ((0 7) (8 1)) ((0 5) (6)) ((0 3) (9 6))
((0 1) (1)))
Then I'm calling some function like this, (declaring var here doesn't seem to do anything, past the initial function call)... I guess some kind of binding from let.
(defun counter (possibleValues)
(let ((var '(0 0 0 0 0 0 0 0 0 0)))
(loop for i from 0 to (list-length possibleValues) do
(loop for j in (cdr (nth i possibleValues)) do
(loop for k in j do
(incf (nth k var)))))
var))
So I can run my list through the function and get something like
(0 8 5 6 3 2 5 2 3 2)
Each position referring to the number found in the list. So the value 8 would refer to how many times 1 was found in all the lists (i'm considering the second list only). Now the problem.... run it twice and...
(0 16 10 12 6 4 10 4 6 4)
I was using an associative list earlier, but in trying to figure this out and keep things simple, i'm now using a list. I guess another question I have is, how can I create associative list elements on the fly? I don't like declaring 'var' like that, but I'm just trying to get around 'let' for the moment. I haven't had much luck with 'setq' or 'setf' either....
Thanks in advance for your help!

Change the initialization form for VAR to be an expression that creates new lists, such as (make-list 10 :initial-element 0) or even (list 0 0 0 0 0 0 0 0 0 0).
Basically, do not ever use quoted objects if you have intentions on modifying them, as the consequences are undefined if you do. In fact, evaluating that function definition gives a warning about that:
; in: LAMBDA NIL
; (INCF (NTH K VAR))
; --> LET*
; ==>
; (SB-KERNEL:%SETNTH #:TMP5 #:TMP4 #:NEW3)
;
; caught WARNING:
; Destructive function SB-KERNEL:%SETNTH called on constant data.
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition

Related

Squared euclidean distance in Racket using a hash-set

I am trying to write a function that computes the squared Euclidean distance. I originally stored the data inside lists of the form:
'(1 8 0 0 0 1 0 5 0 1)
'(1 0 2 0 0 0 0 5 0 0)
And basically what I try to obtain is the sum of:
'(0 64 4 0 0 1 0 0 0 1)
Using lists this isn't hard to achieve, like with the code from bellow:
(define (f a b)
(apply + (map (λ(x y) (sqr (- x y))) a b)))
However the data that I'm working with got quite many zeros in it, so instead I tried to replace lists with hash-sets, like so:
'#hash((0 . 1) (1 . 8) (5 . 1) (7 . 5) (9 . 1))
'#hash((0 . 1) (2 . 1) (7 . 5))
Here when I try to rewrite the f function but with hash-sets I get stuck, because I don't know how to iterate over both of them directly. What I wrote so far doesn't count the elements that are in the second hash-set but not in the first one.
(define (f a b)
(for/fold ([sum 0])
([(k v) (in-hash a)])
(+ sum (sqr (- (hash-ref b k 0) v)))))
Is there a way to achieve this in a fast way (preferably using a single for)? Or perhaps is there a better way to work with sparsed lists (that contain many zeros)?
One solution would be to get a list of all indices which occur in either of the sparse vectors, and then to map over that list of indices to calculate the squared distances:
(define (sparse-sum-of-squares u v)
(let ((indices (remove-duplicates (append (hash-keys u) (hash-keys v)))))
(apply + (map (lambda (i) (let ((x (hash-ref u i 0))
(y (hash-ref v i 0)))
(sqr (- x y))))
indices))))
You should probably do some actual testing on your data to see if performance is an issue before you start complicating the data representation. After fixing the sparse vectors in the posted example so that they match, here are the results:
sparse-vector.rkt> (f '(1 8 0 0 0 1 0 5 0 1)
'(1 0 2 0 0 0 0 5 0 0))
70
sparse-vector.rkt> (sparse-sum-of-squares '#hash((0 . 1) (1 . 8) (5 . 1) (7 . 5) (9 . 1))
'#hash((0 . 1) (2 . 2) (7 . 5)))
70
The thing is, we need to handle missing values in both hashes. Iterating only over indexes with actual values, we can do something like this:
(define (squared-euclidean-distance a b)
(for/fold ([sum 0])
([idx (set-union (hash-keys a) (hash-keys b))])
(+ sum (sqr (- (hash-ref a idx 0)
(hash-ref b idx 0))))))
We simply return 0 if an index is missing. It works as expected:
(squared-euclidean-distance
'#hash((0 . 1) (1 . 8) (5 . 1) (7 . 5) (9 . 1))
'#hash((0 . 1) (2 . 2) (7 . 5)))
=> 70

How would I write a function in Dr. Racket which consumes a list of list of integers and produces a new list of list of integers?

How would I write a function in Dr. Racket which consumes a list of list of integers and produces a new list of list of integers with a transformation (sqr) applied to each element.
Note: There is an equal number of elements in each list.
Here are two examples to show what I am saying:
Example 1:
(list (list 1 2) (list 3 -2))
Should produce:
(list (list 1 4) (list 9 4))
Example 2:
(list (list 3 4 5) (list 2 1 3) (list 2 3 7) (list 0 -3 2))
Should produce:
(list (list 9 16 25) (list 4 1 9) (list 4 9 49) (list 0 9 4))
Here is my code so far:
(define (transform-to-sqr b)
(map sqr b))
If I type in:
(transform-to-sqr (list (list 1 2) (list 3 -2)))
I get an error message saying:
sqr: expected a number; given (list 1 2).
Why is this happening. Can someone please tell me what I am doing wrong.
Thanks for your help.
The map higher-order procedure applies a procedure over the elements of a list, but in this case the elements are lists themselves. To operate on the nested elements, we need to nest calls to map:
(define (transform-to-sqr matrix)
(map (λ (row) (map sqr row))
matrix))
It works as expected:
(transform-to-sqr '((1 2) (3 -2)))
=> '((1 4) (9 4))
(transform-to-sqr '((3 4 5) (2 1 3) (2 3 7) (0 -3 2)))
=> '((9 16 25) (4 1 9) (4 9 49) (0 9 4))

Introducing new symbols into Common-Lisp Function/Macro

I want to define a functionality in common lisp which uses some words/symbols not known to lisp, for example having such a function/macro:
(my-func-or-macro lst key-word idx)
which returns items in the lst upto the idx if the key-word is to and from the idx to the end if the key-word is from.
So practically it should work like:
(my-func-or-macro '(1 2 3 4 5 6) from 3) => '(4 5 6)
and
(my-func-or-macro '(1 2 3 4 5 6) to 3) => '(1 2 3)
Since macros don't evaluate their arguments i think i should be using a macro which doesn't care about from and to (note i don't want to pass quoted args like 'from 'to).
Since every argument to a function is evaluated before the function is executed, you need a symbol that evaluates to itself.
Such symbols are already part of the language: all symbols in the special KEYWORD package evaluate to themselves. Symbols that are written with a leading colon, e. g. :foo are interned into that package.
Also part of the language are keyword arguments that use such keywords to identify parameters:
(defun my-func (list &key from)
(subseq list from))
(my-func '(0 1 2 3 4 5) :from 3)
=> (3 4 5)
You can give default values to such parameters:
(defun my-func (list &key (from 0) (to (length list)))
(subseq list from to))
(my-func '(0 1 2 3 4 5) :from 3)
=> (3 4 5)
(my-func '(0 1 2 3 4 5) :to 3)
=> (0 1 2)
(my-func '(0 1 2 3 4 5) :from 1 :to 4)
=> (1 2 3)
Keyword arguments can be given in any order:
(my-func '(0 1 2 3 4 5) :to 4 :from 1)
=> (1 2 3)

&optional parameter in lisp macros: Why does this variable behave like this?

I'm trying to create a lisp macro that has an &optional parameter with a default value. Unfortunately the parameter is processed differently depending on whether it is read from the default value or from parameters provided to the macro. The code fragment below reproduces the issue:
(setf table1 '((1 2 3)
(4 5 6))
table2 '((10 20 30)
(40 50 60)))
(defmacro test-lambda (f &optional (tableau table1))
`(list ,f ,tableau))
? (test-lambda 0 table2) ;; This works...
(0 ((10 20 30) (40 50 60)))
? (test-lambda 0) ;; ...but this doesn't
> Error: Car of ((1 2 3) (4 5 6)) is not a function name or lambda-expression.
> While executing: CCL::CHEAP-EVAL-IN-ENVIRONMENT, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 >
I don't quite understand why the macro won't work with the default value in the second case. Is there a better way to code this or at least a workaround?
Thanks,
What
You need to quote the default argument value:
(defmacro test-lambda-1 (f &optional (tableau 'table1))
`(list ,f ,tableau))
(test-lambda-1 0)
==> (0 ((1 2 3) (4 5 6)))
Why
You need to think how Common Lisp evaluates your code: when it sees (test-lambda ...), it
expands the macro
evaluates the resulting code
Let us try it:
(macroexpand '(test-lambda 0))
==> (LIST 0 ((1 2 3) (4 5 6))) ; T
(macroexpand '(test-lambda-1 0))
==> (LIST 0 TABLE1) ; T
(macroexpand '(test-lambda 0 table2))
==> (LIST 0 TABLE2) ; T
(macroexpand '(test-lambda-1 0 table2))
==> (LIST 0 TABLE2) ; T
Now you can see where the error is coming from: you did not quote the default value of the argument, so it got evaluated twice.

clisp positive number founder

I am trying to return a list which contains non-negative numbers from function parameter list using clisp.
(defun recursive (L)
(setq ret (list))
(setq first (car L))
(setq rest (cdr L))
(if (null L)
0
(if (>= first 0)
(nconc ret (first))
(recursive rest))))
(setq mylist (list 1 2 3 -1 0 -3))
(write (recursive mylist))
I wrote this and expecting an output as (1 2 3 0)
What is wrong in that code?
Let filter be the function you want to implement.
Then (filter nil) should return nil.
In the general case, you compte (filter (number . tail)) recursively. Assuming that filter computes the list of positive numbers in a list, you can solve the problem for tail, and call (filter tail). In order to solve your current problem, you have to consider if number is positive or not, and add the element to the recursive result accordingly.
(defun filter (list)
(etypecase list
(null nil)
(cons (destructuring-bind (number . tail) list
(if (plusp number)
(cons number (filter tail))
(filter tail))))))
I am using ETYPECASE, PLUSP, DESTRUCTURING-BIND, but you can express the same differently. Note that you used NCONC which requires iterating over the whole list, which is not required and makes your whole aproach quadratic in time.
The above function has a flaw because the size of the call stack grows linearly with the size of your input list. Each time you call filter, a new frame is allocated on the stack, which can be easily seen with TRACE:
CL-USER> (trace filter)
(FILTER)
CL-USER> (filter '(0 1 -2 3 -4 -5 6 7 -8 9))
0: (FILTER (0 1 -2 3 -4 -5 6 7 -8 9))
1: (FILTER (1 -2 3 -4 -5 6 7 -8 9))
2: (FILTER (-2 3 -4 -5 6 7 -8 9))
3: (FILTER (3 -4 -5 6 7 -8 9))
4: (FILTER (-4 -5 6 7 -8 9))
5: (FILTER (-5 6 7 -8 9))
6: (FILTER (6 7 -8 9))
7: (FILTER (7 -8 9))
8: (FILTER (-8 9))
9: (FILTER (9))
10: (FILTER NIL)
10: FILTER returned NIL
9: FILTER returned (9)
8: FILTER returned (9)
7: FILTER returned (7 9)
6: FILTER returned (6 7 9)
5: FILTER returned (6 7 9)
4: FILTER returned (6 7 9)
3: FILTER returned (3 6 7 9)
2: FILTER returned (3 6 7 9)
1: FILTER returned (1 3 6 7 9)
0: FILTER returned (1 3 6 7 9)
This happens because you need to remember each intermediate value of number across recursive calls, in order to cons them with a recursive result. If you could instead have done all your work before descending into a recursive call, then there would be no need to retain intermediate values, and the function would be recursive terminal and could be subject to what is known as tail-call optimization.
In order to do that, you have to build the resulting list before calling the recursive call, through an accumulator:
(defun filter (list accumulator)
(etypecase list
(null accumulator)
(cons (destructuring-bind (head . tail) list
(if (plusp head)
(filter tail (cons head accumulator))
(filter tail accumulator))))))
Notice the repetition, which can be refactored as:
(filter tail (if (plusp head) (cons head accumulator) accumulator))
Here above, we added an accumulator, which holds the new list. Initially, you should pass an empty list. When you reach the end of your input list, you return the accumulator. Otherwise, you add the number to the accumulator before calling filter recursively. The difference is that you don't need to store intermediate values in the call stack. The trace macro produces this:
0: (FILTER (0 1 -2 3 -4 -5 6 7 -8 9) NIL)
1: (FILTER (1 -2 3 -4 -5 6 7 -8 9) NIL)
2: (FILTER (-2 3 -4 -5 6 7 -8 9) (1))
3: (FILTER (3 -4 -5 6 7 -8 9) (1))
4: (FILTER (-4 -5 6 7 -8 9) (3 1))
5: (FILTER (-5 6 7 -8 9) (3 1))
6: (FILTER (6 7 -8 9) (3 1))
7: (FILTER (7 -8 9) (6 3 1))
8: (FILTER (-8 9) (7 6 3 1))
9: (FILTER (9) (7 6 3 1))
10: (FILTER NIL (9 7 6 3 1))
10: FILTER returned (9 7 6 3 1)
9: FILTER returned (9 7 6 3 1)
8: FILTER returned (9 7 6 3 1)
7: FILTER returned (9 7 6 3 1)
6: FILTER returned (9 7 6 3 1)
5: FILTER returned (9 7 6 3 1)
4: FILTER returned (9 7 6 3 1)
3: FILTER returned (9 7 6 3 1)
2: FILTER returned (9 7 6 3 1)
1: FILTER returned (9 7 6 3 1)
0: FILTER returned (9 7 6 3 1)
Please note that the function is tail-recursive, but doesn't look like it was optimized away because there is an arrow-shaped trace. However, trace is not a reliable way of knowing if the function is or isn't tail-recursive, because the act of tracing changes hat is actually done. Or, maybe the debug quality is so high that tail-call optimization is not applied. This depends on your implementation. Please note that the trace clearly shows how the intermediate list is built, and how the result is passed unchanged from deep levels to higher ones. See also that the list is being built in reverse, because we keep calling cons with the accumulator (which is efficient, contrary to nconc).
Since you didn't specify if you want the elements of the list to retain the same order as the input list, I assumed that this is not required.
However, you could also call NREVERSE on the resulting list to reverse it destructively (i.e. in-place, without allocating memory). This is ok if here because you own the fresh list being built, so you can safely modify it before giving it to the caller. This is best done by wrapping the implementation detail inside a local function:
(defun filter (list)
(labels ((filter (list accumulator)
(etypecase list
(null accumulator)
(cons (destructuring-bind (head . tail) list
(filter tail (if (plusp head)
(cons head accumulator)
accumulator)))))))
(nreverse (filter list nil))))
Note that filter is lexically bound to a local function inside the global filter function. See also LABELS.
However, you can better spend your time than writing recursive functions to perform loops. Common Lisp provide iteration construction, which means you can simply do this:
(defun filter (list)
(loop for number in list
when (plusp number)
collect number))
Note that removing elements from lists is also easily done with REMOVE-IF-NOT.
First off, your code doesn't work, because of the way you are using first as a function ((first)) in the then-branch of your if.
Apart from that, every time you call recursive, you re-initialize ret to an empty list. And inside the if you only recurse if the number is not bigger than 0.
Here's a working solution using cond:
(defun filter-non-negative (l)
(cond
((null l) ;; empty list
nil)
((>= (first l) 0) ;; number >= 0
(cons (first l) (filter-non-negative (rest l))))
(t ;; all other cases
(filter-non-negative (rest l)))))
(write (filter-non-negative '(1 2 3 -1 0 -3)))
;; (1 2 3 0)
First of all, the variables ret, first and rest should be defined locally with a let. In your version they are global variables. Note that you don't need these variables at all, you can simply use the function calls directly.
In the line before last, you have (first), which will signal an error because this function expects an argument. However, what you want is not the function first but the variable first, therefore you need (list first).
When the list is null, you return a 0. Since you will reach this point at the end of every recursive call, this will add a 0 to any input argument. You should return nil instead.
Finally, instead of nconc look at the function cons.
Incidentally, note that there is a function remove-if that will do exactly the job you want, but I understand that you are trying to learn about recursive calls.
I hope this helps.
You want to keep the positive numbers. Positive numbers are greater 0.
Let's remove all numbers which are not positive:
CL-USER 24 > (remove-if-not #'plusp (list 1 2 3 -1 0 -3))
(1 2 3)
or
CL-USER 25 > (remove-if (complement #'plusp) (list 1 2 3 -1 0 -3))
(1 2 3)