You are on page 1of 55

boolean, Scheme will treat any value that

Different AI algorithm are tested is not #f as a true value.


using lisp (LISt Processing
2.1.2  Numbers
Programming) programming
using Dr scheme application. Scheme numbers can be integers (eg, 42),
rationals (22/7), reals (3.1416), or complex
Data types (2+3i). An integer is a rational is a real is a
complex number is a number. Predicates
A data type is a collection of related exist for testing the various kinds of
values. These collections need not be numberness:
disjoint, and they are often hierarchical.
Scheme has a rich set of data types: (number? 42) => #t
some are simple (indivisible) data types (number? #t) => #f
and others are compound data types (complex? 2+3i) => #t
made by combining other data types. (real? 2+3i) => #f
(real? 3.1416) => #t
2.1  Simple data types (real? 22/7) => #t
(real? 42) => #t
The simple data types of Scheme include (rational? 2+3i) => #f
booleans, numbers, characters, and (rational? 3.1416) => #t
symbols. (rational? 22/7) => #t
(integer? 22/7) => #f
2.1.1  Booleans (integer? 42) => #t

Scheme’s booleans are #t for true and #f Scheme integers need not be specified in
for false. Scheme has a predicate decimal (base 10) format. They can be
procedure called boolean? that checks if its specified in binary by prefixing the
argument is boolean. numeral with #b. Thus #b1100 is the
SANDEEP KUMAR http://san24mca.blogspot.com/

number twelve. The octal prefix is #o and


(boolean? #t) => #t the hex prefix is #x. (The optional decimal
(boolean? "Hello, World!") => #f prefix is #d.)

The procedure not negates its argument, Numbers can tested for equality using the
considered as a boolean. general-purpose equality predicate eqv?.

(not #f) => #t (eqv? 42 42) => #t


(not #t) => #f (eqv? 42 #f) => #f
(not "Hello, World!") => #f (eqv? 42 42.0) => #f

The last expression illustrates a Scheme


convenience: In a context that requires a
However, if you know that the arguments (abs 3) => 3
to be compared are numbers, the special (abs -4) => 4
number-equality predicate = is more apt.
This is just the tip of the iceberg. Scheme
(= 42 42) => #t provides a large and comprehensive suite
(= 42 #f) -->ERROR!!! of arithmetic and trigonometric
(= 42 42.0) => #t procedures. For instance, atan, exp, and
sqrt respectively return the arctangent,
Other number comparisons allowed are <, natural antilogarithm, and square root of
<=, >, >=. their argument.

(< 3 2) => #f 2.1.3  Characters


(>= 4.5 3) => #t
Scheme character data are represented by
Arithmetic procedures +, -, *, /, expt have prefixing the character with #\ . Thus, #\c
the expected behavior: is the character c. Some non-graphic
characters have more descriptive names,
(+ 1 2 3) => 6 eg, #\newline, #\tab. The character for
(- 5.3 2) => 3.3 space can be written #\  , or more
(- 5 2 1) => 2 readably, #\space.
(* 1 2 3) => 6
(/ 6 3) => 2 The character predicate is char?:
(/ 22 7) => 22/7
(expt 2 3) => 8 (char? #\c) => #t
(expt 4 1/2) => 2.0 (char? 1) => #f
(char? #\;) => #t
For a single argument, - and / return the
negation and the reciprocal respectively: Note that a semicolon character datum
does not trigger a comment.
(- 4) => -4
(/ 4) => 1/4 The character data type has its set of
SANDEEP KUMAR http://san24mca.blogspot.com/

comparison predicates: char=?, char<?,


The procedures max and min return the char<=?, char>?, char>=?.
maximum and minimum respectively of
the number arguments supplied to them. (char=? #\a #\a) => #t
Any number of arguments can be so (char<? #\a #\b) => #t
supplied. (char>=? #\a #\b) => #f

(max 1 3 4 2 3) => 4 To make the comparisons case-insensitive,


(min 1 3 4 2 3) => 1 use char-ci instead of char in the procedure
name:
The procedure abs returns the absolute
value of its argument. (char-ci=? #\a #\A) => #t
(char-ci<? #\a #\B) => #t
(quote E)
The case conversion procedures are char-
downcase and char-upcase: Scheme symbols are named by a sequence
of characters. About the only limitation on
(char-downcase #\A) => #\a a symbol’s name is that it shouldn’t be
(char-upcase #\a) => #\A mistakable for some other data, eg,
characters or booleans or numbers or
2.1.4  Symbols compound data. Thus, this-is-a-symbol,
i18n, <=>, and $!#* are all symbols; 16, -i
The simple data types we saw above are (a complex number!), #t, "this-is-a-string",
self-evaluating. i.e., if you typed any and (barf) (a list) are not. The predicate for
object from these data types to the listener, checking symbolness is called symbol?:
the evaluated result returned by the listener
will be the same as what you typed in. (symbol? 'xyz) => #t
(symbol? 42) => #f
#t => #t
42 => 42 Scheme symbols are normally case-
#\c => #\c insensitive. Thus the symbols Calorie and
calorie are identical:
Symbols don’t behave the same way. This
is because symbols are used by Scheme (eqv? 'Calorie 'calorie)
programs as identifiers for variables, and => #t
thus will evaluate to the value that the
variable holds. Nevertheless, symbols are a We can use the symbol xyz as a global
simple data type, and symbols are variable by using the form define:
legitimate values that Scheme can traffic
in, along with characters, numbers, and the (define xyz 9)
rest.
This says the variable xyz holds the value
To specify a symbol without making 9. If we feed xyz to the listener, the result
Scheme think it is a variable, you should will be the value held by xyz:
SANDEEP KUMAR http://san24mca.blogspot.com/

quote the symbol:


xyz
(quote xyz) => 9
=> xyz
We can use the form set! to change the
Since this type of quoting is very common value held by a variable:
in Scheme, a convenient abbreviation is
provided. The expression (set! xyz #\c)

'E Now

will be treated by Scheme as equivalent to xyz


=> #\c
New strings can be created by appending
2.2  Compound data types other strings:

Compound data types are built by (string-append "E "


combining values from other data types in "Pluribus "
structured ways. "Unum")
=> "E Pluribus Unum"
2.2.1  Strings
You can make a string of a specified
Strings are sequences of characters (not to length, and fill it with the desired
be confused with symbols, which are characters later.
simple data that have a sequence of
characters as their name). You can specify (define a-3-char-long-string (make-string
strings by enclosing the constituent 3))
characters in double-quotes. Strings
evaluate to themselves. The predicate for checking stringness is
string?.
"Hello, World!"
=> "Hello, World!" Strings obtained as a result of calls to
string, make-string, and string-append are
The procedure string takes a bunch of mutable. The procedure string-set!
characters and returns the string made replaces the character at a given index:
from them:
(define hello (string #\H #\e #\l #\l #\o))
(string #\h #\e #\l #\l #\o) hello
=> "hello" => "Hello"

Let us now define a global variable 2.2.2  Vectors


greeting.
Vectors are sequences like strings, but
(define greeting "Hello; Hello!") their elements can be anything, not just
SANDEEP KUMAR http://san24mca.blogspot.com/

characters. Indeed, the elements can be


Note that a semicolon inside a string vectors themselves, which is a good way
datum does not trigger a comment. to generate multidimensional vectors.

The characters in a given string can be Here’s a way to create a vector of the first
individually accessed and modified. The five integers:
procedure string-ref takes a string and a (0-
based) index, and returns the character at (vector 0 1 2 3 4)
that index: => #(0 1 2 3 4)

(string-ref greeting 0) Note Scheme’s representation of a vector


=> #\H value: a # character followed by the
vector’s contents enclosed in parentheses.
The elements of a dotted pair can be
In analogy with make-string, the procedure replaced by the mutator procedures set-
make-vector makes a vector of a specific car! and set-cdr!:
length:
(set-car! x 2)
(define v (make-vector 5))
(set-cdr! x #f)
The procedures vector-ref and vector-set!
access and modify vector elements. The x
predicate for checking if something is a => (2 . #f)
vector is vector?.
Dotted pairs can contain other dotted pairs.
2.2.3  Dotted pairs and lists
(define y (cons (cons 1 2) 3))
A dotted pair is a compound value made
by combining any two arbitrary values into y
an ordered couple. The first element is => ((1 . 2) . 3)
called the car, the second element is called
the cdr, and the combining procedure is The car of the car of this list is 1. The cdr
cons. of the car of this list is 2. i.e.

(cons 1 #t) (car (car y))


=> (1 . #t) => 1

Dotted pairs are not self-evaluating, and so (cdr (car y))


to specify them directly as data (ie, => 2
without producing them via a cons-call),
one must explicitly quote them: Scheme provides procedure abbreviations
for cascaded compositions of the car and
'(1 . #t) => (1 . #t) cdr procedures. Thus, caar stands for “car
of car of”, and cdar stands for “cdr of car
SANDEEP KUMAR http://san24mca.blogspot.com/

(1 . #t) -->ERROR!!! of”, etc.

The accessor procedures are car and cdr: (caar y)


=> 1
(define x (cons 1 #t))
(cdar y)
(car x) => 2
=> 1
c...r-style abbreviations for upto four
(cdr x) cascades are guaranteed to exist. Thus,
=> #t cadr, cdadr, and cdaddr are all valid.
cdadadr might be pushing it.
When nested dotting occurs along the Indeed, if we know all the elements of a
second element, Scheme uses a special list, we can use quote to specify the list:
notation to represent the resulting
expression: '(1 2 3 4)
=> (1 2 3 4)
(cons 1 (cons 2 (cons 3 (cons 4 5))))
=> (1 2 3 4 . 5) List elements can be accessed by index.

i.e. (1 2 3 4 . 5) is an abbreviation for (1 . (define y (list 1 2 3 4))


(2 . (3 . (4 . 5)))). The last cdr of this
expression is 5. (list-ref y 0) => 1
(list-ref y 3) => 4
Scheme provides a further abbreviation if
the last cdr is a special object called the (list-tail y 1) => (2 3 4)
empty list, which is represented by the (list-tail y 3) => (4)
expression (). The empty list is not
considered self-evaluating, and so one list-tail returns the tail of the list starting
should quote it when supplying it as a from the given index.
value in a program:
The predicates pair?, list?, and null? check
'( ) => ( ) if their argument is a dotted pair, list, or
the empty list, respectively:
The abbreviation for a dotted pair of the
form (1 . (2 . (3 . (4 . ( ))))) is (pair? '(1 . 2)) => #t
(pair? '(1 2)) => #t
(1 2 3 4) (pair? '()) => #f
(list? '()) => #t
This special kind of nested dotted pair is (null? '()) => #t
called a list. This particular list is four (list? '(1 2)) => #t
elements long. It could have been created (list? '(1 . 2)) => #f
by saying (null? '(1 2)) => #f
SANDEEP KUMAR http://san24mca.blogspot.com/

(null? '(1 . 2)) => #f


(cons 1 (cons 2 (cons 3 (cons 4 '()))))
2.2.4  Conversions between data types
but Scheme provides a procedure called
list that makes list creation more Scheme offers many procedures for
convenient. list takes any number of converting among the data types. We
arguments and returns the list containing already know how to convert between the
them: character cases using char-downcase and
char-upcase. Characters can be converted
(list 1 2 3 4) into integers using char->integer, and
=> (1 2 3 4) integers can be converted into characters
using integer->char. (The integer
corresponding to a character is usually its (string->symbol "string")
ascii code.) => string

(char->integer #\d) => 100 2.3  Other data types


(integer->char 50) => #\2
Scheme contains some other data types.
Strings can be converted into the One is the procedure. We have already
corresponding list of characters. seen many procedures, eg, display, +,
cons. In reality, these are variables holding
(string->list "hello") => (#\h #\e #\l #\l the procedure values, which are
#\o) themselves not visible as are numbers or
characters:
Other conversion procedures in the same
vein are list->string, vector->list, and list- cons
>vector. => <procedure>

Numbers can be converted to strings: The procedures we have seen thus far are
primitive procedures, with standard global
(number->string 16) => "16" variables holding them. Users can create
additional procedure values.
Strings can be converted to numbers. If the
string corresponds to no number, #f is Yet another data type is the port. A port is
returned. the conduit through which input and
output is performed. Ports are usually
(string->number "16") associated with files and consoles.
=> 16
In our “Hello, World!” program, we used
(string->number "Am I a hot number?") the procedure display to write a string to
=> #f the console. display can take two
arguments, one the value to be displayed,
string->number takes an optional second and the other the output port it should be
SANDEEP KUMAR http://san24mca.blogspot.com/

argument, the radix. displayed on.

(string->number "16" 8) => 14 In our program, display’s second argument


was implicit. The default output port used
because 16 in base 8 is the number is the standard output port. We can get the
fourteen. current standard output port via the
procedure-call (current-output-port). We
Symbols can be converted to strings, and could have been more explicit and written
vice versa:
(display "Hello, World!" (current-output-
(symbol->string 'symbol) port))
=> "symbol"
2.4  S-expressions
If the head of the form is a special form,
All the data types discussed here can be the evaluation proceeds in a manner
lumped together into a single all- idiosyncratic to that form. Some special
encompassing data type called the s- forms we have already seen are begin,
expression (S for symbolic). Thus 42, #\c, define, and set!. begin causes its subforms
(1 . 2), #(a b c), "Hello", (quote xyz), to be evaluated in order, the result of the
(string->number "16"), and (begin (display entire form being the result of the last
"Hello, World!") (newline)) are all s- subform. define introduces and initializes a
expressions. variable. set! changes the binding of a
Chapter 3 variable.

Forms 3.1  Procedures

The reader will have noted that the We have seen quite a few primitive
Scheme example programs provided thus Scheme procedures, eg, cons, string->list,
far are also s-expressions. This is true of and the like. Users can create their own
all Scheme programs: Programs are data. procedures using the special form lambda.
For example, the following defines a
Thus, the character datum #\c is a procedure that adds 2 to its argument:
program, or a form. We will use the more
general term form instead of program, so (lambda (x) (+ x 2))
that we can deal with program fragments
too. The first subform, (x), is the list of
parameters. The remaining subform(s)
Scheme evaluates the form #\c to the value constitute the procedure’s body. This
#\c, because #\c is self-evaluating. Not all procedure can be called on an argument,
s-expressions are self-evaluating. For just like a primitive procedure:
instance the symbol s-expression xyz
evaluates to the value held by the variable ((lambda (x) (+ x 2)) 5)
xyz. The list s-expression (string->number => 7
"16") evaluates to the number 16.
SANDEEP KUMAR http://san24mca.blogspot.com/

If we wanted to call this same procedure


Not all s-expressions are valid programs. If many times, we could create a replica
you typed the dotted-pair s-expression (1 . using lambda each time, but we can do
2) at the Scheme listener, you will get an better. We can use a variable to hold the
error. procedure value:

Scheme evaluates a list form by examining (define add2


the first element, or head, of the form. If (lambda (x) (+ x 2)))
the head evaluates to a procedure, the rest
of the form is evaluated to get the We can then use the variable add2 each
procedure’s arguments, and the procedure time we need a procedure for adding 2 to
is applied to the arguments. its argument:
(add2 4) => 6 In general, the lambda parameter list can
(add2 9) => 11 be a list of the form (x ...), a symbol, or a
dotted pair of the form (x ... . z). In the
3.1.1  Procedure parameters dotted-pair case, all the variables before
the dot are bound to the corresponding
The parameters of a lambda-procedure are arguments in the procedure call, with the
specified by its first subform (the form single variable after the dot picking up all
immediately following the head, the the remaining arguments as one list.
symbol lambda). add2 is a single-argument
— or unary — procedure, and so its 3.2  apply
parameter list is the singleton list (x). The
symbol x acts as a variable holding the The Scheme procedure apply lets us call a
procedure’s argument. Each occurrence of procedure on a list of its arguments.
x in the procedure’s body refers to the
procedure’s argument. The variable x is (define x '(1 2 3))
said to be local to the procedure’s body.
(apply + x)
We can use 2-element lists for 2-argument => 6
procedures, and in general, n-element lists
for n-argument procedures. The following In general, apply takes a procedure,
is a 2-argument procedure that calculates followed by a variable number of other
the area of a rectangle. Its two arguments arguments, the last of which must be a list.
are the length and breadth of the rectangle. It constructs the argument list by prefixing
the last argument with all the other
(define area (intervening) arguments. It then returns the
(lambda (length breadth) result of calling the procedure on this
(* length breadth))) argument list. Eg,

Notice that area multiplies its arguments, (apply + 1 2 3 x)


and so does the primitive procedure *. We => 12
could have simply said:
SANDEEP KUMAR http://san24mca.blogspot.com/

3.3  Sequencing
(define area *)
We used the begin special form to bunch
3.1.2  Variable number of arguments together a group of subforms that need to
be evaluated in sequence. Many Scheme
Some procedures can be called at different forms have implicit begins. For example,
times with different numbers of let’s define a 3-argument procedure that
arguments. To do this, the lambda displays its three arguments, with spaces
parameter list is replaced by a single between them. A possible definition is:
symbol. This symbol acts as a variable that
is bound to the list of the arguments that (define display3
the procedure is called on. (lambda (arg1 arg2 arg3)
(begin
(display arg1)
(display " ") (if (< p 90)
(display arg2) 'low-pressure) ;no ``else'' branch
(display " ") => low-pressure
(display arg3)
(newline)))) Scheme provides some other conditional
forms for convenience. They can all be
In Scheme, lambda-bodies are implicit defined as macros (chap 8) that expand
begins. Thus, the begin in display3’s body into if-expressions.
isn’t needed, although it doesn’t hurt.
display3, more simply, is: 4.1  when and unless

(define display3 when and unless are convenient


(lambda (arg1 arg2 arg3) conditionals to use when only one branch
(display arg1) (the “then” or the “else” branch) of the
(display " ") basic conditional is needed.
(display arg2)
(display " ") (when (< (pressure tube) 60)
(display arg3) (open-valve tube)
(newline))) (attach floor-pump tube)
(depress floor-pump 5)
(detach floor-pump tube)
Chapter 4 (close-valve tube))
Conditionals
Assuming pressure of tube is less than 60,
Like all languages, Scheme provides this conditional will attach floor-pump to
conditionals. The basic form is the if: tube and depress it 5 times. (attach and
depress are some suitable procedures.)
(if test-expression
then-branch The same program using if would be:
SANDEEP KUMAR http://san24mca.blogspot.com/

else-branch)
(if (< (pressure tube) 60)
If test-expression evaluates to true (ie, any (begin
value other than #f), the “then” branch is (open-valve tube)
evaluated. If not, the “else” branch is (attach floor-pump tube)
evaluated. The “else” branch is optional. (depress floor-pump 5)
(detach floor-pump tube)
(define p 80) (close-valve tube)))

(if (> p 70) Note that when’s branch is an implicit


'safe begin, whereas if requires an explicit begin
'unsafe) if either of its branches has more than one
=> safe form.
The same behavior can be written using A special case of the cond can be
unless as follows: compressed into a case expression. This is
when every test is a membership test.
(unless (>= (pressure tube) 60)
(open-valve tube) (case c
(attach floor-pump tube) ((#\a) 1)
(depress floor-pump 5) ((#\b) 2)
(detach floor-pump tube) ((#\c) 3)
(close-valve tube)) (else 4))
=> 3
Not all Schemes provide when and unless.
If your Scheme does not have them, you The clause whose head contains the value
can define them as macros (see chap 8). of c is chosen.

4.2  cond 4.4  and and or

The cond form is convenient for Scheme provides special forms for boolean
expressing nested if-expressions, where conjunction (“and”) and disjunction (“or”).
each “else” branch but the last introduces a (We have already seen (sec 2.1.1)
new if. Thus, the form Scheme’s boolean negation not, which is a
procedure.)
(if (char<? c #\c) -1
(if (char=? c #\c) 0 The special form and returns a true value if
1)) all its subforms are true. The actual value
returned is the value of the final subform.
can be rewritten using cond as: If any of the subforms are false, and
returns #f.
(cond ((char<? c #\c) -1)
((char=? c #\c) 0) (and 1 2) => 2
(else 1)) (and #f 1) => #f
SANDEEP KUMAR http://san24mca.blogspot.com/

The cond is thus a multi-branch The special form or returns the value of its
conditional. Each clause has a test and an first true subform. If all the subforms are
associated action. The first test that false, or returns #f.
succeeds triggers its associated action. The
final else clause is chosen if no other test (or 1 2) => 1
succeeded. (or #f 1) => 1

The cond actions are implicit begins. Both and and or evaluate their subforms
left-to-right. As soon as the result can be
4.3  case determined, and and or will ignore the
remaining subforms.
(and 1 #f expression-guaranteed-to-cause-
error) The form set! modifies the lexical binding
=> #f of a variable.

(or 1 #f expression-guaranteed-to-cause- (set! x 20)


error)
=> 1 modifies the global binding of x from 9 to
20, because that is the binding of x that is
visible to set!. If the set! was inside add2’s
Chapter 5 body, it would have modified the local x:
Lexical variables
(define add2
Scheme’s variables have lexical scope, i.e. (lambda (x)
they are visible only to forms within a (set! x (+ x 2))
certain contiguous stretch of program text. x))
The global variables we have seen thus far
are no exception: Their scope is all The set! here adds 2 to the local variable x,
program text, which is certainly and the procedure returns this new value of
contiguous. the local x. (In terms of effect, this
procedure is indistinguishable from the
We have also seen some examples of local previous add2.) We can call add2 on the
variables. These were the lambda global x, as before:
parameters, which get bound each time the
procedure is called, and whose scope is (add2 x) => 22
that procedure’s body. Eg,
(Remember global x is now 20, not 9!)
(define x 9)
(define add2 (lambda (x) (+ x 2))) The set! inside add2 affects only the local
variable used by add2. Although the local
x => 9 variable x got its binding from the global
x, the latter is unaffected by the set! to the
SANDEEP KUMAR http://san24mca.blogspot.com/

(add2 3) => 5 local x.


(add2 x) => 11
x => 20
x => 9
Note that we had all this discussion
Here, there is a global x, and there is also a because we used the same identifier for a
local x, the latter introduced by procedure local variable and a global variable. In any
add2. The global x is always 9. The local x text, an identifier named x refers to the
gets bound to 3 in the first call to add2 and lexically closest variable named x. This
to the value of the global x, ie, 9, in the will shadow any outer or global x’s. Eg, in
second call to add2. When the procedure add2, the parameter x shadows the global
calls return, the global x continues to be 9. x.
A procedure’s body can access and modify The local variable initializations — x to 1;
variables in its surrounding scope provided y to 2; z to 3 — are not considered part of
the procedure’s parameters don’t shadow the let body. Therefore, a reference to x in
them. This can give some interesting the initialization will refer to the global,
programs. Eg, not the local x:

(define counter 0) (let ((x 1)


(y x))
(define bump-counter (+ x y))
(lambda () => 21
(set! counter (+ counter 1))
counter)) This is because x is bound to 1, and y is
bound to the global x, which is 20.
The procedure bump-counter is a zero-
argument procedure (also called a thunk). Sometimes, it is convenient to have let’s
It introduces no local variables, and thus list of lexical variables be introduced in
cannot shadow anything. Each time it is sequence, so that the initialization of a
called, it modifies the global variable later variable occurs in the lexical scope of
counter — it increments it by 1 — and earlier variables. The form let* does this:
returns its current value. Here are some
successive calls to bump-counter: (let* ((x 1)
(y x))
(bump-counter) => 1 (+ x y))
(bump-counter) => 2 => 2
(bump-counter) => 3
The x in y’s initialization refers to the x
5.1  let and let* just above. The example is entirely
equivalent to — and is in fact intended to
Local variables can be introduced without be a convenient abbreviation for — the
explicitly creating a procedure. The special following program with nested lets:
form let introduces a list of local variables
SANDEEP KUMAR http://san24mca.blogspot.com/

for use within its body: (let ((x 1))


(let ((y x))
(let ((x 1) (+ x y)))
(y 2) => 2
(z 3))
(list x y z)) The values bound to lexical variables can
=> (1 2 3) be procedures:

As with lambda, within the let-body, the (let ((cons (lambda (x y) (+ x y))))
local x (bound to 1) shadows the global x (cons 1 2))
(which is bound to 20). => 3
Inside this let body, the lexical variable new lexical variables like let does. It
cons adds its arguments. Outside, cons modifies the bindings of existing lexical
continues to create dotted pairs. variables, and the modification ceases as
soon as the fluid-let does.
5.2  fluid-let
To drive home this point, consider the
Here is a definition of a rather more program
complicated macro, fluid-let . fluid-let
specifies temporary bindings for a set of (let ((counter 99))
already existing lexical variables. Given a (display (bump-counter)) (newline)
fluid-let expression such as (display (bump-counter)) (newline)
(display (bump-counter)) (newline))
(fluid-let ((x 9) (y (+ y 1)))
(+ x y)) which substitutes let for fluid-let in the
previous example. The output is now
A lexical variable is visible throughout its
scope, provided it isn’t shadowed. 4
Sometimes, it is helpful to temporarily set 5
a lexical variable to a certain value. For 6
this, we use the form fluid-let.
i.e. the global counter, which is initially 3,
(fluid-let ((counter 99)) is updated by each call to bump-counter.
(display (bump-counter)) (newline) The new lexical variable counter, with its
(display (bump-counter)) (newline) initialization of 99, has no impact on the
(display (bump-counter)) (newline)) calls to bump-counter, because although
the calls to bump-counter are within the
This looks similar to a let, but instead of scope of this local counter, the body of
shadowing the global variable counter, it bump-counter isn’t. The latter continues to
temporarily sets it to 99 before continuing refer to the global counter, whose final
with the fluid-let body. Thus the displays value is 6.
in the body produce
SANDEEP KUMAR http://san24mca.blogspot.com/

counter => 6
100 
101  fluid-let is a nonstandard special form.
102 

After the fluid-let expression has Chapter 6


evaluated, the global counter reverts to the Recursion
value it had before the fluid-let.
A procedure body can contain calls to
counter => 3 other procedures, not least itself:

Note that fluid-let has an entirely different (define factorial


effect from let. fluid-let does not introduce
(lambda (n) This won’t quite work, because the
(if (= n 0) 1 occurrences of local-even? and local-odd?
(* n (factorial (- n 1)))))) in the initializations don’t refer to the
lexical variables themselves. Changing the
This recursive procedure calculates the let to a let* won’t work either, for while
factorial of a number. If the number is 0, the local-even? inside local-odd?’s body
the answer is 1. For any other number n, refers to the correct procedure value, the
the procedure uses itself to calculate the local-odd? in local-even?’s body still
factorial of n - 1, multiplies that subresult points elsewhere.
by n, and returns the product.
To solve problems like this, Scheme
Mutually recursive procedures are also provides the form letrec:
possible. The following predicates for
evenness and oddness use each other: (letrec ((local-even? (lambda (n)
(if (= n 0) #t
(define is-even? (local-odd? (- n 1)))))
(lambda (n) (local-odd? (lambda (n)
(if (= n 0) #t (if (= n 0) #f
(is-odd? (- n 1))))) (local-even? (- n 1))))))
(list (local-even? 23) (local-odd? 23)))
(define is-odd?
(lambda (n) The lexical variables introduced by a letrec
(if (= n 0) #f are visible not only in the letrec-body but
(is-even? (- n 1))))) also within all the initializations. letrec is
thus tailor-made for defining recursive and
These definitions are offered here only as mutually recursive local procedures.
simple illustrations of mutual recursion.
Scheme already provides the primitive 6.2  Named let
predicates even? and odd?.
A recursive procedure defined using letrec
6.1  letrec can describe loops. Let’s say we want to
SANDEEP KUMAR http://san24mca.blogspot.com/

display a countdown from 10:


If we wanted the above procedures as local
variables, we could try to use a let form: (letrec ((countdown (lambda (i)
(if (= i 0) 'liftoff
(let ((local-even? (lambda (n) (begin
(if (= n 0) #t (display i)
(local-odd? (- n 1))))) (newline)
(local-odd? (lambda (n) (countdown (- i 1)))))))
(if (= n 0) #f (countdown 10))
(local-even? (- n 1))))))
(list (local-even? 23) (local-odd? 23))) This outputs on the console the numbers
10 down to 1, and returns the result liftoff.
Scheme allows a variant of let called iteration. So go ahead, use recursion to
named let to write this kind of loop more write loops. It’s safe.
compactly:
Here’s another example of a useful tail-
(let countdown ((i 10)) recursive procedure:
(if (= i 0) 'liftoff
(begin (define list-position
(display i) (lambda (o l)
(newline) (let loop ((i 0) (l l))
(countdown (- i 1))))) (if (null? l) #f
(if (eqv? (car l) o) i
Note the presence of a variable identifying (loop (+ i 1) (cdr l)))))))
the loop immediately after the let. This
program is equivalent to the one written list-position finds the index of the first
with letrec. You may consider the named occurrence of the object o in the list l. If
let to be a macro (chap 8) expanding to the the object is not found in the list, the
letrec form. procedure returns #f.

6.3  Iteration Here’s yet another tail-recursive


procedure, one that reverses its argument
countdown defined above is really a list “in place”, ie, by mutating the contents
recursive procedure. Scheme can define of the existing list, and without allocating
loops only through recursion. There are no a new one:
special looping or iteration constructs.
(define reverse!
Nevertheless, the loop as defined above is (lambda (s)
a genuine loop, in exactly the same way (let loop ((s s) (r '()))
that other languages bill their loops. Ie, (if (null? s) r
Scheme takes special care to ensure that (let ((d (cdr s)))
recursion of the type used above will not (set-cdr! s r)
generate the procedure call/return (loop d s))))))
SANDEEP KUMAR http://san24mca.blogspot.com/

overhead.
(reverse! is a useful enough procedure that
Scheme does this by a process called tail- it is provided primitively in many Scheme
call elimination. If you look closely at the dialects, eg, MzScheme and Guile.)
countdown procedure, you will note that
when the recursive call occurs in
countdown’s body, it is the tail call, or the 6.4  Mapping a procedure across a list
very last thing done — each invocation of
countdown either does not call itself, or A special kind of iteration involves
when it does, it does so as its very last act. repeating the same action for each element
To a Scheme implementation, this makes of a list. Scheme offers two procedures for
the recursion indistinguishable from this situation: map and for-each.
The map procedure applies a given
procedure to every element of a given list, Scheme’s reader procedures take an
and returns the list of the results. Eg, optional input port argument. If the port is
not specified, the current input port
(map add2 '(1 2 3)) (usually the console) is assumed.
=> (3 4 5)
Reading can be character-, line- or s-
The for-each procedure also applies a expression-based. Each time a read is
procedure to each element in a list, but performed, the port’s state changes so that
returns void. The procedure application is the next read will read material following
done purely for any side-effects it may what was already read. If the port has no
cause. Eg, more material to be read, the reader
procedure returns a specific datum called
(for-each display the end-of-file or eof object. This datum is
(list "one " "two " "buckle my shoe")) the only value that satisfies the eof-object?
predicate.
has the side-effect of displaying the strings
(in the order they appear) on the console. The procedure read-char reads the next
character from the port. read-line reads the
The procedures applied by map and for- next line, returning it as a string (the final
each need not be one-argument newline is not included). The procedure
procedures. For example, given an n- read reads the next s-expression.
argument procedure, map takes n lists and
applies the procedure to every set of n of 7.2  Writing
arguments selected from across the lists.
Eg, Scheme’s writer procedures take the object
that is to be written and an optional output
(map cons '(1 2 3) '(10 20 30)) port argument. If the port is not specified,
=> ((1 . 10) (2 . 20) (3 . 30)) the current output port (usually the
console) is assumed.
(map + '(1 2 3) '(10 20 30))
SANDEEP KUMAR http://san24mca.blogspot.com/

=> (11 22 33) Writing can be character- or s-expression-


based.
Chapter 7
I/O The procedure write-char writes the given
character (without the #\) to the output
Scheme has input/output (I/O) procedures port.
that will let you read from an input port or
write to an output port. Ports can be The procedures write and display both
associated with the console, files or write the given s-expression to the port,
strings. with one difference: write attempts to use a
machine-readable format and display
7.1  Reading doesn’t. Eg, write uses double quotes for
strings and the #\ syntax for characters. j
display doesn’t. => ello

The procedure newline starts a new line on Assume the file greeting.txt does not exist
the output port. before the following programs are fed to
the listener:
7.3  File ports
(define o (open-output-file "greeting.txt"))
Scheme’s I/O procedures do not need a
port argument if the port happens to be (display "hello" o)
standard input or standard output. (write-char #\space o)
However, if you need these ports (display 'world o)
explicitly, the zero-argument procedures (newline o)
current-input-port and current-output-port
furnish them. Thus, (close-output-port o)

(display 9) The file greeting.txt will now contain the


(display 9 (current-output-port)) line:

have the same behavior. hello world 

A port is associated with a file by opening 7.3.1  Automatic opening and closing of


the file. The procedure open-input-file file ports
takes a filename argument and returns a
new input port associated with it. The Scheme supplies the procedures call-with-
procedure open-output-file takes a input-file and call-with-output-file that
filename argument and returns a new will take care of opening a port and
output port associated with it. It is an error closing it after you’re done with it.
to open an input file that doesn’t exist, or
to open an output file that already exists. The procedure call-with-input-file takes a
filename argument and a procedure. The
SANDEEP KUMAR http://san24mca.blogspot.com/

After you have performed I/O on a port, procedure is applied to an input port
you should close it with close-input-port or opened on the file. When the procedure
close-output-port. completes, its result is returned after
ensuring that the port is closed.
In the following, assume the file hello.txt
contains the single word hello. (call-with-input-file "hello.txt"
(lambda (i)
(define i (open-input-file "hello.txt")) (let* ((a (read-char i))
(b (read-char i))
(read-char i) (c (read-char i)))
=> #\h (list a b c))))
=> (#\h #\e #\l)
(define j (read i))
The procedure call-with-output-file does
the analogous services for an output file. String ports need not be explicitly closed.

7.4  String ports 7.5  Loading files

It is often convenient to associate ports We have already seen the procedure load
with strings. Thus, the procedure open- that loads files containing Scheme code.
input-string associates a port with a given Loading a file consists in evaluating in
string. Reader procedures on this port will sequence every Scheme form in the file.
read off the string: The pathname argument given to load is
reckoned relative to the current working
(define i (open-input-string "hello world")) directory of Scheme, which is normally the
directory in which the Scheme executable
(read-char i) was called.
=> #\h
Files can load other files, and this is useful
(read i) in a large program spanning many files.
=> ello Unfortunately, unless full pathnames are
used, the argument file of a load is
(read i) dependent on Scheme’s current directory.
=> world Supplying full pathnames is not always
convenient, because we would like to
The procedure open-output-string creates move the program files as a unit
an output port that will eventually be used (preserving their relative pathnames),
to create a string: perhaps to many different machines.

(define o (open-output-string)) DrScheme provides the load-relative


procedure that greatly helps in fixing the
(write 'hello o) files to be loaded. load-relative, like load,
(write-char #\, o) takes a pathname argument. When a load-
(display " " o) relative call occurs in a file foo.scm, the
SANDEEP KUMAR http://san24mca.blogspot.com/

(display "world" o) path of its argument is reckoned from the


directory of the calling file foo.scm. In
You can now use the procedure get- particular, this pathname is reckoned
output-string to get the accumulated independent of Scheme’s current directory,
string in the string port o: and thus allows convenient multifile
program development.
(get-output-string o)
=> "hello, world"
ASSINGMENT -1

1) Evaluate following expressions :


a. Add 4 integers
(define ( add a b c d) ( + a b c d))
b. Multiply three numbers.
(define (mul a b c) ( * a b c))
c. Divide 20 in another three numbers in such a way that the result will
be 1. (use a single line statement.
(/ 12 3 2 2)

d. Find out the remainder of any two integer values


(define (rem a b)(remainder a b))

2. Calculate the followings in prefix form:

a) 7 *(7 + 5) /9

(* 7 ( /(+ 4 5) 9))
SANDEEP KUMAR http://san24mca.blogspot.com/

b)10 * (5 -3) + 8

(+ (* 10 ( - 5 3 )) 8)

c)10+7*15/5

(+ 9 ( * 7 (/ 15 5)))

d)(9-7) + (6-2) * (4 +7)

( + ( - 9 7 ) ( * ( - 6 2 ) ( + 4 7 )))
3.Define two variables ‘a’ and ’ b’ and assign two values to it . Then add
and multiply the two variables to get the result.

(begin
(define a 5)
(define b 4)
(define ( add a b) ( + a b ))
)

Output
> ( add a b)
9

4.Define three variables a,b,c and assign integer values into it. Then evaluate
the expression (a +b) +(c*c)/b

(begin
(define a 5)
(define b 4)
(define c 6)
(define ( sol a b c ) ( + (+ a b )(/ ( * c c ) b)))
)
Output

> ( sol a b c )
18

5.Write a Scheme procedure to display the sum and average of three numbers.
SANDEEP KUMAR http://san24mca.blogspot.com/

(define (avg a b) (/ ( + a b )2))

Output
> (avg 4 8)
6

ASSINGMENT -2
1 Evaluate the following expression:
5 + ⅓ + (2 - (3 - (6 + ⅓)))

(/( + 5 (/ 1 3) (- 2 (- 3 (+ 6 (/ 1 3))))) (* 3 ( - 6 2 ) (- 3 7)))


Output
-2/9

2)Utopias taxes accountants always use programs that compute income taxes
even though the tax rate is a solid never -changing 15% . define the program
tax , which determines the tax on the gross pay also define net pay . the
program determines the net pay of an employee from the number of hours
worked . Assume an hourly rate of $12.
(define (tax nhour )(/(*(* nhour 12) 15 ) 100))
(define (netpay nhour) (display "net pay is $") (-(* nhour 12) (tax nhour)))
(tax 5)

Output
9
> (netpay 5)
net pay is $51

3.An old style movie theater has simple profit program . each customer pay
$5 per ticket .every performance costs the theater $20 ,plus $50 per
attendee, .develop the program total profit it consumes the number of
attendees (of a show ) and produces how much income the attendees produce
.

(begin
(define (attende x )
(define a 0)
(set! a x)
SANDEEP KUMAR http://san24mca.blogspot.com/

(display "total no of attende ")


(display a)
(display "\nprofit $")
(display (- (- ( * a 5) 20) (* a 0.5)))
(display "\nattende produce $ ")
(display (* a 5))
))

Output
> (attende 5 )
total no of attende 5
profit $2.5
attende produce $ 25
4) To find the volume & area of a cylinder which consumes the radius of a
cylinder base disk and its height.

(define (cylinder r h)
(display "Area::")
(display(+ (* 3.14 r h)(* 3.14 r r)))
(display "sq. unit \n Volume::")
(display (* 3.14 r r h))
(display "cubic unit")
)

Output
> (cylinder 3 5)
Area::75.36sq. unit
Volume::141.29999999999998cubic unit

5)Write a program to find the maximum of three number

(begin
(define (max a b c)
(define m 0)
(if (and (> a b)
(> a c))
(set! m a))
(if ( and (> b a)
(> b c))
(set! m b))
(if (and ( > c a)
(> c b))
SANDEEP KUMAR http://san24mca.blogspot.com/

(set! m c))
(display "max is ")
(display m)
))

Output
> (max 45 25 5)
max is 45
> (max 34 56 4)
max is 56
> (max 3 56 67)
max is 67
6)Write a program to find the minimum of threee numbers
(begin
(define (min a b c)
(define m 0)
(if (and (< a b)
(< a c))
(set! m a))
(if ( and (< b a)
(< b c))
(set! m b))
(if (and ( < c a)
(< c b))
(set! m c))
(display "minimum is ")
(display m)
))

Output
> (min 2 4 5)
minimum is 2
> (min 56 5 7)
minimum is 5
> (min 34 56 4)
minimum is 4

7) Develop the program like interest -rate it consumes a deposit amount ,


instead of the rate ,it produces the actual amount of interest . That the money
earns in a year .the bank pays a flat 4% for deposits of up to $100 a flat
4.5%per year for deposits of up to $5000 and a flat 5 % form deposit of more
than Rs. 5000
SANDEEP KUMAR http://san24mca.blogspot.com/

(define (interest Depo_amt)


(if(> Depo_amt 5000)
(begin
(display "The Interest is = ")
(display (/ (* Depo_amt 5.0) 100))
))
(if (and (> Depo_amt 1000) (<= Depo_amt 5000))
(begin
(display "The Interest is = ")
(display (/ (* Depo_amt 4.5) 100))
))
(if (<= Depo_amt 1000)
(begin
(display "The Interest is= ")
(display (/ (* Depo_amt 4.0) 100)))
)
)

Output
> (interest 5643)
The Interest is = 282.15
> (interest 2643)
The Interest is = 118.935
> (interest 643)
The Interest is= 25.72

ASSINGMENT -3
Use of car and cdr :
(define (vld_num lst)
(let a ((templst lst))
(if (null? templst) #t
(begin
(if (number? (car templst)) (a (cdr templst))
#f)))))

1 Write a program to print the odd number from 1 to n.

(define (odd n)
(define i 1)
(let loop()
SANDEEP KUMAR http://san24mca.blogspot.com/

(if (< i n)
(begin
(display i) (display "\n")
(set! i (+ i 2))
(loop)))))

Output
> (odd 7)
1
3
5
2) Write a program to print the given pattern:
1
12
123
1234

(define (pattern n)
(define i 1)
(define l 1)
(let loop()
(if (<= l n)
(begin
(let loop1()
(if (<= i l)
(begin
(display i) (set! i (+ i 1)) (loop1))
(begin
(newline) (set! i 1))))
(set! l (+ l 1)) (loop)))))

Output
> (pattern 6)
1
12
123
1234
12345
123456
SANDEEP KUMAR http://san24mca.blogspot.com/

3) A local discount store has a policy of putting labels with dates on all of its
new merchandise . If as item has not sold within two weeks the store
discounts the item by 25% for the third week , 50% for the fourth week ,
and 75% for the fifth week . After that no additional discount are given .
Develop the function new-price , which takes the initial price of an item
and the number of wiiks since the item was dated and produce the selling
price of the item.
(define (new_price sp wk)
(if (= wk 3)
(begin
(set! sp (- sp (* 0.25 sp)))))
(if (= wk 4)
(begin
(set! sp (- sp (* 0.50 sp)))))
(if (> wk 4)
(begin
(set! sp (- sp (* .75 sp)))))
sp)
Output
> (new_price 3 4)
1.5
> (new_price 3 7)
0.75
> (new_price 3 3)
2.25

4 ) A manufacturing company measured the productivity of its workers and


found that between the hour of 6 am and 10 am they could produce 30 piece
/hour /worker ,between 10 am and 2 pm they could produce 40
piece/hour/worker , and between 2 pm and 6 pm they could produce 35
piece/hr/worker . Develop a function that takes hr. of day between 6 am and 6
pm in 24 hrs. format along with the number of worker and computer the total
number of pieces produced during that hour.

(define (products hrs wrk)


(define pc 0)
(cond
[(and (> hrs 6) (< hrs 10)) = (set! pc (* 30 wrk))]
[(and (>= hrs 10) (< hrs 14)) = (set! pc (* 40 wrk))]
[(and (>= hrs 14) (< hrs 18)) = (set! pc (* 35 wrk))]
SANDEEP KUMAR http://san24mca.blogspot.com/

[else "INVALID ENTRY"])


pc)

Output
> (products 9 6)
180

5 , 6) Develop a function to print the largest element in a list of number and also
find the position of largest number.

(define (comp_list lst)


(define g (list-ref lst 0))
(define pos 0)
(define lth (length lst))
(define i 0)
(let loop()
(if (< i lth)
(begin
(if (> (list-ref lst i) g)
(begin (set! g (list-ref lst i)) (set! pos i)))
(set! i (+ i 1))(loop))))
(display "The greatest number is:")
(display g)
(display " position=")
(display (+ pos 1)))

Output
> (define lis(list 3 23 4 23))
> (comp_list lis)
The greatest number is:23 position=2

7) First n Fibonacci series [n value to be passed as an argument]

(define (fibonacci n)
(define p 0)
(define c 1)
(define nxt 1)
(define i 2)
(display p)(display " ")(display c)
(let loop()
(if (< i n)
(begin
SANDEEP KUMAR http://san24mca.blogspot.com/

(set! p c) (set! c nxt) (set! nxt (+ c p)) (display " ") (display c) (set! i (+ i 1))
(loop)))))

Output
> (fibonacci 6)
011235

8) Enter three number through list and then display their sum.
(define (sum_list lst)
(define s 0)
(define i 0)
(define l (length lst))
(let loop()
(if (< i l)
(begin
(set! s (+ s (list-ref lst i))) (set! i (+ i 1)) (loop))))
(display "sum =") s)

Output
> (define lst(list 3 23 4 23))
> (sum_list lst)
sum =53

9 Find the total number of occurrence of a particular digit in a given list .

(define (search lst ele)


(define l (length lst))
(define i 0)
(define c 0)
(let loop()
(if (< i l)
(begin
(if (= ele (list-ref lst i))
(set! c (+ c 1)))
(set! i (+ i 1)) (loop))))
(display ele) (display " occurs ") (display c) (display " times."))

Output
> (define lst(list 3 23 4 23 45 34 23 4 2 56 67 89 23))
> (search lst 23)
23 occurs 4 times.
SANDEEP KUMAR http://san24mca.blogspot.com/

10 Find the Greatest common divisor of two number.


(define (gcd x y)
(define rem 1)
(let loop()
(if (not (= rem 0))
(begin
(set! rem (remainder x y)) (set! x y) (set! y rem) (loop))))
(display "GCD=") x)
Output
> (gcd 45 3)
GCD=3
ASSINGMENT - 4

1. Write a program to check the leap year

(define (leap_year a)
( if (or (and (= (remainder a 4) 0) ( not (= (remainder a 100 ) 0))) (=
(remainder a 400 ) 0))
(display "leap year")
(display "not leap year")
))

Output
> (leap_year 1978)
not leap year
> (leap_year 2004)
leap year

2. Find out the reverse of given number.

(define (reverse n)
(define r 0)
(define s 0)
(let loop()
(if (> n 0)
(begin

(set! r (remainder n 10))


(set! n (quotient n 10))
SANDEEP KUMAR http://san24mca.blogspot.com/

(set! s (+ (* s 10) r))


(loop))))
(display s))
Output
> (reverse 543)
345

2. Check whether the input number is prime or not.

(define (primechk num)


( define c 0)
( define i 1)
(let loop()
( if ( <= i num)
( begin
( if ( =( remainder num i) 0)
(set! c ( + c 1)))
( set! i( + i 1))
(loop))))
( if (= c 2)
( display "prime number")
(display "not prime number.") ))
Output
> (primechk 41)
prime number
> (primechk 45)
not prime number.

4. Define a list of 5 numbers and find its average.


(define lst (list 10 20 30 40 50))
(define (avg_list lst)
(define s 0)
(define i 0)
(define l (length lst))
(let loop()
(if (< i l)
(begin
(set! s (+ s (list-ref lst i))) (set! i (+ i 1)) (loop))))
(display "average =" ) (/ s 5))
Output
> (avg_list lst)
average =30
SANDEEP KUMAR http://san24mca.blogspot.com/

5. Define a list of 10 elements and display the 4th element.


(define lst (list 10 20 30 40 50 45 34 56 67 5))
(define p 0)
(define (pos i)
(set! p (list-ref lst (- i 1)))
(display p))
Output
> (pos 4)
40

6. Define 2 list of 3 elements each and add a new list to it.


(define lst1 (list 10 20 30 ))
(define lst2 (list 40 50 60 ))
(display ( append lst1 lst2))
Output
(10 20 30 40 50 60)

ASSINGMENT -5

Do Loop
Syntax:

( Do ((initialization (iteration)))
((termination condition))
( body.......
.....
......
))
Example :
(do ((i 1(+ i 1)))
((> i 5))
(begin
(display i)
(newline))
) Test output ....yourself

1. Find the factorial value of inputted number using DO Loop

(define (fact n)
SANDEEP KUMAR http://san24mca.blogspot.com/

(define b 1)
(do ((i n(- i 1)))
((< i 1))
(begin
(set! b (* b i))
)
) (display b))

Output
> (fact 5)
120
2. Print the series 1,1/2,1/3,1/4 …..upto 1/n using DO Loop.

(define (series n )
(do ((i 1(+ i 1)))
((> i n))
(begin
(display " ")
(display (/ 1 i))
)
))

Output
> (series 5)
1 1/2 1/3 1/4 1/5

3. Input your name, age, basic salary as argument. Calculate TA=45% of


basic,DA=55% of basic, HRA= 35% of basic. Display the salary slip.

(define (salary name age sal)


(define sala 1)
(define ta (* sal (/ 45 100)))
(define da (* sal (/ 55 100)))
(define hra (* sal (/ 35 100)))
(display "Name=")(display name)(newline)
(display "Age=") (display age)(newline)
(set! sala (+ sal ta da hra))
(display "basic salary=")
(display sal)
SANDEEP KUMAR http://san24mca.blogspot.com/

(display " ta=")


(display ta)
(display " da=")
(display da)
(display " hra=")
(display hra) (newline)
(display "salary(basic salary+ta+da+hra)= ") sala)

Output
> (salary "sandeep" 22 4000)
Name=sandeep
Age=22
basic salary=4000 ta=1800 da=2200 hra=1400
salary(basic salary+ta+da+hra)= 9400

4. Input your name, branch and 4 paper marks as argument. Calculate total and
percentage. Calculate the grade as follows
90% and above Grade ‘O’.
80% and above Grade ‘A’
70% and above Grade ‘B’
60% and above Grade ‘C’
Display the suitable mark sheet.

(define (grade name branch m1 m2 m3 m4)


(define total 1)
(define percent 1)
(display "Name=")(display name)(newline)
(display "Branch=") (display branch)(newline)
(set! total (+ m1 m2 m3 m4))
(set! percent (/ total 4.0))
(display "total= ") (display total)(newline)
(display "percent= " ) (display percent) (newline)
(if (and (> percent 59 ) (< percent 70))
(display "C grade"))
(if (and (> percent 69) (< percent 80))
(display "B grade"))
(if (and (> percent 79 ) (< percent 90))
(display "A grade "))
(if (> percent 89 )
(display "O grade"))
)
SANDEEP KUMAR http://san24mca.blogspot.com/

Output
>(grade "san" "mca" 70 70 70 70)
Name=san
Branch=mca
total= 280
percent= 70.0
B grade

ASSINGMENT -6

User input from key board:


Use of Read: Using the Read Statement we can read our data from the key
board .
Example : Input two values from key board and display the values through a
function :
(display "enter x value")
(define x(read)) ; reading from key board
(display "enter y value")
(define y(read)) ; reading from key board

(define (disp x y) ; Defining Function and Body


(display x)
(newline)
(display y)
)
(disp x y) ; calling the function

1. Input principal, time, rate of interest from the key board and find simple
interest and absolute amount.
(display "enter pricipal value= ")
(define p(read))
(newline) (display "enter rate = ")
(define r(read))
(newline) (display "enter time= ")
(define t(read))
(define (SI p r t)
(define si 1)
(newline) (display "Principal= ") (display p)
(newline) (display "Rate= ") (display r)
(newline) (display "Time= ") (display t)
(set! si (/ (* p r t ) 100))
(newline) (display "SIMPLE INTEREST = ") (display si)
SANDEEP KUMAR http://san24mca.blogspot.com/

(newline)(display "AMOUNT= ")(display (+ p si)))


(SI p r t)

Output
enter pricipal value = 1000

enter rate = 45.5

enter time = 3

Principal= 1000
Rate= 45.5
Time= 3
SIMPLE INTEREST = 1365.0
AMOUNT= 2365.0

2. Find out the area of rectangle ,triangle and circle using appropriate input
from the key board.

(newline) (display "enter length of rectangle") (define l(read))


(newline) (display "enter width of rectangle ") (define w(read))
(define ar 1)
(newline) (display "length of rectangle= ") (display l)
(newline) (display "Width of rectangle= ") (display w)
(set! ar (* l w))
(newline) (display "AREA OF RECTANGLE = ") (display ar)
(newline) (display " enter base of triangle= ") (define b(read))
(newline) (display " enter height of triangle= ") (define h(read))
(define area 1)
(newline) (display "entered data for triangle")
(newline) (display "Base of triangle=") (display b)
(newline) (display "Height of triangle=") (display h)
(set! area (* 0.5 b h))
(newline) (display "AREA OF TRIANGLE = ") (display area)
(newline) (display " enter the radius of circle ") (define r(read))
(define cir 1)
(set! cir ( * 3.14 r r))
(display "area of circle = ") (display cir)

Output
enter length of rectangle34
enter width of rectangle 45

length of rectangle= 34
SANDEEP KUMAR http://san24mca.blogspot.com/

Width of rectangle= 45
AREA OF RECTANGLE = 1530

enter base of triangle= 56


enter height of triangle= 78

entered data for triangle


Base of triangle=56
Height of triangle=78
AREA OF TRIANGLE = 2184.0
enter the radius of circle 67
area of circle = 14095.46
3.Input lower bound , upper bound and display the prime numbers within the
range.
(define i 1)
(define c 0)
(display "\n Enter the lower bound ")
(define l(read))
(display "\n Enter the upper bound ")
(define n(read))
(let loop()
(if (<= l n)
(begin
(set! c 0)
(set! i 1)
(let loop()
(if (<= i l )
(begin
(if (= 0 (remainder l i ))
(set! c (+ c 1)))
(set! i (+ i 1))
(loop))))
(if (= c 2)
(begin
(display l)(display " ")))

(set! l (+ l 1))
(loop))))

Output
Enter the lower bound 4
SANDEEP KUMAR http://san24mca.blogspot.com/

Enter the upper bound 53


5 7 11 13 17 19 23 29 31 37 41 43 47 53

4. Input the number of lines and display the pattern as follows:


*
* *
* * *
* * * *
* * * * *

(display "Enter the number of lines= ") (define n(read))


;(define (pattern n)
(define i 1)
(define l 1)
(let loop()
(if (<= l n)
(begin
(let loop1()
(if (<= i l)
(begin
(display " ") (display "*") (set! i (+ i 1)) (loop1))
(begin
(newline) (set! i 1))))
(set! l (+ l 1)) (loop))))

Output
Enter the number of lines= 5
*
* *
* * *
* * * *
* * * * *

ASSINGMENT -7
Use of Read:

Example1 :

(display "enter x value ")


(define x(read)) ;reading from the key board
(display "enter y value ")
SANDEEP KUMAR http://san24mca.blogspot.com/

(define y(read)) ;reading from the key board

(define (disp)
(display "X value ")
(display x)
(display "\n y value") ; \n for (newline)
(display y)
)

(disp) ;Calling the function (disp)


[ Execute the program and check output ….Yourself ]
Example 2:To read the value of variables within a function body

(define p 0)
(define q 0)

(define (readx) ; The function (readx)

(display "enter value ")


(set! p(read)) ;Use of read inside a function
(display "enter value ")
(set! q(read)) ;Use of read inside a function

(display "P value is :")


(display p)
(newline)
(display "Q value is :")
(display q)
)

(readx) ; Calling of function (readx).

[ Execute the program and check output ….Yourself ]

Use of Write :
Example:
(write "enter x value ")
(define x(read)) ;reading from the key board
(write "enter y value ")
(define y(read)) ;reading from the key board
SANDEEP KUMAR http://san24mca.blogspot.com/

(define (disp)
(write "X value ")
(write x)
(newline)
(write "Y value ")
(write y)
)

(disp) ;Calling the function (disp)

[Execute the program and check output ….Yourself]


Use of multiple functions & calling of multiple functions :

Example1:

(define ( x ) ; defining function (x)


(display "first function")
)

(define ( y ) ; defining function (y)


(display "second function")
)

(define ( xy ) ; defining function (xy)


(x) ; calling function (x)
(newline)
(y) ; calling function (y)
)

(xy) ; calling function (xy)

[Execute the program and check output ….Yourself]


Example2:
Check the difference between “display” and “write” .

(display "enter x value ")


(define x(read)) ; reading from the key board
(display "enter y value ")
(define y(read)) ; reading from the key board

(define (disp1) ; Defining function (disp1)


SANDEEP KUMAR http://san24mca.blogspot.com/

(display "X value ")


(display x)
(newline)
(display "Y value ")
(display y)
); End of function (disp1)

(write "enter x value ")


(define x(read)) ; reading from the key board
(write "enter y value ")
(define y(read)) ; reading from the key board

(define (disp2) ; Defining function (disp2)


(write "X value ")
(write x)
(newline)
(write "Y value ")
(write y)
); End of function (disp2)

(define (disp) ; Defining function (disp) to call another functions


(disp1) ; calling of the function (disp1)
(newline)
(disp2) ; calling of the function (disp2)
)
(disp) ; calling of the function (disp)

[Execute the program and check output ….Yourself]

Lambda function :
Example1:

(define add2
(lambda (x)
(+ x 2)))

Output:
SANDEEP KUMAR http://san24mca.blogspot.com/

> (add2 5)
7

Example2:
(define area
(lambda (length breadth)
(* length breadth)))

Output:
>(area 5 7)
35

Example3:
(define display3
(lambda (arg1 arg2 arg3)

(display arg1)
(display " ")
(display arg2)
(display " ")
(display arg3)
(newline)))

Output
>(display3 5 6 7)
5 6 7

Compare the followings :


(Doing the same calculation in different ways)
Example 4:
Using function calculation multiply, add and subtract two numbers.

(define ( calculation x y)
(display (* x y))
(newline)
(display (+ x y))
(newline)
(display (- x y))
)

Execute:
> (calculation 12 10)
SANDEEP KUMAR http://san24mca.blogspot.com/

Using lambda function multiply, add and subtract two numbers.

(define calculation
( lambda (x y)
(display (* x y))
(display (+ x y))
(display (- x y))
))

Execute:
> (calculation 12 10)
1. Using a single lambda function calculate area and perimeter of rectangle,
square and circle

(define figures
(lambda (l b s r)
(display "Rectangle:\nArea=") (display (* l b))
(display "\tPerimeter=") (display (* (+ l b) 2 ))
(display "\nSquare:\nArea=") (display (* s s))
(display "\tPerimeter=") (display (* 4 s))
(display "\nCirle:\nArea=") (display (* 3.14 r r))
(display "\tPerimeter=") (display (* 2 3.14 r))))

Output

> (figures 4 5 6 3)
Rectangle:
Area=20 Perimeter=18
Square:
Area=36 Perimeter=24
Cirle:
Area=28.259999999999998 Perimeter=18.84 |#

2) (a) Area of rectangle


(define a_rec
(lambda (length breadth)
(display "area of rectangle= ")
(* length breadth)))

Output
> (a_rec 3 4)
SANDEEP KUMAR http://san24mca.blogspot.com/

area of rectangle= 12

(b)Perimeter of rectangle
(define p_rec
(lambda (length breadth)
(display "Perimeter of rectangle= ")
(* 2 ( + length breadth))
)
)

Output
> (p_rec 4 5)
Perimeter of rectangle= 18
(c)Area of square
(define a_sqr
(lambda (h)
(display "area of square= ")
(* h h )))

Output
> (a_sqr 3)
area of square= 9

(d)Perimeter of square
(define p_sqr
(lambda (h)
(display "Perimeter of rectangle= ")
(* 4 h)
)
)
Output
> (p_sqr 3)
Perimeter of rectangle= 12

(e)Area of circle
(define a_cir
(lambda (r)
(display "area of circle= ")
(* 3.14 r r)
)
SANDEEP KUMAR http://san24mca.blogspot.com/

Output
> (a_cir 3)
area of circle= 28.259999999999998

(f)Perimeter of circle
(define p_cir
(lambda (r)
(display "Perimeter of circle= ")
(* 2 3.14 r )
)
)

Output
> (p_cir 3)
Perimeter of circle= 18.84

3 .Add, multiply and subtract two numbers in separate functions and call the
functions within a single function to display the result.

(write "Enter 1st number :" )


(define x(read)) ; reading from the key board
(display "Enter 2nd number :")
(define y(read)) ; reading from the key board

(define (add) ; Defining function (add)


(display "\nADDITION= ")
(display (+ x y)))
(define (sub) ; Defining function (sub)
(display "\nSUBTRACTION= ")
(display(- x y)))
(define (mul) ; Defining function (mul)
(display "\nMULTIPLICATION= ")
(display (* x y)))
(define (disp) ; Defining function (disp) to call another functions
(add) ; calling of the function (add)
(sub) ; calling of the function (sub)
(mul) ;calling of the function (mul)
)
(disp)
SANDEEP KUMAR http://san24mca.blogspot.com/

Output

"Enter 1st number"4


Enter 2nd number3

ADDITION= 7
SUBTRACTION= 1
MULTIPLICATION= 12

4.Write three functions to


(a)to generate odd numbers within 50
(b)to generate even numbers within 50
(c)to generate non prime numbers within 50
Call the above three functions as per your choice within another function.
(define (odd_num)
(define n 1)
(let loop()
(if (<= n 50)
(begin
(if (= (remainder n 2) 1)
(begin
(display n) (display "\t")))
(set! n (+ n 1))
(loop)))))

(define (even_num)
(define n 1)
(let loop()
(if (<= n 50)
(begin
(if (= (remainder n 2) 0)
(begin
(display n) (display "\t")))
(set! n (+ n 1))
(loop)))))

(define (prime)
(define n 1)
(define i 1)
(define c 0)
(let loop()
(if (<= n 50)
SANDEEP KUMAR http://san24mca.blogspot.com/

(begin
(let loop1()
(if (<= i (/ n 2))
(begin
(if (= (remainder n i) 0)
(set! c (+ c 1))) (set! i (+ i 1)) (loop1))))
(if (> c 1)
(begin
(display n) (display "\t")))
(set! n (+ n 1)) (set! c 0)
(set! i 1) (loop)))))
(display "1. Odd numbers within 50.\n2. Even numbers within 50.\n3. Non-
prime numbers within 50.\nENTER CHOICE:")
(define choice(read))
(cond
[(= choice 1) = (odd_num)]
[(= choice 2) = (even_num)]
[(= choice 3) = (prime)])

Output
1. Odd numbers within 50.
2. Even numbers within 50.
3. Non-prime numbers within 50.
ENTER CHOICE:3
4 6 8 9 10 12 14 15 16 18 20 21 22
24 25 26 27 28 30 32 33 34 35 36 38
39 40 42 44 45 46 48 49 50

5. Input meter number, consumer number, previous unit reading, current


unit reading. Calculate the electric charges per month as per following
conditions:
(a) up to 100 units 50 paisa per unit
(b) from 101 to 200 units 2 Rupees per unit
(c) above 200 units Rs. 4 per unit.

(define (ebill name cno lr cr)


(define r (- cr lr))
(define bill 0)
(define gt1 0)
SANDEEP KUMAR http://san24mca.blogspot.com/

(define gt2 0)
(define ir 0)
(display name) (display "\t") (display cno)
(display "\nStart Reading:") (display lr)
(display "\nEnd Reading:") (display cr)
(if (> r 200)
(begin
(set! ir (- r 200)) (set! gt2 (* ir 4)) (set! r (- r ir)) (newline)
(display ir) (display " x 4=") (display gt2)))
(if (> r 100)
(begin
(set! ir (- r 100)) (set! gt1 (* ir 2)) (set! r (- r ir)) (newline)
(display ir) (display " x 2=") (display gt1)))
(newline)
(display r) (display " x 0.50=") (display (* r 0.50))
(set! bill (+ gt1 gt2 (* r 0.50)))
(display "\nBill=") (display bill))

Output
> (ebill "sk" 241255 2000 2400)
sk 241255
Start Reading:2000
End Reading:2400
200 x 4=800
100 x 2=200
100 x 0.50=50.0
Bill=1050.0

ASSINGMENT -8
Structure :

(define-struct s (field_1 field_2 field_3 ....field_n) ) : => Defines a structure


and field variables.

(define instance_name (make-structure_name val1 val2 val3 ..val_n) :=> to


create the instance of structure and provide value to it. (just like constructor
operation)

make-s :=> a constructor procedure that takes n arguments and returns a new
structure value.

s? :=> a predicate procedure that returns #t for a value constructed by make-s


and #f for any other value.
SANDEEP KUMAR http://san24mca.blogspot.com/

s-field :=> for each field, an accessor procedure that takes a structure value and
extracts the value for field.

set-s-field! :=> for each field, a mutator procedure that takes a structure and a
new field value. The field value in the structure is destructively updated with the
new value, and void is returned.

(set-s-field! instance (read) ) :=> To read the value in run time .

Example #1:

(define-struct cons-cell (car cdr))


(define x (make-cons-cell 1 2))
(cons-cell? x) ; => #t
(cons-cell-car x) ; => 1
(set-cons-cell-car! x 5)
(cons-cell-car x) ; => 5

Example #2 :
(For Structure definition, assigning value, retriving the value.)

(define-struct s (a b c d))
(define x (make-s 100 24.50 'raja "we are good"))
(define y (make-s 10 245.50 "we are good" 'ramji))

(display"a value for instance x: ") ( s-a x)


(display"b value for instance x: ") ( s-b x)
(display"c value for instance x: ") ( s-c x)
(display"d value for instance x: ") ( s-d x)

(display"a value for instance y: ") ( s-a y)


(display"b value for instance y: ") ( s-b y)
(display"c value for instance y: ") ( s-c y)
(display"d value for instance y: ") ( s-d y)

[ Check its output Yourself ]|#

1. Create a structure personal and put data in various fields like name, age,
designation, salary. Create three difference instances and assign data into it.
SANDEEP KUMAR http://san24mca.blogspot.com/

Display the information in various fields and various instances.

(define-struct personal(name age desig sal))


(define x (make-personal 'Sandeep 24 "Soft eng" 34000))
(define y (make-personal 'Rabi 23 'Manager 44000))
(define z (make-personal "Ramesh Das" 23 'CEO 524000))

(display"Name ") ( personal-name x)


(display"Age :") ( personal-age x)
(display"Designation: ") ( personal-desig x)
(display"Salary: ") ( personal-sal x)

(display"Name ") ( personal-name y)


(display"Age :") ( personal-age y)
( display"Designation: ") ( personal-desig y)
(display"Salary:") ( personal-sal y )

(display"Name ") ( personal-name z)


(display"Age :") ( personal-age z )
(display"Designation: ") ( personal-desig z)
(display"Salary:") ( personal-sal z)

Output
Name Sandeep
Age :24
Designation: "Soft eng"
Salary: 34000
Name Rabi
Age :23
Designation: Manager
Salary:44000
Name "Ramesh Das"
Age :23
Designation: CEO
Salary:524000
2. Create a structure student and take various fields like name, date-of-birth,
branch, subject1_mark, subject2_mark, subject3_mark, subject4_mark.
Create two instances and assign values into it. Display the record
information and also total and percentage of marks for each record.

(define-struct student(name dob br sub1 sub2 sub3 sub4))


(define std1(make-student 'sandy '24dec1985 'mca 58 84 78 96))
SANDEEP KUMAR http://san24mca.blogspot.com/

(define std2(make-student 'syedul '5may1987 'mca 88 89 68 76))


(define tot 0)
(define per 0)
(set! per (/ (+ (student-sub1 std1) (student-sub2 std1) (student-sub1 std1)
(student-sub1 std1)) 4 ))
(set! tot (+ (student-sub1 std1) (student-sub2 std1) (student-sub1 std1) (student-
sub1 std1)))
(display"NAME: ") ( student-name std1)
(display"DOB: ") ( student-dob std1)
(display"BRANCH: ") ( student-br std1)
(display"TOATAL: ") tot
(display"PERCENTAGE: ") per
(set! per (/ (+ (student-sub1 std2) (student-sub2 std2) (student-sub1 std2)
(student-sub1 std2)) 4 ))
(set! tot (+ (student-sub1 std2) (student-sub2 std2) (student-sub1 std2) (student-
sub1 std2)))
(display"NAME: ") ( student-name std2)
(display"DOB: ") ( student-dob std2)
(display"BRANCH: ") ( student-br std2)
(display"TOATAL: ") tot
(display"PERCENTAGE: ") per

Output
NAME: sandy
DOB: 24dec1985
BRANCH: mca
TOATAL: 258
PERCENTAGE: 64 1/2
NAME: syedul
DOB: 5may1987
BRANCH: mca
TOATAL: 353
PERCENTAGE: 88 1/4

3.Create a structure Sales and take various fields like sale_id, salesman_name,
Sale_date, Amount and assign initial values to it. Then re-assign the value to the
various ;fields of structure.
(define-struct Sales(sale_id sal_name sale_date amt))
(define x (make-Sales 's001 'market '23sep09 4500))
(display "INITIAL VALUE\n")
(display "SALE ID : ") (Sales-sale_id x)
SANDEEP KUMAR http://san24mca.blogspot.com/

(display "SALE NAME: ") (Sales-sal_name x)


(display "SALE DATE :" ) (Sales-sale_date x)
(display "AMOUNT :" ) (Sales-amt x)
(set-Sales-sale_id! x 's00r )
(set-Sales-sal_name! x 'fan )
(set-Sales-sale_date! x '23aug90 )
(set-Sales-amt! x 9000 )
(display "VALUE AFTER RE-ASSIGN \n")
(display "SALE ID : ") (Sales-sale_id x)
(display "SALE NAME: ") (Sales-sal_name x)
(display "SALE DATE :" ) (Sales-sale_date x)
(display "AMOUNT :" ) (Sales-amt x)
Output
INITIAL VALUE
SALE ID : s001
SALE NAME: market
SALE DATE :23sep09
AMOUNT :4500
VALUE AFTER RE-ASSIGN
SALE ID : s00r
SALE NAME: fan
SALE DATE :23aug90
AMOUNT :9000

4. Create a structure of your own and take any 4 fields and assign the value
in run time ;to it. Display the data.
(define-struct personal(name age branch state))
(define x (make-personal 's 34 'a 'b))
(display "ENTER NAME : ") (set-personal-name! x (read) )
(display "ENTER AGE : ") (set-personal-age! x (read) )
(display "ENTER BRANCH:") (set-personal-branch! x (read) )
(display "ENTER STATE: ") (set-personal-state! x (read) )
(display"Name ") ( personal-name x)
(display"Age :") ( personal-age x)
(display"Branch: ") ( personal-branch x)
(display"State: ") ( personal-state x)

Output
ENTER NAME : SANDEEP
SANDEEP KUMAR http://san24mca.blogspot.com/

ENTER AGE : 24
ENTER BRANCH:MCA
ENTER STATE: BIHAR
Name SANDEEP
Age :24
Branch: MCA
State: BIHAR

ASSINGMENT -9
1. “findMaxNum” takes a list of numbers as input argument and returns the
maximum number from the list.
Example : (findMaxNum (list 10 20 30 70 40)) → 70
(define (findmax l)
(define len (length l))

(define max 0)
(do ((i 1(+ i 1)))
((> i len))
(begin (if (< max (car l))
(begin (set! max (car l))
(set! l (cdr l)))
(set! l (cdr l)))))
(display max))

(define l(list 100 300 500 200 3))

(findmax l)

Output
500

2.A function "compareSalary" takes two employee structures instance and


returns "equal" if the salary is same else returns "unequal".

Employee structure contains empID, empName & salary.

(define (compare_salary)
(define-struct employee(id name sal))

(define emp1 (make-employee "emp-1" "Abhisek" 20000))


(define emp2 (make-employee "emp-2" "Sandy" 30000))
SANDEEP KUMAR http://san24mca.blogspot.com/

(display"Enter value for Emp_id: ") (set-employee-id! emp1(read))


(display"Enter value for Emp_name: ") (set-employee-name! emp1(read))
(display"Enter value for Salary: ") (set-employee-sal! emp1(read))

(display"Enter value for Emp_id: ") (set-employee-id! emp2(read))


(display"Enter value for Emp_name: ") (set-employee-name! emp2(read))
(display"Enter value for Salary: ") (set-employee-sal! emp2(read))

(if (= (employee-sal emp1) (employee-sal emp2))


(display "Salaries of both employees are same")
(display "Salaries of both employees are not same")))
Output
(compare_salary)
(compare_salary)
Enter value for Emp_id: 1001
Enter value for Emp_name: Abihsek
Enter value for Salary: 40000
Enter value for Emp_id: 1002
Enter value for Emp_name: Sandeep
Enter value for Salary: 38000
Salaries of both employees are not same
3. Write function in scheme to add the all elements of a numeric list and
display the result.

(define add(list))
(define (addition add)
(define sum 0)(define l (length add))
(define a 0)
(do ((i 1 (+ i 1)))
((> i l))
(if (number? (car add))
(begin (set! sum (+ sum (car add)))(set! add (cdr add)))
(set! add (cdr add))))(display sum))

Output
> (define list1(list 3 34 45 3 4 15 30))
> (addition list1)
134
4. Write scheme function to find the string having maximum length from a
SANDEEP KUMAR http://san24mca.blogspot.com/

string list.

(define str(list))
(define (maxstring str)
(define max 0)
(define l (length str))
(define a "0")
(do ((i 1 (+ i 1)))
((> i l))
(if (< max (string-length (car str)))
(begin (set! max (string-length (car str)))(set! a (car str))
(set! str (cdr str)) )
(set! str (cdr str))
))(display "maximum length of string:")(display max)(newline)(display
"string is:=")(display a))

Output
> (define str_list (list "my" "name" "sandeep kumar" "mithilesh" "syedul"
"abhisek mohanty"))
> (maxstring str_list)
maximum length of string:15
string is:=abhisek mohanty

5. Write a scheme function to find the number of occurrence of a digit in a


multi-digit number.

(display "Enter the value of a: ")


(define a 0)
(set! a(read))(define n 0)
(set! n a)
(define (count n1)
(define c 0)
(do ((i 1(+ i 1)))
((= 0 n))
(begin
(if (= (remainder n 10) n1)
(set! c (+ c 1))))
(begin (set! n (floor(/ n 10)))))
(display n1)(display "occurs ")(display c)(display " times"))
Output
Enter the value of a: 4565754545656786774534564576
> (count 4)
4occurs 6 times
SANDEEP KUMAR http://san24mca.blogspot.com/

You might also like