Lisp: How to write a Higher Order Function - lisp

I have this problem to work on:
The sum higher order procedure can be generalised even further to capture the idea of combining terms with a fixed operator. The mathematical product operator is a specific example of this idea, with multiplication replacing the addition of the summation operator.
The procedure accumulate, started below, is intended to capture this idea. The combiner parameter represents the operator that is used to reduce the terms, and the base parameter represents the value that is returned when there are no terms left to be combined. For example, if we have already implemented the accumulate procedure, then we could define the sum procedure as:
(define sum (accumulate + 0))
Complete the definition of accumulate so that it behaves according to this description.
(define accumulate
(lambda (combiner base)
(lambda (term start next stop)
(if (> start stop)
...
...))))
I inserted as the last two lines:
base
(combiner base (accumulate (combiner start stop) start next stop))
but, I have no idea if this is correct nor how to actually use the sum procedure to call accumulate and hence sum up numbers.

This is a great way to learn how to fish. Much better
than being given a fish.
Until then, here's how to approach the problem. Write a
function which would do what (accumulate + 0) would do. Don't use the accumulate function; just write a defun which which does what your homework asks. Next, write a function which would do what (accumulate * 1) would do. What are the similarities, what are the differences between the two functions. For the most part, they should be identical except for the occurrence of the + and * operators.
Next, note that the accumulate function is to return a function which will look a lot like the two functions you wrote earlier. Now, using the insight that two functions you wrote are very similar, think how to apply that to the function which (defun accumulate ...) is to return.

Related

Attempting to define a function that provides the minimum integer in a list of numbers SPECIFICALLY using do loops (not do* or dolist, etc.)

I have an assignment for class specifically testing our understanding of do, asking to define a function to produce the minimum of a list of numbers. We are asked to also use a secondary function ("smaller") to do so.
I have no previous experience coding, and am forced to stay within the boundaries of do; I've been reading up on the issue as much as I can, but almost everything I find just suggests using other methods (do*, COND, etc.).
I defined a simple "smaller" as:
(defun smaller (x y)
(if (< x y) x y))
I then approached the problem as such:
(defun minimum (lst)
"(lst)
Returns the minimum of a list of numbers."
(do ((numbers lst (cdr numbers))
(min (car numbers) (smaller min (cadr numbers))))
((null numbers) min)))
I feel there's an issue where the "smaller" function can't be applied on the first loop (feedback about this would be great), otherwise my immediate issue is getting an error of: "UNBOUND-VARIABLE" for the variable "NUMBERS". I am not sure which 'area' is causing the confusion: if I have poorly formatted the do loop entirely, or if one of the second/third/etc. "numbers" is causing an issue.
Can someone provide some feedback? -- again keeping in mind that we are limited specifically to simple do loops, and that I definitely don't have a perfect understanding of what I've already got down.
Thanks so much in advance.
Do binds in parallel, so numbers is not bound when min is first bound. You could fix that by using (car lst) instead of (car numbers) there.
You need to fix the end condition then: (cadr numbers) is nil on the last iteration, you need to stop before that.
For better readability, I'd suggest to use first and second instead of car and cadr here.
You could still refer to numbers as long as you used do*, which is a sequentially binding variant of do. Then you'd have to use car instead of cadr - you're now picking the first number from an already reduced list. And you'd need to modify your end condition to avoid calling smaller with a NIL argument - you should be able to figure this out easily.

What is the difference between Clojure clojure.core.reducers/fold and Scala fold?

