Creating an empty list in Racket - list

I'm teaching myself LISP with online text of Structure and Interpretation of Computer Programs, but it differs in small details with the Racket program I'm running to learn LISP on. For example, SICP says that the terminating element of any list is 'nil', but Racket doesn't support 'nil'. How do I create an empty list in Racket so I can test my own procedures?

The empty list is denoted '(). So you can create a list like
(cons 1 (cons 2 (cons 3 '())))
This produces the list
'(1 2 3)

Sean's answer is correct. However, if you want to be able to type nil, then that's easy too. Just run this once at the start of your session:
(define nil '())

In Racket the empty list is designated as either:
'()
or as:
null
I would say that null is probably the more idiomatic of the two, and it dovetails consistently with the predicate null?, which tests for the empty list.
See the docs.

Related

Racket lists incompatible with r6rs?

I'm writing a program in which i have to reuse code from one of my professors. My program is written in Racket and the code i want to reuse is written in r6rs.
When I want to test my program it always fails.
This is because I call a procedure with as argument a list (racket list), but that procedure is in the R6RS file. In the R6RS file there is (assert (list? argument)) , this is always false...
Here a simple example :
Racket code :
#lang racket
(require "test2.ss")
(define a (list 1 2 3))
(b a)
R6RS code :
#!r6rs
(library
(test)
(export b)
(import (rnrs base (6))
(rnrs control (6))
(rnrs lists (6))
(rnrs io simple (6)))
(define (b a)
(display "a is : ") (display a) (newline)
(display "list? : ") (display (list? a)) (newline)))
The list? test in the R6RS file is always false... even if I pass as argument a newly created list like in the above example.
How can I do the same as in the example above, so that the list? tests results true.
Thanks for your help!
EDIT : I could not find a r6rs test that results in true on a immutable list, but I found another way to resolve my problem (by passing a mutable list to the procedure).
Racket pairs are different from Scheme pairs since Racket pairs are immutable while Scheme pairs are not.
As far as I know, there is no way to check for Racket's immutable lists in pure RnRS Scheme. However, it is possible to use Scheme's mutable lists in Racket (though of course that isn't really recommended).
#lang racket
(require compatibility/mlist
"test2.ss")
(define a (mlist 1 2 3))
(b a)
Here's an excerpt from the documentation for compatibility/mlist:
This compatibility/mlist library provides support for mutable lists. Support is provided primarily to help porting Lisp/Scheme code to Racket.
Use of mutable lists for modern Racket code is strongly discouraged. Instead, consider using lists.
Still, if you need to interact with Scheme code, that's probably your only reasonable option.
This is just an addendum to Alexis King's answer (code examples can't be in comments). Since the r6rs language (as implemented in Racket) uses mutable lists, and all racket libraries expect immutable lists, you can't reuse the r6rs code as-is. The fastest way to reuse the code is to port it to the #lang racket language.
Change the language, remove the import statement, and then fix each error one at a time.
#lang racket
(define (b a)
(display "a is : ") (display a) (newline)
(display "list? : ") (display (list? a)) (newline)))
When you say your code is written in Racket. Do you mean Racket, the software, or #!racket, one of the multiple compatible languages that Racket (the software) supports?
Since your library is written in #!r6rs, you either need to port it to a #!racket module or you main program can be written in #!r6rs and you can use the library as is. A third option is to make mutable lists to pass to the library function and convert back but or ban lists all togerther, but I find this option somewhat suboptimal.
To do full #!r6rs you need to install your library like this:
plt-r6rs --force --install ./test.sls
I assume test.sls is in the current directory. You'll get a confirmation. you need not restart DrRacket. (Force is not needed, but it will overwrite an earlier version.) Then you just change your code to be Scheme code:
#!r6rs
(import (rnrs)
(test))
(define a (list 1 2 3))
(b a) ; #<void> (and prints stuff to stdout)
Hit [Run] in DrRacket and see the magic!

Scheme - Testing if argument is a list (proper or improper)

I'm very new to scheme and am trying to figure out how to define a function that tests if the parameter to that function is a list, where being a proper list doesn't matter.
I've discerned that I need to check if the argument is either the empty list or a pair. I have the empty list case working fine, but I'm not sure how to check for the pair. I'm just coming off working with prolog, so my initial thought was to do something like this:
(define list?
(lambda (ls)
(if (or (eq? ls (quote()))
(cons(car(ls) cdr(ls))))
true false)))
My thinking was that if scheme could car and cdr the parameter, then it must be a pair, and it would return true. Otherwise it would just fail.
However, passing the argument '(1 2) yields this result:
(list? '(1 2))
. . application: not a procedure;
expected a procedure that can be applied to arguments
given: (1 2)
arguments...: [none]
I don't really understand what's going on here. Additionally, I feel like my thinking as to how to make this function is flawed, but I don't really know how to correct it.
EDIT: Is the issue that (if .....) is looking for a boolean from cons?
You have right idea! But the main reason why your code is not working is that on fourth line you have wrong brackets. This is right transcription of your code:
(define list?
(lambda (ls)
(if (or (eq? ls (quote()))
(cons (car ls) (cdr ls)))
#t #f)))
But in my opinion this solution is bad for these reasons:
If you supply improper list to this procedure it will end by an error when trying to do car or cdr.
For example: (1 2 3 . 4) will end by an error.
In Scheme you have to use literals #t and #f to denote true and false.
Cons always end by "true"
It will not check entire list.
I would write that procedure like this:
(define list?
(lambda (ls)
(if (null? ls)
#t
(and (pair? ls)
(list? (cdr ls))))))
Lets try this on an example: (3 . 4). It is just pair - not a list.
The ls is (3 . 4). Is it null? No, then continue to second if branch.
Is it pair? Yes - continue in and and recursively call list? with 4
The ls is 4. Is it null? No. Again, continue to second branch.
Is it pair? No! Procedure returns #f

Scheme list always in reverse order

Probably a trivial question for most of the more advanced schemers here, but as a newcomer, I've found this to be a problem.
I need a way to construct a new list that is in the same order it was when it came in. As an example, say we are given a list '(1 2 0 3 4 0 0 5). But traversing the list and passing the cdr back as the 1st argument ends up constructing the new list backwards.
Here's an example in code:
I pass it an "old-list" that needs work done on it and an empty list as "new-list" to be formed and returned.
note that taking 0s out is just here as "some condition" that the new list must meet
(define (form-new-list old-list new-list)
(cond ((null? old-list) new-list)
(else
(if (eq? (car old-list) 0) (form-new-list (cdr old-list) new-list)
(form-new-list (cdr old-list) (cons (car old-list) new-list))))))
;test
(form-new-list '(1 2 0 3 4 0 0 5) '()) ; gives (5 4 3 2 1)
;but want (1 2 3 4 5)
I DO NOT just want to reverse the list that is returned with a reverse procedure, but rather, want the new list to be put together in the correct order in the first place.
Is there some kind of "trick" to this, like making the recursive call somewhere else perhaps?
Any advice is greatly appreciated.
You're looking for the natural way to traverse a list using recursion. Use this procedure as a template for your solution - it simply copies a list exactly as it is received:
(define (copy lst)
(if (null? lst)
'()
(cons (car lst)
(copy (cdr lst)))))
Notice the following points:
The recursion ends when the input list is null, and given that we're building a new list, the correct value to return is the null list
We're interested in building a new list, we do this by consing a new element for the output list, which in this case happens to be the first element of the input list (its car part)
Finally, the recursive step advances by invoking the procedure with the rest of the input list (its cdr part)
As usual, I end up my answers to people learning how to think recursively by recommending you take a look at either The Little Schemer or How to Design Programs, both books will teach you how to grok recursive processes in general, using Scheme.

Racket - output content of a list

I have defined a list (in Racket/Scheme):
(define myList (cons 'data1 (cons 'data2 (cons 'data3 (cons 'data4 empty)))))
or
(list 'data1 'data2 'data3 'data4)
And I want to write a function that cycles through the list and outputs all values of the list.
(define (outputListData list)
(cond
[(null? list) list]
[else (getListData)]))
With what function can I cycle through the content of the list? I know one can use first & rest to get list data, but I guess that's not the right way here.
BTW: Is there a good, compact racket reference like php.net? I find the official Racket docs very confusing ...
You can use a for loop. Example:
(for ([x (list 1 2 3)])
(printf "~s -> ~s\n" x (* x x)))
There are more functional ways to do this, of course, but this way works too. You'll probably want to look at a textbook like How To Design Programs to do the recursive approach. See: http://www.ccs.neu.edu/home/matthias/HtDP2e/
dyoo's solution is nice and succinct in a Scheme like Racket that has useful iteration routines built in. Just FYI, though, your 'outputListData' is not far from being the standard recursive way to do this. You just need to change a couple of lines:
(define (outputListData list)
(cond
[(null? list) #f] ; actually doesn't really matter what we return
[else (printf "~s\n" (first list)) ; display the first item ...
(outputListData (rest list))])) ; and start over with the rest
Since this is an "imperative" kind of procedure that isn't designed to return a value, it doesn't really matter what we do with an empty list so long as we stop recurring (to avoid an infinite loop). If the list isn't empty, we output the first element and start over recursively with the rest of the list.
BTW, here's another way you could write something almost identical if you just needed a "for" loop in the middle of some other function:
(let loop ((l (list 'foo 'bar 'baz 'quux))) ; or put whatever input you need
(cond ((null? l) #f)
(else
(printf "~s\n" (first l))
(loop (rest l)))))
One way to think about this "named let" is that it defines a temporary function called loop, which works just like outputListData above. Scheme has the nice property that it won't grow the stack for "tail calls" like these, so you can always write what would be an "iterative" for or while loop in this recursive style.
I highly recommend The Little Schemer by Friedman and Felleisen for a quick intro to this style of function writing! I found it through Douglas Crockford's page here.
Edit as per comments: Use for-each
(for-each display myList)
Try this:
(void (map display myList))
Breaking it down:
(void x) causes x to be ignored instead of returned to the REPL/parent expression as a value.
(map function lst): For a list '(a1 a2 ... an) returns the list '((function a1) (function a2) ... (function an)).
So we use map to display all the items, but since we only care about the side-effect and not the return value, we call void on the returned list.
Official docs:
void
map
I think the solution that is the easiest to understand it to come up with a so called "list-eater" function. This is the way my university introduced recursion and lists in Racket. Also most books on Racket (i.e. "How To Design Programs" or "Realm Of Racket") explain it this way. This is the code:
(define my-list (list 'data1 'data2 'data3 'data4))
(define (print-list a-list-of-data)
(when (not (empty? a-list-of-data))
(print (first a-list-of-data))
(print-list (rest a-list-of-data))))
If you call the function with the example list my-list, you will get the following output:
(print-list my-list)
'data1'data2'data3'data4
The function does the following: As long as the given list is not empty, it grabs the first element of that list and passes it to the function print. Then, it tells itself to do the exact same thing with the rest of the list. (It calls itself on the rest of the list.) This second part is what they call recursion.
However, you can shorten that by using a function called map:
(define (print-list a-list-of-data)
(map print a-list-of-data))
This basically says that you want the function print to be called on each element of the given list. The output is exactly the same.
Hope it helped!

common lisp cons creates a list from two symbols, clojure cons requires a seq to cons onto?

(Disclaimer - I'm aware of the significance of Seqs in Clojure)
In common lisp the cons function can be used to combine two symbols into a list:
(def s 'x)
(def l 'y)
(cons s l)
In clojure - you can only cons onto a sequence - cons hasn't been extended to work with two symbols. So you have to write:
(def s 'x)
(def l 'y)
(cons s '(l))
Is there a higher level pattern in Clojure that explains this difference between Common LISP and Clojure?
In Clojure, unlike traditional Lisps, lists are not the primary data structures. The data structures can implement the ISeq interface - which is another view of the data structure it's given - allowing the same functions to access elements in each. (Lists already implement this. seq? checks whether something implements ISeq.(seq? '(1 2)), (seq? [1 2])) Clojure simply acts differently (with good reason), in that when cons is used, a sequence (it's actually of type clojure.lang.Cons) constructed of a and (seq b) is returned. (a being arg 1 and b arg 2) Obviously, symbols don't and can't implement ISeq.
Clojure.org/sequences
Sequences screencast/talk by Rich Hickey However, note that rest has changed, and it's previous behaviour is now in next, and that lazy-cons has been replaced by lazy-seq and cons.
clojure.lang.RT
In Common Lisp CONS creates a so-called CONS cell, which is similar to a record with two slots: the 'car' and the 'cdr'.
You can put ANYTHING into those two slots of a cons cell.
Cons cells are used to build lists. But one can create all kinds of data structures with cons cells: trees, graphs, various types of specialized lists, ...
The implementations of Lisp are highly optimized to provide very efficient cons cells.
A Lisp list is just a common way of using cons cells (see Rainer's description). Clojure is best seen as not having cons cells (although something similar might hide under the hood). The Clojure cons is a misnomer, it should actually just be named prepend.
In Clojure the use of a two-element vector is preferred: [:a :b]. Under the hood such small vectors are implemented as Java arrays and are extremely simple and fast.
A short hand for (cons :a '(:b)) (or (cons :a (cons :b nil))) is list: (list :a :b).
When you say
> (cons 'a 'b)
in common lisp you dont get a list but a dotted pair: (a . b), whereas the result of
> (cons 'a (cons 'b nil))
is the dotted pair (a . ( b . nil)).
In the first list the cdr() of that is not a list, since it is here b and not nil, making it an improper list. Proper lists must be terminated by nil. Therefore higher order functions like mapcar() and friends won't work, but we save a cons-cell. I guess the designers of Clojure removed this feature because of the confusion it could cause.