[comp.sys.mac.programmer] Passing Fuctions

heddle@clas01.cebaf.gov (David Heddle) (05/01/91)

Dear Friends:

Can anybody supply an example of Think Pascal code wherein one
passes a function?  For example, suppose I want to write an
integration routine which accepts the integrand as an argument:


function Integrate(integrand:ProcPtr;
                    LowerLimit:real;
                    UpperLimit:real):real;


begin
end;


How do I implement a function that can be passed into "integrand"?
For simplicity, assume it is a real function of one real variable.
What I'd like to do is something like:

function ComplicatedFunction(x:real):real;

begin
end;

and then call via:

Result := Integrate(@ComplicatedFunction, 0.0, 1.0);

but it doesn't work. Is it possible that I must use assembly
language? If so, does anyone have an example I can cannibalize?

cheers,

dph

kurash@gile (Mark Valence) (05/01/91)

In article <1991Apr30.194745.623@murdoch.acc.Virginia.EDU> you write:
>Dear Friends:
>
>Can anybody supply an example of Think Pascal code wherein one
>passes a function?  For example, suppose I want to write an
>integration routine which accepts the integrand as an argument:
>
>
>function Integrate(integrand:ProcPtr;
>                    LowerLimit:real;
>                    UpperLimit:real):real;
>
>
>begin
>end;
>

Two ways:

1)   RTFM.

function Integrate( function integrand (r: Real): Real;
					LowerLimit: Real;
					UpperLimit: Real): Real;

begin
	...
	result := integrand(realNum);
	...
end;

function Complicated (r: Real): Real;
begin
	...
end;

begin
	...
	answer := Integrate (Complicated, llim, ulim);
	...
end.


>
>How do I implement a function that can be passed into "integrand"?
>For simplicity, assume it is a real function of one real variable.
>What I'd like to do is something like:
>
>function ComplicatedFunction(x:real):real;
>
>begin
>end;
>
>and then call via:
>
>Result := Integrate(@ComplicatedFunction, 0.0, 1.0);
>
>but it doesn't work. Is it possible that I must use assembly
>language? If so, does anyone have an example I can cannibalize?
>
>cheers,
>
>dph

2)  If you really want to use a proc pointer, you will need to write
a small inline procedure.  If you know assembly language (or even
better, machine language), then this won't be too hard.  In asm.,
something like:

function CallIntegrand (param: Real; pp: ProcPtr): Real;
inline
	$205F,	{MOVE.L	(SP)+, A0}
	$4E90;	{JSR	(A0)}

function Integrate (integrand: ProcPtr; llim, ulim: Real): Real;
begin
	...
	result := CallIntegrand(realNum, integrand);
	...
end;

begin
	...
	answer := Integrate(@Complicated, llim, ulim);
	...
end.

Same implementation of Complicated as above.

The great thing about that inline code is, the same two instructions
can be used for ANY procedure/function declaration.  I.e., for any
routine declaration:

	function CallFoobar(param1: Type1; ... paramN: TypeN; pp: ProcPtr): RetType;
	inline
		$... as above

(Foobar could also be a procedure).  The BAD thing about this method is
that there is no type checking/parameter list matching done by the
compiler.  You should really consider using the first method (no pun).

Hope that helps,

Mark.