Racket, get a value from a list using an index - racket

I want to get a element from a list giving an index. But the index will by get trough another function:
#lang racket
(define (list-index e lst)
(if (null? lst)
0
(if (equal? (car lst) (car e))
1
(+ 1 (list-index e (cdr lst))))))
(list-ref '(aa bb cc dd ee ff) (list-index e lst))
Example:
If I execute: (list-index '(c) '(a b c d)) this returns "3" and now I want to use that number to get "cc" in the second funtion with the list '(aa bb cc dd ee ff).
The issues are:
The (list-index e lst) is giving an error in the second function.
I dont know how to combine both funtions.

First, note that list-ref considers first element at position 0, so
(list-ref '(aa bb cc dd ee ff) 3)
would output 'dd, not cc.
Second, (list-index e lst) is producing an error because both e and lst are undefined/unbound variables within the expression. To apply the procedure (or any function in general), you have to pass it actual values, or identifiers bound to values within scope. For example, the following would work and output 'dd:
> (list-ref '(aa bb cc dd ee ff) (list-index '(c) '(a b c d)))
'dd
To output cc, you can do
(list-ref '(aa bb cc dd ee ff) (sub1 (list-index '(c) '(a b c d))))
'cc
or you can modify list-index itself to output 0-indexed positions.

Related

Lisp function that recursively adds elements to a list

I working on a lisp function that will accept two parameters, the second of which is a list. It will take the first parameter and add it after every element of the second parameter. This is as far as I got:
(defun rd(list n1 lis2)
(rd ((n1) (cdr (lis2))))
(cons (n1) (cons (car (lis2))))
)
If the two parameters are 'aa and '(b c d f), the desired output should be: aa b aa c aa d aa f aa
Don't put variables inside (), that's for calling functions.
If the function takes two parameters, the parameter list should just be (n1 lis2), no need for list before that.
You're not doing anything with the result of the recursive call. You need to combine it with n1 and the first element of lis2.
A recursive function has to check for the base case, otherwise it will recurse infinitely.
(defun rd (n1 lis2)
(if (null lis2)
(list n1) ;; Add n1 at the end
(list* n1 (car lis2) (rd n1 (cdr lis2))))) ;; put n1 before every element
(rd 'aa '(1 2 3 4 5)) ;; => (aa 1 aa 2 aa 3 aa 4 aa 5 aa)
If you want insert the element after each head of the input list:
(defun f (a l)
(cond
((null l) l)
(T (cons (car l) (cons a (f a (cdr l)))))
)
)
(format t "~a" (f 'aa '(1 2 3 3 4 5 5 6)))
(1 AA 2 AA 3 AA 3 AA 4 AA 5 AA 5 AA 6 AA)
In this case, if l is an empty list, the output will be NIL.
Otherwise if you want insert the element before every tail of the list (included the last tail, i.e. the empty list)
(defun f (a l)
(cond
((null l) (list a))
(T (cons a (cons (car l) (f a (cdr l)))))
)
)
In this case:
(format t "~a" (f 'aa '(1 2 3 3 4 5 5 6)))
(AA 1 AA 2 AA 3 AA 3 AA 4 AA 5 AA 5 AA 6 AA)
If l is an empty list, the output will be the list (aa).

For loop which prints out every 3rd number

I'm trying to make a for loop that iterates over a list of numbers and prints out every 3rd number.
Edit: I've only figured out how to use the for loop but I'm not entirely sure if there's a specific function I can use to only show every 3rd number. I feel like I might be on the right path when using car/cdr function except I'm getting an error
rest: contract violation
expected: (and/c list? (not/c empty?))
given: 0
My code:
(for/list ([x (in-range 20)] #:when (car(cdr(cdr x)))) (displayln x))
I'm trying to make a for loop that iterates over a list of numbers and prints out every 3rd number.
Typically it is more useful to create a new list with the desired values, and then print those values, or pass them to a function, or do whatever else may be needed. for/list does indeed return a list, and this is one reason for problems encountered by OP example code. (Other problems in OP code include that x is a number with [x (in-range 20)], so (cdr x) is not defined).
A possible solution would be to recurse over the input list, using take to grab the next three values, keeping the third, and using drop to reduce the input list:
;; Recurse using `take` and `drop`:
(define (every-3rd-1 lst)
(if (< (length lst) 3)
'()
(cons (third (take lst 3))
(every-3rd-1 (drop lst 3)))))
Another option would be to recurse on the input list using an auxiliary counter; starting from 1, only keep the values from the input list when the counter is a multiple of 3:
;; Recurse using an auxilliary counter:
(define (every-3rd-2 lst)
(define (every-3rd-helper lst counter)
(cond [(null? lst)
'()]
[(zero? (remainder counter 3))
(cons (first lst) (every-3rd-helper (rest lst) (add1 counter)))]
[else (every-3rd-helper (rest lst) (add1 counter))]))
(every-3rd-helper lst 1))
Yet another possibility would be to use for/list to build a list; here i is bound to values from the input list, and counter is bound to values from a list of counting numbers:
;; Use `for/list` to build a list:
(define (every-3rd-3 lst)
(for/list ([i lst]
[counter (range 1 (add1 (length lst)))]
#:when (zero? (remainder counter 3)))
i))
This function (or any of them, for that matter) could be usefully generalized to keep every nth element:
;; Generalize to `every-nth`:
(define (every-nth n lst)
(for/list ([i lst]
[counter (range 1 (add1 (length lst)))]
#:when (zero? (remainder counter n)))
i))
Finally, map could be used to create a list containing every nth element by mapping over a range of every nth index into the list:
;; Use `map` and `range`:
(define (every-nth-map n lst)
(map (lambda (x) (list-ref lst x)) (range (sub1 n) (length lst) n)))
If what OP really requires is simply to print every third value, rather than to create a list of every third value, perhaps the code above can provide useful materials allowing OP to come to a satisfactory conclusion. But, each of these functions can be used to print results as OP desires, as well:
scratch.rkt> (for ([x (every-3rd-1 '(a b c d e f g h i j k l m n o p))])
(displayln x))
c
f
i
l
o
scratch.rkt> (for ([x (every-3rd-2 '(a b c d e f g h i j k l m n o p))])
(displayln x))
c
f
i
l
o
scratch.rkt> (for ([x (every-3rd-3 '(a b c d e f g h i j k l m n o p))])
(displayln x))
c
f
i
l
o
scratch.rkt> (for ([x (every-nth 3 '(a b c d e f g h i j k l m n o p))])
(displayln x))
c
f
i
l
o
scratch.rkt> (for ([x (every-nth-map 3 '(a b c d e f g h i j k l m n o p))])
(displayln x))
c
f
i
l
o
Here is a template:
(for ([x (in-list xs)]
[i (in-naturals]
#:when some-condition-involving-i)
(displayln x))

Cannot understand output in the second case

(define c
(let ((d 10))
(set! d (- d 2))
d))
(define c1
(let ((d 10))
(lambda (p)
(set! d (- d p))
d)))
Now for c c the output is 8 8.
But for (c1 2) (c1 2) the output is 8 6. Why is that so?
I think I need an insight to how function calls are actually evaluated.
According to me, the evaluation should be as, (in the second case) for the first call, a local environment for function c1 is created where the value of d is 10 and then the procedure evaluation takes place normally. Then as soon as this call ends the whole environment is destroyed and for the second call the same whole process (as above) occurs. So the second output value should also be 8. But it is 6, why is that so?
Are you thinking this:
(define c1
(let ((d 10))
(lambda (p)
(set! d (- d p))
d)))
It is exactly the same as:
(define c1
(lambda (p)
(let ((d 10))
(set! d (- d p))
d)))
It is not. In the first the variable d is created before the lambda and thus it is the same free variable for each and every invocation of c1. Thus changing d alters next call.
The second one creates d at invocation and it gets destroyed when the call is finished.
In the first Scheme evaluates the let form. It creates d and then evaluates the lambda so d becomes a free variable in its closure that is returned. The define syntax then creates a global variable c1 with that resulting closure value. The let is out of scope, but d doesn't get garbage collected since it is still referenced by one value, the closure.
A let can be rewritten as an immediate application of a lambda abstraction
(mylet ([var rhs] ...) body ...) => ((lambda (var ...) body ...) rhs ...)
De-sugaring c's let yields
(define c ((lambda (d) (set! d (- d 2)) d) 10))
Which is just an application of 10 onto a function (which we call f)
(define f (lambda (d) (set! d (- d 2)) d))
(define c
(f 10))
c
c
As for c1, we have nested lambdas
(define f1 (lambda (d) (lambda (p) (set! d (- d p)) d)))
((f1 10) 2)
((f1 10) 2)
8 and 8. (Which is what you expected). But really, what's happening is
(define c1
(f1 10))
(c1 2)
(c1 2)
returns 8 and 6
The d gets memoized (here is an example of fibonacci using the same wrapping of a memoize procedure and set!).
Moreover, for set!, you can't have naive substitution. The racket's evaluation model explains how "a new location is created for each variable on each application":
Since the value associated with argument variable x can be changed,
the value cannot be substituted for x when the procedure is first
applied.
tl;dr evaluation of c1 yields a lambda that closes over pending substitution (environment). Which is then mutated by set! on each call.

Creating a custom reverse of list

I'm trying to create a custom reverse of list in Lisp. I'm pretty new to Lisp programming, and still struggling with syntax. This is my code so far
(defun new-union(l1 l2)
(setq l (union l1 l2))
(let (res)
(loop for x in l
do(setq res (cons (car l) res))
do(setq l (cdr l)))))
Here I'm taking two lists, and forming union list l. Then for reversing the list l I'm accessing element wise to append it to a new list res. Then consequently using the cons, car and cdr to update the list.
However, I'm getting a weird output. Can someone please suggest where I'm going wrong?
I'm aware of an inbuilt function for the same called nreverse , but I wanted to experiment to see how the Lisp interprets the data in list.
On printing res at the end, for example
(new-union '(a b c) '(d e f))
the output for above call gives me
(L A A A A A A A X X)
I think I'm doing the looping wrong.
Problems
(summary of previous comments)
Bad indentation, spaces, and names; prefer this:
(defun new-union (l1 l2)
(setq list (union l1 l2))
(let (reversed)
(loop for x in list
do (setq res (cons (car list) reversed))
do (setq list (cdr list)))))
Usage of SETQ on undeclared, global variables, instead of a LET
Mutation of the structure being iterated (LIST)
Not using X inside the LOOP (why define it?)
The return value is always NIL
Refactoring
(defun new-union (l1 l2)
(let ((reverse))
(dolist (elt (union l1 l2) reverse)
(push elt reverse))))
Define a local reverse variable, bound to NIL by default (you could set it to '(), this is sometimes preferred).
Use DOLIST to iterate over a list and perform side-effects; the third argument is the return value; here you can put the reverse variable where we accumulate the reversed list.
For each element elt, push it in front of reverse; if you want to avoid push for learning purposes, use (setf reverse (cons elt reverse)).
Common Lisp is multi-paradigm and favors pragmatic solutions: sometimes a loop is more natural or more efficient, and there is no reason to force yourself to adopt a functional style.
Functional implementation
However, lists provide a natural inductive structure: recursive approaches may be more appropriate in some cases.
If you wanted to use a functional style to compute reverse, be aware that tail-call optimization, though commonly available, is not required by the language specification (it depends on your implementation capabilities and compiler options).
With default settings, SBCL eliminates calls in tail positions and would eliminate the risk of stack overflows with large inputs. But there are other possible ways to obtain bad algorithmic complexities (and wasteful code) if you are not careful.
The following is what I'd use to define the combination of union and reverse; in particular, I prefer to define a local function with labels to avoid calling new-union with a dummy nil parameter. Also, I iterate the list resulting from the union only once.
(defun new-union (l1 l2)
(labels ((rev (list acc)
(etypecase list
(null acc)
(cons (rev (rest list)
(cons (first list) acc))))))
(rev (union l1 l2) nil)))
Trace
0: (NEW-UNION (A B C) (D E F))
1: (UNION (A B C) (D E F))
1: UNION returned (C B A D E F)
1: (REV (C B A D E F) NIL)
2: (REV (B A D E F) (C))
3: (REV (A D E F) (B C))
4: (REV (D E F) (A B C))
5: (REV (E F) (D A B C))
6: (REV (F) (E D A B C))
7: (REV NIL (F E D A B C))
7: REV returned (F E D A B C)
6: REV returned (F E D A B C)
5: REV returned (F E D A B C)
4: REV returned (F E D A B C)
3: REV returned (F E D A B C)
2: REV returned (F E D A B C)
1: REV returned (F E D A B C)
0: NEW-UNION returned (F E D A B C)
Remark
It is quite surprising to reverse the result of union, when the union is supposed to operate on unordered sets: the order of elements in the result do not have to reflect the ordering of list-1 or list-2 in any way. Sets are unordered collections having no duplicates; if your input lists already represent sets, as hinted by the name of the function (new-union), then it makes no sense to remove duplicates or expect the order to be meaningful.
If, instead, the input lists represents sequences of values, then the order matters; feel free to use append or concatenate in combination with remove-duplicates, but note that the latter will remove elements in front of the list by default:
(remove-duplicates (concatenate 'list '(4 5 6) '(2 3 4)))
=> (5 6 2 3 4)
You may want to use :from-end t instead.
Ok...I think you want to take two lists, combine them together, remove duplicates, and then reverse them.
Your biggest problem is that you're using loops instead of recursion. LISP was born to do list processing using recursion. It's far more natural.
Below is a very simple example of how to do that:
(defvar l1 '(a b c)) ;first list
(defvar l2 '(d e f)) ;second list
(defun my-reverse (a b) ;a and b are lists
"combines a and b into lst, removes duplicates, and reverses using recursion"
(let ((lst (remove-duplicates (append a b))))
(if (> (length lst) 0)
(append (last lst) (my-reverse nil (butlast lst)))
nil)))
Sample Run compiled in SLIME using SBCL
; compilation finished in 0:00:00.010
CL-USER> l1 ;; verify l1 variable
(A B C)
CL-USER> l2 ;; verify l2 variable
(D E F)
CL-USER> (append l1 l2) ;; append l1 and l2
(A B C D E F)
CL-USER> (my-reverse l1 l2) ;; reverse l1 and l2
(F E D C B A)

How does "Cons" work in Lisp?

I was studying Lisp and I am not experienced in Lisp programming. In a part of my studies I encountered the below examples:
> (cons ‘a ‘(a b)) ----> (A A B)
> (cons ‘(a b) ‘a) ----> ((A B).A)
I was wondering why when we have (cons ‘a ‘(a b)) the response is (A A B) and why when we change it a little and put the 'a after (a b), the response is a dotted list like ((A B).A)? What is the difference between the first code line and the second one? What is going on behind these codes?
It's pretty easy to understand if you think of them as cons-cells.
In short, a cons cell consists of exactly two values. The normal notation for this is to use the dot, e.g.:
(cons 'a 'b) ==> (A . B)
But since lists are used so often in LISP, a better notation is to drop the dot.
Lists are made by having the second element be a new cons cell, with the last ending a terminator (usually nil, or '() in Common Lisp). So these two are equal:
(cons 'a (cons 'b '())) ==> (A B)
(list 'a 'b) ==> (A B)
So (cons 'a 'b) creates a cell [a,b], and (list 'a 'b) will create [a, [b, nil]]. Notice the convention for encoding lists in cons cells: They terminate with an inner nil.
Now, if you cons 'a onto the last list, you create a new cons cell containing [[a, [b, nil]], a]. As this is not a "proper" list, i.e. it's not terminated with a nil, the way to write it out is to use the dot: (cons '(a b) 'a) ==> ((a b) . a).
If the dot wasn't printed, it would have to have been a list with the structure [[a, [b, nil]], [a, nil]].
Your example
When you do (cons 'a '(a b)) it will take the symbol 'a and the list '(a b) and put them in a new cons cell. So this will consist of [a, [a, [b, nil]]]. Since this naturally ends with an inner nil, it's written without dots.
As for (cons '(a b) 'a), now you'll get [[a, [b, nil]], a]. This does not terminate with an inner nil, and therefore the dot notation will be used.
Can we use cons to make the last example end with an inner nil? Yes, if we do
(cons '(a b) (cons 'a '())) ==> ((A B) A)
And, finally,
(list '(a b) 'a))
is equivalent to
(cons (cons (cons 'a (cons 'b '())) (cons 'a '())))
See this visualization:
CL-USER 7 > (sdraw:sdraw '(A A B))
[*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
A A B
CL-USER 8 > (sdraw:sdraw '((A B) . A))
[*|*]--->A
|
v
[*|*]--->[*|*]--->NIL
| |
v v
A B
Also:
CL-USER 9 > (sdraw:sdraw '(A B))
[*|*]--->[*|*]--->NIL
| |
v v
A B
CL-USER 10 > (sdraw:sdraw (cons 'A '(A B)))
[*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
A A B
CL-USER 11 > (sdraw:sdraw (cons '(A B) 'A))
[*|*]--->A
|
v
[*|*]--->[*|*]--->NIL
| |
v v
A B
A cons is a data structure that can contain two values. Eg (cons 1 2) ; ==> (1 . 2). The first part is car, the second is cdr. A cons is a list if it's cdr is either nil or a list. Thus
(1 . (2 . (3 . ()))) is a list.
When printing cons the dot is omitted when the cdr is a cons or nil. The outer parentheses of the cdr is also omitted. Thus (3 . ()) is printed (3) and (1 . (2 . (3 . ()))) is printed (1 2 3). It's the same structure, but with different visualization. A cons in the car does not have this rule.
The read function reads cons with dot and the strange exceptional print format when the cdr is a list. It will at read time behave as if it were cons.
With a special rule for both read and print the illusion of a list is complete even when it's chains of cons.
(cons ‘a ‘(a b)) ----> (A . (A B))
(cons ‘(a b) ‘a) ----> ((A B) . A)
When printing, the first is one list of 3 elements since the cdr is a list.
A list (a b c) is represented (stored internally) as three cons-cells: (cons 'a (cons 'b (cons 'c '()). Note that the last pair has '() in its cdr.
Series of cons-cells whose last cdr is '() is printed as a list by the printer. The example is thus printed as (a b c).
Let's look at: (cons 'a '(a b)).
The list '(a b) is represented as (cons 'a (cons 'b '()). This means that
(cons 'a '(a b)) produces: (cons 'a (cons 'a (cons 'b '())).
Let's look at: (cons '(a b) 'a).
The list '(a b) is represented as (cons 'a (cons 'b '()). This means that
(cons (cons '(a b) 'a)) produces (cons (cons 'a (cons 'b '()) 'a).
Note that this series does not end in '(). To show that the printer uses dot notation. ( ... . 'a) means that a value consists of a series of cons-cells and that the last cdr contains 'a. The value (cons (cons 'a (cons 'b '()) 'a) is thus printed as '((a b) . a).
cons is just a pair data type. For example, (cons 1 2) is a pair of 1 and 2, and it will be printed with the two elements seperated by a dot like (1 . 2).
Lists are internally represented as nested conses, e.g. the list (1 2 3) is (cons 1 (cons 2 (cons 3 '())).