g+f: A tool to make a bit easier exporitng of FORTRAN libraries
into guile interpreter.
================================================================

Author.
=======
Valentin V. Kamyshenko
Dep. of Computer Modeling in Materials Science
Institute for Problems in Materials Science, NASU
252142, 3, Krzhyzhanovsky str., Kiev, Ukraine
e.mail: 	val@altavista.net

Why g+f?
========
I use guile mainly as an extension language for scientific
computations. Although my own last FORTRAN program was written in
1988 (now I use C), I prefer to use `standard' FORTRAN libraries
instead of C, because:
	1. There are currently available much more good scientific
libraries, written in FORTRAN, that in C (see, for example,
www.netlib.org).
	2. There are too many bad scientific libraries, written in
C or C++, and sometimes it takes too much time to understand, that
they are "bad":).
	3. It is easier (for me) to call FORTRAN routines in my
programs, because the interface to FORTRAN routines does not carry
the author's individuality :) - you always have the same very
limited number of types - char, int, float, double and
corresponding arrays - and may not expect any surprises and caveats
that are so usual in C++ programs.

The idea behind g+f was to have a simple tool for writing wrappers
of FORTRAN routine for guile as easily as possible => no time to
spend after reading (and understanding) the documentation
(usually, comments) to the routine; and that the corrsponding
guile function must be convenient to use. This means, in
particular, that when an argument of the guile routine is the
`uniform vector', there is no need to pass it's length as a
separate argument: that is, there must be a possibility to
transform the FORTRAN call
	foo(n, a)
to just
	foo(a)
in guile. 
Also, the working arrays, that are passed as aruments in "good
written" FORTRAN routines (because of the lack of the possibility
to allocate memory in FORTRAN) become unnecessary in their Guile
counterparts.

How to use it.
==============
The `g+f' file (with the default extension .g+f, .gPf, or .gpf)
describe a guile module and consists of a set of individual
descriptions for each routine.

In simple cases the description is smth. like:
	int foo(double a[n], int n) => foo(a);

More complex commented example below shows how to define matrix
multiplication in Guile, using the BLAS-3 FORTRAN function.
Note, that only a part of the full functionality of the FORTRAN 
routine will be used.

1. int zsymm(char side,char uplo, int m, int n,
2.	complex alpha, 
3.	complex a[mm], int lda,  
4.	complex b[ldbn], int ldb,
5.	complex beta, 
6.	complex c[ldcn], int ldc ) =>
7. blas:*zs(a,b) return(c) {
8.	side := 'l';
9	uplo := 'l';
10.	m := (int)sqrt(mm);
11.	lda := m;
12.	n := ldbn / m;
13.	ldb := n;
14.	(real alpha) := 1;
15.	(image alpha) := 0;
16.	(real beta) := 0;
17.	(image beta) := 0;
18.	ldc := m;
19.	ldcn := m*n;
20. }

Lines 1-6: FORTRAN routine, that returns in array `c' the
result of
	alpha * a*b + beta * c, if side=='l' or side=='L'
or
	alpha * b*a + beta * c, if side=='r' or side=='R'
`a' is a symmetrical matrix of the dimension m*m if side=='l', or
n*n, if side=='r'. `b' and `c' are the m*n matrices. Parameter
`uplo' defines which part of matrix `a' will be used as input to
the routine. `lda', `ldb' and `ldc' are the `row dimensions' of
corresponding matrices.

Line 6: `=>' shows the beginning of Guile function description.
Line 7: Arguments of the Guile routine must be present in the
	list of quasi-FORTRAN arguments.
	Scalar arguments are passed `by values', vector arguments
	are passed `by reference' (as in C).
Line 7: `return' statement may have one or more arguments, or may 
	be absent. More than one argument means that the function
	returns a list of corresponding values.
Line 7,20: `{...}' - (re)defenitions of constants and dimensions
	of temporary arrays. May be absent (`;' must be used 
	instead of `{}' in that case).
Lines 8-18: calculation and setting of constants.
	`:=' must be delimited by spaces
	Any C expression may be used between `:=' and `;'. It is 
	copied literary to the output.
Line 14-17: working with complex parameters. In RHS they may be
	referenced as `alpha._real_part' and `alpha._imag_part'.
Line 19: setting dimension of temporary array `c'.

When .g+f file is ready, the .c file is generated with the use
of `g+f.scm' script. For example:
	g+f.scm -m local/users/val/foo -o foo.c bar.g+f
After compilation of foo.c, the shared library libfoo.so (or 
libfoo.sa or whatever) must be present (for example) in
	/usr/local/share/guile/site/local/users/val
(I always use the dynamic loaded modules).

Random notes for myself (and, maybe, somebody else).
====================================================
* The easiest way to compile and install:
	libtool gcc -O3 -Wall -c foo.c
	libtool --mode=link g77 -o libfoo.la foo.lo \
		-rpath /usr/local/share/guile/site/local/users/val \
		-export-dynamic -llapack -lblas
	libtool install -s libfoo.la /usr/local/share/guile/site/local/users/val/
	
* Strings of variable lengths in FORTRAN are passed as two 
  arguments: the string itself as char*, and as an additional 
  integer parameter (to the end of the arguments list).

* Compile fortran libraries with the analog of gcc's -fno-automatic
  flag, if you are not 100% sure, what are you doing :) (that is,
  declare all variables in FORTRAN source to be `static').

* Do not forget about the `anti-mathematical' order of FORTRAN
  arrays ({1 2 3 0 4 5 0 0 6} is the low-triangle 3*3 matrix!).
	

Limitations.
============
* No support for functional arguments.
* No support for multi-dimensional arrays.
* Only uniform arrays may be used.
* No comments and/or documentation strings in .g+f files.
* No default values nor keys.

TODO.
=====
* Support for functional arguments.
* Automatic generation of .texi files.
* Use gh_lease.
* Multi-dimensional arrays.
* Default values.
* Passing each argument by value or by reference (possibility
  to choose).
* Using sllgen.scm (or flex/bison?).
* Is it possible to do all this "on fly" (guile-ffi)?

===
I will be very appreciated for any comments, questions and
suggestions.


--
Good Luck,
	V.K.
