Syntax for if-then-else in Racket - syntax

I have a problem with Racket.
(I'm using the tutorial at http://docs.racket-lang.org/guide/conditionals.html)
I tried to write a function that does this: If x is smaller than 4, then it should be incremented by 1, else it should be multiplied by 2.
(define (number x)
(if (< x 4) 'x+1 'x*2))
So I compiled it on DrRacket, but it does nothing. The (if (< x 5) 'x+1 'x*2)) -Part is marked black! I think the Problem is the ' thing.

In Lisps, the ' is a shorthand for the quote operator, which prevents an S-Expression or symbol from being evaluated. While x would normally be a variable, quoting it turns it into a kind of lightweight string. Quotes are not part of the if syntax. It makes no sense to use quoting in your case.
Furthermore, Lisps do not use infix operators. Addition is just an ordinary function and everything, including addition, is written as an S-Expression. So instead of x + 1 we would write (+ x 1).
So our function would then look like:
(define (number x)
(if (< x 4)
(+ x 1)
(* x 2)))

Related

Why doesn't this Racket code terminate?

I'm reading about lazy evaluation and having trouble understanding a basic example they gave.
#lang racket
(define (bad-if x y z)
(if x y z))
(define (factorial-wrong x)
(bad-if (= x 0)
1
(* x (factorial-wrong (- x 1)))))
(factorial-wrong 4)
I'm a little confused as to why this program never terminates. I know the following code works just fine:
(define (factorial x)
(if (= x 0)
1
(* x (factorial (- x 1)))))
(factorial 4)
So I'm assuming it has something to do with scope. I tried step by step debugging and factorial-wrong executes the recursion function even when x is mapped to 0.
The standard if
(if test-expr then-expr else-expr)
will only evaluate either then-expr or else-expr, depending on test-expr, because this if is either a special form or a syntactic extension based on a special form, which means it doesn't follow the normal evaluation rules.
bad-if, on the other hand, is a standard procedure. In that case, Scheme first evaluates both expressions since they are parameters to the procedure bad-if before actually executing bad-if. So, even for x = 0, (* x (factorial -1)) will be evaluated, which will in turn evaluate (* x (factorial -2)) and so on, in an endless loop.
Use the stepper!
To be more specific:
Snip the #lang racket off the top of your program
Change the language level to "Intermediate Student"
Click on the Step button. Watch carefully to see where things go off the rails.

Scheme notation for "and" conditional

