[Prev][Next][Index][Thread]

Re: small Q



On Tue, 8 Aug 2000, Bruce Hoult wrote:
> In article <398F745E.33516CAC@worldnet.att.net>, bstewart@bix.com 
> wrote:
> 
> > In fact, it occurs to me that a nice extension to the language would be
> > to allow more than two procedures in call-with-values - each procedure's
> > (values ..) form would supply arguements to the procedure to its right,
> > forming a kind of pipeline. 
> 
> In Dylan you need to do this as multiple statements [...]
> If it happens that you always want to use them all in the same order (as
> above) then you can use #rest and apply:
> 
> let (#rest results) = foo();
> let (#rest results) = apply(bar, results);
> let (#rest results) = apply(baz, results);

Since Dylan already has "compose" for functions, it would seem reasonable
to add a "compose-applied":

define function compose-applied
    (function-1 :: <function>, #rest more-functions)
 => (function-1-after-more :: <function>)
  local method binary-compose-applied (f1 :: <function>, f2 :: <function>)
   => (f1-then-f2 :: <function>)
    method (#rest args)
      let (#rest results-2) = apply(f2, args);
      apply(f1, results-2)
    end
  end binary-compose-applied;
  reduce(binary-compose-applied, function-1, more-functions)
end function compose-applied;

Then the above becomes

  compose-applied(baz, bar, foo)()

[Aside:
I like ML's ability to define new operators, which it uses to make
"o" (I read it as "of") the operator for composition:

  (baz o bar o foo)(x)  (* "baz of bar of foo of x" *)

We could use \^ for this in Dylan (with \+ for disjoin and \* for conjoin) 
but (a) compose is associative whereas \^ (for numbers) isn't; and (b) we
don't have enough operators for both compose and compose-applied (in ML
you could invent an "oo" operator, say).  Writing higher-order functions
like this can be really (visually) confusing if you're not used to it but
wonderfully concise when you get used to it.
]




Follow-Ups: References: