Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

let-fluid implementation

5 views
Skip to first unread message

Isidor Zeuner

unread,
Jan 12, 2002, 1:49:27 PM1/12/02
to
Hi! is there a way to implement a portable version of let-fluid for any
r5rs-compliant scheme system?
Many thanks, Isidor Zeuner

Ray Dillinger

unread,
Jan 22, 2002, 12:56:02 AM1/22/02
to

That depends. What does let-fluid do?

Bear

Dorai Sitaram

unread,
Jan 22, 2002, 12:38:14 PM1/22/02
to
In article <3C4CFF91...@sonic.net>,

Unlike fluid-let, which temporarily sets arbitrary
lexical variables within its dynamic scope, let-fluid
temporarily grows a single dedicated global variable
holding the "fluid environment", a map from "fluid
variables" to their values. Fluid variables are
therefore not lexical variables, and are accessed with
something like (fluid x) and modified with something
like (set-fluid! x v). An R5RS implementation
should now readily suggest itself.

fluid-let imposes less syntax and can basically have
any lexical variable masquerade as a fluid.
let-fluid requires you specify fluid variables
explicitly, with the advantage that they are cleanly
different from "usual" variables.

(Great naming differentiation.)

--d


Ray Dillinger

unread,
Jan 24, 2002, 9:20:53 PM1/24/02
to

Dorai Sitaram wrote:
> Is there a way to implement a portable version of let-fluid in r5rs?

> Ray Dillinger <be...@sonic.net> wrote:
> > What does let-fluid do?

Dorai Sitaram wrote:
> Unlike fluid-let, which temporarily sets arbitrary
> lexical variables within its dynamic scope, let-fluid
> temporarily grows a single dedicated global variable
> holding the "fluid environment", a map from "fluid
> variables" to their values. Fluid variables are
> therefore not lexical variables, and are accessed with
> something like (fluid x) and modified with something
> like (set-fluid! x v). An R5RS implementation
> should now readily suggest itself.

Not yet, it hasn't. I'm still not understanding what
you mean when you use the words "fluid variables".
How are they different from ordinary variables?

> fluid-let imposes less syntax and can basically have
> any lexical variable masquerade as a fluid.
> let-fluid requires you specify fluid variables
> explicitly, with the advantage that they are cleanly
> different from "usual" variables.

By "lexical variables" do you mean variables with
Lexical Scope? This sort of implies that maybe you
are using "fluid variables" to mean variables with
Dynamic Scope?

Kent Dybvig once suggested this, but I cannot understand
how it works. It seems to me that you need to have the
syntax expand into some kind of definition at top-level
for the variable to remain in scope when you pass it
somewhere outside of lexical scope. And I don't see
this code doing that.


(define-syntax fluid-let
(syntax-rules ()
((fluid-let () e1 e2 ...)
(let () e1 e2 ...))
((fluid-let ((x v) binding ...) e1 e2 ...)
(let ((old-x x))
(set! x v)
(let ((result (fluid-let (binding ...) e1 e2 ...)))
(set! x old-x)
result)))))

Bear

Dorai Sitaram

unread,
Jan 25, 2002, 10:13:34 AM1/25/02
to
In article <3C50C0EA...@sonic.net>,

Ray Dillinger <be...@sonic.net> wrote:
>
>
>Dorai Sitaram wrote:
>> Is there a way to implement a portable version of let-fluid in r5rs?

?

>> Ray Dillinger <be...@sonic.net> wrote:
>> > What does let-fluid do?
>
>Dorai Sitaram wrote:
>> Unlike fluid-let, which temporarily sets arbitrary
>> lexical variables within its dynamic scope, let-fluid
>> temporarily grows a single dedicated global variable
>> holding the "fluid environment", a map from "fluid
>> variables" to their values. Fluid variables are
>> therefore not lexical variables, and are accessed with
>> something like (fluid x) and modified with something
>> like (set-fluid! x v). An R5RS implementation
>> should now readily suggest itself.
>
>Not yet, it hasn't. I'm still not understanding what
>you mean when you use the words "fluid variables".
>How are they different from ordinary variables?

They are different in that they are looked up in an
environment different from the lexical environments
where variables are usually looked up in Scheme. To
implement this in R5RS, you use a distinguished global
variable to hold the fluid environment, and fashion
syntax to look up and modify the fluid variables
in it. let-fluid extends this fluid environment, and
the extension is visible throughout its (let-fluid's)
dynamic scope.

Here's an R5RS impl (barring typos -- since this
is only elucidatory):

