Why does DrRacket seem to identify this as a tail call? - scheme

Consider this snippet:
#lang racket
(define (f i)
(if (> i 5)
0
(+ 1 (f (+ 1 i)))))
Here, the call to f is not in tail position, and when I debug, I see a growing stack of the form
(+ ...)
(f ...)
(f ...)
(f ...)
(f ...)
This is expected. However, when I hover over the beginning of the last line, a light purple arrow appears and points to the beginning of the function definition. If I understand the documentation correctly, it indicates tail position. What am I missing?

The form which is the last line is in tail position with respect to f. The recursive call to f, however, isn't: if you hover over the f you'll get a pale blue arrow which tells you that it's the same f the function is binding. Here's a screenshot showing both things:
All of the (if ...) form and both of its consequents are in tail position. The f is the same f defined by the function, but is not in tail position.

When you move to B and you see A ➯ B. It means you can find B's define in A.
When you move to A and you see A ➯ B. You can see variable bound occurrence.

Related

How to create a lambda procedures?

I need to complete an assignment for my college course using Scheme. I've never coded in Scheme before so I have no clue what I'm doing. Our assignment is to define an anonymous function that computes the discriminant of a quadratic function. I keep running into the error: "Invalid `define'. Any help would be appreciated.
(define roots (lambda(abc))(
(lambda(discriminant))(
list(/(+(-b) discriminant)(*2a))
(/(-(-b) discriminant)(*2a))
)
(sqrt - (*bb)(*4ac))
)
First, you should learn a bit about what Scheme code looks like; find some example code (in your textbook, or online, or in answers here on SO) and notice how parentheses and whitespace are used. Then emulate that. You can't arbitrarily place parentheses or arbitrarily remove whitespace in Scheme (or in any Lisp).
For example, in the posted code (-b) gets two things wrong. First, -b is treated as one symbol, not as the negation of the value of b. Further, placing the symbol in parentheses indicates a procedure call; given an s-expression (f x), f is either a syntactic keyword (in which case (f x) is interpreted as a macro call), or (f x) is interpreted as a procedure call. If it is a procedure call and f is not bound to a procedure, then an exception is raised. So (-b) attempts to call a procedure named -b, which does not exist (unless you have defined it), raising an exception. You can use (- b), with a space between the - procedure and the symbol b; this evaluates to the negation of the value of b.
Similarly, *2a is interpreted as a symbol, not an expression; placing the *2a between parentheses is interpreted as a procedure call. The interpreter (or compiler) is expecting that *2a is a procedure which takes no arguments. You need to add the spaces: (* 2 a); this is interpreted as a call to the procedure * with the arguments 2 and a.
(*bb) and (*4ac) have exactly the same problems. The second case is interesting because when it is correctly written it illustrates one of the advantages of prefix notation. Since * is associative, it does not matter what order multiple values are multiplied in. To express naively 4 * a * c in prefix notation you could write (* 4 (* a c)), explicitly ordering the multiplications. You could also write this as (* (* 4 a) c), multiplying in a different order. It does not matter what order you multiply in, so you might as well just write (* 4 a c), so long as your language supports this notation. It turns out that Scheme and other Lisps do support this notation.
Another problem with s-expression notation in the posted code (after fixing the problems noted above): (sqrt - (* b b) (* 4 a c)). This is attempting to call the sqrt procedure on the arguments -, (* b b), and (* 4 a c). But sqrt is not a higher-order procedure (i.e., it does not take procedures as arguments), and it in fact only takes one argument. It was meant to apply the - procedure to the arguments (* b b) and (* 4 a c), subtracting them before taking the square root: (sqrt (- (* b b) (* 4 a c))).
The first lambda expression has a formal parameter list containing only one parameter: abc. As before, this is a mistake. The intention was to define three parameters: don't skimp on spaces: (lambda (a b c)).
The other significant problem is that there are syntax errors in the lambda expressions: (lambda (a b c)) has no body, but a lambda expression must have at least one expression in its body. This was probably intended to wrap the lambda expression which follows. Similarly, the inner lambda expression is missing its body. It was probably intended to wrap the (list ;;...) form that follows.
With that done, the inner lambda expression is itself inside of a pair of parentheses, taking the expression (sqrt (- (* b b) (* 4 a c))) as its argument. This is the lambda form of a let binding. Thus, the inner lambda takes one argument, discriminant, and evaluates the list form that is its body. Since the inner lambda expression itself occurs in the first position of an s-expression, it is part of a procedure call, and this inner anonymous procedure is then called on its argument, binding discriminant to the value obtained by evaluating that argument, which is (sqrt (- (* b b) (* 4 a c))). This all occurs inside of the outer lambda, which takes the three arguments a, b, and c. So, root is a function taking three arguments, and returning a list of roots, after binding the result of the discriminant calculation to discriminant (as a way of both simplifying the expression of the roots and ensuring that the discriminant need only be calculated one time).
Here is the fixed-up code. Note that I only added some spaces and added or moved a few parentheses; nothing else was changed:
(define roots
(lambda (a b c)
((lambda (discriminant)
(list (/ (+ (- b) discriminant) (* 2 a))
(/ (- (- b) discriminant) (* 2 a))))
(sqrt (- (* b b) (* 4 a c))))))
Pay attention to what this looks like. In Lisps you should almost never leave parentheses hanging on lines by themselves, and you should always place a space between arguments. Remember that everything is a procedure call.
Here is a sample interaction. Notice that you can represent negative numbers as -1 instead of (- 1) (you can do either if you wish). You just can't express a negative value using a variable as -b.
> (roots 1 0 -1)
(1 -1)
> (roots 1 8 15)
(-3 -5)

Racket - lang plai - define-type and type-case explanations

Can someone try and explain these two functions: "define-type" and "type-case" in the PLAI scheme in racket? I'm a noob programmer and I don't really understand the documentation on the racket website. If anyone could provide examples, it would greatly be appreciated. Thanks.
Here is a little example of how to use define-type and type-case:
#lang plai
; A ListOfNumbers are either
; is either an empty list of numbers
; or is constructed to two things a, and, d,
; where a is a number and d is a list of numbers.
(define-type ListOfNumbers
(Empty)
(Cons (a number?) (d ListOfNumbers?)))
; construct a list of numbers as an example
(define a-list (Cons 42 (Cons 43 (Empty))))
a-list ; prints: (Cons 42 (Cons 43 (Empty)))
(type-case ListOfNumbers a-list
(Empty () "the list is empty")
(Cons (a d) (~a "the first number in the list is " a)))
; prints: "the first number in the list is 42"
I'm not super experienced with Lisp/Scheme/Racket, but it looks like this question is still unanswered after 5 years, so I'll give it a shot.
First of all, note that not everything is a function. For example, when you use define to define a function or some other value, define is not acting as a function. A function is something that takes some input, and then returns some output. define does not do this. Instead, it changes the environment that you're programming in such a way that a new name exists that can be used to refer to some value.
So for example, in...
(define cadr
(lambda (x)
(car (cdr x))))
... define modifies the programing environment so that the function cadr now exists. cadr is a function (if you invoke it with some input, it will yield some output), but define itself is not a function (you're not invoking define with some input in order to get some output).
With that distinction hopefully cleared up, define-type is not a function. It is similar to define in that it modifies the programming environment to make it so that you have new names to refer to certain values. It is used to define a new type, along with some functions the allow you to work with that type.
An example taken from the Racket documentation:
> (define-type Shape
[circle (radius : number)]
[rectangle (width : number)
(height : number)])
> (define (area [s : Shape])
(type-case Shape s
[circle (r) (* (* r r) 3.14)]
[rectangle (w h) (* w h)]))
> (area (circle 1))
- number
3.14
> (area (rectangle 2 3))
- number
6
Here it defines a new type Shape which it says has two variants: circle and rectangle. It further says that in the case of the circle variant, the interesting piece of data is its radius, which is a number; and in the rectangle variant, there's two pieces of data (or "fields"), which are its width and height (both numbers).
It then defines a new function area, which is expected to take a single input of type Shape (the type we just declared earlier). The type-case expression is used to specify how to compute the area of a Shape depending on which variant we're dealing with. If we're dealing with a circle then we can compute the area by squaring the radius and multiplying it by Pi. If we're dealing with a rectangle, then we can compute the area by multiplying its width by its height.
Earlier, I said define-type is not a function, but by virtue of using it, it defines a new type and a bunch of functions that allow us to work with that type. So what are these new functions it defines? See this example:
> (define c (circle 10))
> c
- Shape
(circle 10)
> (circle? c)
- boolean
#t
> (circle-radius c)
- number
10
> (define r (rectangle 2 3))
> (+ (rectangle-width r) (rectangle-height r))
- number
5
Here we then use define to modify the programming environment so that the name c refers to a circle we created with radius 10. circle? is a function that automatically got created when we did the define-type in the earlier example, and it returns whether or not the shape we're dealing with is a circle variant (as opposed to a rectangle variant). Similar, the circle-radius, rectangle-width and rectangle-height functions were automatically defined for us when we used define-type, which allow us to access the fields inside of the data type.

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)

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)

