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