Arc Forumnew | comments | leaders | submitlogin
Arrays
10 points by jivestgarden 6283 days ago | 6 comments
Here is an example of an array library implemented entirely in arc . The arrays are not built-in data types, such as common Common Lisp (and Scheme) arrays, but rather settable, stateful functions, that take integer arguments.

For example

  arc> (= v (array 4 '(a b c d)))
  #<procedure>
makes a vector,

  arc> (v 1)
  b
gets an element, and

  arc> (array>list v)
  (array (4) (a b c d)) 
spits out the whole content. The rank of the array is in (v 'rank) while (v 'dim) gives dimension. Calling the array with no arguments gives basic info. Elements are set with the <- macro:

  arc> (<- (v 0) 0)
  0
  arc> (array>list v)
  (array (4) (0 b c d))
The <- is basically a wrapper for (v 'setter).

As an example of usage, take matrix inversion

  arc> (array>list (inv (array '(2 2) '((1 -1) (-1 4)))))
  (array (2 2) ((4/3 1/3) (1/3 1/3)))
The array implementation is at "http://folk.uio.no/jornv/arc/array.arc"

Basically I think using functions as arrays are a good thing since there are no accessors (a pain in the ...), and you do not need to know what's under the hood - it can be hash tables, row major arrays or column major arrays, all appearing similar.



2 points by nex3 6283 days ago | link

Why not use (= (v 0) 0) for setting an element?

-----

3 points by jivestgarden 6283 days ago | link

The = macro looks into a database of settable functions and there is no way to update the database at array creation. In order to use = I must either change let, with, and withs, or, introduce settable accessors, such as aref, but as I said, accesssors are not nice (I use arrays a lot in common lisp, and the accessors are driving me mad). The <- is actually a lot more general than =; it can set anything that returns its own setter, not just arrays. It is not suited for hash-tables, though, since they are likely to contain the key Xsetter.

-----

4 points by nex3 6283 days ago | link

Actually, with only a tiny modification of the core code and using tagging as a typing mechanism, you can set this sort of array in more or less the same way you set hashes:

  ; Added as line 454 of ac.scm:
  ((ar-tagged? fn) (ar-apply (ar-rep fn) args))

  ; Added to arc.arc
  (let old sref
    (def sref (com val ind)
      (if (no (isa com 'array)) (old com val ind)
        ((com 'setter) val ind))))

  ; Added at the end of your array code (or directly to make-array-wrapper)
  (let old make-array-wrapper
    (def make-array-wrapper (dim store)
      (annotate 'array (old dim store))))
If you don't want to patch that manually, I've added your array lib and my patches to the Anarkies.

-----

2 points by jivestgarden 6283 days ago | link

Patches are not a good thing since they breake the fundamental idea of arc: a language implmented in itself. Also you will soon run into trouble when introducing other array types, such are diagonal, bi-diagonal, tri-diagonal, upper-triangular, etc, and not to talk of foreign arrays, all requiring a new patch. (I can think 100 different array types, it should not require 100 patches.) However, it might be that a solution is to improve the arc type system itself, which seems over-simplified.

-----

3 points by nex3 6282 days ago | link

I disagree. If by "patch" you mean modifying the behavior of sref via Arc code, I think that's very much in tune with the fundamental principles of arc. I also think that working from basic principles - type, rep, and annotate (nee tag) - is a much more Arc-ish way to make a type system than having something deep and complex built in.

As for defining new accessors for every new type, it would be easy to modify sref to do a table like = does, and make defining accessors as easy as defset is now.

-----

1 point by jivestgarden 6282 days ago | link

I think we need to do both, both spawn functionality based on types, but also build more complex constructs at the the top of the simpler. The = and the <- do different things, the = depends on type, <- is a lot more general and depends on what the object itself returns. Arrays are higher order objects, and they depend on element-type, indexing, and, the physical store (currently only hash tables, but it should be raw memory segments for fast arrays) . So the true "type" of the array is a tuple of three (when i said 100 types I though about all the combinations. In reality there are infinitely many, but most them are not needed). In reality what I do in the library is to make a lexical type, that is created with the object, and is thrown away when its not needed anymore. However, a third possibility, is to make something like a template system. This is not easily done in CL, but should be possible in arc due to first class macros. How to actually do this, I do not know.

-----