;*fluid-environment* is an alist of fluid variables

(define *fluid-environment* '())

;let-fluid introduces new fluid vars for use within
;its dynamic scope

(define-syntax let-fluid
(syntax-rules (*fluid-environment*)
((let-fluid ((x v) ...) e ...)
(let ((old-fluid-environment *fluid-environment*))
(set! *fluid-environment*
(append (list (cons 'x v) ...) *fluid-environment*))
(let ((result (begin e ...)))
(set! *fluid-environment* old-fluid-environment)
result)))))

;(fluid x) access the value of the fluid var x

(define-syntax fluid
(syntax-rules (*fluid-environment*)
((fluid x)
(cond ((assv 'x *fluid-environment*) => cdr)
(else (error 'fluid "~a not found" ',x))))))

;(set-fluid! x v) sets the value of
;the fluid var x to v

(define-syntax set-fluid!
(syntax-rules (*fluid-environment*)
((set-fluid! x v)
(cond ((assv 'x *fluid-environment*)
=> (lambda (c) (set-cdr! c v)))
(else (error 'set-fluid! "~a not found" ',x))))))

and perhaps a

(define-syntax define-fluid
(syntax-rules (*fluid-environment*)
((define-fluid x v)
(set! *fluid-environment*
(cons (cons 'x v) *fluid-environment*)))))

Example:

(define add-to-fluid-x
(lambda (y)
(+ y (fluid x))))

(let-fluid ((x 9))
(add-to-fluid-x 3))
=> 12 ;even though the accessing of the fluid var x
;takes place outside the let-fluid's lex scope

OK, I thought I was explaining how let-fluid
differed from fluid-let. From the above it looks like
you want to know the how of fluid-let?

In any case, the code just above is fluid-let, not the
let-fluid that I was going on about. fluid-let, unlike
let-fluid, side-effects existing lexical variables and
therefore doesn't need special syntax to access or
modify them. The side-effect it causes remains
in effect (modulo dynamically nested fluid-lets) as
long as the fluid-let is in effect (ie, its dynamic
scope).

--d

bri...@zipcon.net

unread,
Jan 25, 2002, 4:02:13 PM1/25/02
to
OK - dumb questions time.

What am I gong to use let-fluid OR fluid-let for ? I've never found
myself in a situation where I was looking around for something like
them.

Brian

--

"There is no right place for the dead to live."

-- Kai, last of the Brunnen-G

Jeffrey Siegal

unread,
Jan 25, 2002, 7:11:40 PM1/25/02
to
bri...@zipcon.net wrote:

> OK - dumb questions time.
>
> What am I gong to use let-fluid OR fluid-let for ? I've never found
> myself in a situation where I was looking around for something like
> them.

It can be used as a way to reduce the number of explicit parameters that
need to be passed around to convey state, without having to resort to
globals.

For example, (with-output-to-file "foo.txt" (lambda () (write "abc"))
could be viewed as equivalent to something like:

(let-fluid ((*standard-output* (open-output-file "foo.txt"))
(write "abc"))

A similar example would be a graphics system:

(let-fluid ((*foreground-color* (string->color "blue"))
(*line-width* 5))
(draw-line x1 y2 x2 y2))

bri...@zipcon.net

unread,
Jan 25, 2002, 10:22:52 PM1/25/02
to
>>>>> "Jeffrey" == Jeffrey Siegal <j...@quiotix.com> writes:

Jeffrey> bri...@zipcon.net wrote:
>> OK - dumb questions time.
>> What am I gong to use let-fluid OR fluid-let for ? I've never found
>> myself in a situation where I was looking around for something like
>> them.

Jeffrey> It can be used as a way to reduce the number of explicit parameters
Jeffrey> that need to be passed around to convey state, without having to
Jeffrey> resort to globals.

Jeffrey> For example, (with-output-to-file "foo.txt" (lambda () (write "abc"))
Jeffrey> could be viewed as equivalent to something like:

Jeffrey> (let-fluid ((*standard-output* (open-output-file "foo.txt"))
Jeffrey> (write "abc"))

Oh - I think I may have misunderstood the operation of it.

That is useful (duh).

Now I understand why so many scheme's seem to provide it.

0 new messages