Re: A pragmatic solution to using arrays in picolisp

2015-02-17 Thread Mansur Mamkin
I support the last idea about that isn't necessary to touch core 
language, and if someone needs array support, it could be implemented 
the same way as e.g. ext and ht libraries.


Best regards,
Mansur

--- skipped ---

I don't think it's necessary to add arrays to the core language however,
given a sufficiently featured array library, picolisp's FFI interface
can be used to provide a nice abstraction above it.  This is similar to
how numeric arrays are used in Python with the numpy package.  Functions
are provided to copy data into and out of arrays from lists,
dictionaries, or files, and the actual operations on the arrays are
carried out by a native C library (and often third party libraries like
blas/lapack).  The arrays themselves are just opaque pointers to
corrected sized and memory ordered malloc'ed regions.

--- skipped ---
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A pragmatic solution to using arrays in picolisp

2015-02-17 Thread Michel Pelletier
Arrays are very useful for numeric computing over linked lists.  Contiguous
blocks of linear memory are much more efficient, improving on numeric
density, cache occupancy, and being able to take advantage of specific CPU
vector instructions.  For GPU based computing, contiguous arrays are
essential and linked lists are useless, they must be scanned in linear time
and no warp-level parallelization is possible.

I don't think it's necessary to add arrays to the core language however,
given a sufficiently featured array library, picolisp's FFI interface can
be used to provide a nice abstraction above it.  This is similar to how
numeric arrays are used in Python with the numpy package.  Functions are
provided to copy data into and out of arrays from lists, dictionaries, or
files, and the actual operations on the arrays are carried out by a native
C library (and often third party libraries like blas/lapack).  The arrays
themselves are just opaque pointers to corrected sized and memory ordered
malloc'ed regions.

Googling 'C array library' returns many interesting hits.  Judy arrays also
look very interesting: http://judy.sourceforge.net/

-Michel

On Tue, Feb 17, 2015 at 9:04 AM, Enrique Sánchez petenr...@gmail.com
wrote:

  But if you have such a redundant structure, where the array elements
  point into the list, you have a large overhead to build both the array
  and the list.

 I think that building trees take more overhead than executing a
 malloc and building a linear list. (And probably more cons cells).

  You can't do any changes (cons, insert, delete, reverse)
  without rebuilding the array. And - as before - you have to keep track
  of your arrays to know when to dispose them.

 There's no point in creating array helpers for small lists elements.
 These helpers are only useful for large lists.

 Most of us always use these big arrays as global, static (in the C
 sense), created at the beginning of a program, living during the whole
 lifetime of a program, and being disposed of manually at the end of
 the program, or automatically by the system at program end.  During
 their life, these arrays don't grow, the structure remains the same,
 because they have the nature of an array.

 Of course I could use the allocation and disposing of small arrays at
 many points in the source code with this system, as you fear, like C
 and C++ programmers do. But that is hell, I would not do that.  They
 do that because they don't have other means.

 So the allocation and disposing using malloc() and free(), are only
 made typically for a pair of big arrays at two well known points in
 the source code, and that's it.

 The following is a typical program showing the use of array helpers:

 (setq *Ram   (array (readFile 65536 ram.bin))  # memory array
 *PC0   # Program pointer
 *SP16384   # Stack pointer
 *Reg1 0  *Reg2 0  *Reg3 0  # general registers
 *Run   T )

 (while *Run
(setq *P (nth: *Ram *PC)) # random access
(execute *P) )

 [... here would be all the main code ...]

 (dispose *Ram) # optional
 (bye)


 For this kind of program, using trees to emulate raw memory array
 functionality seems convoluted, and I guess at least 10 times slower.
 Convoluted because of the emulation of a more primitive structure by
 means of a more complex one.

 The most important data structure in Picolisp, the cons cell, is
 nothing more than a array element, addressable by a pointer, that is
 just an array index. If I want to use Picolisp to do exploratory
 programming of computer interpreters, then having arrays seems
 natural.

  I'm still not convinced at all that accessing list elements by a numeric
  index is really needed, or at least justifies the effort. The mentioned
  'hash' mechanism is alread there, in constructs like the built-in
  'cache' function (see also the answer by Denis Fourt).

 If you consider that for building interpreters, emulating raw memory
 indexes with trees is appropiate, then I don't think so. I see it
 half way as convoluted as clogging the symbol table with symbols like
 'M1, 'M2 ... for doing that.

 Or may be you consider that trees are not appropiate for that kind of
 application, as is my opinion, and your solution is to resort to
 another computer language, as C, for doing that kind of programming.
 In this case I would understand your choice. I would like to be able
 to do that kind of low level programming in picolisp.

 The implementation effort would be about 20 lines of code.


 --
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe



