[Chicken-hackers] functors

2011-03-24 Thread Felix
Hello!


For quite a while I thought about how to implement functors,
i.e. modules that take modules as parameters. After several failed
attempts with macros that expand into modules I now tried a different
approach by directly integrating this into the core system. Tests pass
and things appear to work fine, but I'm unsure whether the approach is
sound or whether it s considered useful. This also adds a few
generalizations to the module system, and I present the concepts here
in case someone has suggestions or criticisms.


Interfaces:

It is possible to define /interfaces/ (named groups of exports),
for example:

(define-interface ARITHMETIC 
  (+ - * /))

(module foo (this that (interface: ARITHMETIC) the-other)
  ...)

The export list of a module may optionally be an interface name
so

(module bar ((interface: ARITHMETIC)) ...)

could also be written as

(module bar ARITHMETIC ...)

[This implies an interface may not be named *]

The syntax is a bit ugly, but I couldn't think of a better way, which
doesn't introduce ambiguity into the syntax. For symmetry, there is
now also (syntax: SYNTAXIDENTIFIER [IMPLICITEXPORT ...]), equivalent
to (SYNTAXIDENTIFIER [IMPLICITEXPORT ...]). This is not enforced in
the moment, but may be useful for documentation purposes.


Functors:

A /functor/ is a module that takes other modules as parameters,
binding the argument modules to temporary identifiers inside the body:

(functor (linear-search-functor (S FINITE-SET)) (search)
  (import scheme S)
  ...)

Inside linear-search-functor, S refers to some module that
satisfies the interface SEQUENCE, that is, which exports at least
the identifiers defined in the interface. The general syntax is:

(functor (FUNCTORNAME (ARGUMENT1 EXPORTLIST1) ...) FUNCTOREXPORTS BODY ...)

One uses a functor by /instantiating/ it:

(module my-search = (linear-search-functor some-key-value-store))
(import my-search)
(search ...)

This will expand into a module definition containing the body of the
functor linear-search-functor, and with imports of S redirected to
the module some-key-value-store. This could be simply done by syntax
that expands into a module, but functor-instantiation will check that
the argument modules satisfy the required exports. Also, the functor
itself will be put into a module, so an import-library can be
generated and installed for it.

I'm not sure if simply substituting the functor body in the
instantiation is a problem - exccessive use may result in code bloat,
which means functors should be restricted to the part that is truly
specialized to the argument modules. Standard ML compilers IMHO
generate only a single functor body, but it is very difficult to find
much information about functor implementation, apart from a lot of
type-theoretic mumbo jumbo. Scheme48 apparently has higher-order
modules, but only hints at them in the manual. Another difference is
that an import may refer to a procedure in one instantiation and to
syntax in another one. Restricting this looks like a loss of
expressivity to me, so full functor-body substitution seems to be the
only option. On the other hand, this allows the body to compile to
heavily specialized code if the imports refer to syntax, low-level
intrinsics or those core library procedures that the compiler is able
to optimize well (or for which type-information is available in the
forthcoming type-driven specialization optimization which is
currently in the works). I have seen heavily optimized libraries once
or twice, which basically where just a macro parameterized with
primitive operations that expands into a set of procedure
definitions. I remember a really badass red-black tree implementation
by Marc Feeley, but can't recall where I found it. It was written in
this style and would be a perfect use case for a functor.

Anyway, that's it.


cheers,
felix

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] functors

2011-03-24 Thread Felix
 One question: right now it is necessary to define an intermediary module
 and then another one to actually instantiate the functor like. in this
 example from the documentation:
 
   (module nums (multiply)
 (import scheme)
 (define (multiply x y) (* x y)))
 
   (module number-squarer = (squaring-functor nums))
 
 
 Maybe I didn't understand it all correctly but is there syntax for
 folding that into one definition? E.g. something like this:
 
 (module number-squarer ((instantiates: squaring-functor))
   (import scheme)
   (define (multiply x y) (* x y)))
 

squaring-functor takes any number of arguments, so your example
would probably an abbreviation for the common case of instantiating
a functor with a single argument module and providing the body of
that argument at the same step. Interesting! I'll ponder this.


cheers,
felix

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] functors

2011-03-24 Thread Thomas Chust
2011/3/24 Felix fe...@call-with-current-continuation.org:
 [...]
 (module foo (this that (interface: ARITHMETIC) the-other)
  ...)
 [...]

Hello,

just a small remark about the syntax: I find this use of keywords
rather unintuitive. I would either expect to be able to write
something like this:

  (module foo (bar baz #:interface ARITHMETIC boing) ...)

Or something like this:

  (module foo (bar baz (interface ARITHMETIC) boing) ...)

But a keyword in operator position is unusual and looks rather strange
to me.

Ciao,
Thomas


-- 
When C++ is your hammer, every problem looks like your thumb.

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] functors

2011-03-24 Thread Felix
 Hello,

Hi!

 
 just a small remark about the syntax: I find this use of keywords
 rather unintuitive. I would either expect to be able to write
 something like this:
 
   (module foo (bar baz #:interface ARITHMETIC boing) ...)
 
 Or something like this:
 
   (module foo (bar baz (interface ARITHMETIC) boing) ...)
 
 But a keyword in operator position is unusual and looks rather strange
 to me.

The problem is that the latter example is ambiguous - it is the same
as exporting a macro interface that implicitly exports the binding
ARITHMETIC. The former example doesn't also looks confusing to me,
but that is more a matter of taste. The use of a keyword is indeed not
everybodies taste, but I couldn't come up with a better syntax that
is both unambiguous and obvious.


cheers,
felix

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] functors

2011-03-24 Thread Felix
From: Moritz Heidkamp mor...@twoticketsplease.de
Subject: Re: [Chicken-hackers] functors
Date: Thu, 24 Mar 2011 12:12:50 +0100

 Maybe I didn't understand it all correctly but is there syntax for
 folding that into one definition? E.g. something like this:
 
 (module number-squarer ((instantiates: squaring-functor))
   (import scheme)
   (define (multiply x y) (* x y)))
 

One possible syntax would be:

(module number-squarer = squaring-functor
  (import scheme)
  ...)


cheers,
felix

___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-hackers