[EMAIL PROTECTED] wrote:
>[EMAIL PROTECTED] wrote:
>
> > Hello [EMAIL PROTECTED]!
> >
> > On 16-Giu-00, you wrote:
> >
> > j> Just a thought.... most of the "philosophical" questions /
> > j> discussions here about i.e. object lifecycle, scope, bindings,
> > j> etc. would be simply, formally, and workably solved if Rebol
> > j> had a true lexical scoping model. As it is, it's sort of the
> >
> > If you by lexical scoping intend that of C/C++ etc. (I'm not very
> > familiar with language theory terms), then I vote AGAINST that.
> > REBOL's static binding is FAR more powerful (and simple!) than
> > lexical scoping.
>
>Cf. Scheme. In particular, check out the flexibility you get in
>building i.e. custom object systems, dispatchers, etc. when you couple
>lexical scoping with first-class closures. (Which we have a base for,
>sort of, in blocks.)
I come from a strong Scheme background, and I've found that
REBOL is already well suited for applying Scheme techniques.
It already has first-class closures (func is a function, you
know), and is much better at the data-as-code trick than you
could ever manage in Scheme.
Lexical scoping is emulated quite well as an intended side
effect of REBOL's direct binding mechanisms. Direct binding
is much more powerful than that though, allowing easy access
to multiple lexical contexts without having to jump through
the hoops that Scheme requires.
The most detailed documentation for REBOL direct binding and
contexts that I've seen is an argument on the subject that
Gabriele and I had on this mailing list last fall. It is
probably in the mailing list archives at rebol.org with the
subject Contexts. If not, tell me and I'll try to bundle them
and send them to you.
Here's an example of a function in REBOL that uses its first
class closure capabilities. It's a replacement for Andrew's
include function that I wrote a while ago when I needed it
to be more robust. Sorry if it's a little long, but it was
easier to cut-and-paste a practical example than to come up
with a trivial example on the fly :)
One of the settings in the header is significant, so save
this script to a file and do it from there.
REBOL [
Title: "Script Requirements Manager"
Date: 18-May-2000
File: %require.r ; Used internally, see source for details.
Author: "Brian Hawley"
Email: [EMAIL PROTECTED]
Rights: "Copyright (C) Brian Hawley 2000, rights under LGPL"
Version: 0.1.0
Purpose: "Manages script dependencies and current versions"
Comment: trim/auto {
Require manages script dependencies in a way similar to
C/C++ #include but limiting inclusion to only a single time,
or optionally when the script has been modified. The list of
included scripts will be carried over if you do or require
%require.r again.
This script demonstrates a technique for implementing static
local variables, initialized using compose, and some other
fun tricks.
See http://www.bigfoot.com/~brian.hawley/rebol/ for updates.
}
Category: [script advanced]
]
unprotect 'require
require: func [
"Runs a script or scripts if not included yet, or perhaps if new."
[catch]
scripts [file! url! block!] "The script(s) required."
/yet? "Check when a script has been included (none if never)."
/new "Update if script has changed."
/list-scripts "Return a copy of the list of included scripts."
/local script-list stime iref itime e
] compose [
comment "The list of included scripts, modified in place."
script-list: (
; Carry over existing list of included scripts, if any
if not all [
; Check for an existing list
block? require: try [require/list-scripts []]
; Test the integrity of the list
even? length? require: head require
foreach [f d] require [
either all [
any [file? :f url? :f] date? :d
] [true] [break/value false]
]
] [require: []]
; Add the current script to the list
use [f d] [
f: clean-path system/script/header/file
if date? d: try [modified? f] [
change any [find/last require f tail require] reduce [f d]
]
]
; Return the list
reduce [require]
)
; Handle list query operations, if any
if yet? [
return either block? scripts [none] [
pick any [
find/last script-list clean-path scripts tail script-list
] 2
]
]
; Deal with the single case
if not block? scripts [scripts: reduce [scripts]]
; Include file/url list
foreach script scripts [
if all [
if any [file? :script url? :script] [script: clean-path script]
date? stime: try [modified? script]
any [
itime: none
none? iref: find/last script-list script
not date? itime: pick iref 2
all [new stime > itime]
]
] [
change any [iref tail script-list] reduce [copy script stime]
if error? set/any 'e try [do script] [
while [iref: find script-list script] [remove/part iref 2]
if date? itime [append script-list reduce [script itime]]
throw e
]
]
]
either list-scripts [return copy/deep script-list] [exit]
]
protect 'require