Update element of immutable vector - vector-set - racket

I'm using vectors to build a table for implement a dynamic program, it involves updating each element of the vector sequentially. But why is there no vector-set for immutable vectors? There is only vector-set! for mutable vectors, but we can see that there is dict-set and dict-set! for immutable and mutable dictionaries, also there is hash-set and hash-set! for immutable and mutable hash tables.

The reason why vector-set is missing, is to prevent people inadvertently using it without realizing the operation is O(n) and not O(1). Since vector-set! is O(1) it is not unlikely for someone to make this mistake.
Furthermore it is simple to write a vector-set when it is really needed:
#lang racket
(define (vector-set v i o)
(vector->immutable-vector
(for/vector ([j (in-range (vector-length v))])
(if (= i j)
o
(vector-ref v j)))))
(vector-set (vector-immutable 10 11 12 13) 2 'a)
Output:
'#(10 11 a 13)

Related

coerce function in common lisp -- arrays and lists

I am seeing different behavior of coerce between different versions of Common Lisp - wondering which one is "right" or is the standard ambiguous on this seemingly simple question:
is
(coerce '(1 2 3) 'array)
correct lisp? It works fine in Clozure Common Lisp but not in sbcl.
And when it does not work what is the easiest way to coerce a list into an array?
Thanks
The specification says:
If the result-type is a recognizable subtype of vector, and the object is a sequence, then the result is a vector that has the same elements as object.
array is not a subtype of vector -- vectors are 1-dimensional arrays, but array includes arrays with any number of dimensions.
You can use one of these
(coerce '(1 2 3) 'vector)
(coerce '(1 2 3) '(array t (*)))
In the second version, (*) specifies a single dimension whose size is unspecified.
Your use is unspecified, so implementations are free to implement it as they please. If it returns a value, the value has to be an ARRAY of some kind.
To add to Barmar's answer (this is really a comment, but it's too long), while it's fine for CCL to do what it does, I think it's clear that something like this would be very hard to define in a standard.
Consider something like this:
(coerce '((1 2 3) (4 5 6) (7 8 9)) 'array)
What is the result of this meant to be? Should it be:
a vector each of whose elements is a three-element list?
the equivalent of (make-array '(3 3) :initial-contents '((1 2 3) (4 5 6) (7 8 9)))?
the transpose of that array?
I think either of the first two are reasonable interpretations: sometimes you will want one, sometimes the other. The third is probably not reasonable given CL is a row-major language.
So if (coerce ... 'array) were in the standard, how would you specify which of these you wanted? If you just chose one, which should it be (and how do you now reach agreement with the people on the committee who think it should be the other!)?

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> )

setf seems to change both its arguments when they are given by aref

In Lisp, I've defined an array a and then let b be equal to a. I now want to redefine an entry of b to be equal to a different entry in a, like this:
(setf a (make-array '(2 2) :initial-contents '((1 2) (3 4))))
(setf b a)
(setf (aref b 0 0) (aref a 0 1))
So now, b will be #2A((2 2) (3 4)), which is all well and good. But what puzzles me is that a is also now #2A((2 2) (3 4)).
My question is this: why has applying setf to an entry of b changed a as well? I can get around this by introducing an intermediate variable with (setf x (aref a 0 1)) and then applying (setf (aref b 0 0) x), but this seems like a strange workaround to me.
Your (setf b a) in the second line does what is sometimes called a shallow copy in other languages. That is, b does not become an independent copy of the array a, but rather becomes just another name for the exact same array. As a result, when you modify b, you are modifying a as well.
If you want b to be a true, independent copy ("deep copy") of the array, then you'll need to allocate a new array and copy the elements of a into it. One way to do this is for 1-dimensional arrays is with the copy-seq function. For fancier arrays you might also look at this question about how to copy 2d arrays which talks about some available libraries and approaches.

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.

Lisp: How to write a Higher Order Function

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.