An article published in C Vu magazine, December 2001, vol. 16, No. 6, pp. 36-37.
by Association of C & C++ Users (ACCU)

Member Experiences

collated by Francis Glassborow

Well actually this time all I have is one of my own. SoftIntegration kindly sent me a review copy of version 2 of their Ch Language Environment and here are my first impressions.

The Ch Language Environment Version 2.0

report by Francis Glassborow

The package sent to me was much more than most would get because it included not only a 600 page loose leaf user guide but release versions of the product for Windows (95/98/Me/2000 and NT4), Linux, Solaris and HP-UX. I think that means that the only widely used desktop OS that is not covered is Apple's. Before I go any further let me point you to www.SoftIntegration.com where you will find a wealth of material. Most importantly you will find downloadable evaluation version of the enterprise edition appropriate to your platform. The reason I give you this information here is to make it easy for you to find when you have a moment to give the product a test-drive (and hopefully, add your impressions in a future edition of C Vu)

The Basics
At its simplest Ch is an interpreter for extended version of C90. It allows you to type in C statements and they will be acted on immediately. It allows you to execute a file of C source code. Nothing particularly special with that. It seems fairly fast (for an interpreter) and the following small program takes about five minutes on my AMD Athlon 800 based machine. However look carefully at this source because it will give you some hints as to the simpler extensions that Ch provides.

#include <iostream.h>
#define upper 1000000
void printout(int primes[0:upper]){
     int newline = 0;
     int i;
     for(i=0; i<upper; i++){
          if(primes[i]){
               newline++;
               if(newline>10){
                    cout << "\n";
                    newline=0;
               }
               cout << primes[i] <<' ';
          }
      }
      cout << primes[upper];
      cout << primes[upper+1];
}
int main(){
	int primes[1:upper];
	int i=0;
	for(i=1; i<=upper; i++){
		primes[i] = i*2-1;
	}
	primes[1] = 0;
	int mark=3;
	do{
		for(i=mark*mark/2+1; i<=upper; i+=mark){
			primes[i]=0;
		}
		for(i=(mark+1)/2 + 1; i<=upper; i++){
			if(primes[i]){
				mark=primes[i];
				break;
			}
		}
	}while(mark*mark>upper); 
	printout(primes);
	return 0;
}

No, that first line is not an error. Ch supports features from C++. C++ like i/o, classes with public and private access but no inheritance. That is only a corner of the extensions, more about this in a moment. However even that bit greatly adds to the expressiveness available to the user.

Now move down a couple of lines and look at that function definition. Notice anything odd? Yes it allows me to specify exactly what shape array I intend to pass and what range of indexes are valid for it (in this case the array is locally indexed from 0 to upper - there is a limitation to this syntax in that the range must be given explicitly, constant expressions do not seem to work, i.e. 99 is fine, but 100-1 is not).

If you look down to my main() you will see that there I have declared my array as being [1:upper]. In other words its index range runs from 1 to upper, which is not the same. When I call printout later I get a warning about this but the program continues because there is a sensible, but imperfect, option available. Arrays are range checked if the interpreter knows the range (that was the reason for making that parameter the way it was rather than making it an int*) but when there is a mismatch as there is here you can still get beyond the end problems. If you look towards the end of printout you will see a couple of lines that use primes[upper] and primes[upper+1]. The latter generates a warning and the interpreter uses the value in the last actual element of the array. However we lied about the size of the array so the former case prints garbage.

The rest of the program is fairly close to Standard C, with a little C++ thrown in. It computes all the primes less than two million. It took about 15 seconds to do the computation and 20secs to display the results. Not lightening fast but pretty good. I increased the value of upper to ten million (so as to compute and display all primes less than twenty million) and it took about 150 seconds to compute them and three minutes to display them. When I get a moment I will move over to my machine that has 256 Mbytes of memory and see just when the system refuses to try through exhaustion of resources or otherwise. Note that I am already using over forty million bytes.

To pass arrays of different length and bounds to the function printout(), it can be defined as follows:

void printout(int primes[0:]){
        int newline = 0;
        int i;
        int num;
        num = (int)shape(primes);
        for(i=0; i<num; i++){
                if(primes[i]){
                        newline++;
                        if(newline>10){
                                cout << "\n";
                                newline=0;
                        }
                        cout << primes[i] <<' ';
                }
        }
        cout << primes[num];      // warning for array out of bounds
        cout << primes[num+1];    // warning for array out of bounds
}
The number of elements of the array passed can be obtained by the generic function shape() which returns a computational array with the shape of the passed array.

And More
Just a little program:

#include <iostream.h>
#include <array.h>
int main(){
	array complex A[3] = {complex(1,1), complex(2,3), complex(4,3)};
	array complex B[3] = A;
	cout << A << '\n';
	A *= 3;
	A[2] = 100;
	A -= B;
	cout << A;
	cout << log(A);
	cout << sin(A);
	return 0;
}

It does not do anything useful other than demonstrates that Ch supports arrays as first class objects and supports complex numbers. However for those working in some areas of numerics that is a massive gain.

And here is a third sampler:

#include <iostream.h>
#include <array.h>
int main(){
	array int A[3][2] ={{1,2}, {5,2}, {3,2}};
	array int B[2][3] = transpose(A);
	cout<< (A*B);
	cout << sin(A);
	return 0;
}
Yes, you are right, it supports full matrix arithmetic out of the box.

What Else?
Well I have already mentioned that it supports classes with member functions and access control. They also can have constructors and destructors. It also supports some of the new C99 features such as variable length arrays (and as we saw above, complex). Ch supports local functions as well.

That would already be pretty attractive to many of us. However it has strings as first class objects and adds a foreach keyword that allows iteration with string data in three forms:

foreach(token; expr1; expr2; expr3) 
        statement
foreach(token; expr1; expr2) 
        statement
foreach(token; expr1) 
        statement
token, expr1, expr2 and expr3 must all be of string type or pointer to char. For example, executing the code below
#include <stdio.h>
int main() {
        char *s;
        foreach(s;"abc 123 ABC"){
               printf("s = %s\n", s); 
        }
}

gives the following output:

s = abc
s = 123
s = ABC

Ch supports a substantial range of 2D and 3D plotting facilities, tools for numerical analysis and a great deal more.

For me, one of the great points in its favour is that I can start writing perfectly ordinary C as it was in the early part of the 90's. However when I want to satisfy my numerical interests I can just extend my use of Ch. I do not have to learn an entirely new language with subtly different semantics to one that I am used to.

Cost?
Well how much it costs will depend on how much of the product you want. There are a range of options depending on how much you want and who you are (there are reasonable but not brilliant student rates). Perhaps the biggest bargain is that offered to instructors at academic institutions where in exchange for buying a copy of the Professional Edition you get fifty licences. If I was teaching programming to engineering or science students I would look very closely at this product because the combination of Standard C (and close to the latest standard) with the substantial extensions that support the kind of thing such students would wish to do is close to ideal.

I think that if you are interested in scientific and engineering and want/need to do some programming as part of that interest this is a product you should at least know about so that you make a firm decision to adopt it or not. Give it a run, see if it meets your needs. The time it will save in programming mathematical problems will soon justify the cost. Of course you could always buy Mathematica but you know that isn't cheap either.