If statements in Racket - if-statement

I am trying to construct a function "number-crop" which takes three arguments x a b. If x is to the left of the closed interval [a, b] on the number line, then return a. If x is to the right of the interval, then return b. Otherwise, just return x. This is what I have:
(define (number-crop x a b)
(if (max x a b) x b)
(if (min x a b) x a))
I am returned with the error, "define: expected only one expression for the function body, but found 1 extra part". I am new to Racket so I am still trying to understand how if statements work within the language.

Scheme/Racket if expressions always have exactly one condition and exactly two branches. Since they are expressions, not statements, this makes them very useful, and they function much like the conditional “ternary” operator in languages in the C family. However, when you have multiple conditions, you likely want something closer to if...else if chains, which is provided via the cond form.
The cond form is just like if, except with the ability to have any number of “clauses” which are each determined by a single condition. Using cond, your number-crop function would look like this:
(define (number-crop x a b)
(cond
[(< x a) a]
[(> x b) b]
[else x]))
(Note that else is special inside of cond—it replaces the condition for the last clause, and it always runs if the other cases fail.)
This would likely work, but if you already have access to min and max, you don’t actually need to branch at all! If you use those two functions together, you can write number-crop with neither if nor cond:
(define (number-crop x a b)
(min (max a x) b))
This works because composing both min and max will effectively clamp the value within the given range, provided that a is always the minimum and b is always the maximum.

In Scheme (Racket), functions are defined to return one thing. In your case it is clear: the result of the operation you describe. However, Scheme is different from most imperative languages in several respects. For example, if you look at your expression inside the define, it contains two expressions, one after the other. This contradicts the "one expression that calculates the function" assumption in Scheme.
Moreover, even if you write it in an imperative language, you'd use nested ifs, that you can of course use here. Something along the lines of:
(define (number-crop x a b)
(if (= x (max x a b))
b
(if (= x (min x a b))
a
x)))

Related

I need help to understand a lisp program that finds the depth of a list