For an SICP course we are learning Scheme and we had an assignment that asked us to check if a point was in an axis-aligned rectangular. I did it like this:
(define in-rect?
(lambda (px py rx1 ry1 rx2 ry2)
(<= (* (- px rx1) (- px rx2)) 0) and
(<= (* (- py ry1) (- py ry2)) 0)))
I did this according to my previous C habits and forgot about Polish notation for a while there. The interpreter that our online tutor program uses runs this code "correctly", as I intended. However, AFAIK, this usage of 'and' should syntactically be wrong. DrRacket points out a syntax error when I try to run this.
Then how did this evaluate to correct values for every test case on the online tutor? Is this option also valid maybe?
The syntax for and is the same as for most expression - it uses prefix notation; also it can have zero or more arguments, which don't necessarily have to be boolean expressions:
(and <exp1> <exp2> <exp3> ...)
For your code it should look as follows:
(define in-rect?
(lambda (px py rx1 ry1 rx2 ry2)
(and (<= (* (- px rx1) (- px rx2)) 0)
(<= (* (- py ry1) (- py ry2)) 0))))
As to why your code seemed to work in the online tutor, it's because the interpreter probably evaluated the body of the lambda inside an implicit begin with three expression (first <= expression, and special form, second <= expression), returning just the value of the last condition. Although it's weird that it worked at all, because an and without arguments generally rises a "bad syntax" or similar error - it all depends on how it was implemented, but doesn't seem like a standards-compliant interpreter.
To make sure everything's clear, take a look at the documentation, because and behaves slightly different than what you'd expect, coming from a C background. Remember that and short-circuits at the first false condition:
(and (+ 1 1) #f (/ 1 0)) ; will work without a division by zero error
^
evaluation stops here
=> #f
And notice that and returns the value of the last expression it encounters, because in Scheme anything that is not explicitly #f, is considered true:
(and #t (* 2 3) (+ 1 1))
^
evaluation stops here
=> 2
(<= (* (- px rx1) (- px rx2)) 0)
and
(<= (* (- py ry1) (- py ry2)) 0)
Is actually three different (potential) values/expressions. Because you didn't wrap it in a begin, the interpreter might return the leftmost or the rightmost as the value of the lambda depending on your implementation.
Your online interpreter probably implemented and as a primitive function, rather than a macro or syntax, or simply isn't strick about not using macros/syntactic keywords as expressions.
If the interpreter thinks and has some sort of value (and/or is a valid expression) it can proceed to returning the value of the first of third expression in your lambda body.

Getting elisp to return a function as return value

I'm trying to create a function in elisp that returns another function. I looked at this answer to a similar question (how to return function in elisp) but did not understand the answer (I'm literally just starting learning elisp today, so please excuse my ignorance). I thought a simpler example would help. First, consider a function that test whether a number is divisible by 5:
(defun divisible-by-5 (x)
;; tests whether a number is divsible by 5.
(setq remainder (% x 5))
(if (= remainder 0) 1 0)
)
This works fine:
(divisible-by-5 25)
1
Now suppose I want to create a function that can create more of these kinds of test functions---something like:
(defun divisible-by-z (z)
(lambda (z)
(setq remainder (% x z))
(if (= remainder 0) 1 0))
)
This does not work. E.g.,
(defun divisible-by-3 (divisible-by-z 3))
(divisible-by-3 4)
returns an error. I think even seeing an elisp-idiomatic example of how one would implement this pattern would be helpful.
First, make sure you have lexical-binding enabled. The simplest way to do so is to evaluate (setq lexical-binding t) in your current buffer. More information on the topic can be found here.
Your definition of divisible-by-z is basically correct except that you have a mistype (naming both parameters z; the lambda's parameter should be x). Also, it would be more idiomatic to introduce the binding for remainder with let - setq is generally reserved for mutating bindings that already exist. Here's the result:
(defun divisible-by-z (z)
(lambda (x)
(let ((remainder (% x z)))
(if (= remainder 0) 1 0))))
You can't use defun to create divisible-by-3 in quite the way you've tried - it's expecting the argument list for a new function to be where you have the call to divisible-by-z.
You could either create a global, dynamic binding with
(defvar divisible-by-3 (divisible-by-z 3))
Or a local, lexical binding with
(let ((divisible-by-3 (divisible-by-z 3)))
...)
Either way, you'll then need to use funcall to call the function
(funcall divisible-by-3 9) ; => 1
Of course, you could also skip giving it its own name entirely and simply
(funcall (divisible-by-z 3) 10) ; => 0
funcall is necessary because Emacs Lisp is (basically) a Lisp-2, meaning it can attach both a function and a value to a given symbol. So when you're treating functions as values (returning one from a function or passing one in to a function as a parameter) you essentially have to tell it to look in that value "cell" rather than the usual function cell. If you search for "Lisp-1 vs Lisp-2" you'll find more than you want to know about this.
A possible solution:
(defun divisible-by-3 (x)
(funcall (divisible-by-z 3) x))
Another (perhaps simpler) method is to include x as a variable to be passed to the function:
(defun divisible-by-z (x z) "
Check if x is divisible by z.
If so, return 0.
If not, return the remainder."
(if (% x z) (% x z) 0))
thus:
(divisible-by-z 5 2) --> 1
(divisible-by-z 4 2) --> 0

Why not letrec as fix?

In the paper Fixing Letrec: A Faithful Yet Efficient Implementation
of Scheme’s Recursive Binding Construct by Dybvig et al. it is said that (emphasis mine):
A theoretical solution to these problems is to restrict letrec so
that its left-hand sides are unassigned and right-hand sides are lambda
expressions. We refer to this form of letrec as fix, since it amounts to
a generalized form of fixpoint operator. The compiler can handle fix
expressions efficiently, and there can be no violations of the letrec
restriction with fix. Unfortunately, restricting letrec in this manner is not an option for the implementor and would in any case reduce the generality and convenience of the construct.
I have not scrutinized the R5RS report, but I have used letrec and the equivalent "named let" in Scheme programs and the unfortunate consequences mentioned in the paper are not clear to me, can someone enlighten me ?
The R5RS letrec restriction says something like these are in violation:
(let ((x 10))
(letrec ((x x))
x))
(letrec ((y (+ x 5))
(x 5))
(list x y))
Thus, it's not specified what would happen and it would certainly not be portable Scheme. It may evaluate to 10 and (5 10), the implementation might signal an error or you get an undefined value that might result in an error getting signaled. I have tested Racket, Gambit, Chicken and Ikarus and not one of them signal anything in the first case and they all evaluate to an unspecified value. Ikarus is the only one that returned (5 10) in the latter while the others all got contract errors since an unspecified value as argument violates +'s contract. (Ikarus always evaluates operands right to left)
The R[567]RS reports all state that if all expressions are lambda expressions you have nothing to worry about and I think that is the clue. Another is that you should not try to shadow like you would do with (named) let.
There is a follow up on the original paper that is entitled Fixing letrec (reloaded) that has macros that implements the "fix".
With equational syntax,
letrec x = init-x
y = init-y
body....
the restriction is that no RHS init... expression can cause evaluation of (or assignment to) any of the LHS variables, because all init...s are evaluated while all the variables are still unassigned. IOW no init... should reference any of the variables directly and immediately. It is OK of course for any of the init...s to contain lambda-expressions which can indeed reference any of the variables (that's the purpose of letrec after all). When these lambda-expressions will be evaluated, the variables will be already assigned the values of the evaluated init... expressions.
The authors say, to require all the RHSes to be lambda-expressions would simplify the implementation, because there's no chance for misbehaving code causing premature evaluation of LHS variables inside some RHS. But unfortunately, this changes letrec's semantics and thus is not an option. It would also prohibit simple use of outer variables in RHSes and thus this new cut-down letrec would also be less general and less convenient.
You also mention named let but it is not equivalent to letrec: its variables are bound as-if by let, only the looping function itself is bound via letrec:
(let ((x 1)(y 2))
(let g ((x x) (y x))
(if (> x 0) (g (- x y) y) (display x)))
(display x))
01
;Unspecified return value
(let ((x 1)(y 2))
(letrec ((g (lambda (x y)
(if (> x 0) (g (- x y) y) (display x)))))
(g x x)) ; no 'x' in letrec's frame, so refer to outer frame
(display x))
01
;Unspecified return value

Using 'define' in Scheme

I'm new to Scheme and was just curious about 'define'. I've seen things like:
(define (square x) (* x x))
which makes sense [Function name 'square' input parameter 'x']. However, I found some example code from the 90's and am trying to make sense of:
(define (play-loop-iter strat0 strat1 count history0 history1 limit) (~Code for function~)
Except for the function name, are all of those input parameters?
Short answer - yes, all the symbols after the first one are parameters for the procedure (the first one being the procedures's name). Also it's good to point out that this:
(define (f x y)
(+ x y))
Is just syntactic sugar for this, and both forms are equivalent:
(define f
(lambda (x y)
(+ x y)))
In general - you use the special form define for binding a name to a value, that value can be any data type available, including in particular functions (lambdas).
A bit more about parameters and procedure definitions - it's good to know that the . notation can be used for defining procedures with a variable number of arguments, for example:
(define (f . x) ; here `x` is a list with all the parameters
(apply + x))
(f 1 2 3 4 5) ; 0 or more parameters can be passed
=> 15
And one final trick with define (not available in all interpreters, but works in Racket). A quick shortcut for defining procedures that return procedures, like this one:
(define (f x)
(lambda (y)
(+ x y)))
... Which is equivalent to this, shorter syntax:
(define ((f x) y)
(+ x y))
((f 1) 2)
=> 3
Yes, strat0 through limit are the parameters of the play-loop-iter function.
The general form for define is:
(define (desired-name-of-procedure item-1 item-2 item-3 ... item-n)
(; what to do with the items))
Another way to explain the behaviour of define, is in terms of "means of combination", and "means of abstraction".
[A] The means of combination in simple terms:
The syntax (item-1 item-2 item-3 ... ... item-n) is the fundamental means of combination provided by Scheme (and Lisp in general.)
All code is a list represented using the above pattern
The very first (leftmost) item is always treated as an operator
Parentheses enforce the application of the operator... The leftmost item is required to accept all the items that follow, as arguments
[B] means of abstraction is simply; a way to name things.
An example will demonstrate how this all folds into the idea of the define primitive...
Example--Arriving at define in a bottom-up way
Consider this expression:
(lambda (x y) (* x y))
In plain English, the above expression translates to "Create a nameless procedure that accepts two arguments, and returns the value of the their product". Note that this generates a nameless procedure.
More accurately, in terms of means of combination, Scheme provides us the keyword lambda as a primitive operator that creates user-defined procedures.
The leftmost item--lambda--is passed items (x y) and (* x y) as arguments, and the operator-application rule forces lambda to do something with the items.
The way lambda is defined internally causes it to parse the list (x y), and treat x and y as arguments to pass to the list (* x y), which lambda assumes is the user's definition of what to do when arguments x and y are encountered. Any value assigned to x and y will be processed in accordance with the rule (* x y).
Enter, means of abstraction...
Suppose I wanted to refer to this type of multiplication at several places in my program, I might tweak the above lambda expression like this:
(define mul-two-things (lambda (x y) (* x y)))
define takes mul-two-things and the lambda expression as arguments, and "binds" them together. Now Scheme knows that mul-two-things should be associated with a procedure to take two arguments and return their product.
As it happens, the requirement of naming procedures is so very common and provides so much power of expression, that Scheme provides a cleaner-looking shortcut to do it.
Like #oscar-lopez says, define is the "special form" Scheme provides, to name things. And as far as Scheme's Interpreter is concerned, both the following definitions are identical:
(define (mul-two-things x y) (* x y))
(define mul-two-things (lambda (x y) (* x y))

Resources