About how to profiling with-stack-sampling: - scheme

Supposed MIT-Scheme 9.2 and these procedures:
(define (max x y) (if (<= x y) y x))
(define (maxall l) (reduce max 0 l))
the procedures are compiled (p. 51, Ch. 6 in User's Manual):
1 ]=> maxall
;Value 3: #[compiled-procedure 3 ("foo" #x4) #x3 #x1b9ee4]
and it works:
1 ]=> (maxall '(1 3 2))
;Value: 3
but profiling with with-stack-sampling failed:
1 ]=> (with-stack-sampling 10 maxall)
;Stack-sampling...
;The procedure #[compiled-procedure 3 ("foo" #x4) #x3 #x1b9ee4] has been called with 0 arguments; it requires exactly 1 argument.
;To continue, ...
Interpreter says wrong number of arguments, but I don't think so
because the usage of with-stack-sampling is described in p. 51 of User's manual:
with-stack-sampling interval procedure
Applies procedure to zero arguments. ...,
How did I do wrong? and How should I apply the function to an argument with profiling it?

Related

Getting an wrong answer in scheme program

I am trying to find the cube root of a number using Newton's method. I wrote scheme procedures as follows:
(define (cbrt x)
(cbrt-iter 1.0 x))
(define (cbrt-iter guess x)
(if (good-enough? guess x) guess (cbrt-iter (improve guess x) x)))
(define (good-enough? guess x)
(< (- guess (improve guess x)) 0.00001))
(define (improve guess x)
(/ (+ (/ x (* guess guess)) (* 2 guess)) 3))
(cbrt 27)
(cbrt 8)
(cbrt 64)
Actually I am working on Exercise 1.8 of the famous (or may be infamous) book SICP. then I run scheme < cuberoot.scm and got the following result:
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2019 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Thursday September 5, 2019 at 11:51:46 AM
Release 10.1.10 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118
1 ]=> (define (cbrt x)
(cbrt-iter 1.0 x))
;Value: cbrt
1 ]=> (define (cbrt-iter guess x)
(if (good-enough? guess x) guess (cbrt-iter (improve guess x) x)))
;Value: cbrt-iter
1 ]=> (define (good-enough? guess x)
(< (- guess (improve guess x)) 0.00001))
;Value: good-enough?
1 ]=> (define (improve guess x)
(/ (+ (/ x (* guess guess)) (* 2 guess)) 3))
;Value: improve
1 ]=> (cbrt 27)
;Value: 1.
1 ]=> (cbrt 8)
;Value: 1.
1 ]=> (cbrt 64)
;Value: 1.
1 ]=>
End of input stream reached.
Post proelium, praemium.
The program is always producing 1. as a result. I also tried adjusting the threshold value in good-enough? procedure from 0.00001 to 0.0001 and so on but that didn't worked.
Please explain what went wrong and how to fix that.
You need to include an (abs ...) in good-enough?, otherwise you don't just see if two values are close enough, but just if one value is greater than another (approximately).
(define (good-enough? guess x)
(< (abs (- guess (improve guess x))) 0.00001))
MIT-SCHEME can help you, see Tracing Procedures in MIT-Scheme. Tracing is a way for the interpreter to indicate what expression currently being computed, and what result it yields. After having entered your definitions, you can trace your procedures as follows:
(trace cbrt-iter)
(trace good-enough?)
(trace improve)
(trace cbrt)
Here is the interaction with input 64:
1 ]=> (cbrt 64)
[Entering #[compound-procedure 15 cbrt]
Args: 64]
[Entering #[compound-procedure 12 cbrt-iter]
Args: 1.
64]
[Entering #[compound-procedure 13 good-enough?]
Args: 1.
64]
[Entering #[compound-procedure 14 improve]
Args: 1.
64]
[22.
<== #[compound-procedure 14 improve]
Args: 1.
64]
[#t
<== #[compound-procedure 13 good-enough?]
Args: 1.
64]
[1.
<== #[compound-procedure 12 cbrt-iter]
Args: 1.
64]
[1.
<== #[compound-procedure 15 cbrt]
Args: 64]
;Value: 1.
Each time you call a traced procedure, you see:
[Entering ...]
Each time that procedure exits, its value is printed:
[XYZ
<== <CALL THAT PRODUCED THE VALUE>]
Here, you can see that (improve 1. 64) returned 22, and that 22 is a good-enough value, from the result of (good-enough? 1. 64). Then you can see that (cbrt-iter 1. 64) returned 1.

