[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Jul 15 10:13:37 1993 
Subject:function composition 
From:jonr (Jonathan Rowe) 
Volume-ID:930715.03 


We all know that

    (f <> g) (x)

is equivalent to

    g( f(x) )

but how about combining functions with more than one argument?

Let's have

     (( f & g ) <> h)( x, y )

equivalent to

    h( f(x), g(y) )

We can do this as follows (as long as pdnargs is not a fictitious quantity):


define 6 &( f1, f2 ) -> p;
    lvars f1 f2 p n1 n2;
    pdnargs( f1 ) -> n1;
    pdnargs( f2 ) -> n2;
    procedure();
        lvars a1 a2;
        conslist( n2 ) -> a2;
        conslist( n1 ) -> a1;
        explode( a1 ); f1();
        explode( a2 ); f2();
    endprocedure(%%) -> p;          ;;; see note below
    n1 + n2 -> pdnargs( p );
enddefine;

and then we can do nice things like:

: vars foo = [ [1 a] [2 b] [3 c] ];
: syssort( foo, hd & hd <> nonop > ) =>
** [[3 c] [2 b] [1 a]]


Note on bizarre use of closure:

If you set up a procedure which makes use of a lexical variable from an
enclosing scope, you can't update the pdnargs of it.

define foo(a) -> p;
    lvars a p;
    procedure();
        lvars x;
            -> x;
        [^x ^a];
    endprocedure -> p;
    1 -> pdnargs(p);
enddefine;

: foo(1) -> baz;

;;; MISHAP - CAN'T ALTER PDNARGS
;;; INVOLVING:  <procedure>
;;; DOING    :  pdnargs foo compile pop_setpop_compiler runproc runproc
     compile pop_setpop_compiler

Making it a closure cures this. I'll submit a bug report on this unless
someone quickly comes up with a very good reason for this behaviour.

( While I'm whinging, I also consider it highly undesireable for the error
trace to include the list "compile pop_setpop_compiler runproc runproc
compile pop_setpop_compiler" ).


Jon Rowe.