Board index » delphi » BP7: Function of type function

BP7: Function of type function

I am writing a routine which should read a string like ' Sin(x)*x+x ' and
calculate the result. It works already, but the string is analysed
each time x is changed. So the routine is slow. I thought I should write
a preprocessor which analyses the string once and build a nested function
hierachy.

My problem: The following works fine:

type fun=function(x,y:real):real;

function test1(x,y:real):real;
begin
 test1:=x+y;
end;

function test2(x,y:real):real;
begin
 test2:=x-y;
end;

var a:fun;

begin
a:=test1;
writeln(a(3,4));
a:=test2;
writeln(a(3,4));
end.

Now the problem:

I tried to create a function analyse

....
 test2:=x-y;
end;

function analyse(ch:char):fun;  <------- Compiler will not compile this line
begin
 case ch of
 '+': analyse:=test1;
 '-': analyse:=test2;
 end;
end;

var a:fun;

begin
a:=analyse('+');
writeln(a(3,4))
a:=analyse('-');
writeln(a(3,4));
end.

What did I do wrong ?? Any help would be appreaciated.

          Frank Fetthauer phy...@aixrs1.hrz.uni-essen.de

 

Re:BP7: Function of type function


In article <407u3o$...@sun1.uni-essen.de>,
   phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) wrote:
Quote
>Path:

news.cfa.org!newsfeed.internetmci.com!EU.net!Germany.EU.net!zib-berlin.de!uni-
duisburg.de!sun1.hrz.uni-essen.de!aixrs1.hrz.uni-essen.de!phy580

Quote
>From: phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer)
>Newsgroups: comp.lang.pascal.borland
>Subject: BP7: Function of type function
>Date: 8 Aug 1995 14:59:04 GMT
>Organization: Universitaet Essen GH, Germany      
>Lines: 59
>Message-ID: <407u3o$...@sun1.uni-essen.de>
>NNTP-Posting-Host: aixrs1.hrz.uni-essen.de
>X-Newsreader: TIN [version 1.2 PL2]
>Status: N

>I am writing a routine which should read a string like ' Sin(x)*x+x ' and
>calculate the result. It works already, but the string is analysed
>each time x is changed. So the routine is slow. I thought I should write
>a preprocessor which analyses the string once and build a nested function
>hierachy.

> *** deleted section ***

>function analyse(ch:char):fun;  <------- Compiler will not compile this line

(*
  Passing of procedural variables can be tricky, but if you study
  it a while, it will all make sense (or you'll stop worrying about
  how it works, just that it works).

  Turbo Pascal won't/can't return typed procedures on the stack via
  a function, but it can return the procedure's address as a pointer
  (which is what you really want).

  A couple of general guidelines first...

   ..  .  .  .  ..  . .  ..  .  .  ..  .  .  ..  .  .  ..  .  .  ..  .  .

  * Be sure to declare any procedures that you pass arround like
    this as far or enable the {$F+} compiler directive.

   ..  .  .  .  ..  . .  ..  .  .  ..  .  .  ..  .  .  ..  .  .  ..  .  .

  * You should also have a typed pointer of these procedure/function types,
    or you must type cast the pointers when referenced.

       type
          fun = function(x,y:real):real;
          pfun = ^fun;

   ..  .  .  .  ..  . .  ..  .  .  ..  .  .  ..  .  .  ..  .  .  ..  .  .

  * Use the @ operator the retrieve the address of procedures you will pass.
    When you dereference a pointer of type pfun in a variable of type fun,
    use the @parameter of the LEFT side of the assignment - I love this
stuff!.

         var
            a : fun;
            b : pfun
         begin
            @a := b;
         end;

   ..  .  .  .  ..  . .  ..  .  .  ..  .  .  ..  .  .  ..  .  .  ..  .  .

   I hope that was somewhat understandable. If not, try the code below.

    *)

program test;

type
   fun = function(x,y:real):real;
   pfun = ^fun;  { pointer to a fun function }

function test1(x,y:real):real; far;
begin
   test1:=x+y;
end;

function test2(x,y:real):real; far;
begin
   test2:=x-y;
end;

function analyse(ch:char): pfun; { <------- Compiler *WILL* compile this line

Quote
}

begin
 case ch of
 '+': analyse:=@test1;
 '-': analyse:=@test2;
 end;
end;

var
   a : fun;
begin
   @a := analyse('+');   { @ assignment on LEFT side }
   writeln(a(3,4););
   @a := analyse('-');
   writeln(a(13,4));
end.

--------------------------------------------------------------------------
  .         .
   ..     ..
    ... ...        N O R T H W E S T   C O M P U T E R   S E R V I C E S
     .....         email: nwc...@thiefriverfalls.polaristel.net
    ... ...
   ..     ..       Commercial Programming Services/Support
  .         .

Re:BP7: Function of type function


In article <407u3o$...@sun1.uni-essen.de>, phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) says:

Quote
>type fun=function(x,y:real):real;
>function analyse(ch:char):fun;  <------- Compiler will not compile this line
>...
>What did I do wrong ?? Any help would be appreaciated.

Frank,

Look at the help for implementation of a function.
The only valid result types are ordinal, real, string, and pointer!

Regards,
Wouter.

Re:BP7: Function of type function


Frank Fetthauer (phy...@aixrs1.hrz.uni-essen.de) wants to compile the
following bit of code ('beautyfied' by me):

  type
    Fun = function(x,y : Real) : Real ,

  :
  :

  function Analyse(...) : Fun ;

This is not possible, since Pascal (not only Borland) only allows functions
to return 'simple types'.
My solution is to change the definition of Analyse to:

  procedure Analyse(... ;
                    var Resulting_function : Fun) ;