Lazy stream of random(s): When does evaluation happen?

The following code, I thought, should define a stream of random numbers between 1 and 10:
(define random-stream (stream-cons (random 1 11) random-stream))
However, what it actually does is define a stream of a specific random number. For example:
> (stream->list (stream-take random-stream 10))
'(5 5 5 5 5 5 5 5 5 5)
I presume this is the random number that (random 1 11) produces when the definition is first parsed. I got around this by making random-stream an argument-less function:
(define (random-stream) (stream-cons (random 1 11) (random-stream)))
This works:
> (stream->list (stream-take (random-stream) 10))
'(6 1 10 9 4 2 2 3 3 10)
So it looks to me that constants are, understandably, evaluated at read time, whereas functions are evaluated at call time. Usually this wouldn't matter, but in the case of a stream -- where you've got a recursive definition -- this makes a difference.
Is this how it works, or is it more subtle than this? Are there other cases one should be aware of regarding this difference?
Making random-stream an argument-less function is the correct solution.
(define (random-stream) (stream-cons (random 1 11) (random-stream)))
I will explain why.
When you define a stream normally with (define my-stream (stream-cons ....)), there is only one value for the stream. Any reference to my-stream will produce the same value.
(define my-stream (stream-cons (random 1 11) my-stream))
The my-stream inside the "rest" is literally the same value eq? to the one my-stream.
> (eq? my-stream (stream-rest my-stream))
#true
So because they are the same value, they can be substituted in function calls. If (stream-first my-stream) returns 5, then (stream-first (stream-rest my-stream)) must also return 5. (This is because stream-first is a "pure" function in the sense that it returns the same output for the same inputs.)
> (eq? (stream-first my-stream) (stream-first (stream-rest my-stream)))
#true
This is not the case with the function version because every time the function is called it creates a new stream value.
(define (random-stream) (stream-cons (random 1 11) (random-stream)))
> (eq? (random-stream) (random-stream))
#false
> (eq? (stream-first (random-stream)) (stream-first (random-stream)))
#false
Since the "rest" field also calls (random-stream), the rest is different from the whole.
> (define generated-stream (random-stream))
> (eq? generated-stream (stream-rest generated-stream))
#false
> (eq? (stream-first generated-stream) (stream-first (stream-rest generated-stream)))
#false
I agree with the other answer that the problem with OP code is that random-stream is a stream for which (stream-first random-stream) is some random number, while (stream-rest random-stream) is also the same stream beginning with the same number.
I don't quite agree with "an argument-less function is the correct solution," though.
One alternative solution would be to use stream-map to map random numbers over the natural numbers:
(define random-stream/1-10
(stream-map (lambda (x) (random 1 11)) (in-naturals)))
It would be even better to create a function that makes a stream of random numbers:
(define (random-stream a b)
(stream-map (lambda (x) (random a b)) (in-naturals)))
This function can be used to create a stream (note that in-naturals is also a function that creates streams):
random_streams.rkt> (define my-stream (random-stream 1 11))
random_streams.rkt> (stream->list (stream-take my-stream 10))
'(1 1 2 7 5 7 4 2 2 9)
Using this idea of a function that creates streams, the stream-cons method can be rescued:
(define (random-stream-cons a b)
(stream-cons (random a b) (random-stream-cons a b)))
When stream-first is called on a stream created with random-stream-cons, a random number is returned; when stream-rest is called on the same stream, another stream with a random number as its first element is returned.
The created streams are persistent:
random_streams.rkt> (stream->list (stream-take random-stream/1-10 10))
'(10 9 9 1 2 7 6 2 6 6)
random_streams.rkt> (stream->list (stream-take random-stream/1-10 15))
'(10 9 9 1 2 7 6 2 6 6 10 1 2 8 5)
random_streams.rkt> (define my-stream-1 (random-stream 1 11))
random_streams.rkt> (stream->list (stream-take my-stream-1 10))
'(1 4 1 10 7 9 9 9 2 9)
random_streams.rkt> (stream->list (stream-take my-stream-1 15))
'(1 4 1 10 7 9 9 9 2 9 2 3 9 9 10)
random_streams.rkt> (define my-stream-2 (random-stream-cons 1 11))
random_streams.rkt> (stream->list (stream-take my-stream-2 10))
'(10 4 6 1 4 2 10 5 3 6)
random_streams.rkt> (stream->list (stream-take my-stream-2 15))
'(10 4 6 1 4 2 10 5 3 6 1 5 7 5 5)
This random-stream-cons/1-10 function is essentially the same as the earlier random-stream-cons function (but with no arguments); yet neither of them are streams. Both of them are functions that create streams:
(define (random-stream-cons/1-10) (stream-cons (random 1 11) (random-stream-cons/1-10)))
Each time that one of these stream creation functions is called, a new stream is returned:
random_streams.rkt> (stream->list (stream-take (random-stream-cons/1-10) 10))
'(10 8 3 10 8 8 1 8 4 5)
random_streams.rkt> (stream->list (stream-take (random-stream-cons/1-10) 10))
'(1 8 7 3 8 2 2 10 6 5)
This might be just what is desired; such functions are very useful, for example, in iteration contexts:
random_streams.rkt> (for ([x (stream-take (random-stream 1 11) 5)])
(displayln x))
2
8
9
1
3
So, functions that return streams are useful, and the resulting streams can be bound to a symbol if desired. For streams that may be needed multiple times with different values, arguments can be provided in custom stream-creation functions. But for one-off streams, stream-map already does the job of returning a stream which can be bound to a symbol just as OP had originally written.