Re: A pragmatic solution to using arrays in picolisp

2015-02-17 Thread Yiorgos Adamopoulos
On Tue, Feb 17, 2015 at 2:30 AM, Denis Fourt denis.p...@hotmail.com wrote:
 If I may provide an advice, in Purely Functional Data Structures from
 Chris Okasaki (Cambridge University Press, 1998), you will find various data
 structures based on lists which come close to regular arrays in term of
 access performance. This might be what you are looking for.

And if you do now want to start from the book, you may start with
Okasaki's PhD Thesis:

http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
-- 
If technology is your thing plan to die reading manuals --Gene Woolsey
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A pragmatic solution to using arrays in picolisp

2015-02-16 Thread Enrique Sánchez
I've changed my mind.

If we have a linear list for which we need fast access, we can do
another thing:  Instead of substituting the list with an array
structure, we can keep the list and use an array as a helper of the
original list.

That means that instead of storing the elements of a linear list in
the buckets of the array and getting rid of the list, we can store
the cdr's of the list and keep the list.

So we can get rid of the 'get: and 'set: functions, that are very
rigid, and break the Lisp programming style, as you said, and have only
a 'nth: accessor.

This has two advantages:

1. First (the big advantage) is that we retain all the usual list
functions at our disposal, restoring Lisp programming style.

2. The patch to the garbage collector gets simpler:

for (int i=1; i=current; i++) # loop thru each array
   if (void **p=arrays[i]) # only if array hasn't been disposed of
   markAll(p[1]); # we only need to traverse the first bucket

--
So, recapitulating we would have only 3 functions:

(setq *Ram (array (need 131072 0)))
(nth: *Ram 5)
(dispose *Ram)

This use of arrays as helpers associated with some lists, instead of
substitutes of lists, makes arrays even more segregated from the core
of the language. I think that makes them more acceptable.


-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A pragmatic solution to using arrays in picolisp

2015-02-16 Thread Enrique Sánchez
On 2015-02-15 02:29, Alex Gilding wrote:
 One cheap workaround for this would simply be to have a nogc function that
 temporarily disables the GC around a piece of code. If you're crunching data 
 in
 arrays, you probably want to isolate that operation in its own little
 high-performance block anyway.

I would add some code to the garbage collector, 
in order to keep the array items protected.

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


RE: A pragmatic solution to using arrays in picolisp

2015-02-16 Thread Denis Fourt
If I may provide an advice, in Purely Functional Data Structures from Chris 
Okasaki (Cambridge University Press, 1998), you will find various data 
structures based on lists which come close to regular arrays in term of access 
performance. This might be what you are looking for.
A simplified ML syntax is used in this book (because ML uses static types), 
some parts are dedicated to performance analysis and there are some interesting 
suggestions hidden in some of the exercices, if I remember well.
Regards,
Denis

 From: petenr...@gmail.com
 To: picolisp@software-lab.de
 Subject: Re: A pragmatic solution to using arrays in picolisp
 Date: Mon, 16 Feb 2015 20:19:40 +0100
 
 I've changed my mind.
 
 If we have a linear list for which we need fast access, we can do
 another thing:  Instead of substituting the list with an array
 structure, we can keep the list and use an array as a helper of the
 original list.
 
 That means that instead of storing the elements of a linear list in
 the buckets of the array and getting rid of the list, we can store
 the cdr's of the list and keep the list.
 
 So we can get rid of the 'get: and 'set: functions, that are very
 rigid, and break the Lisp programming style, as you said, and have only
 a 'nth: accessor.
 
 This has two advantages:
 
 1. First (the big advantage) is that we retain all the usual list
 functions at our disposal, restoring Lisp programming style.
 
 2. The patch to the garbage collector gets simpler:
 
 for (int i=1; i=current; i++) # loop thru each array
if (void **p=arrays[i]) # only if array hasn't been disposed of
markAll(p[1]); # we only need to traverse the first bucket
 
 --
 So, recapitulating we would have only 3 functions:
 
 (setq *Ram (array (need 131072 0)))
 (nth: *Ram 5)
 (dispose *Ram)
 
 This use of arrays as helpers associated with some lists, instead of
 substitutes of lists, makes arrays even more segregated from the core
 of the language. I think that makes them more acceptable.
 
 
 -- 
 UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
  

Re: A pragmatic solution to using arrays in picolisp

