Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: ROUND function (like TRUNC, FLOOR, etc...)

From: joel:neely:fedex at: 21-Feb-2002 9:31

Hi, Gabriele, Gabriele Santilli wrote:
> At 20.59 20/02/02, you wrote: > > >Functions have context. Does that mean that functions have objects? > >I wouldn't even have a problem with the statement "An object *is* > >A KIND OF context"... > > Well, I'd say that an OBJECT! is a wrapper around a CONTEXT! (which > is not exposed at the language level). >
Yes. But that wrapper is important (and a distinct idea) because REBOL can do things with objects that it doesn't appear (in general) to do with contexts.
> So the relationship between OBJECT! and CONTEXT! is rather tight; > you can view a OBJECT just as a "named context" if you want. > > But I think the reason for calling that function 'CONTEXT is > different. What is the simplest way to make a context? >
I can think of at least two simple ways:
>> use [counter] [
[ counter: 0 [ counter-reset: func [] [counter: 0] [ counter-up: func [] [counter: counter + 1] [ counter-down: func [] [counter: counter - 1] [ ]
>> counter-up
== 1
>> counter-up
== 2
>> counter-up
== 3
>> counter-up
== 4
>> counter-down
== 3
>> counter-down
== 2
>> counter-reset
== 0
>> countobj: make object! [
[ counter: 0 [ reset: func [] [counter: 0] [ up: func [] [counter: counter + 1] [ down: func [] [counter: counter - 1] [ ]
>> countobj/up
== 1
>> countobj/up
== 2
>> countobj/up
== 3
>> countobj/up
== 4
>> countobj/down
== 3
>> countobj/down
== 2
>> countobj/reset
== 0 It seems to me that these are equally simple to write and use as long as I only need one counter. What I gain by using an object instead of an anonymous scope is the ability to ask REBOL to "make me another" whenever I want. Another way to create a context (admittedly not quite as simple, but IMHO almost so) would be:
>> countfunc: func [/reset /up /down /local counter] [
[ counter: [0] [ if reset [change counter 0] [ if up [change counter counter/1 + 1] [ if down [change counter counter/1 - 1] [ counter/1 [ ]
>> countfunc/up
== 1
>> countfunc/up
== 2
>> countfunc/up
== 3
>> countfunc/up
== 4
>> countfunc/down
== 3
>> countfunc/down
== 2
>> countfunc/reset
== 0 Minor differences in simplicity aside, each of these cases creates a context and provides an interface to manipulate the state of that context. If REBOL were ever enhanced to expose contexts as first-class values, we might be able to do useful things like: 1) ask for the context of a specific word; 2) use a context as the explicit second argument to BIND; 3) use a context as the first argument of IN; 4) be able easily to ask whether two words belonged to the same context; 5) ask whether a specific word belonged to a specific context; and so on ... Making contexts first-class would be consistent with the REBOL approach that "everything is just a value" and would likely help de-mystify some of the more interesting things that REBOL can do that can't even be *said* in some other languages. A nice notation for (1) would be context some-word except that CONTEXT is now in use as a fairly trivial shortcut. We certainly couldn't say context? some-word because (at least if there's going to be some semblance of consistency) that would be asking whether SOME-WORD is a value of type CONTEXT! instead. That leaves us with something like get-context some-word which isn't too horrible, I guess, but the opportunity for confusion remains because the value of context some-block would be of OBJECT! and not CONTEXT! type. I know that I'm talking about hypotheticals when thinking about context as a first-class type. However, the *concept* of context seems to me very important in understanding how REBOL behaves. I simply think that anything that muddles up our terminology makes explaining/learning REBOL harder than necessary. -jn-