Procedure printf in Scheme - scheme

For example, when I use the procedure printf on the list '((2 t r d)), the last line in my output is
'(#<void>)
and the number of times '(#<void>) appears depend on the number of list nested. Can you please explain this for me???
This is my printf function
(define counting
(lambda (lst)
(if (null? lst)
'()
(printf "~a, ~s\n" (car lst) (length (cdr lst))))))
I have try to other procedure like fprintf and using this form
(fprintf (current-output-port) "~a, ~s\n" (car lst) (length (cdr lst)))
Same thing happens!

AFAIK there is no such procedure in the Scheme standard so you might need to add a tag for a implementation that has it. I know racket has printf.
A (display x) (and (printf x) in racket) alone usually don't display so what produced (#<void>) is not in the question. In Scheme every procedure evaluates to a value. To illustrate this try doing:
(map display '(1 2 3 4))
Which will return a list with 4 unspecified values since map makes a list of the results. display (and printf in racket) prints the result of the evaluation of the argument but doesn't need to return anything since the standard doesn't say that is should. Most implementations do this by returning an undefined object, but some actually return the argument too. The main function of them is to do side effect of displaying something on screen and that it has done. for ignoring return values you can use for-each which is map just for side effects.
(for-each display '(1 2 3 4))
When that said in Scheme it's normal that every procedure return something and you misread output with the REPLs printing of the returned values.

You said that 'the last line of your output is '(#<void>) - this is occurring because your Scheme environment is displaying 1) what you want to be printed and 2) the returned value of the evaluated expression. For example
> (list (display 1))
1(#<void>)
The '1' is printed and then the list result is printed. Since you are typing in an interactive session you will always get the returned value displayed. You can't really hide the returned value however most Schemes will recognize a 'undefined' return value and not print it.
> (display 1)
1
In the above, even though display returns #<void> the interpreter knows not to show it.

Related

Writing a function that takes a function as an argument in Racket

This is a hw assignment that requires me to write a scheme function that takes a function(with two params) and a list as parameters, then returns a list where each consecutive pair of the elements of the list is replaced by the value of the function applied to these two elements.
For example - If the list has an odd number of elements, the last element is ignored. For example, (apply-to-pairs (lambda (x y) (+ x y)) '(3 9 5 8 2 4 7)) should return (12 13 6).
so far what I have got is:
(define (fn-name fn l)
(if (null? (cdr l))null
(cons
(fn((car l)(car (cdr l)))
(fn-name fn (cdr l))))))
However, im getting this error in Racket(DrRacket):
application: not a procedure;
expected a procedure that can be applied to arguments
given: 3
arguments...:
9
... and it highlights fn((car lst)(car (cdr lst))). I'm trying to find out how to handle the function parameter. Thanks for the help!
As you already did you just apply fn like you would with any primitives like +. However you have extra parenthesis around (car lst) and (car (cdr lst)) which means you expect first element to also be a procedure you call with the second element as it's only argument and then fn only get one argument (the result of that if 3, 5 or 2 happens to be procedures) Perhaps you instead wanted (fn (car lst) (cadr lst)) (I'm using shothand for car+cdr)
Your base case should check both l and (cdr l) for null since if either one is you are fnished. (Try calling it with (fn-name + '(5))). You can use special form or to do that like (or test1 test2).
Also notice that null is not usually a bound symbol in Scheme. You either need to define it (define null '()) or use '().
EDIT ABout too many results..
Notice that when you have applied the first round withe the first two elements of the list you recurse with a new l starting at the list except the very first element.. That means you then will process 9 and 5 in the next iteration instead of 5 and 8. To fix that you need to use cddr (cdr+cdr) instead of just cdr.

empty list without empty word in Scheme

I am writing a recursion function returning an empty list in the base case. However the output of functions shows "empty" word in the my list, which I don't want.Like this;
(list (list 'abc) (list 'def) empty (list 'ghi))
How can I prevent this? Thanks.
The problem is probably because Racket has several printing styles for values. Try changing it (in the language selection dialog) to "write" or whatever it's called, which should make it output ((abc) (def) () (ghi)) instead.
The empty that you see in the result is not a "word" -- note that it's not quoted. If you do expect an empty list in the result, then it looks like you got one. You can even check for that:
> (empty? (third (list (list 'abc) (list 'def) empty (list 'ghi))))
#t
Without knowing details, my best guess would be something like
(let ((result (recursive-call ...)))
(if (null? result) (resursive-call (cdr whatever-list))
(cons result (cdr whatever-list)))
Essentially, just check if the result is the empty list, and if so, don't put it into the list that you're returning.

Adding arguments to list causes error

I tried an example where we need to pass a list as arguments and if condition succeeds I want to add result to a new list.
Here's the code:
(define get-description
(lambda (codeValue newList)
(cond
((= (car codeValue) 1) (cons "A" newlist))
((= (car codeValue) 2)(cons "B" newlist))
((= (car codeValue) 3) "C")
(else "Negative numbers are not valid"))))
I pass this as the function call:
(get-description (list 1 2 3) (list))
I get output:
(cons "A" empty)
Output should just show: (A)
I am using DrRacket for writing my programs and have chosen language mode as: Beginning Student.
Why do I get cons and A with "" and empty in my newlist?
Please don't use "Beginning Student" as a language type in Racket. That's a subset specially made for the HtDP book. The languages "racket", "r5rs", "pretty big", are more like real Schemes and should all work for The Little Schemer.
In your arguments list, you have (codeValue newList), but in the program body you refer to newlist. All of the Schemes that I've used are case-sensitive. Changing your newList to newlist made your program run perfectly fine on Chez Scheme and Guile too.
Edit: To clarify, "A" is a string. Scheme also has the additional data type of symbol, which is just a name and nothing else (and is probably what you want here). You probably want to (cons 'A newlist) rather than (cons "A" newlist) if you're expecting (A).
Other Schemes would print just ("A"). Such output is clearly an idiosyncrasy of the Racket language.
As for why the A is in quotation marks, that's because it's a string object, and that's simply how string objects are printed. But if you were to DISPLAY such an object, you'd get the A by its lonesome.

Practical Scheme Programming

It's been a few months since I've touched Scheme and decided to implement a command line income partitioner using Scheme.
My initial implementation used plain recursion over the continuation, but I figured a continuation would be more appropriate to this type of program. I would appreciate it if anyone (more skilled with Scheme than I) could take a look at this and suggest improvements. I'm that the multiple (display... lines is an ideal opportunity to use a macro as well (I just haven't gotten to macros yet).
(define (ab-income)
(call/cc
(lambda (cc)
(let
((out (display "Income: "))
(income (string->number (read-line))))
(cond
((<= income 600)
(display (format "Please enter an amount greater than $600.00~n~n"))
(cc (ab-income)))
(else
(let
((bills (* (/ 30 100) income))
(taxes (* (/ 20 100) income))
(savings (* (/ 10 100) income))
(checking (* (/ 40 100) income)))
(display (format "~nDeduct for bills:---------------------- $~a~n" (real->decimal-string bills 2)))
(display (format "Deduct for taxes:---------------------- $~a~n" (real->decimal-string taxes 2)))
(display (format "Deduct for savings:-------------------- $~a~n" (real->decimal-string savings 2)))
(display (format "Remainder for checking:---------------- $~a~n" (real->decimal-string checking 2))))))))))
Invoking (ab-income) asks for input and if anything below 600 is provided it (from my understanding) returns (ab-income) at the current-continuation. My first implementation (as I said earlier) used plain-jane recursion. It wasn't bad at all either but I figured every return call to (ab-income) if the value was below 600 kept expanding the function.
(please correct me if that apprehension is incorrect!)
First of all, you don't need a continuation. According to the standard, Scheme will always perform tail call optimization. A tail call is a function call which is in the final position in a function; after that call is run, nothing else will happen. In that situation, we don't need to preserve the activation record we're currently in; as soon as the function we call returns, we'll just pop it. Consequently, a tail call reuses the current activation record. As an example, consider this:
(define (some-function x y)
(preprocess x)
(combine (modified x) y))
(some-function alpha beta)
When we call some-function, we allocate space for its activation record on the stack: local variables, parameters, etc. We then call (preprocess x). Since we need to return to some-function and keep processing, we have to preserve some-function's activation record, and so we push a new activation record on for preprocess. Once that returns, we pop preprocess's stack frame and keep going. Next, we need to evaluate modified; the same thing has to happen, and when modified returns, its result is passed to combine. One would think we'd need to create a new activation record, run combine, and then return this to some-function—but some-function doesn't need to do anything with that result but return it! Thus, we overwrite the current activation record, but leave the return address alone; when combine returns, then, it will return its value to exactly what was waiting for it. Here, (combine (modified x) y) is a tail call, and evaluating it doesn't require an extra activation record.
This is how you can implement loops in Scheme, for instance:
(define (my-while cond body)
(when (cond)
(body)
(my-while cond body)))
(let ((i 0))
(my-while (lambda () (< i 10))
(lambda () (display i) (newline) (set! i (+ i 1)))))
Without tail call optimization, this would be inefficient, and would potentially overflow with a long-running loop building up lots of calls to my-while. However, thanks to tail call optimization, the recursive call to my-while cond body is a jump, and allocates no memory, making this as efficient as iteration.
Secondly, you don't need any macros here. While you can abstract out the display block, you can do this with a plain function. Macros allow you, on some level, to change the syntax of the language—add your own sort of define, implement some type-case construct which doesn't evaluate all its branches, etc. Of course, it's all still s-expressions, but the semantics are no longer simply "evaluate the arguments and call the function". Here, however, function-call semantics are all you need.
With that said, I think this is how I'd implement your code:
(require (lib "string.ss"))
(define (print-report width . nvs)
(if (null? nvs)
(void)
(let ((name (car nvs))
(value (cadr nvs)))
(display (format "~a:~a $~a~n"
name
(make-string (- width (string-length name) 2) #\-)
(real->decimal-string value 2)))
(apply print-report width (cddr nvs)))))
(define (ab-income)
(display "Income: ")
(let ((income (string->number (read-line))))
(if (or (not income) (<= income 600))
(begin (display "Please enter an amount greater than $600.00\n\n")
(ab-income))
(begin (newline)
(print-report 40 "Deduct for bills" (* 3/10 income)
"Deduct for taxes" (* 2/10 income)
"Deduct for savings" (* 1/10 income)
"Remainder for checking" (* 4/10 income))))))
First, at least in my version of mzscheme, I needed a (require (lib "string.ss")) line to import real->decimal-string. Next, I abstracted out the display block you were talking about. What we see is that each line wants to print the money in the same format at the 40th column, printing a tag name and a row of dashes in front of it. Consequently, I wrote print-report. The first argument is the initial width; in this case, 40. The remaining arguments are field-value pairs. The length of each field (plus two for the colon and the space) are subtracted from the width, and we generate a string consisting of that many dashes. We use format to lay the fields out in the right order, and display to print the string. The function recurses over all the pairs (using tail recursion, so we won't blow the stack).
In the main function, I moved the (display "Income: ") to before the let; you ignore its result, so why assign it to a variable? I then augmented the if condition to test if input is false, which happens when string->number can't parse the input. Finally, I removed your local variables, since all you do is print them, and used Scheme's fraction syntax instead of division. (And of course, I use print-report instead of displays and formats.)
I think that's all; if you have any other questions about what I did, feel free to ask.

Function in Scheme that checks whether the length of a list is even

Hi I have edited the code for function in scheme that checks whether the length of a list is even.
(define even-length?
(lambda (l)
(cond
((null? l)#f)
((equal? (remainder (length(l)) 2) 0) #t)
(else #f))))
Is it corrrect?
You seem to have the syntax for if and cond all mixed up. I suggest referring to the language reference. if only has two clauses, and you don't write else for the else clause. (Hint: You shouldn't need an if for this function at all.)
Also, consider whether it makes sense to return null if the list is null; probably you want to return #t or #f instead.
Oh yeah, and rewrite your call of length to be a proper prefix-style Scheme function call.
The code is clearly wrong -- your %2 assuming infix notation, where Scheme uses prefix notation. The syntax of your if is wrong as well -- for an if, the else is implicit (i.e. you have if condition true-expression false-expression. In this case, you're trying to return #t from one leg and #f from another leg -- that's quite unnecessary. You can just return the expression that you tested in the if.
Edit: one other detail -- you should really rename this to something like even-length?. Even if I assume that it's a predicate, a name like even would imply to me that (even 3) should return #f, and (even 4) should return #t -- but in this case, neither works at all.
Edit2: Since mquander already gave you one version of the code, I guess one more won't hurt. I'd write it like:
(define (even-length? L) (even? (length L)))
I don't like using lower-case 'l' (but itself) much, so I've capitalized it. Since even? is built in, I've used that instead of finding the remainder.
Running this produces:
> (even-length? `(1 2 3))
#f
> (even-length? `(1 2 3 4))
#t
>
This is different from what you had in one respect: the length of an empty list is 0, which is considered an even number, so:
(even-length? `())
gives #t.
(define even-length? (lambda (l)
(even? (length l))))
Usage:
(even-length? '(1 2 3 4))
#t
(even-length? '(1 2 3 ))
#f
As others pointed out, there is indeed a predicate to check evenness of a number, so why not using it?
EDIT: I just saw Jerry Coffin wrote the same function witht the same example... Sorry for repeating :-)

Resources