dev-serveez
[Top][All Lists]
Advanced

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

Re: [dev-serveez] help: guile


From: Martin Grabmueller
Subject: Re: [dev-serveez] help: guile
Date: Thu, 19 Jul 2001 21:01:44 +0200

> From: stefan <address@hidden>
> Date: Thu, 19 Jul 2001 17:59:52 +0200 (CEST)
> 
>  * How do I define local variables in procedures ?
>    In the following example I want `ret' to be local and not global.
> 
> =================================================================
> (define (echo-handle-request sock request len)
>   (define ret '())
>   (if (and (>= (binary-length request) 4) 
>            (= 0 (binary-search request "quit")))
>     (set! ret -1)
>     (begin
>       (svz:sock:print sock (binary-concat 
>         (string->binary "Echo: ") request))
>       (set! ret 0)))
>   ret)
> =================================================================

`ret' is already a local variable in this example.  A `define' inside
a lambda body is a so-called `internal define' and equivalent to a
`letrec' expression.  Which brings me to the normal way for defining
local variables: Scheme has three syntactic forms for creating local
variables: `let', `let*' and `letrec'.  They bind variables to values
for the scope of their bodies and are used like this:

(define (echo-handle-request sock request len)
  (let ((ret '()))
    (if (and (>= (binary-length request) 4)
             (= 0 (binary-search request "quit")))
        (set! ret -1)
        (begin
          (svz:sock:print sock (binary-concat
             (string->binary "Echo: ") request))
          (set! ret 0)))
     ret))

There are subtle semantic differences between the three versions of
`let', if you want to know the details, either consult the current
GRM, or ask specific questions.

> 
>  * How do I tell guile to return from a procedure with a certain value ?
>    Also in the given example it could be nice to break somewhere in the
>    procedure with a given return value. The only possibility I know until
>    now is to write the return value at the end of the procedure...

You can not only place the value at the end of the procedure, but at
all places which are in `tail position', that means all places which
are the last executed commands of a procedure invocation.  This can be
for example both branches of a `if' or all branches of a `cond'
expression.  For the example given above, this would look like the
following:

(define (echo-handle-request sock request len)
  (if (and (>= (binary-length request) 4)
           (= 0 (binary-search request "quit")))
        -1  
        (begin
          (svz:sock:print sock (binary-concat
             (string->binary "Echo: ") request))
          0)))

As you can see, only one of the two branches will be taken, and the
last value of the taken branch will be returned from the procedure,
because the `if' is already the last expression in the procedure body.

Another possibility is to use the procedure
`call-with-current-continuation'.  It is a control structure so
powerful that it can emulate most other control structures (return,
break, continue, throw etc.), but it's also so powerful that nearly
nobody understands all complications it brings :) I assume you don't
want to know about it, but for education's sake:


(define (echo-handle-request sock request len)
  (call-with-current-continuation
    (lambda (cont)
      (if (and (>= (binary-length request) 4)
               (= 0 (binary-search request "quit")))
          (cont -1)
          (begin
            (svz:sock:print sock (binary-concat
               (string->binary "Echo: ") request))
            (cont 0))))))

In this example, there is no advantage over the previous example, but
this would change if loops were involved.  You can think of `cont' in the
example above to work like `return' in C.

>  * Could you Martin please think of another (more complex) example for a
>    guile server if have some spare time ?

I'll have a look.  This Guile Server thingy sounds really cool, but I
have not yet have time to look into it unfortunately.

> I just implemented the SMOB I recently discussed with you. It is fairly
> documented under "Writing servers -> Guile servers". Would like you to
> have a look at... since you're the master of guile.

Will do.

HTH,
  'martin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]