Print value -and- call function? - scheme

I am new to scheme, and have the following question:
If I want a function to also print -the value- of an expression and then call a function, how would one come up to doing that?
For example, I need the function foo(n) to print the value of n mod 2 and call foo(n/2), I would've done:
(define foo (lambda (n) (modulo n 2) (foo (/ n 2))))
But that, of course, would not print the value of n mod 2.

Here is something simple:
(define foo
(lambda (n)
(display (modulo n 2))
(when (positive? n)
(foo (/ n 2)))))
Note the check of (positive? n) to ensure that you avoid (/ 0 2) forever and ever.

I'm terrible at Lisp, but here's an idea: Maybe you could define a function that prints a value and returns it
(define (debug x) (begin (display x) (newline) x))
Then just call the function like
(some-fun (debug (some expression)))

As #Juho wrote, you need to add a display. But, your procedure is recursive without a base case, so it will never terminate.
Try this:
(define foo
(lambda (n)
(cond
((integer? n) (display (modulo n 2))
(newline)
(foo (/ n 2)))
(else n))))
then
> (foo 120)
0
0
0
1
7 1/2

Usually when dealing with more than one thing it's common to build lists to present a solution when the procedure is finished.
(define (get-digits number base)
(let loop ((nums '()) (cur number))
(if (zero? cur)
nums
(loop (cons (remainder cur base) nums)
(quotient cur base)))))
(get-digits 1234 10) ; ==> (1 2 3 4)
Now, since you use DrRacket you have a debugger so you can actually step though this code but you rather should try to make simple bits like this that is testable and that does not do side effects.
I was puzzled when you were taling about pink and blue output until I opened DrRacket and indeed there it was. Everything that is pink is from the program and everything blue is normally not outputed but since it's the result of top level forms in the IDE the REPL shows it anyway. The differences between them are really that you should not rely on blue output in production code.
As other has suggested you can have debug output with display within the code. I want to show you another way. Imagine I didn't know what to do with the elements so I give you the opportunity to do it yourself:
(define (get-digits number base glue)
(let loop ((nums '()) (cur number))
(if (zero? cur)
nums
(loop (glue (remainder cur base) nums)
(quotient cur base)))))
(get-digits 1234 10 cons) ; ==> (1 2 3 4)
(define (debug-glue a d)
(display a)
(newline)
(cons a d))
(get-digits 1234 10 debug-glue) ; ==> (1 2 3 4) and displays "4\n3\n2\n1\n"

Related

Geometric Series function in Scheme language

Im trying to learn scheme and Im having trouble with the arithmetic in the Scheme syntax.
Would anyone be able to write out a function in Scheme that represents the Geometric Series?
You have expt, which is Scheme power procedure. (expt 2 8) ; ==> 256 and you have * that does multiplication. eg. (* 2 3) ; ==> 6. From that you should be able to make a procedure that takes a n and produce the nth number in a specific geometric series.
You can also produce a list with the n first if you instead of using expt just muliply in a named let, basically doing the expt one step at a time and accumulate the values in a list. Here is an example of a procedure that makes a list of numbers:
(define (range from to)
(let loop ((n to) (acc '())
(if (< n from)
acc
(loop (- 1 n) (cons n acc)))))
(range 3 10) ; ==> (3 4 5 6 7 8 9 10)
Notice I'm doing them in reverse. If I cannot do it in reverse I would in the base case do (reverse acc) to get the right order as lists are always made from end to beginning. Good luck with your series.
range behaves exactly like Python's range.
(define (range from (below '()) (step 1) (acc '()))
(cond ((null? below) (range 0 from step))
((> (+ from step) below) (reverse acc))
(else (range (+ from step) below step (cons from acc)))))
Python's range can take only one argument (the upper limit).
If you take from and below as required arguments, the definition is shorter:
(define (range from below (step 1) (acc '()))
(cond ((> (+ from step) below) (reverse acc))
(else (range (+ from step) below step (cons from acc)))))
Here is an answer, in Racket, that you probably cannot submit as homework.
(define/contract (geometric-series x n)
;; Return a list of x^k for k from 0 to n (inclusive).
;; This will be questionable if x is not exact.
(-> number? natural-number/c (listof number?))
(let gsl ((m n)
(c (expt x n))
(a '()))
(if (zero? m)
(cons 1 a)
(gsl (- m 1)
(/ c x)
(cons c a)))))

In Scheme, how can I display something multiply times?

`(display-n "*" 4)`
****
This code should give 4 stars. How can I display this?
Also, this code should fit in this:
Finally figured out the entire good code. Thanks for all the hints and feedback!
(define (display-n k n)
(if (> n 0)
(do ((x 0 (+ x 1)))
((= x n))
(display k))))
(define (parasol n)
(define (triangle i)
(if (< i n)
(begin
(display-n " "(- n i 1))
(display-n "*" (+ (* 2 i) 1))
(newline)
(triangle (+ i 1)))))
(define (stick i)
(if (< i 3)
(begin
(display-n " " (- n 1))
(display "*") (newline)
(stick (+ i 1)))))
(triangle 0)
(stick 0))
(parasol 5)
Phrased differently, your question is:
How can I repeat an operation `n` times?
The solution is to use a loop. In Scheme you can choose between a "named let" or a "do loop".
See detailed explanation here:
What does the "do" control construct do in Scheme?
(define (display-n n k)
(if (> k 0)
(do ((x 0 (+ x 1)))
((= x k))
(display n))))
Found it. I'll put this here if an unfortunate soul is looking for the same thing.
For this specific case, since you're only outputting a single character long string, you can just make a string of n copies of that character and print it instead of using an explicit loop:
(define (display-n k n)
(display (make-string n (string-ref k 0))))
(display-n "*" 4)
or if passing a character instead of a string:
(define (display-n k n)
(display (make-string n k)))
(display-n #\* 4)
While knowing how to repeat an arbitrary task a given number of times is generally useful and probably a big point of the exercise, being able to find simpler approachs for special cases is also a good skill to have.

How does the named let in the form of a loop work?

In an answer which explains how to convert a number to a list the number->list procedure is defined as follows:
(define (number->list n)
(let loop ((n n)
(acc '()))
(if (< n 10)
(cons n acc)
(loop (quotient n 10)
(cons (remainder n 10) acc)))))
Here a "named let" is used. I don't understand how this named let works.
I see that a loop is defined where the variable n is equal to n, and the variable acc equal to the empty list. Then if n is smaller than 10 the n is consed to the acc. Otherwise, "the loop" is applied with n equal to n/10 and acc equal to the cons of the remainder of n/10 and the previous accumulated stuff, and then calls itself.
I don't understand why loop is called loop (what is looping?), how it can automatically execute and call itself, and how it will actually add each number multiplied by its appropriate multiplier to form a number in base 10.
I hope someone can shine his or her light on the procedure and the above questions so I can better understand it. Thanks.
The basic idea behind a named let is that it allows you to create an internal function, that can call itself, and invoke it automatically. So your code is equivalent to:
(define (number->list n)
(define (loop n acc)
(if (< n 10)
(cons n acc)
(loop (quotient n 10)
(cons (remainder n 10) acc))))
(loop n '()))
Hopefully, that is easier for you to read and understand.
You might, then, ask why people tend to use a named let rather than defining an internal function and invoking it. It's the same rationale people have for using (unnamed) let: it turns a two-step process (define a function and invoke it) into one single, convenient form.
It's called a loop because the function calls itself in tail position. This is known as tail recursion. With tail recursion, the recursive call returns directly to your caller, so there's no need to keep the current call frame around. You can do tail recursion as many times as you like without causing a stack overflow. In that way, it works exactly like a loop.
If you'd like more information about named let and how it works, I wrote a blog post about it. (You don't need to read it to understand this answer, though. It's just there if you're curious.)
A normal let usage can be considered an anonymous procedure call:
(let ((a 10) (b 20))
(+ a b))
;; is the same as
((lambda (a b)
(+ a b))
10
20)
A named let just binds that procedure to a name in the scope of the procedure so that it is equal to a single procedure letrec:
(let my-chosen-name ((n 10) (acc '()))
(if (zero? n)
acc
(my-chosen-name (- n 1) (cons n acc)))) ; ==> (1 2 3 4 5 6 7 8 9 10)
;; Is the same as:
((letrec ((my-chosen-name
(lambda (n acc)
(if (zero? n)
acc
(my-chosen-name (- n 1) (cons n acc))))))
my-chosen-name)
10
'()) ; ==> (1 2 3 4 5 6 7 8 9 10)
Notice that the body of the letrec just evaluates to the named procedure so that the name isn't in the environment of the first call. Thus you could do this:
(let ((loop 10))
(let loop ((n loop))
(if (zero? n)
'()
(cons n (loop (- n 1))))) ; ==> (10 9 8 7 6 5 4 3 2 1)
the procedure loop is only in the environment of the body of the inner let and does not shadow the variable loop of the outer let.
In your example, the name loop is just a name. In Scheme every loop is ultimately done with recursion, but usually the name is used when it's tail recursion and thus an iterative process.

Do two things in Racket "for loop"

I'm running a for loop in racket, for each object in my list, I want to execute two things: if the item satisfies the condition, (1) append it to my new list and (2) then print the list. But I'm not sure how to do this in Racket.
This is my divisor function: in the if statement, I check if the number in the range can divide N. If so, I append the item into my new list L. After all the loops are done, I print L. But for some unknown reason, the function returns L still as an empty list, so I would like to see what the for loop does in each loop. But obviously racket doesn't seem to take two actions in one "for loop". So How should I do this?
(define (divisor N)
(define L '())
(for ([i (in-range 1 N)])
(if (equal? (modulo N i) 0)
(append L (list i))
L)
)
write L)
Thanks a lot in advance!
Note: This answer builds on the answer from #uselpa, which I upvoted.
The for forms have an optional #:when clause. Using for/fold:
#lang racket
(define (divisors N)
(reverse (for/fold ([xs '()])
([n (in-range 1 N)]
#:when (zero? (modulo N n)))
(displayln n)
(cons n xs))))
(require rackunit)
(check-equal? (divisors 100)
'(1 2 4 5 10 20 25 50))
I realize your core question was about how to display each intermediate list. However, if you didn't need to do that, it would be even simpler to use for/list:
(define (divisors N)
(for/list ([n (in-range 1 N)]
#:when (zero? (modulo N n)))
n))
In other words a traditional Scheme (filter __ (map __)) or filter-map can also be expressed in Racket as for/list using a #:when clause.
There are many ways to express this. I think what all our answers have in common is that you probably want to avoid using for and set! to build the result list. Doing so isn't idiomatic Scheme or Racket.
It's possible to create the list as you intend, as long as you set! the value returned by append (remember: append does not modify the list in-place, it creates a new list that must be stored somewhere) and actually call write at the end:
(define (divisor N)
(define L '())
(for ([i (in-range 1 N)]) ; generate a stream in the range 1..N
(when (zero? (modulo N i)) ; use `when` if there's no `else` part, and `zero?`
; instead of `(equal? x 0)`
(set! L (append L (list i))) ; `set!` for updating the result
(write L) ; call `write` like this
(newline)))) ; insert new line
… But that's not the idiomatic way to do things in Scheme in general and Racket in particular:
We avoid mutation operations like set! as much as possible
It's a bad idea to write inside a loop, you'll get a lot of text printed in the console
It's not recommended to append elements at the end of a list, that'll take quadratic time. We prefer to use cons to add new elements at the head of a list, and if necessary reverse the list at the end
With all of the above considerations in place, this is how we'd implement a more idiomatic solution in Racket - using stream-filter, without printing and without using for loops:
(define (divisor N)
(stream->list ; convert stream into a list
(stream-filter ; filter values
(lambda (i) (zero? (modulo N i))) ; that meet a given condition
(in-range 1 N)))) ; generate a stream in the range 1..N
Yet another option (similar to #uselpa's answer), this time using for/fold for iteration and for accumulating the value - again, without printing:
(define (divisor N)
(reverse ; reverse the result at the end
(for/fold ([acc '()]) ; `for/fold` to traverse input and build output in `acc`
([i (in-range 1 N)]) ; a stream in the range 1..N
(if (zero? (modulo N i)) ; if the condition holds
(cons i acc) ; add element at the head of accumulator
acc)))) ; otherwise leave accumulator alone
Anyway, if printing all the steps in-between is necessary, this is one way to do it - but less efficient than the previous versions:
(define (divisor N)
(reverse
(for/fold ([acc '()])
([i (in-range 1 N)])
(if (zero? (modulo N i))
(let ([ans (cons i acc)])
; inefficient, but prints results in ascending order
; also, `(displayln x)` is shorter than `(write x) (newline)`
(displayln (reverse ans))
ans)
acc))))
#sepp2k has answered your question why your result is always null.
In Racket, a more idiomatic way would be to use for/fold:
(define (divisor N)
(for/fold ((res null)) ((i (in-range 1 N)))
(if (zero? (modulo N i))
(let ((newres (append res (list i))))
(displayln newres)
newres)
res)))
Testing:
> (divisor 100)
(1)
(1 2)
(1 2 4)
(1 2 4 5)
(1 2 4 5 10)
(1 2 4 5 10 20)
(1 2 4 5 10 20 25)
(1 2 4 5 10 20 25 50)
'(1 2 4 5 10 20 25 50)
Since append is not really performant, you usually use cons instead, and end up with a list you need to reverse:
(define (divisor N)
(reverse
(for/fold ((res null)) ((i (in-range 1 N)))
(if (zero? (modulo N i))
(let ((newres (cons i res)))
(displayln newres)
newres)
res))))
> (divisor 100)
(1)
(2 1)
(4 2 1)
(5 4 2 1)
(10 5 4 2 1)
(20 10 5 4 2 1)
(25 20 10 5 4 2 1)
(50 25 20 10 5 4 2 1)
'(1 2 4 5 10 20 25 50)
To do multiple things in a for-loop in Racket, you just write them after each other. So to display L after each iteration, you'd do this:
(define (divisor N)
(define L '())
(for ([i (in-range 1 N)])
(if (equal? (modulo N i) 0)
(append L (list i))
L)
(write L))
L)
Note that you need parentheses to call a function, so it's (write L) - not write L. I also replaced your write L outside of the for-loop with just L because you (presumably) want to return L from the function at the end - not print it (and since you didn't have parentheses around it, that's what it was doing anyway).
What this will show you is that the value of L is () all the time. The reason for that is that you never change L. What append does is to return a new list - it does not affect the value of any its arguments. So using it without using its return value does not do anything useful.
If you wanted to make your for-loop work, you'd need to use set! to actually change the value of L. However it would be much more idiomatic to avoid mutation and instead solve this using filter or recursion.
'Named let', a general method, can be used here:
(define (divisors N)
(let loop ((n 1) ; start with 1
(ol '())) ; initial outlist is empty;
(if (< n N)
(if(= 0 (modulo N n))
(loop (add1 n) (cons n ol)) ; add n to list
(loop (add1 n) ol) ; next loop without adding n
)
(reverse ol))))
Reverse before output since items have been added to the head of list (with cons).

Printing First two numbers in scheme

I'm trying to print the first 2 numbers in a list coded in Scheme. I'm having a bit of trouble doing this. I get an error when I run the procedure. Any suggestions on how I can get this to work
(define (print-two-nums n nums)
( list-ref nums(+ (cdr nums) n)))
( print-two-nums 2'(5 5 4 4))
It looks like you were wavering between the ideas of "print two numbers" and "print n numbers." If you really want just the two first numbers of a list, you can write:
(define (print-two-nums nums)
(print (list (car nums) (cadr nums))))
But for the more general first n numbers, you can use:
(define (print-n-nums n nums)
(print (take nums n)))
To print the first n numbers, you could use this simple procedure
(define (print-n-nums L n) (cond
((or (= 0 n) (null? L)) '())
(else (cons (car L) (print-n-nums (cdr L) (- n 1))))))
(print-n-nums (list 1 2 3) 2)
;Output: (1 2)
You could further abstract the cons operation and define print-n-nums as a higher order procedure to carry out the desired operation. For example, if we wanted to add the first n numbers of a list, we could define the following procedure. Here OPERATION is a function that we pass to the list-operator function. Thus, here we want to perform the + operation. In the case above, we want to perform the cons operation. The initial parameter is just how we want to handle the edge case.
(define (list-operator L n OPERATION initial) (cond
((or (= 0 n) (null? L)) initial)
(else (OPERATION (car L) (list-operator (cdr L) (- n 1) OPERATION initial)))))
(list-operator (list 1 2 3) 2 + 0)
;Output: 3
Now, if you wanted the product of the first 2 numbers, you would just do
(list-operator (list 1 2 3) 2 * 1)

Resources