I'm fairly new to Scheme and I'm using DrRacket as my IDE.
If i have a small program, for example - a program that's given a number, would generate a list from 0 to that number:
(define (helper num mylist)
(cond [(zero? num) (append (list 0) mylist)]
[else (helper (- num 1) (append (list num) mylist))]))
(define (genlist num)
(helper num '()))
(genlist 10) => '(0 1 2 3 4 5 6 7 8 9 10)
I'm coming from a Java background, and there is obviously no print statement here. So how does it "decide" to output mylist to the console? What "tells" it to do so?
genlist doesn't print the list, it only returns it. It's the REPL that prints it because it prints the return value of whichever expression you enter.
It also prints the values of any non-void expressions that are written at the top level of your file when you load it.
The interpreter (REPL) always prints the value of the expression you entered.
If we define
(define (foo a)
(display a)
a)
(define (bar a)
(display a))
we get the output
> (bar "hello")
hello
> (foo "hello")
hello"hello"
where the hellos (without quotation marks) are output by the procedures, and then the REPL prints the result of the procedure calls, which is nothing for the first, and "hello" for the second.
In DrRacket, the outputs also have different colours.
(Also note that a string that is a value is printed differently from a string that is a procedure's output.)
Related
I try to create a procedure that converts a binary number in a list to a string. Sample output: (binary->string '(1 1 0 1 0 0)) should give "110100".
(define reduce
(lambda (op base x) ;passing by name
(if (null? x)
base
(op (car x) (reduce op base (cdr x))))))
And here is my code:
(define (binary->string lst)
(reduce (number->string lst list->string )))
I know it is wrong but it is the best I came out with so far. Please help me to make it work properly.
Before I will show you solution, here is some advice: when you write Racket code, you should check correct number of arguments and their type.
In this case, you know that reduce needs (op base x), that are three arguments, but when you use some unknown function, like number->string, there is Racket documentation and after short search, you fill find number->string entry:
(number->string z [radix]) → string?
z : number?
radix : (or/c 2 8 10 16) = 10
Returns a string that is the printed form of z (see Printing Numbers) in the base specified by radix. If z is inexact, radix must be 10, otherwise the exn:fail:contract exception is raised.
Examples:
(number->string 3.0)
"3.0"
(number->string 255 8)
"377"
As you can see, you can call this function with one or two arguments, but in both cases, they have to be number. But with this call (number->string lst list->string ), you are passing list and procedure- so I can already tell that your code will end with error. And when you try to call your function in REPL, exactly this happens:
> (binary->string '(1 0 0 1))
. . number->string: contract violation
expected: number?
given: '(1 0 0 1)
argument position: 1st
other arguments...:
After you carefully check what did you write, you should be able to predict what will happen, before you even run your code.
Here is solution:
(define (binary->string lst)
(reduce string-append "" (map number->string lst)))
You will use map to create string from each number in list, then you join these strings with your reduce and string-append.
I want to make a program that makes a conversion simulating a for loop, for example:
orig value converted
1 2.2
2 4.4
...
199 437.8
So far, what I have done is the following:
(define (conv ini)
(if (> ini 199)
0
(begin(
(display (* ini 2.2))
(newline)
(conv (+ ini 1))))))
but when I want to run it I got the following error:
arity mismatch;
the expected number of arguments does not match the given number
expected: 1
given: 2
arguments...:
I see that my recursion call is fine, so I cannot get it which one is the problem.
The syntax of begin is (begin form ...) not (begin (form ...)): your function should be
(define (conv ini)
(if (> ini 199)
0
(begin
(display (* ini 2.2))
(newline)
(conv (+ ini 1)))))
(Or, if you are enamoured of a syntax like that, you could define
(define-syntax beguine
(syntax-rules ()
[(_ (form ...))
(begin form ...)]))
and then (beguine (...)) will work.)
...
(begin(
(display (* ini 2.2))
...))))
In your code you actually try to execute (OP ...), where OP is the value of (display ...), which for sure is not a function.
So I doubt a lot your output is the output of what you pasted in your question.
In the Chez Scheme REPL, is it possible to get the previous result? For example in ruby's irb repl, underscore can be used.
For example can I do the following?
> (+ 2 3)
5
> (+ 1 <something>)
And get 6?
Chez Scheme does not have a built in way to do this, but being scheme, we can roll our own:
(define repl
(let ([n 1])
(lambda (expr)
(let-values ([vals (eval expr)])
(for-each (lambda (v)
(unless (eq? (void) v)
(let ([sym (string->symbol (format "$~a" n))])
(set! n (+ n 1))
(printf "~a = " sym)
(pretty-print v)
(set-top-level-value! sym v))))
vals)))))
(new-cafe repl)
repl is now a function that takes an expression, evaluates it, stores the non-void results into ids of the form $N where N is monotonically increasing, and prints out the results. new-cafe is a standard chez function that manages the Reading, Printing, and Looping parts of REPL. It takes a function that manages the Evaluation part. In this case, repl also needs to manage printing since it shows the ids associated with the values.
Edit:
I found a slightly better way to do this. Instead of having a custom repl, we can customize only the printer. Now this function is no longer responsible for also evaluating the input.
(define write-and-store
(let ([n 1])
(lambda (x)
(unless (eq? (void) x)
(let ([sym (string->symbol (format "$~a" n))])
(set! n (+ n 1))
(set-top-level-value! sym x)
(printf "~a = " sym)
(pretty-print x)
(flush-output-port (console-output-port)))))))
(waiter-write write-and-store)
A simple usage example:
> (values 1 2 3 4)
$1 = 1
$2 = 2
$3 = 3
$4 = 4
> (+ $1 $2 $3 $4)
$5 = 10
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"
I was writing a function to switch the last element of a list to the beginning:
(define last-elem
(lambda (l)
(car (reverse l))))
(define all-but-last
(lambda (l)
(reverse (cdr (reverse l)))))
(define (last-to-first x) (append (list last-elem x) (all-but-last x)))
(last-to-first '(1 2 3 4 5 6))
It didn't work and I knew why. I forgot to put the brackets around list last-elem x
The thing is, I was curious about the output of the wrongly-typed code:
(#<Closure> (1 2 3 4 5 6) 1 2 3 4 5)
What is the meaning if this? How did it come out to this?
In Racket, the output is
'(#<procedure:last-elem> (1 2 3 4 5 6) 1 2 3 4 5)
which is a little clearer.
A reference to a function is always stored with its referencing environment, a.k.a. as a closure, and your Scheme implementation chooses to display it that way.
(list last-elem x)
doesn't call the function last-elem. It simply returns a list of two elements: the value of the variable last-elem (which is a procedure) and the value of the argument x. You want:
(list (last-elem x))
But there's no reason to make a list in the first place. Try:
(define (last-to-first x)
(cons (last-elem x) (all-but-last x)))
In Scheme, all identifiers denote either a syntactic keyword (bound to a 'transformer') or a variable (bound to a value). In your code last-elem denotes a variable bound to a function, which you defined. When you write:
(list last-elem x)
the interpreter/compiler produces a list with the value of last-elem and x. Thus, the result of #<Closure> in the list.