This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Series and gcc


> From: Barry Perlman <perlman@merl.com>
> Date: Fri, 23 Feb 2001 14:23:50 -0500 (EST)

> The STL provides aggregate functions ( transform(), for_each() )
> that hide loops, but they require the existence of containers of
> data.

Coding in C++ doesn't require the existance of containers of data.
Similar effects can be achieved.

> Series operate on aggregate data, but require no memory for the data.

C++ can operate on aggregate data and doesn't require memory for the
data.

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

In C++, one can have unbounded data come from a generating function as
well.  Further these can be pluged into anything that works with input
iterators, for example, if an input iterator is used.

> Personally, I think this is pretty interesting work, and it has the 
> potential for changing the way many programs are written.

I think one would need to see why C++ cannot be used to solve these
problems.  If C++ allows for the natural coding of things, why not use
it instead of inventing yet another new language construct.

> Example of series:

> 1. Suppose you wanted to sum up the squares of the odd integers between
>    1 and 100.

>    Using series, you could write this:

>      sum = collectSum(mapFn(square, chooseIf(odd, intsTo100())));

And in C++ one can write:

sum = collectSum(mapFn(square, chooseIf(odd, intsTo100())));

Just in case you wonder how:


#include <stdio.h>

class ints {
public:
  int max;
  int cur;
  ints(int i) : max(i), cur(0) { }
  ints(const ints &o) : max(o.max), cur(o.cur) {
  }
  ints& operator ++() {
    ++cur;
    return *this;
  }
  ints& operator ++(int i) {
    ++cur;
    return *this;
  }
  int operator *() {
    return cur;
  }
  operator bool () {
    return cur != max+1;
  }
  bool operator == (ints &o) {
    return (cur == o.cur && max == o.max);
  }
  bool operator != (ints &o) {
    return !(*this == o);
  }
};

class intsTo100 : public ints {
public:
  intsTo100() : ints(100) { }
};

template <class Series>
int collectSum(Series f) {
  int s = 0;
  while (f) {
    s += *f;
    ++f;
  }
  return s;
}

int square (int i) {
  return i*i;
}

bool odd(int i) {
  return i&1;
}

template <class C, class T>
class chooseIfC {
public:
  C cond;
  T series;
  void maybeskip() {
    if (series && ! cond(*series))
      ++series;
  }
  chooseIfC(C c, T s) : cond(c), series(s) {
    maybeskip();
  }
  void operator ++() {
    ++series;
    maybeskip();
  }
  operator bool () {
    return series;
  }
  int operator *() {
    return *series;
  }
};

template <class F, class T>
chooseIfC<F,T> chooseIf(F f, T t) {
  return chooseIfC<F,T>(f, t);
};

template <class F, class T>
class mapFnC {
public:
  T series;
  F fun;
  mapFnC(F f, T t) : fun(f), series(t) {
  }
  int operator *() {
    return fun(*series);
  }
  void operator ++() {
    ++series;
  }
  operator bool () {
    return series;
  }
};

template <class F, class T>
mapFnC<F,T> mapFn(F f, T t) {
  return mapFnC<F,T>(f, t);
}

int main() {
  int sum;
  sum = collectSum(mapFn(square, chooseIf(odd, intsTo100())));
  printf("sum is %d\n", sum);
}

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

>    Using series, you could write this:

>      series rad;
>      rad = mapFn(modPi, scanFile());
>      sinTotal = collectSum(mapFn(sin, rad));
>      cosTotal = collectSum(mapFn(cos, rad));

This syntax cannot be directly supported in C++, as either the file
must be read multiple times, or the contents of the file stored
(buffered bewteen the two collectSum calls, if we are to preserve the
users expectation that the first collectSum statement completes before
the second collectSum statement begins.  If we relax any of those
constraints, then it again is a simple enough to implement in C++.

I don't see anything terrible hard to do in C++ directly.  So the open
question is, why not just use C++?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]