This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Series and gcc
- To: gcc at gcc dot gnu dot org, Igor Markov <imarkov at umich dot edu>
- Subject: Re: Series and gcc
- From: Barry Perlman <perlman at merl dot com>
- Date: Fri, 23 Feb 2001 14:23:50 -0500 (EST)
- Cc: Barry Perlman <perlman at merl dot com>
- References: <3A709891.9903F5EA@umich.edu>
Hi,
My name is Barry Perlman, and I am interested in the use of
"series" as an alternative programming technology. Series
are described in the paper by Dick Waters at:
http://www.acm.org/pubs/citations/journals/toplas/1991-13-1/p52-waters/
The fundamental idea of series is that data can be efficiently
processed in streams, rather that looping through data sets and
handling each element individually. The advantage of the stream model
is that code is easier to read and write. (Two simple examples are
provided at the end of this message.)
Comparison with the STL is natural, but there are some significant
differences. The STL provides aggregate functions ( transform(),
for_each() ) that hide loops, but they require the existence of
containers of data.
Series operate on aggregate data, but require no memory for the data.
Instead, each data element is calculated on an as-needed basis.
This has some implications:
- Series can be unbounded streams of data. Unlike istream, however, the
unbounded data can come from a generating function, not only from an
input device.
- Intermediate series are free, intermediate containers are expensive.
This allows series to be used with a much cleaner syntax than STL
containers.
Of course nothing comes for free, and the use of series data without
requiring any intermediate storage only works with certain restrictions.
The tradeoff is that the restrictions are not particularly onerous,
and indeed most currently written loops already conform. (STL, of course,
has no such restrictions, but that's because it requires memory for
the containers.)
Ultimately, what counts is the appearance of the code and the efficiency
of its execution. I believe series has a contribution to make here,
because the code looks simpler, but should compile to essentially the
same object as code written in vanilla C.
I have written a series library that works interpretively in Java
and have written most of such an interpretive version in C.
Dick and I would like to get a fully compiled version working in C,
but this requires more extensive knowledge of the compiler than I
possess.
Personally, I think this is pretty interesting work, and it has the
potential for changing the way many programs are written.
Is anyone on this list interested in helping to enhance gcc to be
able to support series?
Thanks,
Barry
=====================================================================
Example of series:
1. Suppose you wanted to sum up the squares of the odd integers between
1 and 100.
In vanilla C you could write something like this:
int sumSquareOdds (void) {
int i, j, sum = 0;
for (j = 1; j < 100; j++) {
if (j%2 == 1) {
i = j**2;
sum += i;
}
return sum;
}
Using series, you could write this:
sum = collectSum(mapFn(square, chooseIf(odd, intsTo100())));
2. Suppose you wanted to examine a file of floating point numbers,
take the sine and cosine of each number mod pi, and then add all
the sines and cosines together producing two sums.
In vanilla C you could write something like this (some details omitted):
float n, rad, s, c, sinTotal, cosTotal;
sinTotal = 0;
cosTotal = 0;
while (fscanf(fp, "%f", &n) == 1) {
rad = n%pi;
s = sin(rad);
c = cos(rad);
sinTotal += s;
cosTotal += c;
}
Using series, you could write this:
series rad;
rad = mapFn(modPi, scanFile());
sinTotal = collectSum(mapFn(sin, rad));
cosTotal = collectSum(mapFn(cos, rad));
Please note that the use of the intermediate series rad had no cost
here. If this code were written using STL, the creation of an intermediate
container to hold the rad values would consume memory, which could be
expensive if the set of values was large. Also, please note that there
is no necessity for mechanisms like compose() or bind2nd() when using
series.
=====================================================================