just got back for ELS 2017 in Brussels, which went very well; thanks especially to Didier Verna, Irene Durand and Alberto Riva. It was a particularly good edition of the event.
Cheers
> 42 * 1:5 # The ':' operator produces a vector.
[1] 42 84 126 168 210
> a = array(11:14, dim = c(2, 2), dimnames = list(list("a", "b"), list("x", "y")))
> a
x y
a 11 13
b 12 14
In brief, you have a matrix with "named" rows and columns. There are other idiosyncrasies but this is already something interesting to deal with, as you can now write things like:> a[1, "y"] [1] 3 > a["b", ] x y 12 14The second "indexing" selects, or slices, the entire second row (counting from 1) and, as a result, returns a vector with the column names retained.
> a[2]
[1] 12
> a[42]
[1] NA # 'NA' is the 'not available' indicator.
> a[c(2, 3, 4, 10)]
[1] 12 13 14 NA
Indexing by only one index accesses the underlying vector in column major order. If the index is beyond the current limit, the value NA ('not available') is returned. If the sole index is a vector, then the indexing returns a vector of the values in the array accessed column major order.> a = array(11:19, dim = c(3, 3), dimnames = list(list("a", "b", "c"), list("x", "y", "z")))
> a
x y z
a 11 14 17
b 12 15 18
c 13 16 19
> a[2, "y"] = 42
> a
x y z
a 11 14 17
b 12 42 18
c 13 16 19
> b = array(42, dim = c(2, 2))
> b
[,1] [,2]
[1,] 42 42
[2,] 42 42
> a[2:3, 2:3] = b
> a
x y z
a 11 14 17
b 12 42 42
c 13 42 42
> a[2:3, 2:3] = c(1, 1, 1, 1) > a # This is not a surprise. x y z a 11 14 17 b 12 1 1 c 13 1 1 > a[2:3, 2:3] = c(1, 2, 3, 4, 5, 6) # This is also expected (modulo the 'multiple'.) Error in a[2:3, 2:3] = c(1, 2, 3, 4, 5, 6) : number of items to replace is not a multiple of replacement length > a[c(1, 2, 6, 7)] = c(111, 111, 111, 111) # Ok, understandable. > a x y z a 111 14 111 b 111 1 1 c 13 111 1 > a[c(1, 2, 12, 7)] = c(1, 1, 1, 1) > a # What?!? [1] 1 1 13 14 1 111 1 1 1 NA NA 1Ok, the last example shows how R manages assigning past the limit of the underlying vector.
make-array!)AT is introduced (and its counterpart, (SETF AT).)RHO) will look familiar to a R programmer, but it will not be the same. After all, is it Common Lisp, isn't it?AT Generic FunctionRHO 10 > (defvar qwerty "qwerty")
QWERTY
RHO 11 > (setf (at qwerty 3) #\R)
#\R
RHO 12 > qwerty
"qweRty"
RHO 13 > (at qwerty 4)
#\t
RHO 14 > (defvar a #2A((1 2 3) (4 5 6) (7 8 9)))
A
;;; ...
RHO 16 > (at a 1 1)
5
RHO 17 > (setf (at a 0 0) 42)
42
RHO 18 > a
#2A((42 2 3) (4 5 6) (7 8 9))
The generic function AT also works on structures and class instances.RHO 22 > (defstruct foo a s d)
FOO
RHO 23 > (defvar foo (make-foo :s 42))
FOO
RHO 24 > (at foo 'foo-s) ; In this case the accessor function FOO-S is invoked.
42
RHO 25 > (setf (at foo 'foo-d) "Food")
"Food"
RHO 26 > foo
#S(FOO :A NIL :S 42 :D "Food")
So far, so good. Now let's have some fun.RHO 28 > (setf rr (range 1 9)) ; This would be 'rr = 1:8' in R.
1 2 3 4 5 6 7 8
RHO 29 > (setf rv (vector 1 22/23 -3.2 42 5.8))
1 22/23 -3.2 42 5.8
RHO 30 > (setf rv2 (vector* (list 1 22/23 -3.2 42 5.8)
:names '(a b c d e)))
A B C D E
1 22/23 -3.2 42 5.8
The objects returned by VECTOR and VECTOR* (the full constructor) are wrappers around the underlying CL vectors. Their class is RHO:VECTOR. Note also that *PRINT-READABLY* is set to NIL, therefore, a "pretty printing" of the vectors is produced.RHO 37 > (setf ra (array (range 1 9) :dim '(3 3)))
[, 0] [, 1] [, 2]
[0, ] 1 2 3
[1, ] 4 5 6
[2, ] 7 8 1
RHO 38 > (at ra 1 1)
5
The function RANGE excludes the upper limit (following CL conventions), while the ARRAY constructors "recycles" the values passed to it (following R conventions). The value produces is pretty-printed, while its class is RHO:ARRAY. Indexing is 0-based, as in CL.RHO 3 > (setf rm (matrix '(1 1 2 0) :nrow 2 :ncol 2))
[, 0] [, 1]
[0, ] 1 1
[1, ] 2 0
RHO 4 > (at rm 0 1)
1
RHO 5 > (at rm 1 0)
2
RHORHO, modulo the Common Lisp background choices, bugs and unimplemented features; not many of the last kind.RHO 7 > (setf (dimension-names ra) '(("a" "b") ("x" "y")))
(("a" "b") ("x" "y"))
RHO 8 > ra
[, x] [, y] [, 2]
[a, ] 1 2 3
[b, ] 4 5 6
[2, ] 7 8 1
RHO 9 > (at ra 1 "y")
5
rb and use it as a value to set a sub-matrix of ra.RHO 13 > (setf rb (array 42 :dim '(2 2)))
[, 0] [, 1]
[0, ] 42 42
[1, ] 42 42
RHO 29 > (setf (at ra (vector 1 2) (vector 1 2)) rb)
#2A((42 42) (42 42))
RHO 15 > ra
[, x] [, y] [, 2]
[a, ] 1 2 3
[b, ] 4 42 42
[2, ] 7 42 42
As you can see, everything works as expected.rm; let's use it to set some elements of the array ra, according to the R "access-by-matrix" semantics.RHO 16 > rm [, 0] [, 1] [0, ] 1 1 [1, ] 2 0 RHO 24 > (type-of rm) MATRIX RHO 27 > (setf (at ra rm) 1024) 1024 RHO 28 > ra [, x] [, y] [, 2] [a, ] 1 2 3 [b, ] 4 1024 42 [2, ] 1024 42 42
RHO 29 > (setf (at ra #(1 2) #(1 2)) #(1 1 1 1)) #(1 1 1 1)
RHO 30 > ra
[, x] [, y] [, 2]
[a, ] 1 2 3
[b, ] 4 1 1
[2, ] 1024 1 1
RHO 42 > (setf (at ra #(1 2) #(1 2)) #(11 12 13 14 15))
#(11 12 13 14 15)
RHO 43 > ra
[, x] [, y] [, 2]
[a, ] 1 2 3
[b, ] 4 11 12
[2, ] 1024 13 14
Thanks to Masayuki Takagi, a not-so-obvious bug was fixed in the basic unification machinery of CL-UNIFICATION. This led to the addition of a couple of new utility functions and some other cleanups (hopefully).
The result should be in Quicklisp in the next round. Otherwise you can always clone/update/pull from the main repository.
I just revamped the CL-ENUMERATIONS library and API.
This was simply a nice cleanup of the previous library. The new documentation pages are, of course, generated with a little HEΛP, which also got some fine tuning to be able to generate doc pages from quite a variety of relatively "plain" doc-strings.
Hello there,
After a long time I finally had a few hours (sic!) to get back to actual hacking.
The main thing I did was to get myself re-accustomed with the new common-lisp.net infrastructure based on GitLab. This took some time to "realign" my repositories and getting my head wrapped around the way things work.
The result is that I went back to HEΛP to fix some tricky package issues, which are the result of wanting to be too cocky. Next I want to rework the web page layout in order to use the new HTML5 "semantic" tags.
After that, I will rework the documentation of my libraries and go on to "finish" a couple of other ones I have on the back burner.
Do I have too much on my lisping plate? :) :)
Cheers