The Scheme implementation of map takes N+1 arguments: a procedure of N arguments, and N lists. Further, it terminates mapping when the end of the shortest list is reached.
An alternative is to provide a default value for each list, which will be treated as the next element(s) of each list if it turns out to be shorter than the others.
That is define a procedure streem-map which takes as its arguments:
a procedure of N arguments
a list of N elements, which is the default value for the Nth stream
N streams
Streem-map produces a stream where the first element is the procedure applied to the (N) first elements of the streams, the second element is the same procedure applied to the second elements of the streams, and so on. If the Nth stream becomes empty, streem-map uses the Nth default element. Therefore, the stream produced by streem-map will always have infinite length; if all of the N input streams are of finite length, eventually it will generate lists consisting of the
procedure applied to the N default values.
For example:
(streem-map (lambda (x y z) (* x y z))
‘(0 1 2)
(list->streem ‘(1 2 3))
(list->streem ‘(9 9))
(list->streem ‘(4))
would generate the infinite stream consisting of: ‘(36 36 6 0 0 0 …)
Let's first define a set of basic stream primitives, so that the rest of the code makes sense:
(define-syntax stream-cons
(syntax-rules ()
((stream-cons obj expr)
(cons obj (delay expr)))))
(define stream-car car)
(define (stream-cdr p) (force (cdr p)))
(define stream-null? null?)
With these we can define operations for "streems", our "better streams".
(define (streem-car stream default)
(if (stream-null? stream) default (stream-car stream)))
(define (streem-cdr stream)
(if (stream-null? stream) stream (stream-cdr stream)))
(define (streem-map proc defaults . streams)
(stream-cons (apply proc (map streem-car streams defaults))
(apply streem-map proc defaults (map streem-cdr streams))))
You should be able to easily adapt this to whatever stream library you are already using.
You don't need a separate list->streem conversion, you can pass streem-map regular streams (presumably created with list->stream).
If you use the streams of SRFI-41, this is just an application of stream-unfold. Note: I am the author of SRFI-41.
Related
I am implementing a procedure that takes a number n and a stream, and returns a new stream with the n first elements in the streams
(define (stream-take n stream)
(cond ((stream-null? stream)
(the-empty-stream))
((= n 0) ('()))
(else
(cons (car stream)
(stream-take (- n 1)
(force (cdr stream))
)))))
(stream-take 10 nats)
this code gives the error message
=: contract violation
expected: number?
given: (2 . #<promise>)
argument position: 1st
other arguments...:
('()))
is not a stream. It should return
(the-empty-stream)
instead.
PS:
Note also, I have edited your original post and added (else ...) at the final clause.
('())) means to call the function '(), which for sure won't be a function.
Let a NODE be a function with a STORE in its closure. All leafs of the graph have a STORE that is a single value (either a constant or a variable) and all internal nodes have a STORE that is a list containing:
A symbol representing a function ('+ '* 'cos 'sin etc)
A list of one or more NODES representing the children of this NODE.
A simplification function (which is irrelevant for my question).
Assume [[(NODE f)]] = [[(f STORE)]] if f is a procedure and STORE is the STORE in NODE'S closure.
I am trying to find a way to traverse this tree and print an expression that can be evaluated with (eval). I have come close but I just cannot get it to work.
Here is my code:
(define repr
(lambda(store)
(if (is_leaf? store)
store
(list (car store)
(repr_helper (cadr store) repr)))))
(define repr_helper
(lambda(f_list arg)
(cond ((null? f_list) '())
(else (cons ((car f_list) arg) (repr_helper (cdr f_list) arg))))))
Simple exemple: Assume a tree with a single addition of 4 arguments (creates a + node with 4 children all of which are leaves).
((Add 10 'x 'y 'z) repr)
Output: '(+ (10 x y z)).
Expected output: '(+ 10 x y z)
As you can see the problem comes from the extra parenthesis inside the expression. You can imagine this is even worse for more complex examples. I understand where I create the list and why the parenthesis is there, but I can't seem to find a way to remove it, print the values correctly.
Try modifying the part that builds the list, like this:
(define repr
(lambda (store)
(if (is_leaf? store)
store
(cons (car store)
(repr_helper (cadr store) repr)))))
We just need to add a new item at the head of the list returned by repr_helper, a call to cons will do the trick.
I am wondering how the substitution model can be used to show certain things about infinite streams. For example, say you have a stream that puts n in the nth spot and so on inductively. I define it below:
(define all-ints
(lambda ((n <integer>))
(stream-cons n (all-ints (+ 1 n)))))
(define integers (all-ints 1))
It is pretty clear that this does what it is supposed to, but how would someone go about proving it? I decided to use induction. Specifically, induction on k where
(last (stream-to-list integers k))
provides the last value of the first k values of the stream provided, in this case integers. I define stream-to-list below:
(define stream-to-list
(lambda ((s <stream>) (n <integer>))
(cond ((or (zero? n) (stream-empty? s)) '())
(else (cons (stream-first s)
(stream-to-list (stream-rest s) (- n 1)))))))
What I'd like to prove, specifically, is the property that k = (last (stream-to-list integers k)) for all k > 1.
Getting the base case is fairly easy and I can do that, but how would I go about showing the "inductive case" as thoroughly as possible? Since computing the item in the k+1th spot requires that the previous k items also be computed, I don't know how this could be shown. Could someone give me some hints?
In particular, if someone could explain how, exactly, streams are interpreted using the substitution model, I'd really appreciate it. I know they have to be different from the other constructs a regular student would have learned before streams, because they delay computation and I feel like that means they can't be evaluated completely. In turn this would man, I think, the substitution model's apply eval apply etc pattern would not be followed.
stream-cons is a special form. It equalent to wrapping both arguments in lambdas, making them thunks. like this:
(stream-cons n (all-ints (+ 1 n))) ; ==>
(cons (lambda () n) (lambda () (all-ints (+ n 1))))
These procedures are made with the lexical scopes so here n is the initial value while when forcing the tail would call all-ints again in a new lexical scope giving a new n that is then captured in the the next stream-cons. The procedures steam-first and stream-rest are something like this:
(define (stream-first s)
(if (null? (car s))
'()
((car s))))
(define (stream-rest s)
(if (null? (cdr s))
'()
((cdr s))))
Now all of this are half truths. The fact is they are not functional since they mutates (memoize) the value so the same value is not computed twice, but this is not a problem for the substitution model since side effects are off limits anyway. To get a feel for how it's really done see the SICP wizards in action. Notice that the original streams only delayed the tail while modern stream libraries delay both head and tail.
Just started with Scheme. I'm having problem with printing on console.
A simple list printing example:
(define factorial
(lambda (n)
(cond
((= 0 n) 1)
(#t (* n (factorial (- n 1)))))))
I want to print n, every time the function is called. I figured that I can't do that within the same function? Do I need to call another function just so I can print?
Printing in Scheme works by calling display (and possibly, newline).
Since you want to call it sequentially before/after something else (which, in a functional (or in the case of Scheme, functional-ish) language only makes sense for the called functions side-effects), you would normally need to use begin, which evaluates its arguments in turn and then returns the value of the last subexpression. However, lambda implicitly contains such a begin-expression.
So in your case, it would go like this:
(lambda (n)
(display n) (newline)
(cond [...]))
Two remarks:
You can use (define (factorial n) [...]) as a shorthand for (define factorial (lambda (n) [...])).
The way you implement factorial forbids tail call-optimization, therefore the program will use quite a bit of stack space for larger values of n. Rewriting it into a optimizable form using an accumulator is possible, though.
If you only want to print n once, when the user calls the function, you will indeed need to write a wrapper, like this:
(define (factorial n)
(display n) (newline)
(inner-factorial n))
And then rename your function to inner-factorial.
Can anybody explain an example in Paul Graham's ANSI Common Lisp page 110?
The example try to explain the use &rest and lambda to create functional programming facilities. One of them is a function to compose functional arguments. I cannot find anything explaining how it worked. The code is as follows:
(defun compose (&rest fns)
(destructuring-bind (fn1 . rest) (reverse fns)
#'(lambda (&rest args)
(reduce #'(lambda (v f) (funcall f v))
rest
:initial-value (apply fn1 args)))))
The usage is:
(mapcar (compose #'list #'round #'sqrt)
'(4 9 16 25))
The output is:
((2) (3) (4) (5))
Line 2 and 6 look especially like magic to me.
The compose function returns a closure that calls each of the functions from last to first, passing on the result of each function call to the next.
The closure resulting from calling (compose #'list #'round #'sqrt) first calculates the square root of its argument, rounds the result to the nearest integer, then creates a list of the result. Calling the closure with say 3 as argument is equivalent to evaluating (list (round (sqrt 3))).
The destructuring-bind evaluates the (reverse fns) expression to get the arguments of compose in reverse order, and binds its first item of the resulting list to the fn1 local variable and the rest of the resulting list to the rest local variable. Hence fn1 holds the last item of fns, #'sqrt.
The reduce calls each the fns functions with the accumulated result. The :initial-value (apply fn1 args) provides the initial value to the reduce function and supports calling the closure with multiple arguments. Without the requirement of multiple arguments, compose can be simplified to:
(defun compose (&rest fns)
#'(lambda (arg)
(reduce #'(lambda (v f) (funcall f v))
(reverse fns)
:initial-value arg)))
destructuring-bind combines destructors with binding. A destructor is a function that lets you access a part of a data structure. car and cdr are simple destructors to extract the head and tail of a list. getf is a general destructor framework. Binding is most commonly performed by let. In this example, fns is (#'list #'round #'sqrt) (the arguments to compose), so (reverse fns) is (#'sqrt #'round #'list). Then
(destructuring-bind (fn1 . rest) '(#'sqrt #'round #'list)
...)
is equivalent to
(let ((tmp '(#'sqrt #'round #'list)))
(let ((fn1 (car tmp))
(rest (cdr tmp)))
...))
except that it doesn't bind tmp, of course. The idea of destructuring-bind is that it's a pattern matching construct: its first argument is a pattern that the data must match, and symbols in the pattern are bound to the corresponding pieces of the data.
So now fn1 is #'sqrt and rest is (#'round #'list). The compose function returns a function: (lambda (&rest args) ...). Now consider what happens when you apply that function to some argument such as 4. The lambda can be applied, yielding
(reduce #'(lambda (v f) (funcall f v))
'(#'round #'list)
:initial-value (apply #'sqrt 4)))
The apply function applies fn1 to the argument; since this argument is not a list, this is just (#'sqrt 4) which is 2. In other words, we have
(reduce #'(lambda (v f) (funcall f v))
'(#'round #'list)
:initial-value 2)
Now the reduce function does its job, which is to apply #'(lambda (v f) (funcall f v)) successively to the #'round and to #'list, starting with 2. This is equivalent to
(funcall #'list (funcall #'round 2))
→ (#'list (#'round 2))
→ '(2)
Okay, here goes:
It takes the functions given, reverses it (in your example, it becomes (#'sqrt #'round #'list)), then sticks the first item into fn1, and the rest into rest. We have: fn1 = #'sqrt, and rest = (#'round #'list).
Then it performs a fold, using (apply sqrt args) (where args are the values given to the resulting lambda) as the initial value, and with each iteration grabbing the next function from rest to call.
For the first iteration you end up with (round (apply sqrt args)), and the second iteration you end up with (list (round (apply sqrt args))).
Interestingly, only the initial function (sqrt in your case) is allowed to take multiple arguments. The rest of the functions are called with single arguments only, even if any particular function in the chain does a multiple-value return.
This example stumped me for a day. I could finally understand it by renaming some of the arguments and commenting each line before it made sense. Below is what helped me explain it to myself.
In the book example using the call:
(mapcar (compose #'list #'round #'sqrt) '(4 9 16 25))
The parameter functions becomes (#'LIST #'ROUND #'SQRT)
(defun compose (&rest functions)
(destructuring-bind (fx . fxs) (reverse functions)
;; fx becomes #'SQRT
;; fxs becomes '(#'ROUND #'LIST)
#'(lambda (&rest args) ; This is the function returned as result.
;; The args parameter will be (4) on the mapcar's first
;; iteration on the (4 9 16 25) list passed in the call:
;; (mapcar #'(compose #'List #'round #'sqrt) '(4 9 16 25)) => ((2) (3) (4) (5))
;; or e.g. the (4) in (funcall (compose #'list #'sqrt '(4)) => (2.0)
;; Note that args is not ((#'ROUND #'LIST)).
(reduce #'(lambda (x y) (funcall y x))
;; fxs is (#'ROUND #'LIST) - captuted as closure since it is now
;; locally unbound.
fxs
;; Initial value is: (apply #'SQRT '(4) => 2.0.
;; In Paul Graham's example, the mapcar passes
;; each square number individually.
;; The reverse order of parameters in the second lambda
;; first invokes: (ROUND 2.0) => 2
;; and then invokes: (LIST 2) => (2)
:initial-value (apply fx args)))))