I am trying to convert a C program to Scheme for an assignment I'm working on. The program is supposed to compute the area of a circle given the formal parameter (diameter, in this case). I think I have it figured out but I don't know how to print the actual value to verify it. I've tried just putting in the number into the print call. The way it is now is the method my book used. When I run the program with Dr. Racket I get:
print: undefined;
cannot reference undefined identifier
(define pi 3.14159265)
(define test 5)
(define (areac d)
(lambda (d)
(* pi (/ d 2) (/ d 2)
)))
(print (areac test))
Edit: Language is set to R5RS
If you use "define", you don't have to use "lambda", because "define" is just convenient way to give the name to the lambda-procedure. Your code must look like this:
(define pi 3.14159265)
(define test 5)
(define (areac d)
(* pi (/ d 2) (/ d 2)
))
(display (areac test))
Command for printing data in scgeme is "display". So, just write
(display (areac test))
Related
Is this function from my lecture notes written correctly?
(define foo (λ (f) (+ (f 1) (f 2))))
(foo 3) doesnt work and any more arguments says it expects 1 argument. I assume the lecturer meant:
(define foo (λ (f) (+ f f)) )
As far as I know (f 1) isnt a valid way of saying anything in scheme but if the first is actually a correct function can anyone give me an example of a valid input?
(define foo (λ (f) (+ (f 1) (f 2))))
is ok. It takes a function f as an input. You can call it like this:
(define g (lambda (x) (* x 10)))
(foo g)
Update: I found this example so the function is correct as is. I am actually not sure what is happening here though.
(define foo (λ (f) (+ (f 1) (f 2))))
(foo (λ (x) (* x 2)))
Output: 6
Edit: nevermind as I was typing I eventually understood the syntax. If the parameter f is a function, then (f 1) would mean f with an input of one and then the example makes sense. Should I delete the question probably wont be of use to anyone?
I'm trying to take two pairs '(a . b) '(c . d) and input them into an equation.
(define dist
(lambda (pr)
(sqrt (+ (expt (- (car pr) (car pr) 2)(expt (- (cdr pr) (cdr pr) 2)))
I tried this and a few other ways but I just get errors.
My actual equation seems to work with numbers but I'm not sure how I'm supposed to go about inputting two pairs, or if I'm even supposed to use an equation like the one I have.
I'm worried I'm thinking about this all wrong and nothing in my book mentions how to deal with two pairs and my teacher won't answer. I'm so confused, any tips or explanations would be wonderful.
EDIT:
I should've mentioned that to test my code I have numbers in place of the letters in the pairs for example:
(dist '(2 . 5) '(3 . 1))
I was trying to make it universal since any number has to be able to work with the code. Sorry for the confusion.
Example procedure:
(lambda (a b)
(+ a b))
Here a and b are two arguments. Their names are declared in the formal parameter list and they are used by those names in the body. That a and b might be numbers can only be seen by how they are used in the body of the procedure, but the formal parameter list itself doesn't say anything about type. They could be pairs and + might be lexically bound procedure that does something completely different than adding numbers.
In your procedure you have defined one bound variable pr. This seems from the code to be a pair since you are applying both car and cdr to it. If you need to add another pair you must add it to the formal parameter list with a name of your choosing (like pr perhaps was) and use that name in the procedure body.
You can read more about the format of lambda expressions in the R6RS standard.
You've shown a function dist that accepts two arguments:
(dist '(2 . 5) '(3 . 1))
where the first argument is '(2 . 5) and the second argument is '(3 . 1). But, your defined a function dist that accepts one argument that you've named pr. That won't work - one argument definition but two argument application.
How about:
(define dist
(lambda (arg1 arg2)
(let ((x1 (car arg1))
(y1 (cdr arg1))
(x2 (car arg2))
(y2 (cdr arg2)))
(sqrt (+ (expt (- x2 x1) 2)
(expt (- y2 y1) 2))))))
Im learning for exam of programming in lisp using DrRacket..
In presentation from lectures i found this code:
(define (f a b c)
(define delta)
(begin
(set! delta (- (* b b) (* 4 a c))
(if (>=? delta 0)
(writeln ”są pierwiastki”)
(writeln ”nie ma pierwiastków)))))
But it dont work.
DrRacket is showing:
. define: bad syntax (missing expression after identifier) in: (define delta)
Can't I set delta value later?
What is the problem?
thanks in advance
The original error message is because
(define delta)
is missing a value. Instead it should be something like:
(define delta 0)
There some other issues:
The double quotes weren't the " character and weren't recognized
by Racket.
Some parens were wrong.
Also I don't know why it was define-ing delta, then immediately
set!-ing it.
I tried to fix/simplify what you posted, and came up with the
following. But I'm not really sure what the function is supposed to
do, so I don't know if the example output is correct.
#lang racket
(define (f a b c)
(define delta (- (* b b) (* 4 a c)))
(if (>= delta 0)
(displayln "są pierwiastki")
(displayln "nie ma pierwiastków")))
;; Example output:
(f 1 2 3)
;;-> nie ma pierwiastków
(f 1 200 3)
;;-> są pierwiastki
Try this:
#lang racket
(define (f a b c)
(define delta 0)
(set! delta (- (* b b) (* 4 a c)))
(if (>= delta 0)
(displayln "są pierwiastki")
(displayln "nie ma pierwiastków")))
What was wrong with your code:
It's probably a copy-paste error, but in Scheme we delimit strings using the " character, not ” as in your code. And the last line is missing the closing ".
Although some interpreters accept a define without an initial value, the standard is that a value must be present after the variable name
A closing parenthesis is missing at the end of the set! line
The define and set! lines can be merged into a single line: (define delta (- (* b b) (* 4 a c)))
The >=? operator is not standard in Scheme, it might work in your interpreter but if possible use the standard >=
The writeln procedure is not standard in Scheme, in Racket you can substitute it for displayln
Not really an error, but you don't need to write a begin inside a procedure definition, it's implicit
In conclusion: the code in the question seems to be intended for a different interpreter, this question was tagged racket but believe me, what you have is not valid Racket code - heck, is not even standard Scheme. Make sure to use the correct interpreter, and be very alert for typos in the text.
I think Greg already has a perfect answer to your problem, but I just want to add the obvious let version of his code as well:
;; for a given ax^2+bx+c=0
;; this displays if it has at least one
;; real number answer or not
(define (equation-has-answer a b c)
(let ((delta (- (* b b) (* 4 a c))))
(if (>= delta 0)
(displayln "Has answer(s)")
(displayln "Has no answers"))))
To just make a predicate you can do this:
;; for a given ax^2+bx+c=0
;; this returns #t if it has at least one
;; real number answer and #f otherwise
(define (equation-has-answer? a b c)
(>= (- (* b b) (* 4 a c)) 0))
Let's say I have the following two files:
;; demo.scm
(define-module (demo)
#:export (f))
(define (g x) 1)
(define (f x) (g x))
... and in the same directory:
;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))
(define (g x) (+ x 1))
(display (f 5))
(newline)
Running use-demo.scm in Guile (2), I get the output 1. So it looks like the function f has 'closed over' the function g that's defined in module demo. Is there any way to get around this? I really want to use the version of g that I've redefined in use-demo.scm.
OK, just for the record, I did some research and am posting the solution to this specific problem in case it helps someone.
The trick is to not redefine g locally, but rather to 'inject' the new function into the demo module's mapping of names to values.
(add-to-load-path ".")
(use-modules (demo))
(module-define! (resolve-module '(demo)) 'g
(lambda (x) (+ x 1)))
(display (f 5))
(newline)
If you have specific functions that you'd like to be able to override, you could make them configurable using parameters. This has some advantages:
You don't need to call reload-module to put the module back in its original configuration.
The changes only apply for the scope of the code which needs the modified behaviour.
It works properly when using multiple threads.
Obviously, the main disadvantage is that you need to add some boilerplate for each function that you want to allow to be overridden (although that's what hygienic macros are for, hehe).
The following code may work. I haven't run it.
;; demo.scm
(define-module (demo)
#:export (f))
(define (default-g x) 1)
(define p (make-parameter default-g))
(define (f x) ((p) x))
;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))
(define (my-g x) (+ x 1))
(parameterize ((## (demo) p) my-g)
(display (f 5))
(newline))
Obviously, if you can provide some additional information about what the application for this capability is, I might be able to suggest alternative approaches (there are a few others).
When I enter the following:
(define (root a b c)
(/ (+ (-b) (sqrt (- (exp b 2) (* 4 a c)))) (* 2 a)))
and then enter:
(root 3 6 2)
I get a message indicating that the procedure had two arguments but only requires exactly one. What am I doing wrong?
The exp function doesn't do exponents really, it does something else mathy. (I don't know.)
What you want is usually called pow for "power" but probably isn't defined in your environment, so I suggest you just define your own square method:
(define (square x) (* x x))
And then:
(define (root a b c)
(/ (+ (- b) (sqrt (- (square b) (* 4 a c)))) (* 2 a)))
Edit: Oh, you'll also have to change a couple spacing issues, like (* 4 a c) instead of (*4 a c), and (- b) instead of (-b). You always have to separate the operator from the operands with spaces.
The procedure exp raises the number e to the power of its argument, if you need to raise an argument to the power of another argument, use expt. Even better, given that you only need to square b, a simple multiplication will do. Like this:
(define (root a b c)
(/ (+ (- b) (sqrt (- (* b b) (* 4 a c))))
(* 2 a)))
The function the error refers to is exp which takes only one argument. The exp function calculates the exponential function, not an exponent. You want expt, which raises a root x to the exponent y:
(expt b 2)
You can also just multiply the number times itself.
I usually keep R5RS or The Scheme Programming Language on hand since these basic functions can be hard to keep straight.