On 12 Mar 1999, Niels [ISO-8859-1] Möller wrote:

Hello all,

Now I have some time to comment this message. I am a bit overloaded
nowadays... :(

> This is doable, but highly inconvenient. So we should not have to do
> it, at least not by hand. To make this easier, it would be nice to
> write the control parts in a different language, and generate all
> hooks needed for the ayncronous machinery automatically. I.e. we'd
> like to program the thing as if we could call a function, and have the
> function call return later, and have all needed callbacks and
> continuation structures done someplace out of sight.

Yes, it is really a pain to code it this way.

> 
> To do this, primitive commands on the lsh machinery are still
> written in C. A command takes one argument, and returns one value
> (both represented as struct lsh_object *). A command is an object with
> a method
> 
>   struct lsh_object *call(struct command *self,
>                           struct lsh_object *argument,
>                           struct command_continuation *c)
> 
> It should start doing the operation (and return to the main loop), and
> make sure that when finished, the continuation c is invoked with the
> result of the operation. This is very similar to many of the existing
> lsh abstractions and callbacks.
> 
> But now we use a second language for combining these primitive
> commands to more complex commands. An example, relevant to tcp
> forwarding:
> 
>   (lambda (port connection)
>     (start-io (listen port connection)
>               (open-direct-tcp connection)))
> 
> Everything is executed from left to right. Functions really have only
> one argument; but a function that takes one argument and returns a new
> function accepting the next argument acts a lot like a function of two
> arguments. To be precise, (a b c) is a shorthand for ((a b) c) and
> (lambda (a b) c) is a shorthand for (lambda (a) (lambda (b) c)), but
> that is not very important now.

I don't fully understand the above description. (maybe because I don't
know LISP enough) what does "lambda" mean?

> These three primitives should be easy to implement using the existing
> lsh abstractions. (We need some queues in the channel and
> channel_table objects to keep track of pending requests, but that is
> quite simple).
> 
> I have extended the make_class program to process such expressions (I
> also changed the magic word from "CLASS" to "GABA" to make it more
> unique, and because this feature doesn't have much to do with OO):

What does GABA stand for ? 

> 
> /* GABA:
>    (expr
>      (name local_tcp_forward)
>      (globals
>         (start-io foo_start)
>         (listen foo_listen)
>         (open-direct-tcpip foo_open))
>      (expr (lambda (port connection)
>               (start-io (listen port connection)
>                         (open-direct-tcpip connection)))))
> */
> 
> (The foo_xxx symbols should be replaced with the names of the
> corresponding primitive commands). The make class script generates a
> function local_tcp_forward() which evaluates the given expression and
> returns its value, which is the more complex command. (This evaluation is
> (currently) done without any continuation stuff, so it will break if it
> needs to call any function that would block).
> 
> The current implementation transforms the expression into a very
> unreadable "combinator expression" using the S, K and I combinators;
> these combinators are implemented in C as primitive commands. The
> above translates to
> 
>   A(S2(A(S2(A(K1, S)), A(S2(A(K1, S2(A(K1, foo_start)))), A(S2(A(K1, 
>S2(foo_listen))), K)))), A(S2(A(K1, K)), foo_open));

This sounds chinese to me. What are those combinators? Or better I'll
download your cvs repository, and check your code.

> 
> This representation is very easy to compile to, and easy to execute.
> One nice feature is that all variables (in the example above, the
> variables are the formal parameters PORT and CONNECTION) are
> completely eliminated. It's main drawback is the size of the generated
> expressions, but I think it should be good enough for simple commands
> like this.
> 
> If it turns out to be too unwieldy or inefficient, it can be replaced
> without effecting the main lsh source code much. Reasonable
> alternatives include: A more optimized combinator translator, an
> explicit interpreter (with variables), and compilation directly to
> continuation passing style C code.
> 
> As you probably guessed by now, I think this approach is pretty cool
> ;) We'll see how it turns out.

I also think that this is very cool, since I had to code some of those
"continuation" structures for tcpforwarding, and I can tell it's a pain.

I am mirroring your cvs repo right now. I expect my tcpforwarding code to
be fully reorganized. I may not even recognize it...

--- Bazsi

Reply via email to