Copy of a list (or something else) in Scheme - list

I'm newbie in Scheme and find out that if I change a list with set-car!/set-cdr! (even locally) the parent list is modified too. This is an example what I mean:
(define my-list '(1 2 3 4 5)) ; Original list
(define (function list) ; Some example function
(let ((copy list))
(set-car! copy 'new)
(display copy)
)
(function my-list); will display (new 2 3 4 5)
my-list; but the original is changed "forever" and will be also '(new 2 3 4 5)
My question is:
Is there a way to make a copy of the original list and work only on it, so at the end the original not to be changed?

Your code (let ((copy list)) allows list to be accessed through the name copy. So when you set-car! copy, you are actually set-car!'ing the original list.
The phenomenon of mutation in lisp like languages is a little confusing at first.
Mutation is to be avoided usually, for the reasons you have discovered. Parts of lists and things a floating around. This is because internally each node in a list has two parts - the car is it's value which may point to another list, and it's cdr is the part that follows it - usually this is a lit of things similar to the value in car.
This solves your problem using SRFI1's list-copy function
(let ((copy (list-copy list)))
Here is one way to copy a list (make a new list). This code is not really complete. When we look at it internally it adds pieces of a list in each recursive call. Where do the pieces of each new list-section come from? The cdr is generated with the call (list-copy (cdr list)), while the car is simply taken - not copied! - from the other list.
(define (list-copy list)
(if (null? list) '() (cons (car list) (list-copy (cdr list)))))
The result for you when experimenting, was that the car's of your list copy where borrowed from my-list.
Here is a more proper version:
(define (full-copy list)
(if (null? list)
'()
(if (list? list)
(cons (full-copy (car list)) (full-copy (cdr list)))
list)))
Only the code for the car has changed. Now, the car is reconstructed to. The only parts that are borrowed are the numbers (so this copy is not okay when the numbers are instead something more special). I'm not sure how the srfi1 version works.
The let statement only ever binds one identifier to an object - the object is not copied, you simply have another way to access it. So any changes (use of mutation, as in functions that end in "!") will affect both.

I suggest that when you're learning Scheme or Racket, you avoid all the ! functions such as set-car!, set-cdr!, and set!.
Instead of mutating things, try to think in terms of creating a new thing from the old thing(s).
For instance if you have a list and want something new at the start:
;; Return a new list with `x` replacing the head of the list `xs`.
(define (replace-head xs x) ; list? any? -> list?
(cons x (cdr xs)))
;; Using it:
(replace-head '(1 2 3 4 5) 100)
; => '(100 2 3 4 5)
p.s. A version of replace-head that can handle xs being empty could be:
(define (replace-head xs x) ; list? any? -> list?
(cond [(empty? xs) (list x)]
[else (cons x (cdr xs))]))
(replace-head '(1 2 3 4 5) 100)
; => '(100 2 3 4 5)
(replace-head '() 100)
; => '(100)
You also might find it helpful to look at How to Design Programs, for examples of good ways to design and think in Scheme or Racket.

Related

Gathering elements in range of Min and Max values from a list in Scheme

I am new to Scheme and not currently using (Racket version), therefore I do not have such built in functions as filter and etc.
My task for now is to get elements out of my inputted list, and take out of it only those that are above my MinValue and below my MaxValue
In my "lst" variable for example I have (2 4 1 6 5 4 7 3)
In my "MinValue" I have 2
In my MaxValue I have 5
So that now after I apply something similar like
(remove (< # minVal) lst)
It technically should give remove and left out:
(2 4 4 3)
But I am getting the error:
READ from #<INPUT CONCATENATED-STREAM #<INPUT STRING-INPUT-STREAM> #<IO TERMINAL-STREAM>>: objects printed as # in view of *PRINT-LEVEL* cannot be read back in
Main questions:
Does Scheme has a specific defined variable like # that is iterating through the list when remove/remove-if functions are used, so I can use it?
Is there is a way to get this to work in such way:
(remove (< # minVal) lst)
Thanks!
tag "homework" should be there, but I cannot create it yet
Almost any Scheme I know of includes a filter procedure, it's not specific to Racket, you should be able to use it (remove is not the right tool for this job).
Simply pass a lambda that receives each element in turn and you can set any condition for determining which elements go in the output list:
(filter (lambda (e) (and (>= e 2) (< e 5)))
'(2 4 1 6 5 4 7 3))
=> '(2 4 4 3)
There is no # variable that iterates through a list and gives you each element in turn, to do that you have to explicitly traverse the list using recursion, or use one of the built-in procedures that expect a list and a lambda - the lambda's parameter represents each of the elements.
If for some reason you are not allowed to use filter, it's easy to implement it from scratch, and again notice that we don't need to use remove, and that pred gets called with each of the elements:
(define (filter pred lst)
(cond ((null? lst) '())
((pred (car lst))
(cons (car lst) (filter pred (cdr lst))))
(else (filter pred (cdr lst)))))

Ignore/Delete Repeat Symbols in a Frequency List in Scheme [duplicate]

This is extremely easy if I can use an array in imperative language or map (tree-structure) in C++ for example. In scheme, I have no idea how to start this idea? Can anyone help me on this?
Thanks,
Your question wasn't very specific about what's being counted. I will presume you want to create some sort of frequency table of the elements. There are several ways to go about this. (If you're using Racket, scroll down to the bottom for my preferred solution.)
Portable, pure-functional, but verbose and slow
This approach uses an association list (alist) to hold the elements and their counts. For each item in the incoming list, it looks up the item in the alist, and increments the value of it exists, or initialises it to 1 if it doesn't.
(define (bagify lst)
(define (exclude alist key)
(fold (lambda (ass result)
(if (equal? (car ass) key)
result
(cons ass result)))
'() alist))
(fold (lambda (key bag)
(cond ((assoc key bag)
=> (lambda (old)
(let ((new (cons key (+ (cdr old) 1))))
(cons new (exclude bag key)))))
(else (let ((new (cons key 1)))
(cons new bag)))))
'() lst))
The incrementing is the interesting part. In order to be pure-functional, we can't actually change any element of the alist, but instead have to exclude the association being changed, then add that association (with the new value) to the result. For example, if you had the following alist:
((foo . 1) (bar . 2) (baz . 2))
and wanted to add 1 to baz's value, you create a new alist that excludes baz:
((foo . 1) (bar . 2))
then add baz's new value back on:
((baz . 3) (foo . 1) (bar . 2))
The second step is what the exclude function does, and is probably the most complicated part of the function.
Portable, succinct, fast, but non-functional
A much more straightforward way is to use a hash table (from SRFI 69), then update it piecemeal for each element of the list. Since we're updating the hash table directly, it's not pure-functional.
(define (bagify lst)
(let ((ht (make-hash-table)))
(define (process key)
(hash-table-update/default! ht key (lambda (x) (+ x 1)) 0))
(for-each process lst)
(hash-table->alist ht)))
Pure-functional, succinct, fast, but non-portable
This approach uses Racket-specific hash tables (which are different from SRFI 69's ones), which do support a pure-functional workflow. As another benefit, this version is also the most succinct of the three.
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
You can even use a for comprehension for this:
(define (bagify lst)
(for/fold ((ht #hash()))
((key (in-list lst)))
(hash-update ht key add1 0)))
This is more a sign of the shortcomings of the portable SRFI 69 hashing library, than any particular failing of Scheme for doing pure-functional tasks. With the right library, this task can be implemented easily and functionally.
In Racket, you could do
(count even? '(1 2 3 4))
But more seriously, doing this with lists in Scheme is much easier that what you mention. A list is either empty, or a pair holding the first item and the rest. Follow that definition in code and you'll get it to "write itself out".
Here's a hint for a start, based on HtDP (which is a good book to go through to learn about these things). Start with just the function "header" -- it should receive a predicate and a list:
(define (count what list)
...)
Add the types for the inputs -- what is some value, and list is a list of stuff:
;; count : Any List -> Int
(define (count what list)
...)
Now, given the type of list, and the definition of list as either an empty list or a pair of two things, we need to check which kind of list it is:
;; count : Any List -> Int
(define (count what list)
(cond [(null? list) ...]
[else ...]))
The first case should be obvious: how many what items are in the empty list?
For the second case, you know that it's a non-empty list, therefore you have two pieces of information: its head (which you get using first or car) and its tail (which you get with rest or cdr):
;; count : Any List -> Int
(define (count what list)
(cond [(null? list) ...]
[else ... (first list) ...
... (rest list) ...]))
All you need now is to figure out how to combine these two pieces of information to get the code. One last bit of information that makes it very straightforward is: since the tail of a (non-empty) list is itself a list, then you can use count to count stuff in it. Therefore, you can further conclude that you should use (count what (rest list)) in there.
In functional programming languages like Scheme you have to think a bit differently and exploit the way lists are being constructed. Instead of iterating over a list by incrementing an index, you go through the list recursively. You can remove the head of the list with car (single element), you can get the tail with cdr (a list itself) and you can glue together a head and its tail with cons. The outline of your function would be like this:
You have to "hand-down" the element you're searching for and the current count to each call of the function
If you hit the empty list, you're done with the list an you can output the result
If the car of the list equals the element you're looking for, call the function recursively with the cdr of the list and the counter + 1
If not, call the function recursively with the cdr of the list and the same counter value as before
In Scheme you generally use association lists as an O(n) poor-man's hashtable/dictionary. The only remaining issue for you would be how to update the associated element.

Difference between CDR, CAR and REST, FIRST and possible implementation?

I'm learning a little bit about functional programming in LISP and here's what I've bumped into: LISP uses CAR, CDR functions as well as FIRST and REST functions. Both related to lists.
From what I've learned so far, there's a difference between these two, but I don't quite see what the difference is.
Could anyone sum this up for me? And how do I eventually implement FIRST/REST using CDR, CAR?
Edit: Since accepted answer mentions documentation, but does not link, here is the link for the documentation for CAR/CDR, here then for FIRST/REST.
In addition - important note - that linked documentation is "just implementation notes" for CLISP, which is a commonly used environment. Generally it is almost impossible to find "official documentations" for languages such is this one.
In terms of what they do, car and cdr are equivalent to first and rest. This is quite clear in the documentation. The HyperSpec says on the entry for first, second, &c:
The functions first, second, third, fourth, fifth, sixth, seventh,
eighth, ninth, and tenth access the first, second, third, fourth,
fifth, sixth, seventh, eighth, ninth, and tenth elements of list,
respectively. Specifically,
(first list) == (car list)
(second list) == (car (cdr list))
(third list) == (car (cddr list))
…
Notes:
first is functionally equivalent to car, second is functionally
equivalent to cadr, third is functionally equivalent to caddr, and
fourth is functionally equivalent to cadddr.
Now, there is a difference, not in functionality, but in style, when you're using these functions. This is actually called out in the HyperSpec as well, e.g., in the entry on rest:
Notes:
rest is often preferred stylistically over cdr when the argument is to
being subjectively viewed as a list rather than as a cons.
For instance, consider two ways of mapping over structures built from cons cells. In the first, we're mapping over a tree of cons cells, calling some function with each leaf (i.e., non-cons) of the tree. We check whether something is a cons with consp, and if it is, we recurse onto its car and cdr. We combine the results into a new cons cell by calling cons.
(defun map-over-cons (function tree)
(if (not (consp tree))
(funcall function tree)
(cons (map-over-cons function (car tree))
(map-over-cons function (cdr tree)))))
Alternatively, when we map over a list, we typically check for the terminal condition with endp (or null, but endp emphasizes that we're looking for the end of a list, not just looking for nil), and we call the function on the first of the list and recurse into the rest of the list. While it's pretty common to see the result constructed using cons, there's actually list* that will perform the same task when called with two arguments (in general, it can do a bit more) that emphasizes that a list is being constructed:
(defun map-over-list (function list)
(if (endp list)
'()
(list* (funcall function (first list))
(map-over-list function (rest list)))))
Either of these functions could be written using car, cdr, and cons, or with first, rest, and list*, or any combination of them, but sticking to one or the other helps people that may read the code later (including the original author), and signals the intent of the author.
And how do I eventually implement FIRST/REST using CDR, CAR?
How about:
(defun first (x) (car x))
(defun rest (x) (cdr x))
or possibly even better, if you have symbol-function:
(setf (symbol-function 'first) (symbol-function 'car))
(setf (symbol-function 'rest) (symbol-function 'cdr))
The operations first and rest signals that you are working with a list: a series of pairs ending with the empty list i.e. it is of the form (list x1 ... xn)
The operations car and cdr signals that you are working on a data structure build with pairs, that potentially isn't a list.
That is choose first and rest when you work with lists, to make the code easier for others to read.
Classically, car and cdr have been more machine oriented while first and rest have been more abstract functions. In reality, there is no difference between them. Everyone stuck to car and cdr, so car and cdr prevailed.
If you're having a hard time to finding any differences between car and first, it's because there is none. Look at first as an alias for car.
Definitions?
(defun first (x) (car x))
(defun rest (x) (cdr x))
Firstly, none of these is a predicate (or at least, they aren't what Lisp programmers call "predicates"; in this context, "predicate" means "a function that returns a boolean value").
As to the question, lets hop into a REPL for a minute.
; SLIME 2014-12-23
CL-USER> (describe #'car)
#<FUNCTION CAR>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Return the 1st object in a list.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
CL-USER> (describe #'first)
#<FUNCTION FIRST>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Return the 1st object in a list or NIL if the list is empty.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
CL-USER> (describe #'cdr)
#<FUNCTION CDR>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Return all but the first object in a list.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
CL-USER> (describe #'rest)
#<FUNCTION REST>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Means the same as the cdr of a list.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
So, according to the documentation, and their signatures, car is equivalent to first and cdr is equivalent to rest. Lets test this.
CL-USER> (cons 1 2)
(1 . 2)
CL-USER> (car (cons 1 2))
1
CL-USER> (first (cons 1 2))
1
CL-USER> (cdr (cons 1 2))
2
CL-USER> (rest (cons 1 2))
2
CL-USER> (cons 1 nil)
(1)
CL-USER> (car (cons 1 nil))
1
CL-USER> (first (cons 1 nil))
1
CL-USER> (cdr (cons 1 nil))
NIL
CL-USER> (rest (cons 1 nil))
NIL
CL-USER> nil
NIL
CL-USER> (car nil)
NIL
CL-USER> (first nil)
NIL
CL-USER> (cdr nil)
NIL
CL-USER> (rest nil)
NIL
So, they seem to be the same.

Recursively append the first element of the list to the rest of a list

I am quite new to scheme and I want to take a list such as (1 2 3 4) and send it to a function that will return (4 1 2 3). A second run would return (3 4 1 2) and so on creating a right shifted list with each call to the function.
The first way I figured out to solve this problem is to recursively swap the first and last values of the list. So in scheme I would append the car of the list with the cdr of the list and send the cdr of the list back to my function recursively until only one last swap can be made.
However I am not great with creating recursive functions and I'm having trouble doing it in a new language for me such as scheme. This is what I have tried so far to give an idea of where I want to head.
(define (rShift lst)
(if (null? lst)
'()
(append (cdr lst (car lst))(rShift (cdr lst)))))
The best you can do is take a look at the documentation of your interpreter to see what list functions are available, and construct a solution using them. For example, in Racket using the list procedures will accomplish a straightforward solution:
(define (rShift lst)
(cons ; stick together the solution
(last lst) ; pick the last item
(take lst (sub1 (length lst))))) ; pick all items except the last one
Let's give it a try:
(rShift '(1 2 3 4))
=> '(4 1 2 3)
(rShift (rShift '(1 2 3 4)))
=> '(3 4 1 2)
There are countless ways to solve this problem, I'll leave it to you to find the one that best suits your needs, but remember - always try to solve a problem in terms of the building blocks already at your disposal, and don't reinvent the wheel. Just for fun, here's another way, using reverse:
(define (rShift lst)
(let ((rev (reverse lst)))
(cons (car rev)
(reverse (cdr rev)))))
If you are intent on doing a recursive solution, then you need to ask yourself "what part of the problem can a solve that leaves an identical but smaller part of the problem remaining" and "how do I end the recursion".
For your problem you end the recursion when you have the last element which you then use to add to the front of the list. The problem is that recursing with 'right-shift' can't be sufficient because you need to keep around the list in order to put the last element on its front.
So:
(define (right-shift list)
(if (null? list)
'()
(let shifting ((list list) (result '()))
(if (null? (cdr list))
(cons (car list) (reverse result))
(shifting (cdr list) (cons (car list) result))))))
;; Hey look, it compiles... gosh I love interactive languages.
;; ... and works.
> (right-shift '(1 2 3 4))
(4 1 2 3)
> (right-shift (right-shift '(1 2 3 4)))
(3 4 1 2)

Adding an element to List in Scheme

Below is my code which takes a car element of a list(carVal) and an list(initialized to empty) as parameters. I want to append the element to the list but the same is not working.
(define populateValues
(lambda (carVal currVal)
(append currVal(list carVal ))
(display currVal)))
The display shows empty list all the time () . Can anyone help me understand why?
Well, there is append! as a primitive, which solves most of your problems, as noted already, Scheme tends to frown on mutation, it is possible, but typically avoided, so all procedures that mutate have a ! (called a bang) at their end.
Also, set! does not mutate data, it changes an environment, it makes a variable point to another thing, the original data is left unchanged.
Mutating data in Scheme is quite cumbersome, but, to give you my own implementation of append! to see how it is done:
(define (append! lst . lsts)
(if (not (null? lsts))
(if (null? (cdr lst))
(begin
(set-cdr! lst (car lsts))
(apply append! (car lsts) (cdr lsts)))
(apply append! (cdr lst) lsts))))
Note the use of set-cdr!, which is a true mutator, it only works on pairs, it mutates data in memory, unlike `set!'. If a pair is passed to a function and mutated with set-cdr! or set-car!, it is mutated every-where in the program.
This obeys the SRFI append! spec which says that it should be variadic and that it should return an undefined value, for instance.
(define l1 (list 1 2 3 4))
(define l2 (list 2 3 4))
(define l3 (list 3 1))
(append! l1 l2 l3)
l1
l2
l3
Which displays:
(1 2 3 4 2 3 4 3 1)
(2 3 4 3 1)
(3 1)
As visible, append! can take an infinite number of arguments and it mutates them all but the last.
Scheme might not be the ideal language for you though. The use of append! as said before is nonstandard, instead, append is preferred, which does not mutate and is called for its return value. Which I implement as such:
(define (append . lsts)
(cond
((null? lsts) '())
((null? (car lsts)) (apply append (cdr lsts)))
(else (cons (caar lsts) (apply append (cdar lsts) (cdr lsts))))))
> (append (list 1 2 3) (list 4 5 6) (list 'granny 'porn))
(1 2 3 4 5 6 granny porn)
Which shows a more familiar Scheme style in the absence of mutation, heavy use of recursion
and no use of sequencing.
Edit: If you just want to add some elements to a list and not per se join two though:
(define (extend l . xs)
(if (null? l)
xs
(cons (car l) (apply extend (cdr l) xs))))
(define (extend! l . xs)
(if (null? (cdr l))
(set-cdr! l xs)
(apply extend! (cdr l) xs)))
(extend '(0 1 2 3) 4 5 6)
(define list1 '(0 1 2 3))
(extend! list1 4 5 6)
list1
Which does what you expect
append creates a new list, it does not modify an existing one.
This is because in general, Scheme (and Racket in this case) is a language that prefers functional style.
You could get somewhat closer with a set! -- but even that will disappoint you since it will modify only the local binding.
Note that in Racket in particular, lists are immutable, so there's nothing that can change a list.
Furthermore, even if you could modify a list this way, it's a very inefficient way to accumulate long lists, since you have to repeatedly scan the whole list.
Finally, if you have issues at this level, then I strongly recommend going over HtDP
(append foo bar) returns the concatenation of foo and bar. It doesn't change either foo or bar.
You have to update the value of currVal with set!. Your example should have
(set! currVal (append currVal (list carVal))
(display currVal)
You really need to think about what exact functionality you are looking for
If you want to mutate a referenced list in place, then you have to do the equivalent of append! (as noted in the other answers). But that is dangerous, BECAUSE you may have other code that is counting on the list being immutable, and if you are going to do that, your procedure needs to have a ! in the end to flag that danger.
A cheap approximation to what you want to do, in a more functional style, is:
(define (populateValues carVal currVal)
(let ((ll (append currVal (list carVal))))
(display ll)
ll))
Note that it makes a new list, does the append, displays the result, and RETURNS the new list as a value. This is a useful debugging technique if you don't have access to the intermediate value: bind to a varible, display or log it, and then return it.