Scheme Beginning Student, Function Body Extra Part - scheme

I attempted to follow the solution provided in this question, but it simply didn't work.
Essentially, my function works like so:
(define (item-price size normal-addons premium-addons discount)
(define price 0)
(+ price (* normal-addon-cost normal-addons) (* premium-addon-cost premium-addons) size)
(cond
.. some conditions here
[else price]))
However, I am met with the following error:
define: expected only one expression for the function body, but found 2 extra parts
Now, I've tried wrapping the body of the function in a 'begin', however when run it claims that 'begin' is not defined. I am using the Beginner Student language version as oppose to straight-up Racket. Any insight on a workaround?

The problem remains the same: in the language that's being used, we can't write more than one expression inside a function body, we can't use begin to pack more than one expression, and both let and lambda (which would have allowed us to create local bindings) are forbidden. That's a lot of restrictions, but we can get around using a helper function that calculates the price each time:
(define normal-addon-cost 10) ; just an example
(define premium-addon-cost 100) ; just an example
(define (price size normal-addons premium-addons)
(+ (* normal-addon-cost normal-addons)
(* premium-addon-cost premium-addons)
size))
(define (item-price size normal-addons premium-addons discount)
(cond
... some conditions here ...
[else (price size normal-addons premium-addons)]))
Alternatively: if price is used only once, simply in-line the expression that calculates it, there's no need to create a local variable or a helper function.

Related

Question regarding creation of an absolute value function in scheme

I am currently just starting out working through Structure and Interpretation of Computer Programming, and in a section it is going over the creation of an absolute value function in Scheme (takes a value, and returns its absolute value).
I am following exactly how the book does the function:
(define (abs x)
(cond ((< x 0) (- x))
(else x)))
Unfortunately, this is not providing the desired result as the book says. Instead of returning the absolute value, it just returns the value. For example, I type in -5, the function returns -5.
If it is of any help, I am using the BiwaScheme Interpreter (0.6.4).
Any help is greatly appreciated, thanks.
To call a function, enclose its name in parentheses together with any arguments you wish to supply it with. Example,
> (abs -5)
5
Of course if you just type -5 you are not calling any functions, abs in particular, with it:
> -5
-5
The numeric value is just returned as is, as no function call is indicated.

Having trouble with a function in Scheme

so i am trying to understand this piece of code, and after staring at it for far too long i decided to ask here if anyone could help me understand how and why it works
(define knock-knock
(letrec ([dig (lambda (i)
(cons (* i (list-ref knock-knock (- i 1)))
(dig (+ i 1))))])
(cons 1 (dig 1))))
the function is then called by name with the value:
(list-ref knock-knock 5)
So my main problem is that i can not see where the letrec would end. the other thing is that i am not given a list, so what is the 4th element in the list that i am supposed to reference in line 3?
First, a note: this is not normal Scheme, as it requires lazy evaluation.
In lazy evaluation, values are only computed when they are needed. So, for defining knock-knock, we can just do
(cons 1 <thunk: (dig 1)>)
i.e., we generate a pair, but we don't need the second element, so we defer its evaluation until later.
When we actually want to evaluate the second element, we will already have knock-knock defined, so we can reference it.
The next element is computed by taking the previous (i-1-st) element, and multiplies it by i. So this will generate the series {n!}: 1,1,2,6,24,...
A straightforward translation of this code to the (normally lazy) Haskell language goes like this:
knock :: [Int]
knock = 1 : dig 1
where dig i = (i * knock !! (i-1)) : dig (i+1)

Determine definition and parameter of a Scheme function in the interpreter? / How are functions stored in Scheme?

I want to create a function that can determine the definition of an arbitrary function in scheme. If we call such a function "definition", it would work as such:
(define (triple x) (* 3 x))
(definition triple) would return "(triple x) (* 3 x)".
There would be some implementation problems (such as with n-arity), but I'm concerned mostly with whether or not the definition of individual functions are easily retrievable in Scheme.
As a continuation, is there a way to create a function that can determine the parameters of an arbitrary function? Such that:
(parameters +) returns (number number) or something similar.
These questions both fall under the question of how functions are stored in Scheme - I found some sources which claimed that function definitions are stored with the function name, but I couldn't find out how exactly they were stored.
If this is impossible - is there a language where function definitions are easily retrievable?
There is nothing like that in Scheme. Individual implementations might have that, though.
In Common Lisp there is the standard function function-lambda-expression, which might be able to retrieve source code - depending on the implementation.
Example in LispWorks (reformatted to improve readability here):
CL-USER 65 > (defun triple (x) (* 3 x))
TRIPLE
CL-USER 66 > (function-lambda-expression #'triple)
(LAMBDA (X)
(DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 42201D392B>))
(DECLARE (LAMBDA-NAME TRIPLE))
(* 3 X))
NIL
TRIPLE
SBCL:
* (defun triple (x) (* 3 x))
TRIPLE
* (function-lambda-expression #'triple)
(SB-INT:NAMED-LAMBDA TRIPLE
(X)
(BLOCK TRIPLE (* 3 X)))
NIL
TRIPLE
As you can see it returns three values: the code, whether it is a closure and the name of the function.

Scheme : using lambda as a parameter

hy everyone, for school i have to make a function where lambda is used as a parameter
like so : (string (lambda ...) 5 40) where we have to fill in the dots
this is the function we had to reinvent, the regular string version
(define (string decoration n r) >string decoration is a function that creates a string with either fish or pumpkins hanging on the string
(define (decorations k) >decorations is the recursive function which hangs all the decorations together
(if (= k 1)
(decoration r 10) > here decoration is to be replaced with either a pumpkin or a fish as stated in the parameters
(ht-append (decoration r 10) > ht-append is a function that appends 2 figures Horizontally at the Top
(decorations (- k 1)))))
(hang-by-thread (decorations n))) > hang by thread is a function that hangs all the decorations at a string
all the names should be self-explanatory, the function takes a decoration , either a fish or a pumpkin and hangs it by a thread. But the fish has 3 parameters and the pumpkin has 2 which caused an error. So in a previous exercise we had to make an extra definition called fish-square which uses only 2 parameters to make a fish. Now we have to implement this same squared fish but with a lambda. Any help is greatly appreciated
(define (fish-square wh l) > this is the fish square functio which makes a fish but with 2 times the same parameter so it looks like a square
(vc-append (filled-rectangle 2 l) (fish wh wh))) > the l is the length of the string that attaches the fish to the string at the top
the fish function is just (fish x y) x makes it longer, y makes it taller.
the pumpkin function is just (pumpkin x y) same story
so my question is, how do rewrite the given code , but with lambda as a parameter.
i would upload an image, but my repuation isn't high enough :s
The string procedure as it is already receiving a procedure as a parameter (you don't have to rewrite it!), decoration can be any two-argument function used for decorating. Now when you call it you can pass a named procedure, for example:
(define (decoration r n)
<body>)
(string decoration
5
40)
... Or just as easily, you can pass the same procedure in-line as a lambda, and if I understood correctly, this is what you're supposed to do:
(string (lambda (r n)
<body>)
5
40)
Just replace <body> with the actual body of the decoration you want to use. In othre words: the change you're expected to do is in the way you pass the parameters to the function at invocation time, but you're not expected to change the function itself.
Imagine you have the procedure +. It could be any really. It takes several arguments but you need a different procedure that takes one and adds that to an already constant value 3.
Thus you want to pass + with the extra information that it should add 3.
A full definition of such procedure would be
(define (add3 n)
(+ 3 n))
which is the short form of the full define
(define add3
(lambda (n)
(+ 3 n)))
Now when passing a procedure 3+ you could actually just pass it's definition. These two does the same:
(do-computation add3 data)
(do-computation (lambda (n) (+ 3 n)) data)

Scheme function that returns function is returning unexpected value

I have a function in scheme
(define (m-m f)
(let ((count 0))
(define (h-m-c?) count)
(define (r-c) (begin (set! count 0) count))
(define (m-f m)
(cond ((eq? m 'h-m-c?) (h-m-c))
((eq? m 'r-c) (r-c))
(else (set! count (+ 1 count)) f)))
m-f))
where m-f is a function that is returned.
However, rather than returning a value, it returns
#<procedure:m-f>
It appears there is no error with the code, so why doesn't this return a usable value?
You told it to return m-f. That's the name of a procedure that you defined, so it's returning the procedure. To use this return value, you need to assign it to another variable.
(define thing1 (m-m 'unused))
(define thing2 (m-m 'who-cares))
(thing1 'h-m-c?)
(thing1 'increment)
(thing1 'h-m-c?)
(thing2 'h-m-c?)
Some other commentary:
Procedure names ending in ? are used for predicates that report true/false.
You don't need begin in (r-c). Procedure bodies allow multiple expressions, and execute them in order just like begin.
Why didn't you define a function for the case where count is incremented, like you did for the other cases?
Using the default for incrementing seems inappropriate, you should require a specific m parameter for this.
What's the purpose of the f parameter? The only thing it's used for is to be returned when incrementing? Wouldn't the new value of count be a more useful return value? It seems like it's intended to be a "name" for the instance; if so, perhaps you should add a new operation to return the name, rather than doing this when incrementing.
EDIT:
Based on the answer below, I suspect you're misusing the f parameter. It's probably supposed to be a function that you call when doing the increment. So you need to supply it as a lambda expression, and return (f) rather than just f.

Resources