I came across that Clojure has clojure.core.reducers/fold function.
Also Scala has built-in fold function but could not understand that they are working differently or not?
I assume that you are talking about clojure.core.reducers/fold.
Scala's default fold implementation on sequences is very simple:
collection.fold(identityElem)(binOp)
simply starts with the identityElem and then traverses the collection sequentially, and applies the binary operation binOp to the already accumulated result and the current sequence value, e.g.
(1 to 3).fold(42000)(_ + _)
will result in 42000 + 1 + 2 + 3 = 42006.
Clojure's fold with the full signature
(r/fold n combinef reducef coll)
from the above mentioned package works in parallel in two stages. First, it splits the input into smaller groups of size n (approximately), then reduces each group using reducef, and finally combines the results of each group using combinef.
The main difference is that combinef is expected to be both a zeroary and binary at the same time (Clojure has multi-ary functions), and (combinef) (without arguments) will be invoked to produce identity elements for each partition (thus, this documentation is correct, and this documentation lies).
That is, in order to simulate Scala's fold from the above example, one would have to write something like this:
(require '[clojure.core.reducers :as r])
(r/fold 3 (fn ([] 42000) ([x y] y)) + [1 2 3])
And in general, Scala's fold
collection.fold(identityElement)(binOp)
can be emulated by reducers/fold as follows:
(r/fold collectionSize (fn ([] identityElem) ([x y] y)) binOp collection)
(note the ([x y] y) contraption that throws away the first argument, it's intentional).
I guess the interface wasn't intended to be used with any zero-binary operations that are not monoids, that's the reason why Scala's fold is so awkward to simulate using Clojure's fold. If you want something that behaves like Scala's fold, use reduce in Clojure.
EDIT
Oh, wait. The documentation actually states that
combinef must be associative, and, when called with no
arguments, (combinef) must produce its identity element
that is, we are actually forced to use a monoid as the combinef, so the above 42000, ([x y] y)-example is actually invalid, and the behavior is actually undefined. The fact that I somehow got the 42006 out was a hack in the strictly technical sense that it relied on undefined behavior of a library function to obtain the desired result 42006.
Taking this extra information into account, I'm not sure whether Scala's fold can be simulated by Clojure's core.reducers/fold at all. Clojure's fold seems to be constrained to reductions with a monoid, whereas Scala's fold is closer to the general List catamorphism, at the expense of parallelism.
The clojure.core.reducers namespace is a specialized implementation designed for parallel processing of large datasets. You can find full docs here:
https://clojure.org/reference/reducers.
(r/fold reducef coll)
(r/fold combinef reducef coll)
(r/fold n combinef reducef coll)
r/fold takes a reducible collection and partitions it into groups of
approximately n (default 512) elements. Each group is reduced using
the reducef function. The reducef function will be called with no
arguments to produce an identity value in each partition. The results
of those reductions are then reduced with the combinef (defaults to
reducef) function. When called with no arguments, (combinef) must
produce its identity element - this will be called multiple times.
Operations may be performed in parallel. Results will preserve order.
Until you are maxing out your machine, you should just stick to the basic reduce function:
https://clojuredocs.org/clojure.core/reduce
This is essentially the same as Scala's fold function:
(reduce + 0 [1 2 3 4 5]) => 15
where the function signature is:
(reduce <op> <init-val> <collection-to-be-reduced> )

Calculating factorial using Lisp

I was reading a code sample that calculates the factorial using Lisp as below:
(defun fatorial (n)
(cond
((= n 1) 1)
(t (* n (fatorial (- n 1))))))
So, I was wondering what is t in this code sample? Does it have any special meaning in Lisp? I searched but couldn't find my answer!
That's the symbol LISP uses for True. In a cond in LISPs, the "catch all" at the end uses t to indicate that if none of the preceding conditions evaluate to True, this code will always execute.
Consider it here as the equivalent of an else in an if-else. On the whole, though, it just represents True.
A cond consists of the cond symbol followed by a number of cond clauses, each of which is a list. The first element of a cond clause is the condition; the remaining elements (if any) are the action. The cond form finds the first clause whose condition evaluates to true (ie, doesn't evaluate to nil); it then executes the corresponding action and returns the resulting value.
So, in your code, the firs test checks if n equals 1 and, if so, returns 1. The other clause, starting with "t" (for true in lisp) is the "else" part of the condition.

How to define a function that returns half of input, in two different ways?

I am reading a Gentle Introduction to Symbolic Computation and it asks this question. Basically, the previous content deals with making up bigger functions with small ones. (Like 2- will be made of two 1- (decrement operators for lisp))
So one of the questions is what are the two different ways to define a function HALF which returns one half of its input. I have been able to come up with the obvious one (dividing number by 2) but then get stuck. I was thinking of subtracting HALF of the number from itself to get half but then the first half also has to be calculated...(I don't think the author intended to introduce recursion so soon in the book, so I am most probably wrong).
So my question is what is the other way? And are there only two ways?
EDIT : Example HALF(5) gives 2.5
P.S - the book deals with teaching LISP of which I know nothing about but apparently has a specific bent towards using smaller blocks to build bigger ones, so please try to answer using that approach.
P.P.S - I found this so far, but it is on a completely different topic - How to define that float is half of the number?
Pdf of book available here - http://www.cs.cmu.edu/~dst/LispBook/book.pdf (ctrl+f "two different ways")
It's seems to be you are describing peano arithmetic. In practice it works the same way as doing computation with fluids using cups and buckets.
You add by taking cups from the source(s) to a target bucket until the source(s) is empty. Multiplication and division is just advanced adding and substraction. To halve you take from source to two buckets in alterations until the source is empty. Of course this will either do ceil or floor depending on what bucket you choose to use as answer.
(defun halve (x)
;; make an auxillary procedure to do the job
(labels ((loop (x even acc)
(if (zerop x)
(if even (+ acc 0.5) acc)
(loop (- x 1) (not even) (if even (+ acc 1) acc)))))
;; use the auxillary procedure
(loop x nil 0)))
Originally i provided a Scheme version (since you just tagged lisp)
(define (halve x)
(let loop ((x x) (even #f) (acc 0))
(if (zero? x)
(if even (+ acc 0.5) acc)
(loop (- x 1) (not even) (if even (+ acc 1) acc)))))
Edit: Okay, lets see if I can describe this step by step. I'll break the function into multiple lines also.
(defun half (n)
;Takes integer n, returns half of n
(+
(ash n -1) ;Line A
(if (= (mod n 2) 1) .5 0))) ;Line B
So this whole function is an addition problem. It is simply adding two numbers, but to calculate the values of those two numbers requires additional function calls within the "+" function.
Line A: This performs a bit-shift on n. The -1 tells the function to shift n to the right one bit. To explain this we'll have to look at bit strings.
Suppose we have the number 8, represented in binary. Then we shift it one to the right.
1000| --> 100|0
The vertical bar is the end of the number. When we shift one to the right, the rightmost bit pops off and is not part of the number, leaving us with 100. This is the binary for 4.
We get the same value, however if we perform the shift on nine:
1001| --> 100|1
Once, again we get the value 4. We can see from this example that bit-shifting truncates the value and we need some way to account for the lost .5 on odd numbers, which is where Line B comes in.
Line B: First this line tests to see if n is even or odd. It does this by using the modulus operation, which returns the remainder of a division problem. In our case, the function call is (mod n 2), which returns the remainder of n divided by 2. If n is even, this will return 0, if it is odd, it will return 1.
Something that might be tripping you up is the lisp "=" function. It takes a conditional as its first parameter. The next parameter is the value the "=" function returns if the conditional is true, and the final parameter is what to return if the conditional is false.
So, in this case, we test to see if (mod n 2) is equal to one, which means we are testing to see if n is odd. If it is odd, we add .5 to our value from Line A, if it is not odd, we add nothing (0) to our value from Line A.

extract/slice/reorder lists in (emacs) lisp?

In python, you might do something like
i = (0, 3, 2)
x = [x+1 for x in range(0,5)]
operator.itemgetter(*i)(x)
to get (1, 4, 3).
In (emacs) lisp, I wrote this function called extract which does something similar,
(defun extract (elems seq)
(mapcar (lambda (x) (nth x seq)) elems))
(extract '(0 3 2) (number-sequence 1 5))
but I feel like there should be something built in? All I know is first, last, rest, nth, car, cdr... What's the way to go? ~ Thanks in advance ~
If your problem is the speed then use (vector 1 2 3 4 5) instead of a list, and (aref vec index) to get the element.
(defun extract (elems seq)
(let ((av (vconcat seq)))
(mapcar (lambda (x) (aref av x)) elems)))
If you're going to extract from the same sequence many times of course it make sense to store the sequence in a vector just once.
Python lists are indeed one-dimensional arrays, the equivalent in LISP are vectors.
I've only done simple scripting in elisp, but it's a relatively small language. And extract is a very inefficient function on linked lists, which is the default data structure in emacs lisp. So it's unlikely to be built-in.
Your solution is the best straightforward one. It's n^2, but to make it faster requires a lot more code.
Below is a guess at how it might work, but it might also be totally off base:
sort elems (n log n)
create a map that maps elements in sorted elem to their indices in original elem (probably n log n, maybe n)
iterate through seq and sorted elem. Keep only the indices in sorted elem (probably n, maybe n log n, depending on whether it's a hash map or a tree map)
sort the result by the values of the elem mapping (n log n)
From My Lisp Experiences and the Development of GNU Emacs:
There were people in those days, in 1985, who had one-megabyte machines without virtual memory. They wanted to be able to use GNU Emacs. This meant I had to keep the program as small as possible.
For instance, at the time the only looping construct was ‘while’, which was extremely simple. There was no way to break out of the ‘while’ statement, you just had to do a catch and a throw, or test a variable that ran the loop. That shows how far I was pushing to keep things small. We didn't have ‘caar’ and ‘cadr’ and so on; “squeeze out everything possible” was the spirit of GNU Emacs, the spirit of Emacs Lisp, from the beginning.
Obviously, machines are bigger now, and we don't do it that way anymore. We put in ‘caar’ and ‘cadr’ and so on, and we might put in another looping construct one of these days.
So my guess is, if you don't see it, it's not there.