Mutator elisp functions

How can I define mutator elisp functions? that is, how can I send parameters to an elisp function that can be modified inside the function for use outside the function (similar to non const reference variables or pointers in C++)? For example, suppose I had a function foo defined like
(defun foo (a b c d)
;do some stuff to b, c, and d
.
.
.
)
I might like to call it, say, as follows
(defun bar (x)
(let ((a) (b) (c) (y))
.
.
.
;a, b and c are nil at this point
(foo x a b c)
(setq y (some-other-function-of a b c x and-other-variables))
.
.
.
)) ... )
y)
I know that I could throw all my parameters local to some function into one big old list, evaluate the list at the end of the function and then go fetch these variables from some other list set to be the return value of that function (a list of stuff), i.e.
(setq return-list (foo read-only-x read-only-y))
(setq v_1 (car return-list))
(setq v_2 (cadr return-list))
.
.
but are there any better ways? All I have accomplished so far in my attempts to solve this is exiting the function with variables no different to how they were passed in
As for why I want to be able to do this I am simply trying refactor some large function F in such way that all collections of expressions related to some nameable concepts c live in their own little modules c_1, c_2, c_3, ... c_n that I can call from within F with whatever arguments I need to be updated along the way. That is to say, I would like F to look something like:
(defun F ( ... )
(let ((a_1) (a_2) ... )
(c_1 a_1 ... a_m)
(c_2 a_h ... a_i)
.
.
.
(c_n a_j ... a_k)
.
.
.
))...))
Two ways I can think of:
make the "function" foo a macro and not a function (if possible)
pass a newly created cons (or more of them) into the function, and replace the car and cdr of them via setcar/setcdr
In case the function is too complex, you can also combine both approaches - have a macro foo that creates a cons of a and b and calls a function foo0 with that cons, and later unpacks the car and cdr again.
In case you need more than 2 args, just use more than one cons as a paramter.
Just to show you how it can be done, but please don't do it, it's bad style.
(defun set-to (in-x out-y)
(set out-y in-x))
(let (x)
(set-to 10 'x)
x)
There's a case when this won't work though:
(let (in-x)
(set-to 10 'in-x)
in-x)
It's a bit like this C++ code
void set_to(int x, int* y) {
*y = x;
}
int y;
set_to(10, &y);
Actually I wish there were no non-const references in C++, so that
each mutator would have to be called with a pointer like above.
Again, don't do it unless it's really necessary.
Use instead multiple-value-bind or cl-flet.

Resources