Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!agate!library.ucla.edu!csulb.edu!csus.edu!netcom.com!bakul
From: bakul@netcom.com (Bakul Shah)
Subject: Re: curried vs. tupled
Message-ID: <bakulD6BuIH.1FC@netcom.com>
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
References: <3jplaj$61k@cantaloupe.srv.cs.cmu.edu> <hbaker-1103950901230001@192.0.2.1> 	<BEVAN.95Mar21105145@lemur.cs.man.ac.uk> 	<3kn8rt$fg3@agate.berkeley.edu> <BEVAN.95Mar30095607@lemur.cs.man.ac.uk>
Date: Fri, 31 Mar 1995 22:59:04 GMT
Lines: 72
Sender: bakul@netcom4.netcom.com

bevan@cs.man.ac.uk (Stephen J Bevan) writes:

>In article <3kn8rt$fg3@agate.berkeley.edu> bh@anarres.CS.Berkeley.EDU (Brian Harvey) writes:
>   bevan@cs.man.ac.uk (Stephen J Bevan) writes:
>   |  (define (tree-insert <) (lambda (key value tree) ...))
>   |  (define (tree-lookup <) (lambda (key tree) ...))
>   |
>   |However, the ordering is still defined separately for both insert and
>   |lookup.  This is a) tedious (especially given that in a real tree code
>   |there is likely to be >> 2 functions) and b) makes it possible,
>   |though perhaps not likely, that different ordering functions are
>   |passed to insert and lookup.

>   (define (make-tree-type <)
>     (lambda (message)
>       (cond ((eq? message 'insert) (lambda (key value tree) ...))
>	     ((eq? message 'lookup) (lambda (key tree) ...))
>	     ...)))

>Unless the system optimises out the lookup (when possible) this
>approach is significantly slower than where a direct function call is
>made.  Does anyone know of an available Scheme system that does
>optimise the above type of code into direct calls?  If not, then I'd
>appreciate hearing about other solutions.

What is wrong with doing

  (define tree-type (make-tree-type <))
  (define tree-insert (tree-type 'insert)
  (define tree-lookup (tree-type 'lookup))

?  Now tree-insert, tree-lookup are directly bound to the
corresponding closures and they share the < function, which is
what you wanted.  I would make a couple of changes in Brian
Harvey's solution to make it slightly faster and cleaner:

  (define (make-tree-type <)
    (lambda (message)
      (case message
            ((lookup) (lambda (tree key) ...))
	    ((insert!) (lambda (tree key value) ...))
            ...)))

Another possibility is to return a closure for an object.
That is,

  (define tree-maker
    (lambda (<)
      (let ((tree <tree-representation>))
	(lambda (message)
	  (case message
	        ((lookup)  (lambda (key) ...))
	        ((insert!) (lambda (key value) ...))
	        ...)))))

You use it like

  (define tree0 (tree-maker <))
  (define tree1 (tree-maker <))
  (define tree0-insert! (tree0 'insert!))
  (define tree0-lookup  (tree0 'lookup))
  (tree0-insert 'a 1)
  ((tree1 'insert) 'b 2)

If you operate on the same tree many times, this may be faster.
A bigger advantage (IMHO) is that you've hidden the internal
structure of the tree.  Intuitively it feels like this should
provide better opportunities for optimization (because everything
that can mess with the internal structure of a tree is right
there, in the tree-maker function).

-- bakul
