Scheme: "mcar: contract violation, expected: mpair, given: #<procedure:..."
Solution 1
This can be solved with the SRFI41 Streams library. It's available in many implementations including Racket. Racket also has it's own stream library with many similar procedures/syntax. SRFI41 is available from both #!Racket and #!R6RS.
;(import (rnrs) (srfi :41)) ; For #!R6RS language
(require srfi/41) ; For #!Racket language
(definestream (filteroutmultipliers n v stream)
(let ((a (streamcar stream)))
(cond ((< a n) (streamcons a (filteroutmultipliers n v (streamcdr stream))))
(else (filteroutmultipliers (+ n v) v (if (= a n) (streamcdr stream) stream))))))
(definestream (primes stream)
(let ((a (streamcar stream)))
(streamcons a (primes (filteroutmultipliers (+ a a) a (streamcdr stream))))))
(stream>list (streamtake 20 (primes (streamfrom 2))))
; ==> (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71)
Solution 2
I managed to answer my own question shortly after posting and wanted to share my solution.
In filteroutmults$, each
(cdr lst)
needed to be
((cdr lst))
Since intbuilder$ is a stream, it returns pairs containing an integer and a procedure to get the next integer token. For example:
> (intbuilder$ 2)
(2 . #<procedure:...primestream.rkt:10:8>)
In order to get the next integer, the procedure needs to be invoked. The problem was that (cdr lst) would return the procedure, but not invoke it. To illustrate:
> (cdr (intbuilder$ 2))
#<procedure:...primestream.rkt:10:8>
Once the extra parentheses were added, the next pair was returned:
> ((cdr (intbuilder$ 2)))
(3 . #<procedure:...hedgerh.lab6.rkt:10:8>)
Hopefully that helps someone.
Here is the full definition of filteroutmults$:
(define filteroutmults$
(lambda (num lst)
(if (null? lst)
'()
(if (= (modulo (car lst) num) 0)
(filteroutmults$ num ((cdr lst)))
(cons (car lst) (lambda () (filteroutmults$ num ((cdr lst)))))))))
Comments

Harry Hedger 6 months
I am trying to use streams to generate a list of prime numbers in Scheme and I am encountering an error that I can't seem to wrap my head around. I have been spending hours trying different things and feel like I somewhat understand the problem, but I can't quite wrap my head around it. I have looked at similar posts, but I don't think I'm experienced enough to be able to relate them to my problem.
(define intbuilder$ (lambda (n) (cons n (lambda() (intbuilder$ (+ n 1)))))) (define filteroutmults$ (lambda (num lst) (if (= (modulo (car lst) num) 0) (filteroutmults$ num (cdr lst)) (cons (car lst) (lambda () (filteroutmults$ num (cdr lst))))))) (define take$ (lambda (m s) (if (or (= m 0) (null? s)) '() (cons (car s) (take$ ( m 1) ((cdr s)))))))
intbuilder$ generates an infinite stream of integers starting at n. filteroutmults$ should filter out any nonprime numbers. take$ takes the first m primes from the list.
Here is how I am running it, along with the error message:
> (take$ 10 (filteroutmults$ 2 (intbuilder$ 2))) mcar: contract violation expected: mpair? given: #<procedure:.../primestream.ss:10:8>
I believe the problem has to do with how filteroutmults$ is called in the if/else statement, in that a new int/procedure pair is not passed in, but I can't seem to figure out how to fix it. Any help would be greatly appreciated.

leppie over 8 years
(cons n (lambda() (intbuilder$ (+ n 1))))
and then(filteroutmults$ num (cdr lst))
=> KABOOM! (you probably wantlist
instead ofcons
there) 
Harry Hedger over 8 yearsI figured it out. As I mentioned in my edit, I needed an extra set of parentheses around (cdr lst) in order to invoke it. The lambda prior to (filteroutmults$ num ((cdr lst))) actually makes the procedure lazy so that it doesn't go forever. Thanks for the help!

Sylwester over 8 yearsWhy don't you use SRFI41 Streams library?

leppie over 8 yearsYou should post your solution as the answer.