2015-02-16 Thread Alexander Burger
Hi Enrique,

 If we have a linear list for which we need fast access, we can do
 another thing:  Instead of substituting the list with an array
 structure, we can keep the list and use an array as a helper of the
 original list.

Do you think this is a good idea?

OK, you have a list then, where you can access the elements by index.

But if you have such a redundant structure, where the array elements
point into the list, you have a large overhead to build both the array
and the list. You can't do any changes (cons, insert, delete, reverse)
without rebuilding the array. And - as before - you have to keep track
of your arrays to know when to dispose them.

I'm still not convinced at all that accessing list elements by a numeric
index is really needed, or at least justifies the effort. The mentioned
'hash' mechanism is alread there, in constructs like the built-in
'cache' function (see also the answer by Denis Fourt).

♪♫ Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A pragmatic solution to using arrays in picolisp

2015-02-15 Thread Enrique Sánchez
 thanks for your ideas and elaborations!   


 
thank you for having created picolisp

 Personally, I must say that I am against using arrays
 in PicoLisp, and wrote it up a few years ago in:  
 
   
  
   http://picolisp.com/wiki/?arrayAbstinence

Yes, I have read it. I agree more or less with it.

 Can you give me an example where you need a list with 65536 elements, in  

 a Lisp program? Normally you would use some kind of tree to maintain  

 larger data structures, and you example of using helper list does 

 exactly that. 


If I had a 65536 elements array at my disposal, the first thing I
would do is to couple it to the cute 'hash picolisp function (whose
output is 1..65536) in order to have very good hash tables. (I could
use binary trees instead, hash tables are simpler and a little faster,
binary trees are more powerful).

If one is interested in building virtual machines in picolisp, I think
that one needs arrays, to emulate flat memory above all, but as well
to execute the machine instructions efficiently by table dispatching.

   

 Besides this, technically your implementation looks good. 

 
 It breaks the Lisp programming style though. You can't use the rich set   

 of list-manipulation functions on arrays. To do anything interesting, 

 you have to either fetch the whole array (or parts of it) into a list,

 or operate one by one by accessing individual elements. Very tedious.

I use lists for most tasks, as usual, it's only at very selected
places that I would reach for an array for random access.

 You have to take care of garbage collecting these arrays by yourself, 

 i.e. to know when a given array is no longer needed. and this 

 inconvenience alone destroys the possible advantage of an array.  


Given a function markAll(CELL*) that marks all cons-cells reachable
from a given cell, we can just insert the following code in the
garbage collector marking phase, so that the contents of all arrays
can be protected from being sweeped.

for (int i=1; i=current; i++) # thru each array
   if (void **p=arrays[i]) # only if array hasn't been disposed of
  for (int j=1; j=size(p); j++) # thru each bucket
 markAll(p[j]);

These 4 lines of code (plus the creation and disposing code) are the
price to pay (I think) for having arrays in picolisp.


Enrique.

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A pragmatic solution to using arrays in picolisp

2015-02-15 Thread Alexander Burger
Hi Enrique,

thanks for your ideas and elaborations!

Personally, I must say that I am against using arrays in PicoLisp, and
wrote it up a few years ago in:

   http://picolisp.com/wiki/?arrayAbstinence

Can you give me an example where you need a list with 65536 elements, in
a Lisp program? Normally you would use some kind of tree to maintain
larger data structures, and you example of using helper list does
exactly that.


Besides this, technically your implementation looks good.

It breaks the Lisp programming style though. You can't use the rich set
of list-manipulation functions on arrays. To do anything interesting,
you have to either fetch the whole array (or parts of it) into a list,
or operate one by one by accessing individual elements. Very tedious.

You have to take care of garbage collecting these arrays by yourself,
i.e. to know when a given array is no longer needed. and this
inconvenience alone destroys the possible advantage of an array.

In addition:

 2) I suppose that the garbage collector would have to keep track of
 all those CELL pointers in the array, that are outside of the reach of

Correct. Without that, you can store only short numbers (up to 60 bits)
in such an array. Data of any other type (bignums, symbols or lists)
will be thrown away by the garbage collector and your program will crash
horribly ;)

♪♫ Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A pragmatic solution to using arrays in picolisp

2015-02-14 Thread Alex Gilding
 2) I suppose that the garbage collector would have to keep track of
 all those CELL pointers in the array, that are outside of the reach of
 the picolisp symbol table. That would be the price to pay, I think
 a smaller price than adding another datatype.


One cheap workaround for this would simply be to have a nogc function
that temporarily disables the GC around a piece of code. If you're
crunching data in arrays, you probably want to isolate that operation in
its own little high-performance block anyway.