I need help to understand my code theoretically. Here is my lisp program:
(defun depth (lst)
(if (or (null lst) (atom lst)) 0
(+ 1 (apply 'max (mapcar #'depth lst)))
))
I know it works with this example:
(write (depth '((a (b c) d r ((t))))) -> 3
I just can't understand the else statement of the IF statement that I tried.
If you can help me, it will be very much appreciated. Thank you in advance.
Here is your code, slightly reformatted:
(defun depth (value)
(if (or (null value) (atom value))
0
(+ 1 (apply 'max (mapcar #'depth value)))))
I renamed lst (you could have written it list, by the way) to value, because the name is confusing as it suggest that the variable is always a list, which is not true. The function depth can be called on any value:
(depth "hello")
=> 0
(depth 100)
=> 0
The then branch of the if is evaluated when value is NIL or any atom. Since NIL is also an atom, the test expression could be simplified as (atom value). When value is an atom, the depth is zero.
The else branch of the if is evaluated when value is not an atom, which by definition of atom means value here is a cons. The function also assumes that it is a proper list, and not some circular list.
Since value is a list in that branch, we can call mapcar on it: (mapcar #'depth value); this is where the function assumes the list is proper.
This computes (depth v) for each v in value. More precisely if value is a list of length n, then that call to mapcar evaluates as a list of numbers (D1 ... Dn) where Di is (depth Vi) for all i between 1 and n.
So we know that (apply 'max (mapcar ...)) is (apply 'max depths) for some list depths of numbers. In general:
(apply fn v1 ... vn list)
... is a way to call the function object denoted by the fn expression with at least n elements (v1 to vn), as well as an arbitrary number of additional elements stored in list. When you quote the function, as 'max, or when you write #'max, you refer to a function by its name in the function namespace.
Contrast this to the usual way of calling a function:
(f x y z)
The function name and the number of arguments being passed is fixed: as soon the form is read we knows there is a call to f with 3 arguments.
The apply function is a built-in that allows you to pass additional arguments in a list, in the last call argument. The above call could be written:
(apply #'f x y z ()) ;; note the empty list as a last argument
This could also be written:
(apply #'f (list x y z)) ;; all arguments in the last list
The only difference is probably a matter of runtime efficiency (and with good compilers, maybe there is no difference).
In your example, you do:
(apply max depths)
Which would be the same as writing (pseudo-code):
(max d1 d2 d3 ... dn)
... where depths is the list (list d1 d2 ... dn).
But we can't literally write them all directly, since the content of the list is only known at runtime.
Thus, the call to apply computes the max depths among all the depths computed recursively. Note that the above is a somewhat improper use of apply, since apply should not be called with lists of arbitrary size: there is a limit in the standard named CALL-ARGUMENTS-LIMIT that is allowed to be as low as 50 in theory, the maximum size of such a list (we will see an alternative below).
Finally, depth evaluates (+ 1 ...) on this result. In other words, the whole expression can be summarized as: the depth of a list is 1 added to the maximum depth of all its elements.
Using reduce
Instead of apply, you can use REDUCE to compute max successively on a list. This is preferable to apply because:
there is no limitation for the number of elements, like apply
(reduce 'max depths) ;; works the same, but more reliably
there is no need need to build an intermediate list of depths, you iterate over the list of values, call depth and directly use the result to compute the max. The skeleton is:
(reduce (lambda (max-so-far item) ...)
value
:initial-value 0)
Declarative approach
Instead of reduce, the loop macro can be used as a more readable alternative to express the same computation. I also use typecase which in my opinion makes the intent clearer:
(defun depth (value)
(typecase value
(atom 0)
(cons (1+ (loop for v in value maximize (depth v))))))

Lisp-family: Different evaluation of a symbol call and symbol as argument

Is there a way in lisp-family (EDIT: lisp-1) languages to differentiate symbol evaluation with regard to its position as as function or as an argument (i.e. override eval of this symbol in regard to when it is evaluated)?
As an example (I don't need this functionality, this is an example), I wanted to implement some sort of infix operation on a set of objects, which can be called by an object itself
(my-obj some-operator arg1 ...)
which will actually apply function some-operator to my-obj and arguments.
But when this object is used anywhere else in code as an argument, like:
(some-function my-obj &args...)
it will evaluate to a value of my-obj.
Thank you.
In Racket it is possible to do a couple things in this spirit:
You can define a struct and give it a prop:procedure. When an instance of the struct is supplied in an application, the procedure will be called.
You can override the default #%app with your own function, to redefine application generally, and including things that aren't structs. For example you can do things like emulate Clojure's (key map) syntax, so that ('symbol dict) is actually (hash-ref dict 'symbol).
Being a lisp-1 basically means that you do not evaluate the first slot of a combination any differently than any other slots. To get such behavior for code you write anyway, you need to transform it to code that does what you want under the rules of a lisp-1. Thus you will need to implement a macro that performs this transformation.
For example if you want infix operators you need to write some macro infix and then perhaps you could write:
(infix (+ - * /) (1 + 2 * 5 - 3) / 4)
and have it evaluate to 2.
I have been playing around with the idea of a default procedure in a OO CLOS-like Scheme. eg. that writing
(obj 5 10)
Would validate obj and apply it with arguments if obj is a procedure or method, but if it isn't it would be the same as the default dispatcher eg.
(default-dispatcher obj 5 10)
In such Scheme one could make vector accessors:
(define-method default-dispatcher
"Default dispatcher for vectors"
([obj %vector] [index %number]) -> (vector-ref obj index)
([obj %vector] [index %number] value) -> (vector-set! obj index value)
(args ...) -> (error "No such method"))
; example usage
(define vec (vector 4 5 6 7))
[vec 1] ; => 5
[vec 1 10]
[vec 1] ; => 10
In Racket this is possible by changing the languages #%app syntax.
In the TXR Lisp dialect, the problem is approached from the other end. Starting with Lisp-2 dialect as a basis, can we robe ourselves with some of the expressivity advantages of a Lisp-1 dialect, like eliminating the (function ...), #' and funcall noise from programs that make extensive use of higher order functions?
The design is centered around a special operator called dwim, which stands for either "Do What I Mean" or "Dispatch, in a Way that is Intelligent and Meaningful".
Invocations of the dwim operator are sugared over using square brackets, which are called "DWIM Brackets"
The dwim operator isn't just a macro over Lisp-2; it actually changes the name lookup rules. When we have
(dwim a b c (d e f) g)
Or equivalently:
[a b c (d e f) g]
all of the argument forms which are symbolic (a, b, c and g) are resolved using a special rule which conflates together the function and variable namespaces. This is built into the heart of the language. The operator has direct access to the environment to make this possible.
The special treatment does not recurse into (d e f), which is an ordinary Lisp-2 form. You have to put the DWIM Brackets on that if you want the semantics.
Also, the dwim operator is properly handled by macro expansion. For instance, given:
(symacrolet ((localfun whatever))
(flet ((localfun () ...)))
[a b c localfun] ;; refers to the flet as a function object!
(a b c localfun))) ;; refers to the symbol macro!
The macro expander knows about dwim and its semantics, and so it considers the possibility that localfun refers to the function and variable namespace. The closest lexical binding in either namespace is the flet and so the symbol macro expansion is suppressed (shadowed).
The dwim semantics is implicitly used in the partial evaluating op macro and its "cousins" derived from it.
Range Extraction task from Rosetta Code:
(defun range-extract (numbers)
`#{(mapcar [iff [callf > length (ret 2)]
(ret `#[#1 0]-#[#1 -1]`)
(ret `#{#1 ","}`)]
(mapcar (op mapcar car)
(split [window-map 1 :reflect
(op list #2 (- #2 #1))
(sort (uniq numbers))]
(op where [chain second (op < 1)])))) ","}`)
Y Combinator:
;; The Y combinator:
(defun y (f)
[(op #1 #1)
(op f (op [##1 ##1]))])
;; The Y-combinator-based factorial:
(defun fac (f)
(do if (zerop #1)
1
(* #1 [f (- #1 1)])))
;; Test:
(format t "~s\n" [[y fac] 4])
Moreover, various useful things are function callable in TXR Lisp. For instance, every sequence (list, vector or character string) is regarded as a function which maps numeric indices to elements. Thus we can do:
(mapcar "abc" #(2 1 0)) -> #(#\c #\b #\a)
The accepted answer describes a Racket mechanism for treating structures as functions. TXR has this in the form of lambda methods. This is demonstrated in the "OOP-Based" solution to the Accumulator Factory task in Rosetta:
(defstruct (accum count) nil
(count 0))
(defmeth accum lambda (self : (delta 1))
(inc self.count delta))
We can instantiate a (new (accum 9)) which will produce the values 10, 11, 12, ... when invoked as a function. An optional delta argument can be supplied for an increment other than 1:
(let ((acc (new (accum 0))))
(list [acc 5] [acc 5] [acc])) -> (5 10 11)

Defining an "arg max" like function over finite sets, and proving some of its properties, and avoiding a detour via lists

I'm working with a custom implementation of vectors as functions whose domain is a finite "index set" of natural numbers, and whose image is of some type on which one can define a maximum, usually real. E.g. I could have a two-dimensional vector v with v 1 = 2.7 and v 3 = 4.2.
On such vectors I'd like to define an "arg max" like operator, which tells me the index of the maximum component, 3 in the example of v above. I'm saying "the" index because the "arg max" like operator will additionally accept a tie-breaking function to be applied to components with values. (The background is bids in auctions.)
I know that Max on finite sets is defined using fold1 (of which I do not yet understand how it works). I tried this, which was accepted in itself, but then didn't work for the other things I wanted to do:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = fold1
(λ x y . if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y) N"
Note that furthermore I would like to prove certain properties of my "arg max" like operator, which will likely require induction. I know that there is the rule finite_ne_induct for induction over finite sets. OK, but I would also like to be able to define my operator in such a way that it can be evaluated (e.g. when trying with concrete finite sets), but evaluating
value "arg_max_tb {1::nat} (op >) (nth [27::real, 42])"
with expected return value 1 gives me the following error:
Wellsortedness error
(in code equation arg_max_tb ?n ?t ?v \equiv
fold1 (\lambda x y. if ord_real_inst.less_real (?v y) (?v x) then ...) ?n):
Type nat not of sort enum
No type arity nat :: enum
Therefore I resorted to converting my finite sets to lists. On lists I have been able to define the operator, and to prove some of its properties (can share the code if it's of interest) by induction using list_nonempty_induct.
The working list-based definition looks as follows:
fun arg_max_l_tb :: "(nat list) ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_l_tb [] t v = 0"
(* in practice we will only call the function
with lists of at least one element *)
| "arg_max_l_tb [x] t v = x"
| "arg_max_l_tb (x # xs) t v =
(let y = arg_max_l_tb xs t v in
if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y)"
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = arg_max_l_tb (sorted_list_of_set N) t v"
I didn't succeed to directly define a function over the constructors of a finite set. The following doesn't work:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ participant"
where "arg_max_tb {} t b = 0"
| "arg_max_tb {x} t b = x"
| "arg_max_tb (insert x S) t b =
(let y = arg_max_tb S t b in
if (b x > b y) then x
else if (b x = b y ∧ t x y) then x
else y)"
It gives me the error message
Malformed definition:
Non-constructor pattern not allowed in sequential mode.
⋀t b. arg_max_tb {} t b = 0
Could this be because the list constructors are defined as a datatype, whereas finite sets are merely defined as an inductive scheme?
Whatever – do you know of a way of defining this function over finite sets? Either by writing it down directly, or by some fold-like utility function?
Folding over a finite set requires that the result is independent of the order in which the elements of the set are visited, because sets are unordered. Most lemmas about fold1 f therefore assume that the folding operation f is left-commutative, i.e., f a (f b x) = f b (f a x) for all a, b, x.
The function that you supply to fold1 in your first definition does not satisfy this because the tie-breaking function is an arbitrary predicate. For example, take the tie-breaking function %v v'. True. Hence, if you want to stick to this definition, you will have to find sufficient conditions on the tie-breaking first and thread this assumption through all your lemmata.
Your working solution based on a sorted list of the elements avoids this commutatitivity problem. Your last suggestion with pattern matching on {}, {x} and insert x S does not work for two reasons. First, fun can only pattern-match on datatype constructors, so you would have to use function instead; this explains the error message. But then, you also have to prove the equations do not overlap and you will therefore run into the same problem with commutativity again. Additionally, you will not be able to prove termination because S might be infinite.
The well-sortedness error for code generation comes from the setup for fold1. fold1 f A is defined as THE x. fold1Set f A x where fold1Set f A x holds iff x is the result of folding f over A in some order of the elements. To check that all the results are the same, the generated code naively tests for all possible values of x whether fold1Set f A x holds. If it indeed finds just one such value, then it returns that value. Otherwise, it raises an exception. In your case, x is an index, i.e., of type nat which infinitely many values inhabit. Hence, exhaustive testing is not possible. Technically, this translates as nat not being an instance of the type class enum.
Normally, you derive specialised code equations for everything that you define in terms of fold1. See the code generator tutorial on program refinement.
This question really consists of multiple questions.
Defining a function on finite sets
fold / foldl1
The usual recursion combinator is Finite_Set.fold (or fold1). However, to be able to prove anything fold f z S, the result must be independent of the order f is applied to the elements of S.
If f is associative and commutative, you can use Finite_Set.ab_semigroup_mult.fold1_insert and Finite_Set.fold1_singleton to get simp rules for fold1 f S and you should be able to use finite_ne_induct as your induction rule.
Note that the function (I'll call it f) you give to fold1 is only commutative if t is a linear order:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = fold1
(λ x y . if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y) N"
This is not covered by the existing lemmas on fold1, so you either need to prove a generalized variant of Finite_Set.ab_semigroup_mult.fold1_insert or insert an additional tie-breaker, e.g.
else if (v x = v y ∧ ~t x y ∧ ~t y x ∧ x < y) then x
If t is a linear order, you will be able to remove this additional tie-breaker from the simp rules. Note that this additional tie-breaker is basically what you get from using sorted_list_of_set.
THE / SOME
Your arg_max_tb selects one element of a list with certain properties. This can also be defined directly with the constructs THE x. P x or SOME x. P x (choice operators). The former selects the unique element satisfying the property P (if no unique element exists, the result is undefined), the latter selects some element satisfying the property P (if no such element exists, the result is undefined). Both work for infinite lists, too.
These are often preferable if you don't need executable code.
Getting an executable function
Functions defined by recursion (i.e. primrec, fun or function) are executable by default (if all functions used in their definition are executable, too). THE and SOME can in general only be executed for enumerable domains (this is the error message you got from value -- nat is not enumerable, as it is not finite).
However, you can always give an alternative definition of your function to the code generator. See the Tutorial on Function Definitions, in particular the section about refinement.
If you prefer the formulation with choice operators for proving, but also like your function to be executable, the easiest way might to prove that the definitions of arg_max_tb via choice and sorted_list_of_set are equivalent. Then you can use the [code_unfold] predicate to replace the definition by choice with the (executable) definition by sorted_list_of_set

Evaluate function from list in lisp

I need to write a function in lisp with two arguments - list of argumentless functions and list of integers.
I need to evaluate functions from first list in order given by a second, i.e. (fun '(#'a #'b #'c) '(2 0 1)) should evaluate c, a, b.
I tried such function:
(defun z4(funs kols)
(funcall (nth (first kols) funs))
(z4 funs (rest kols))
)
but in funcall I am geting error
NIL is not of type CONS.
What does it means? I am getting same error by calling simply
(funcall (first funs))
so I assume it is something with with getting function from the list of functions. How can I evaluate function get from list of functions?
With each recursive call you reduce the kols parameter untill it becomes nil. When kols becomes nil you should terminate the recursion, so you should add the test for the terminating condition (i.e., for empty list):
(defun foo (funcs order)
(unless (endp order)
(funcall (nth (first order) funcs))
(foo funcs (rest order))))
I suggest a more readable solution (it's also more preferrable since ANSI Common Lisp Standard doesn't force implementations to perform tail call optimization):
(defun foo (funcs order)
(loop for n in order do (funcall (nth n funcs))))
In the previous examples I assume that you run your functions for their side effects, not for the return values.
Edit 1
As Vatine noted, using nth and lists to provide a collection with random access is not good for the performance, so it might be worth to store functions in a vector (that is a one-dimensional array) rathen than in a list. So, assuming that funcs is a vector of functions, the function can be defined as follows:
(defun foo (funcs order)
(loop for n in order do (funcall (aref funcs n))))
Moreover, we can replace aref with svref if the array of functions is a simple vector (glossary entry). The former is more general, but the latter may be faster in some implementations.
One can create a simple vector of functions using either
(vector #'func-a #'func-b ...)
or
#(func-a func-b ...)
A simple vector of functions can be created using the make-array function as well, but only if :adjustable and :fill-pointer keyword arguments are unspecified or nil.
'(#'a #'b #'c)
is not a list of functions A, B, C. It is this:
((FUNCTION A) (FUNCTION B) (FUNCTION C))
Above are not functions, but lists with the first symbol FUNCTION and then another symbol.
Use either
(list #'a #'b #'c)
or
'(a b c)

Scheme how to create a list

Okay this may sound like a ridiculous question, but how do you return a list in scheme.?
Based on seeing some of your other questions, I think you may be having trouble getting your head wrapped around the concepts central to a functional language such as Scheme.
At the level you're learning Scheme (novice), every function you write has an input and an output, and the body of every function is a single expression. Whatever value that expression evaluates to is returned by the function. There is no need to explicitly "return" anything as you would in an imperative language like Java or C; it just happens as a direct consequence of evaluating the expression.
The body of a function is a single expression. It's not like Java where the body of a method consists of a series of instructions:
do this
then do that
then do something else
then return something (maybe)
Scheme functions evaluate a single expression; nothing more. Here's a simple function that adds 5 to whatever number is passed as an argument:
(define (add5 x)
(+ x 5))
The body of the function is (+ x 5), which is just an expression to be evaluated. The value of x is plugged in, the + (addition) function is applied to x and 5, and the result is returned.
Lists aren't much different. All you need is an expression that will construct a list. Two have already been mentioned: list is used to build a list from scratch if you already have all the elements; cons is used to add a single element to an existing list and is often used recursively.
Here's a function that consumes a number n and builds the list (n n-1 n-2 ... 0)
(define (makelist n)
(if (= n 0)
(list 0) ; base case. Just return (0)
(cons n (makelist (- n 1))))) ; recursive case. Add n to the head of (n-1 n-2 ... 0)
In both the base and recursive cases, a list is returned by simply evaluating an expression that uses one of the list-building functions.
Here's another example. This one uses our add5 function to add 5 to each element of a list of numbers (lon):
(define (add5list lon)
(if (null? lon)
`() ; base case: lon is empty. Return an empty list.
(cons (add5 (car lon)) (add5list (cdr lon))))) ; recursive case.
; Add 5 to the head of lon and prepend it to the tail of lon
Again, both the base and recursive cases are returning lists by evaluating expressions that result in lists.
The key thing to remember about Scheme is all functions return something, and that something is simply the result of evaluating an expression. The body of a Scheme function is a single expression.
You probably want simply: '(2 3 5 7 11) or (list 2 3 5 7 11)?
You can also construct lists by specifying an element and a list to add it to: (cons 2 (cons 3 '()))
Here's an example of returning a list from a function:
(define returnlist
(lambda(a b c)
(cons a (cons b (cons c '())))
))
(returnlist 2 3 4)
Return value will be the list: (list 2 3 4)
Another not-so-well known way to do this:
> ((lambda x x) 2 3 5 7 11)
(2 3 5 7 11)
that is, the "list" function itself can be defined as:
> (define list (lambda x x))