Good luck,
                     Jacob Sparre Andersen.
--
Try Ada 95 - The programming language of today
--
URL's: "mailto:spa...@cats.nbi.dk", "http://fys.ku.dk/~sparre".
--
"We need a plan to diverge from", Fesser

Re:BP7: Function of type function


Quote
phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) wrote:

(Snip)

Re:BP7: Function of type function


In article <409och$...@infoserv.rug.ac.be>, Wouter.Dobbela...@elis.rug.ac.be (Wouter Dobbelaere) says:
Quote

>In article <407u3o$...@sun1.uni-essen.de>, phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) says:

>>type fun=function(x,y:real):real;
>>function analyse(ch:char):fun;  <------- Compiler will not compile this line
>>...
>>What did I do wrong ?? Any help would be appreaciated.

>Frank,

>Look at the help for implementation of a function.
>The only valid result types are ordinal, real, string, and pointer!

>Regards,
>Wouter.

Frank & Wouter,
of course you can return the pointer to the function, ie

function analyse(ch:char) : pointer;
begin
   ...
   analyse := @power;
end;

var
   thisfunction : fun;
begin
....
   @thisfunction := analyse('^');
...

Hope this helps,
Jochen

________________________________________________________________________
joch...@berlin.snafu.de                        71270,3...@compuserve.com
joc...@cs.umd.edu                              enough already

Re:BP7: Function of type function


Quote
phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) wrote:
>type fun=function(x,y:real):real;
>Now the problem:
>I tried to create a function analyse
>function analyse(ch:char):fun;  <------- Compiler will not compile this line
>begin
> case ch of
> '+': analyse:=test1;
> '-': analyse:=test2;
> end;
>end;
>var a:fun;
>begin
>a:=analyse('+');
>writeln(a(3,4))
>a:=analyse('-');
>writeln(a(3,4));
>end.

Functions can only return 'simple types', Strings and Pointers. So
just declare a

type
  pfun = ^fun;

function analyse(ch:char):pfun;
begin
 case ch of
 '+': analyse:=@test1;
 '-': analyse:=@test2;
 end;
end;

var a:fun;

begin
a:=analyse('+')^;
writeln(a(3,4));
a:=analyse('-')^;
writeln(a(3,4));
end.

This will compile, and, I hope, even work.

Regards,
Mathias Block.

Re:BP7: Function of type function


Quote
In article <407u3o$...@sun1.uni-essen.de>, phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) writes:
> I am writing a routine which should read a string like ' Sin(x)*x+x ' and
> calculate the result. It works already, but the string is analysed
> each time x is changed. So the routine is slow. I thought I should write
> a preprocessor which analyses the string once and build a nested function
> hierachy.

> What did I do wrong ?? Any help would be appreaciated.

  The whole idea of a nested function hierarchy is not a good one. A much
  better way of doing this is to create an object structure, like this:

                                *
                               / \
                              /   \
                            Sin    +
                            /      /\
                           /      /  \
                          x      x    x

  Each x-object has a pointer (or something) to somewhere central where the
  current x value is stored. So you change the x value and then call Calculate
  in the uppermost object. This isn't too simple to write, but much easier than
  a function hierarchy. If you don't know anything about objects and don't
  want to learn: use records with a string for *,Sin,+ or x.

  I've written a shareware program that draws the graphs of mathematical
  functions that the user enters as strings. This means that the function has
  to be calculated say 200 times to show one graph. On my 386sx this is done in
  about a second, even for complex functions.

  --Lars M.

Re:BP7: Function of type function


Quote
>In article <407u3o$...@sun1.uni-essen.de>, phy...@aixrs1.hrz.uni-essen.de (Frank Fetthauer) writes:
>> I am writing a routine which should read a string like ' Sin(x)*x+x ' and
>> calculate the result. It works already, but the string is analysed
>> each time x is changed. So the routine is slow. I thought I should write
>> a preprocessor which analyses the string once and build a nested function
>> hierachy.

>> What did I do wrong ?? Any help would be appreaciated.
>  The whole idea of a nested function hierarchy is not a good one. A much
>  better way of doing this is to create an object structure, like this:

>                                *
>                               / \
>                          /    
>                            Sin    +
>                            /      /\
>                           /      /  \
>                          x      x    x
>  Each x-object has a pointer (or something) to somewhere central where the
>  current x value is stored. So you change the x value and then call
>  Calculate
>  in the uppermost object. This isn't too simple to write, but much
>  easier than
>  a function hierarchy. If you don't know anything about objects and don't
>  want to learn: use records with a string for *,Sin,+ or x.
>  I've written a shareware program that draws the graphs of mathematical
>  functions that the user enters as strings. This means that the
>  function has
>  to be calculated say 200 times to show one graph. On my 386sx this is
>  done in
>  about a second, even for complex functions.
>  --Lars M.

Dear Lars,

Using objects is exactly what I am doing. My early version written
several year ago ( Turbo Pascal 3.0 ) did analyse the string each time
the value x was changed. Now I am using an object with a pointer to a
function which has to be caluclated in the current hirachy and two
pointers to objects doing subcalculations. My posted question was the
partial problem of assigning the current function to the object.

Thanks for all the help I got. ( Before I received the first reply I found a
solution by myself. Not the most elegant one: I declared a global ( in
regard to the evaluation unit ) variable to pass the function out of the
subroutine ).

Using objects did speed up the calculation about a factor 100. If someone
is interested in the Borland Pascal 7.0 code he can mail me. I will send
him/her the source code of the unit.

Since I am going on vacation the reply can take about one or two weeks.

                Frank Fetthauer phy...@aixrs1.hrz.uni-essen.de

Other Threads