Racket : How can I turn a stream into a list? - racket

In Racket, how can I turn a stream into a list?
I assumed that there'd be a common interface, but it seems that list oriented functions like map don't work on streams. So how can I turn them into lists?

There's a procedure for that: stream->list. For example:
(define s (stream 1 2 3 4 5))
(stream->list s)
=> '(1 2 3 4 5)
Make sure to check the documentation, there are several procedures for manipulating streams that mirror the ones available for lists.

There's a straightforwardly-named stream->list function. It's provided from the racket/stream library, and you can see many other list-like functions for streams, including stream-map.
(But if you're using that, note that this library can have severe performance penalties over using streams as is.)

In addition to stream->list, there's also a more general sequence->list that turns any sequence? into a list.
> (sequence->list (stream 1 2 3))
'(1 2 3)
> (sequence->list "abc")
'(#\a #\b #\c)
> (sequence->list (set 1 2 3))
'(1 2 3)

Related

Is there a way to get information about a module at read time?

I've since this summer played around with making a toy language in Racket. Every form has a fixed arity and by default applies so parentheses are not needed. eg. + has arity 2 so + 3 + 4 5 is (+ 3 (+ 4 5)) and + + 3 4 5 is (+ (+ 3 4) 5).
To do this I'm storing in the main module the symbols and their arity. The reader doesn't care if it's a special form or procedure, but is there a better way to do this using features from racket? Thus I can import a module metadata and query that instead during parsing?
Here is one way to go from symbol to arity.
#lang racket
(define base-ns (make-base-namespace))
(define (symbol->arity s)
(parameterize ([current-namespace base-ns])
(procedure-arity (namespace-variable-value s))))
(symbol->arity 'cons)

Can I make a macro that expands into more than one value?

Is there a way to define a racket macro foo so that
(list 1 (foo 2 3) 4)
expands into
(list 1 2 3 4)
?
It's currently not possible (and seems unlikely to change in the near future).
Here's one thread discussing this. See in particular the answer by Matthew Flatt:
allowing splicing of results in function-call
subexpressions would break equivalences that are currently exploited by
macros and the compiler.
As other answers have mentioned, you cannot have a macro expand into more than one value, and have that spliced into the calling context. But you can do something similar using quasiquotation.
Assuming your macro is adapted to return a list instead, you can do this (for your given example):
`(1 ,#(foo 2 3) 4)
Example (tested in Racket):
> `(1 ,#(map sqrt '(2 3)) 4)
'(1 1.4142135623730951 1.7320508075688772 4)

How to watch out for the fact that NREVERSE may modify CARs instead

http://www.aiai.ed.ac.uk/~jeff/lisp/cl-pitfalls states this as one of Common Lisp pitfalls
Destructive functions that you think would modify CDRs might
modify CARs instead. (Eg, NREVERSE.)
I am not sure what precautions I am supposed to take. Usual precaution I can take from the fact that NREVERSE may modify CDRs is to use NREVERSE only when the list (the argument) does not share tail with any other lists that my variables may refer to later (except for the variable I save the return value to). What precaution I should take from the fact that NREVERSE may modify CARs? How is this something to watch out for?
Without any context this is very hard to understand.
Example:
(setq list1 (list 1 2 3 4))
We now have a list of four numbers. The variable list1 points to the first cons.
If we look at a destructive reverse we are talking about an operation which may alter the cons cells. There are different ways how this list can be reversed.
We could for example take the cons cells and reverse those. The first cons cell then is the last. The cdr of that cons cell then has to be changed into NIL.
CL-USER 52 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
CL-USER 53 > (nreverse list1)
(4 3 2 1)
Now our variable list1 still points to the same cons cell, but its cdr has been changed:
CL-USER 54 > list1
(1)
To make sure that the variable points to a reversed list, the programmer then has the duty to update the variable and set it to the result of the nreverse operation. One may also be tempted to exploit the observable result that list1 points to the last cons.
Above is what a Lisp developer usually would expect. Most implementation of reverse seem to work that way. But it is not specified in the ANSI CL standard how nreverse has to be implemented.
So what would it mean to change the CARs instead?
Let's look at an alternative implementation of nreverse:
(defun nreverse1 (list)
(loop for e across (reverse (coerce list 'vector))
for a on list do
(setf (car a) e))
list)
Above function let's the chain of cons cells intact, but changes the car.
CL-USER 56 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
Now let's use the new version, nreverse1.
CL-USER 57 > (nreverse1 list1)
(4 3 2 1)
CL-USER 58 > list1
(4 3 2 1)
Now you see the difference: list1 still points to the whole list.
Summary: one needs to be aware that there are different implementations of nreverse possible. Don't exploit the usual behavior, where a variable then will point to the last cons. Just use the result of nreverse and everything is fine.
Side note: where could the second version have been used?
Some Lisp implementations on Lisp Machines allowed a compact vector-like representation of lists. If on such a Lisp implementation one would nreverse such a list, the implementors could provide an efficient vector-like nreverse.
In any case, be it CAR or CDR of cons cell modified, you shouldn't use NREVERSE if any cons cell (including first cons cell) of passed list may be shared with another list. Use REVERSE instead.
BTW, clisp indeed modifies CARs:
> (let ((a (list 1 2 3 4 5 6 7 8 9 0)))
(nreverse a)
a)
(0 9 8 7 6 5 4 3 2 1)

Why do we need `nil`?

I do not see why we need nil [1] when to cons a sequence (so-called proper list) of items. It seems to me we can achieve the same goal by using the so-called improper list (cons-ed pairs without an ending nil) alone. Since Lisps [2] have already provided a primitive procedure to distinguish between a pair? and an atom (some implementations even provide atom?), when defining a procedure on a list, e.g., length, I can do the same with just dotted-pairs, as shown below:
(define len
(lambda (l)
(cond ((pair? l) (+ 1 (len (cdr l))))
(else 1) ) ) )
It is obvious that we can apply this procedure to an improper list like '(1 . (2 . 3)) to get the expected answer 3, in contrast to the traditional (length '(1 2 3)).
I'd like to hear any opinions in defense of the necessity of nil. Thanks in advance.
[1] Let's ignore the debate among nil/NIL, '() and ().
[2] Here it means the Lisp family of languages.
Working with lists without nil (or '()) would be like doing arithmetic without zero. Using only pairs without nil, how would we represent an empty list, or a singleton list '(1)?
It gets worse: since lists don't have to be lists of atoms, but can contain other lists, how would we represent the nested list '(1 2 (3 4))? If we do the following conversions:
'(3 4) => '(3 . 4)
'(1 2 x) => '(1 . (2 . x)) == '(1 2 . x)
we get:
'(1 2 (3 4)) => '(1 . (2 . (3 . 4))) == '(1 2 3 . 4)
But also:
'(1 2 3 4) => '(1 . (2 . (3 . 4))) == '(1 2 3 . 4)
So constructing lists only using pairs and no nil prevents us from distinguishing between a nested list structure and a flat list, at least at the end of the list. You can still include nested lists as any element except the last, so now there's a strange and arbitrary limitation on what the elements of a list can be.
More theoretically, proper lists are an inductively defined data type: a list is either the empty list, or it has a first element, which can be anything, and a rest, which is always another list defined in the same way. Take away the empty list, and now you have a data type where the rest might be another list, or it might be the last element of the list. We can't tell except by passing it to pair?, which leads to the problem with nested listing above. Keeping nil around lets us have whatever we like as list elements, and allows us to distinguish between 1, '(1), '((1)) and so on.
You need it to represent "Nothing".

Using lists with Common LISP

I'm just starting out with LISP, as in, just opened the book, I'm two pages into it. I'm trying to understand what is and what is not an acceptable fn call. Every time I try to execute
(1 2 3 4)
I get an illegal fn call error
same goes for
(cdr (1 2 3 4))
(first (1 2 3 4))
(a b c d)
Are CL programs unable to return lists? How would I go about using these functions or printing a list? I'm using the SLIME implementation if it matters. LISP is very different than anything I've worked with before and I want to be sure I'm getting it conceptually.
You need to quote lists if you are using them as constants. Otherwise, the system will try to call the function 1 on the arguments 2 3 4, which will not work (note that function calls have the same syntax as lists). Your examples should be:
'(1 2 3 4)
(cdr '(1 2 3 4))
(first '(1 2 3 4))
'(a b c d)
Hooo boy.
Look up Practical Common Lisp by Seibel. He's such a nice guy, he put it online for free reading. It's very useful.
Part of the definition of Lisp is this rule:
When a list is seen: Using the first element of the list, apply it to the rest of the list.
But wait: How do you actually enter lists then? There are two functions to do this: QUOTE and LIST.
As an example, let's print a list to the screen on standard out:
(format *standard-output* "~a" '(1 2 3 4))
For format, *standard-output* is aliased to t (well, at least in SBCL!), so usually we see (format t ....