Reversing a simple function in a "creative" way in racket

I need some help :D.
I have written this procedure that turns a string into a list of numbers:
(define (string->encodeable string)
(map convert-to-base-four (map string->int (explode string))))
I need a function that does the exact opposite. In other words, takes a list of a list of numbers in base 4, turn it into base 10, and then creates a string. Is there a "creative" way to reverse my function or do I have to write every opposite step again. Thank you so much for your help.
A standard Scheme implementation using SRFI-1 List library
#!r6rs
(import (rnrs base)
(only (srfi :1) fold))
(define (base4-list->number b4l)
(fold (lambda (digit acc)
(+ digit (* acc 4)))
0
b4l))
(base4-list->number '(1 2 3))
; ==> 27
It works the same in #lang racket but then you (require srfi/1)
PS: I'm not entirely sure if your conversion from base 10 to base 4 is the best solution. Imagine the number 95 which should turn into (1 1 3 3). I would have done it with unfold-right in SRFI-1.
Depends on how you define "creative". In Racket you could do something like this:
(define (f lst)
(number->string
(for/fold ([r 0]) ([i (in-list lst)])
(+ i (* r 4)))))
then
> (f '(1 0 0))
"16"
> (f '(1 3 2 0 2 1 0 0 0))
"123456"
The relationship you're looking for is called an isomorphism
The other answers here demonstrate this using folds but at your level I think you should be doing this on your own – or at least until you're more familiar with the language
#lang racket
(define (base10 ns)
(let loop ((ns ns) (acc 0))
(if (empty? ns)
acc
(loop (cdr ns) (+ (car ns)
(* 4 acc))))))
(displayln (base10 '(3 0))) ; 12
(displayln (base10 '(3 1))) ; 13
(displayln (base10 '(3 2))) ; 14
(displayln (base10 '(3 3))) ; 15
(displayln (base10 '(1 0 0))) ; 16
(displayln (base10 '(1 3 2 0 2 1 0 0 0))) ; 123456
#naomik's answer mentioned isomorphisms. When you construct an isomorphism, you're constructing a function and its inverse together. By composing and joining isomorphisms together, you can construct both directions "at once."
;; Converts between a base 4 list of digits (least significant first, most
;; significant last) and a number.
(define iso-base4->number
(iso-lazy
(iso-cond
;; an iso-cond clause has an A-side question, an A-to-B isomorphism,
;; and a B-side question. Here the A-side is empty and the B-side is
;; zero.
[empty? (iso-const '() 0) zero?]
;; Here the A-side is a cons, and the B-side is a positive number.
[cons?
(iso-join
cons
(λ (r q) (+ (* 4 q) r))
[first iso-identity (curryr remainder 4)]
[rest iso-base4->number (curryr quotient 4)])
positive?])))
This code contains all the information needed to convert a base 4 list into a number and back again. (The base 4 lists here are ordered from least-significant digit to most-significant digit. This is reversed from the normal direction, but that's okay, that can be fixed outside.)
The first cond case maps empty to zero and back again.
The second cond case maps (cons r q) to (+ (* 4 q) r) and back again, but with q converted between lists and numbers recursively.
Just as a cons cell can be split using first and rest, a positivive number can be split into its "remainder-wrt-4" and its "quotient-wrt-4". Since the remainder is a fixed size and the quotient is an arbitrary size, the remainder is analogous to first and the quotient is analogous to rest.
The first and remainder don't need to be converted into each other, so the first iso-join clause uses iso-identity, the isomorphism that does nothing.
[first iso-identity (curryr remainder 4)]
The rest and quotient do need to be converted though. The rest is a list of base 4 digits in least-to-most-significant order, and the quotient is the number corresponding to it. The conversion between them is iso-base4->number.
[rest iso-base4->number (curryr quotient 4)]
If you're interested in how these isomorphism forms like iso-const, iso-cond, and iso-join are defined, this gist contains everything needed for this example.

fetch n-elements from a list Racket

How can I fetch n-elements from a list,
I know about first, rest etc, but what if I want the first 3 elements in a list,
I.E
(get-first 3 (list 1 2 3 4 5 6)) -> (list 1 2 3)
(get-first 5 (list 54 33 2 12 11 2 1 22 3 44)) -> (list 54 33 2 12 11)
This is not homework, but this code will help me complete the bigger picture of an assignment, I am really stuck and just need a few hints.
I am not allowed to use Lambda or build-list and no recursion, I somehow need to b able to do this with just map, filter, foldr etc...
As was mentioned by #AlexisKing, you can simply use the take procedure that's built-in in Racket:
(take '(1 2 3 4 5 6) 3)
=> '(1 2 3)
(take '(54 33 2 12 11 2 1 22 3 44) 5)
=> '(54 33 2 12 11)
If for some reason that's not allowed you can still roll your own version using higher-order procedures and no explicit recursion, but do notice that not using lambda is impossible, the allowed procedures you mention (map, filter, foldr) all receive a lambda as a parameter, and anyway all procedures in Scheme are lambdas under the hood.
Here's a contrived solution, passing an accumulator that remembers in what index we're in the input list while traversing it, and building the output list in the cdr part. It can't be done without using a lambda, but if it bothers you to see it there, extract it to a helper procedure and pass it along:
(define (get-first n lst)
(reverse
(cdr
(foldr (lambda (e acc)
(if (= (car acc) n)
acc
(cons (add1 (car acc))
(cons e (cdr acc)))))
'(0 . ())
(reverse lst)))))
It still works as expected, but never do such a complicated thing when a built-in procedure will do the same:
(get-first 3 '(1 2 3 4 5 6))
=> '(1 2 3)
(get-first 5 '(54 33 2 12 11 2 1 22 3 44))
=> '(54 33 2 12 11)

DrRacket/Scheme: Contract violation, number expected?

So I have 3 functions defined in scheme, sumlist adds up all numbers in a list, and mean gives me the mean of the list. mean2 calls mean and does the same thing, but i get an error. It says the error is coming from sumlist function.
(define (sumlist lst)(if(null? lst)0 (+(car lst)(sumlist(cdr lst)))))
(define mean (lambda x(/(sumlist x)(length x))))
(define mean2 (lambda x(mean x)))
This is how i call the functions
(mean 1 2 3 4 5)
=>3 ;it works
(mean2 1 2 3 4 5)
+: contract violation
expected: number?
given: '(1 2 3 4 5)
argument position: 1st
other arguments...:
0
I'm still new too scheme just got introduced to it last week, but it is really frustrating..what am i doing wrong?
Because (define (x . y) ...) is the same as (define x (lambda y ...)),
the following implementations of identity are the same
(define (fun arg1)
arg1)
(define fun
(lambda (arg1)
arg1)
While the following implementation of list are the same
(define (fun . args)
args)
(define fun
(lambda args
args)
So when you apply (mean2 2 3 4 5) x is the list (2 3 4 5), and (mean '(2 3 4 5)) also wraps all arguments into a list so the call to sumlist turns into (sumlist '((2 3 4 5))). In sumlist you try to do (+ '(2 3 4 5) 0) which won't work since + expects numbers as arguments, not lists. To fix this you need to define mean2 as one of:
;; Just make an alias to mean
(define mean2 mean)
;; wrap mean
(define (mean2 x)
(mean x))
;; use apply
(define (mean2 . x)
(apply mean x)) ; apply undoes list
I'd use the methods in the order of appearance. Sometimes using apply is the best but not if you can just alias or wrap.

Resources