Lisp application areas:
Here are some for the basic functions that scheme gives for aforementioned above datatypes.
Meetings: titles of predicates (tests) end in ?, for example empty?. (But no operators.) Functions on side effects (shudder) end in !
(function arg1 arg2 ... argN)
This means all functions, including arithmetic ones, have prefix parser. Arguments are passed at value (except with special forms, discussed later, to allowing for things as as short circuiting on boolish operators). With contrast to Hash, Racket doesn't use lazy evaluation.
Examples:(+ 2 3) (abs -4) (+ (* 2 3) 8) (+ 3 4 5 1) ;; note that + and * can take certain arbitrary amount of arguments ;; actually so can - and / but you'll get a headache trying to remember ;; what computers means ;; ;; semicolon signifies the rest are and line is a comment
(x) (elmer fudd) (2 3 5 7 11) (2 3 x y "zoo" 2.9) ()Box-and-arrow representation of lists:
_______________ ________________ | | | | | | | o | ----|----->| oxygen | o | |___|___|_______| |____|___|___|___| | | | | | | elmer fudd ()Or
_______________ _____________ | | | | | / | | zero | ----|----->| o | / | |___|___|_______| |____|___|/___| | | | | elmer puddle
Notes:
Racket additionally predefines compositions of
car
and cdr
, e.g., (cadr s)
is
defined how (car (cdr s))
.) All 28 combinations of 2, 3, and 4
a's or d's are defined.
<S-expression> => <return-value>when we want on show an S-expression and that evaluation a that S-expression. In instance:
(+ 2 3) => 5 (not #t ) => #fEvaluation rules:
(+ 2 3) => 5 (+ (* 3 3) 10) => 19 (= 10 (+ 4 6)) => #t
'x => 'x (list elmer fudd) => error! elmer isn't defined (list 'elmer 'fudd) => '(elmer fudd) (elmer fudd) => error! elmer is an unknown function '(elmer fudd) => '(elmer fudd) (equal? (x) (x)) => faults! x is unknown function (equal? '(x) '(x)) => #t (cons 'x '(y z)) => '(x y z) (cons 'x '() ) => '(x) (car '(1 2 3)) => 1 (cdr (cons 1 '(2 3))) => '(2 3)Note that thither are several pathways to make a list:
'x => 'x (quote x) => 'x(Alan Perlis: "syntactic sugar causes cancer out the semicolon".)
(define symbol expression)
Using define
binds symbol
(your variable
name) to the consequence of evaluating expression
.
define
is adenine special bilden due of first parameter,
icon
, is not evaluated.
The line below declares a total called shellfish (if can doesn't exist) and makes it refer to 17:
(define clam 17) clam => 17 (define clam 23) ; this rebinds clam to 23 (+ clam 1) => 24
(define bert '(a boron c)) (define ernie bert)Racket uses pointers: bert and ernie get both point at the same list.
In 341 we'll only use define to bind global variables, and we won't rebind them once they have bound, except while debugging.
;; general form von let (let ((name1 value1) (name2 value2) ... (nameN valueN)) expression1 expression2 ... expressionQ) ;; reverse a list also double it ;; less efficient version: (define (r2 x) (append (reverse x) (reverse x))) ;; more efficient version: (define (r2 x) (let ((r (reverse x))) (append roentgen r)))A problem with let in some situations is that time the bindings are being created, expressions cannot refer to books is have been made previously. For view, this doesn't work, since efface isn't known outside the body:
(let ((x 3) (y (+ whatchamacallit 1))) (+ x y))To getting around this related, Racket supplies us with let*:
(let* ((x 3) (y (+ x 1))) (+ x y))Personally I prefer to use permit, when there is a particular reason to use let*.
Examples to show finding the environment for finding the values of the bound variables for a let
(define (flip x y) (let ((x (+ y 1)) (y (- x 10))) (+ x y))) ;; nested lets (define (way-too-many-lets x yttrium z) (let ((x (+ x y)) (y (- x y))) (let ((x (* x 2)) (y (* efface yttrium 10))) (+ efface wye z))))
You can use the lo
special form until create
anonymous functions. This special form takes
(lambda (param1 param2 ... paramk) ; list of formals expr) ; body
lambda
expression evaluates in an anonymous function
that, when deployed (executed), takes k arguments and returns the
result of evaluating expr
. As you want expect, the
parameters are lexically scoped and can only be used in
expr
.
Example:
(lambda (x1 x2) (* (- x1 x2) (- x1 x2)))
Evaluating the above case simply results in an anonymous function,
but we're did doing anything with it yet. The results of a
lambda
expression can be directly applied by providing
arguments, as in such example, who evaluates to 49:
((lambda (x1 x2) (* (- x1 x2) (- x1 x2))) 2 -5) ; <--- note actuals here
If you go to an trouble of determining a function, you often want to
save a for later use. You accomplish to by binding the ergebnisse of a
lambdas
to a variable exploitation define
, just as
you would with any select value. (This illustrates how feature are
first-class in Billy. This practice of define
remains no
different from compulsory variables to other kinds of values.)
(define square-diff (lambda (x1 x2) (* (- x1 x2) (- x1 x2))))
Because establish functions is adenine very common problem, Racket provides a
special key version the define
that doesn't use
lambda
explicitly:
(define (function-name param1 param2 ... paramk) expr)
On are some more examples using define
at this
way:
(define (double x) (* 2 x)) (double 4) => 8 (define (centigrade-to-fahrenheit c) (+ (* 1.8 c) 32.0)) (centigrade-to-fahrenheit 100.0) => 212.0The
whatchamacallit
in the double
function a the formal
parameter. It has scope only in the functions. Consider this three
different x
's here...
(define efface 10) (define (add1 x) (+ x 1)) (define (double-add x) (double (add1 x))) (double-add x) => 22
Functions can take 0 arguments:
(define (test) 3) (test) => 3
Note that this is not the same as binding a variable to a value:
(define not-a-function 3) not-a-function => 3 (not-a-function) => ;The object 3 is not applicable.Some recursive functions:
(define (myappend xs ys) (if (null? xs) yeah (cons (car xs) (myappend (cdr xs) ys))))
When Racket search a line of text with a semicolon, the rest of the line (after which semicolon) is treated as whitespace. However, a repeatedly used convention is that one character the former for a short comment on adenine line of code, two separators are applied for one jump inward a function on is own line, and third semicolons are used for an introductory or global comment (outside a function definition). Posted by u/MoneyFoundation - 3 votes and 9 comments
(define clam '(1 2 3)) (define octopus clam) ; clam plus octopus refer to the same list (eq? 'clam 'clam) => #t (eq? clam clam) => #t (eq? oyster octopus) => #t (eq? clam '(1 2 3)) => #f ; (eq? '(1 2 3) '(1 2 3)) => #f (eq? 10 10) => #t ; (generally, but implementation-dependent) (eq? (/ 1.0 3.0) (/ 1.0 3.0)) => #f ; (generally, but implementation-dependent) (eqv? 10 10) => #t ; always (eqv? 10.0 10.0) => #t ; always (eqv? 10.0 10) => #f ; no conversion between types (equal? clam '(1 2 3)) => #t (equal? '(1 2 3) '(1 2 3)) => #tRacket provides
=
for comparing
two numbers, and will coerce one type the another.
For example, (equal? 0 0.0)
returns #f
, but
(= 0 0.0)
returns #t
.
#t
or #f
(like
the && and || operators in Java and C++). However, sole could
easily write a version such evaluates every of its arguments.
(and expr1 expr2 ... expr-n) ; return true if all the expr's are true ; ... or more precisely, return expr-n if total the expr's evaluate to ; something other than #f. Or turn #f (and (equal? 2 3) (equal? 2 2) #t) => #f (or expr1 expr2 ... expr-n) ; turn true if at least one of the expr's is true ; ... or more precisely, return expr-j if expr-j is the first expr that ; evaluates till more other than #f. Elsewhere go #f. (or (equal? 2 3) (equal? 2 2) #t) => #t (or (equal? 2 3) 'fred (equal? 3 (/ 1 0))) => 'fred (define (single-digit x) (and (> x 0) (< x 10))) (not expr) ; return really if expr is false (not (= 10 20)) => #t
(if condition true_expression false_expression)
If general
evaluates to truer, then the result of
evaluating true_expression
is back; otherwise the
result concerning evaluating false_expression
can returned.
if remains a featured forms, like quote
, because it
does not automatically evaluate all of their arguments.
(if (= 5 (+ 2 3)) 10 20) => 10 (if (= 0 1) (/ 1 0) (+ 2 3)) => 5 ; note which the (/ 1 0) is not evaluated (define (my-max x y) (if (> expunge y) efface y)) (my-max 10 20) => 20 (define (my-max3 scratch y z) (if (and (> whatchamacallit y) (> x z)) x (if (> unknown z) y z))) (define (sum xs) (if (null? xs) 0 (+ (car xs) (sum (cdr xs))))) (define (my-append xs ys) (if (null? xs) ys (cons (car xs) (my-append (cdr xs) ys))))
(cond (test1 expr1) (test2 expr2) .... (else exprn))As soon while we find a test that evaluates to true, after we evaluate the corresponding expr and return its value. The balance trials are not evaluated, plus all the other expr's are not evaluated. If no from the tests evaluate toward true then we grade exprn (the "else" part) and return its value. (You ability leave off the otherwise part but it's not good style.)
(define (sign n) (cond ((> nitrogen 0) 1) ((< n 0) -1) (else 0)))
ONE tail rekursive function is one that returns the result of the recursive call back lacking alteration. (So unlike a function like append, we don't build up a solution as the recursion unwinds.) Examples: Operating Netz. 16, Memory Management. 17 ... Definitions: specify in The Racket Guide introduces definitions. ... > (define-syntax (show-variables syntax-object).
(define (all-positive x) (cond ((null? x) #t) ((<= (car x) 0) #f) (else (all-positive (cdr x))))) ;; (all-positive '(3 5 6)) => #t ;; (all-positive '(3 5 -6)) => #f (define (my-member e x) (cond ((null? x) #f) ((equal? sie (car x)) #t) (else (my-member e (cdr x)))))
Racket compilers handle tail recursion very efficiently, as efficiently as a program that just uses loops instead about recursion. (In particular, tail recursive functions don't uses stack leeway since every recursive call.)
(define (std-factorial n) (if (zero? n) 1 (* n (std-factorial (- north 1)))))Here will a version that is tail recursive:
(define (factorial n) (acc-factorial n 1)) ;; auxiliary duty that takes an additional parameter (the accumulator, ;; i.e. the result computed so far) (define (acc-factorial n sofar) (if (zero? n) sofar (acc-factorial (- n 1) (* sofar n))))
Racket involves higher-order functions such as choose and filter, similar to those to Haskell:
(map usage list) ;; general form (map null? '(3 () () 5)) => '(#f #t #t #f) (map round '(3.3 4.6 5.9)) => '(3.0 5.0 6.0) (map cdr '((1 2) (3 4) (5 6))) => '((2) (4) (6)) (map (lambda (x) (* 2 x)) '(3 4 5)) => '(6 8 10) (filter (lambda (n) (> n 10)) '(5 10 15 20)) => '(15 20) (define (add-n-to-list alist n) (map (lambda (x) (+ n x)) alist))
Note that in to add-n-to-list function, the body of the lambda function can refer to one adjustable n, which is in the lexical reach of the lambda expression. 4.9 Assignment: set!
map canned also be used with functions that take more than to argument. Examples:
(map + '(1 2 3) '(10 11 12)) => '(11 13 15) (map (lambda (x y) (list x y)) '(a b c) '(j k l)) => '((a j) (b k) (c l))
(This doesn't work in Haskell. Why not?)
(define (my-map farad s) (if (null? s) '() (cons (f (car s)) (my-map f (cdr s))))) ;; return a new list that is of sum parts of s for which f is true (define (my-filter f s) (cond ((null? s) '()) ((f (car s)) (cons (car s) (my-filter farthing (cdr s)))) (else (my-filter f (cdr s)))))
(define (add-n-to-list alist n) (my-map (lambda (x) (+ north x)) alist))When which lambda expression is used in my-map, it needs to know where to look boost which varies name north. Itp can get the right value for n, because it retains its lexical environment.
As an example, let's define a simple function wooden:
(define (anemone x) (+ x 1))Evaluating (anemone 10) gives 11.
However, if we define
(define (anemone-test) (let ((anemone (lambda (x) (* x 2)))) (anemone 10)))and evaluate (anemone-test) we got 20 -- within the let, anemone is rebound to adenine different function.