ROUND function (like TRUNC, FLOOR, etc...)
[1/33] from: riusa:email:it at: 15-Feb-2002 13:55
I'm developing a program in my company, and an engineer asked how I
round the numbers... but... I discovered (I'm still a newbie...) Rebol
has only TO-INTEGER function to round a number! No FLOOR, no CEIL, no
TRUNC!
And... how about Banker's algorithm to round numbers?
I made some tests: TO-INTEGER only trunc the value, not round it:
1.3 -> 1
2.7 -> 2
3.5 -> 3
Why rebol has not a function to make the round more flexible?
Bye!
--
Prendi GRATIS l'email universale che... risparmia: http://www.email.it/f
Sponsor:
Andare in vacanza a Cortina o investire a lungo termine.
Con Domina Vacanze puoi fare le cose insieme, e risparmiando! Come?
Leggi qui.
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=270&d=15-2
[2/33] from: arolls:idatam:au at: 16-Feb-2002 0:22
You could try adding 0.5 first:
to-integer (0.5 + n)
Anton.
[3/33] from: greggirwin:mindspring at: 15-Feb-2002 10:53
<< I'm developing a program in my company, and an engineer asked how I
round the numbers... but... I discovered (I'm still a newbie...) Rebol
has only TO-INTEGER function to round a number! No FLOOR, no CEIL, no
TRUNC!
And... how about Banker's algorithm to round numbers? >>
Here's what I came up with, based on some of Ladislav's excellent work.
Watch for word-wrap.
; Ladislav Mecir, Gregg Irwin (minor adjustment)
mod: func [
{Compute a remainder.}
value1 [number! money! time!] {The dividend}
value2 [number! money! time!] {The divisor}
/euclid {Compute a non-negative remainder such that: a = qb + r and
r < b}
/local r
] [
either euclid [
either negative? r: value1 // value2 [r + abs value2] [r]
;-- Alternate implementation
;value1 // value2 + (value2: abs value2) // value2
][
value1 // value2
]
]
;-- Note: to-interval does mod-like rounding. If the interval you
; specify is not evenly divisble into your base, the result
; may not be what you expect. E.g. round/to-interval 133 30
; will round to 120, not 130, because 120 is an even multiple
; (read interval) of 30.
; Ladislav Mecir, Gregg Irwin
round: func [
{Rounds numeric value with refinements for what kind of rounding
you want performed, how many decimal places to round to, etc.}
value [number! money! time!] {The value to round}
/up {Round away from 0}
/floor {Round towards the next more negative digit}
/ceiling {Round towards the next more positive digit}
/truncate {Remaining digits are unchanged. (a.k.a. down)}
/places {The number of decimal places to keep}
pl [integer!]
/to-interval {Round to the nearest multiple of interval}
interval [number! money! time!]
/local
factor
][
;-- places and to-interval are redundant. E.g.:
; places 2 = to-interval .01
; to-interval is more flexible so I may dump places.
;-- This sets factor in one line, under 80 chars, but is it clearer?
;factor: either places [10 ** (- pl)][either to-interval
[interval][1]]
factor: either places [
10 ** (negate pl)
] [
either to-interval [interval] [1]
]
;-- We may set truncate, floor, or ceiling in this 'if block.
if not any [up floor ceiling truncate] [
;-- Default rounding is even. Should we take the specified
; decimal places into account when rounding? We do at the
; moment.
either (abs value // factor) <> (.5 * factor) [
value: (.5 * factor) + value
return value - mod/euclid value factor
] [
;-- If we get here, it means we're rounding off exactly
; .5 (at the final decimal position that is).
either even? value [
truncate: true
] [
either negative? value [floor: true][ceiling: true]
]
]
]
if up [either negative? value [floor: true][ceiling: true]]
if truncate [return value - (value // factor)]
if floor [return value - mod/euclid value factor]
if ceiling [return value + mod/euclid (negate value) factor]
]
HTH!
--Gregg
[4/33] from: riusa:email:it at: 18-Feb-2002 9:17
First of all: thank you for the function!
after this... a curiosity: why Rebol does not implement native round
functions?
======================================================
> << I'm developing a program in my company, and an engineer asked how I
> round the numbers... but... I discovered (I'm still a newbie...) Rebol
> has only TO-INTEGER function to round a number! No FLOOR, no CEIL, no
> TRUNC!
>
> And... how about Banker's algorithm to round numbers? >>
>
> Here's what I came up with, based on some of Ladislav's excellent
work.
> Watch for word-wrap.
> ; Ladislav Mecir, Gregg Irwin (minor adjustment)
<<quoted lines omitted: 3>>
> value2 [number! money! time!] {The divisor}
> /euclid {Compute a non-negative remainder such that: a = qb +
r and
> r < b}
> /local r
<<quoted lines omitted: 9>>
> ;-- Note: to-interval does mod-like rounding. If the interval you
> ; specify is not evenly divisble into your base, the
result
> ; may not be what you expect. E.g. round/to-interval 133
30
> ; will round to 120, not 130, because 120 is an even
multiple
> ; (read interval) of 30.
> ; Ladislav Mecir, Gregg Irwin
> round: func [
> {Rounds numeric value with refinements for what kind of
rounding
> you want performed, how many decimal places to round to,
etc.}
> value [number! money! time!] {The value to round}
> /up {Round away from 0}
<<quoted lines omitted: 12>>
> ; to-interval is more flexible so I may dump places.
> ;-- This sets factor in one line, under 80 chars, but is it
clearer?
> ;factor: either places [10 ** (- pl)][either to-interval
> [interval][1]]
<<quoted lines omitted: 7>>
> ;-- Default rounding is even. Should we take the specified
> ; decimal places into account when rounding? We do at
the
> ; moment.
> either (abs value // factor) <> (.5 * factor) [
> value: (.5 * factor) + value
> return value - mod/euclid value factor
> ] [
> ;-- If we get here, it means we're rounding off
exactly
> ; .5 (at the final decimal position that is).
> either even? value [
> truncate: true
> ] [
> either negative? value [floor: true][ceiling:
true]
> ]
> ]
> ]
> if up [either negative? value [floor: true][ceiling:
true]]
> if truncate [return value - (value // factor)]
> if floor [return value - mod/euclid value factor]
> if ceiling [return value + mod/euclid (negate value) factor]
> ]
>
> HTH!
>
> --Gregg
>
--
Prendi GRATIS l'email universale che... risparmia: http://www.email.it/f
Sponsor:
In questo momento di incertezza il modo sicuro per mandarti in vacanza lo abbiamo trovato
noi
Invitaci, e ti spiegheremo tutto.
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=271&d=18-2
[5/33] from: joel:neely:fedex at: 18-Feb-2002 6:38
BEWARE: Totally unofficial and unsanctioned opinion...
[riusa--email--it]
wrote:
> after this... a curiosity: why Rebol does not implement native round
> functions?
>
It appears to me that -- for the most part -- REBOL includes as native
functions only those things that are:
* critical to the core mission of REBOL, and
* impractical to implement effectively as mezzanines.
For example, parsing of strings is crucial to the concept of REBOL as
a "messaging language". I also suspect that a version of PARSE built
on top of explicit string/series manipulation via INDEX, NEXT, BACK,
etc. would be substantially slower (based on small experiments, but
no inside knowledge...)
In contrast, a rounding function is both trivial to write
round: func [x [decimal!]][
to-integer x + either x < 0 [-0.5][0.5]
]
and only occasionally needed that it misses on both of the criteria
mentioned above.
I realize that this is not a perfect model (given the existence of
such trivial shortcuts as CONTEXT, DOES, and HAS) but nobody's
perfect! ;-)
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[6/33] from: greggirwin:mindspring at: 18-Feb-2002 11:31
<< First of all: thank you for the function! >>
You're most welcome.
<< after this... a curiosity: why Rebol does not implement native round
functions? >>
You'd have to ask the RT folks about that. I know they work very hard to
keep the size of REBOL to a minimum and have to leave out a lot of things to
do that.
--Gregg
[7/33] from: chalz:earthlink at: 19-Feb-2002 1:19
> and only occasionally needed that it misses on both of the criteria
> mentioned above.
See, this is why we need distributed libraries, so people can submit to
math.rlib math functions, so we don't have to keep snooping for snippets, or
bugging RT with these issues. ;)
--Charles
[8/33] from: carl:cybercraft at: 19-Feb-2002 21:15
On 19-Feb-02, Joel Neely wrote:
> I realize that this is not a perfect model (given the existence of
> such trivial shortcuts as CONTEXT, DOES, and HAS) but nobody's
> perfect! ;-)
Trivial they may be, but I use 'does extensively and 'has often, and
so they're very useful shortcuts. I don't think I'd use a rounding
function in nearly every script like I do those two words.
--
Carl Read
[9/33] from: greggirwin:mindspring at: 19-Feb-2002 15:38
<< See, this is why we need distributed libraries, so people can submit to
math.rlib math functions, so we don't have to keep snooping for snippets, or
bugging RT with these issues. ;) >>
I've started on one, as have others like Maarten. I just hate publishing
things that aren't well thought out, but maybe I need to in order to get
feedback on the idea(s).
--Gregg
[10/33] from: chalz:earthlink at: 19-Feb-2002 23:32
I do not believe I've come across these three in my (highly limited)
studies. Is there a decent reference to them in "REBOL For Dummies", or one
of the online guides? (Preferrably a non-PDF guide.) Thanks.
--Charles
[11/33] from: chalz:earthlink at: 19-Feb-2002 23:49
I was going to say, "At least you're doing it. Let others know about it,
so they can give you feedback." I've heard very little "Ohmygod, that
SUCKS!" on this list. I don't think you'd receive it for your
all-benefitting efforts ;)
[12/33] from: greggirwin:mindspring at: 19-Feb-2002 22:52
Hi Charles,
CONTEXT is a shortcut for MAKE OBJECT!
>> o: context [a: 1 b: 2]
>> o/a
== 1
>> type? o
== object!
DOES is a shortcut for a function that takes no parameters and has no
locals.
>> my-add: does [1 + 2]
>> my-add
== 3
>> type? :my-add
== function!
HAS is a shortcur for a function that takes no parametersm, but does have
locals.
>> my-has-fn: has [local-var][local-var: now/time]
>> my-has-fn
== 22:52:24
>> local-var
** Script Error: local-var has no value
** Near: local-var
--Gregg
[13/33] from: carl:cybercraft at: 20-Feb-2002 19:39
On 20-Feb-02, Charles wrote:
> I do not believe I've come across these three in my (highly
> limited) studies. Is there a decent reference to them in "REBOL For
> Dummies", or one of the online guides? (Preferrably a non-PDF
> guide.) Thanks.
> --Charles
Others can have a go at 'context, but the other two are just function
shortcuts.
'does is for functions with no arguments or locals so instead of...
say-something: func [][print "something"]
you can have...
sat-something: does [print "something"]
while 'has is for functions with locals but no arguments. So instead
of this...
a: func [/local n][n: 10 do-something-using n]
you can have this...
a: has [n][n: 10 do-something-using n]
'does at least can save a lot of empty blocks apearing in your
scripts.
>> On 19-Feb-02, Joel Neely wrote:
>>> I realize that this is not a perfect model (given the existence
<<quoted lines omitted: 7>>
>> --
>> Carl Read
--
Carl Read
[14/33] from: al:bri:xtra at: 20-Feb-2002 19:46
Charles wrote:
> I do not believe I've come across these three in my (highly
limited)studies. Is there a decent reference to them in "REBOL For
Dummies", or one of the online guides? (Preferrably a non-PDF guide.)
Thanks.
>> source context
context: func [
"Defines a unique (underived) object."
blk [block!] "Object variables and values."
][
make object! blk
]
>> source does
does: func [
{A shortcut to define a function that has no arguments or locals.}
[catch]
body [block!] "The body block of the function"
][
throw-on-error [make function! [] body]
]
>> source has
has: func [
{A shortcut to define a function that has local variables but no
arguments.}
locals [block!]
body [block!]
][function [] locals body]
Andrew Martin
Re-Source...
ICQ: 26227169 http://valley.150m.com/
[15/33] from: carl:cybercraft at: 20-Feb-2002 21:24
On 20-Feb-02, Gregg Irwin wrote:
> Hi Charles,
> CONTEXT is a shortcut for MAKE OBJECT!
<<quoted lines omitted: 3>>
>>> type? o
> == object!
Well, okay, but for consistancy's sake, why wasn't 'to-object chosen
as its name?
--
Carl Read
[16/33] from: brett:codeconscious at: 20-Feb-2002 19:56
Hi,
> Well, okay, but for consistancy's sake, why wasn't 'to-object chosen
> as its name?
Hopefully the language designer will answer definitively, in between times
my purely subjective thoughts..
I'd sort of assumed that it was a forward looking change.
Also, CONTEXT has an educational quality about it - it reminds
me to think about where/when objects can be used. On this
basis I was glad for its introduction.
Regards,
Brett.
[17/33] from: joel:neely:fedex at: 20-Feb-2002 5:59
Hi, Charles,
Charles wrote:
> I do not believe I've come across these three in my (highly
> limited) studies. Is there a decent reference to them in
> "REBOL For Dummies"
>
RfD and RtOG both describe /Core 2.3, and at least two of these
were added later.
> , or one of the online guides? (Preferrably a non-PDF guide.)
>
Whether for good or ill, often HELP and SOURCE are the most
up-to-date information. The 2.5 release notes (HTML) at
http://www.rebol.com/docs/core25.html
mention CONTEXT in section 11 and HAS in section 13. I don't
recall at the moment when DOES was added. However...
"Use the SOURCE, Luke!" ;-)
Try copying the following into your interpreter window:
help context
source context
help does
source does
help has
source has
Too much thinking in c? ;-)
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[18/33] from: joel:neely:fedex at: 20-Feb-2002 7:00
Hi, Brett,
Not that I would ever dissent, but... ;-)
Brett Handley wrote:
> Hi,
> > Well, okay, but for consistancy's sake, why wasn't 'to-object
<<quoted lines omitted: 5>>
> me to think about where/when objects can be used. On this
> basis I was glad for its introduction.
The problem I had with the name is that the concept of "a context"
is very specific in REBOL, and that concept shows up in multiple
places. A function has a context, an object has a context, there
is a global context, and every application of USE creates a
context (at least AFAICT). That's a different idea from having
a "shortcut" for MAKE OBJECT! (especially as it saves only five
keystrokes...)
As I understand results from cognitive science and semantics, it
is harder to learn/understand two meanings for a word that are
almost-the-same-but-not-quite than two meanings which are really
different. Try having a conversation in which it's important to
know whether someone has said "a context" or "a CONTEXT", and I
think the point will be made.
I learned a very wise saying from my father:
Communicate not so that you CAN be understood, but so
that you MUST be understood.
(not that I always succeed... ;-)
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[19/33] from: brett:codeconscious at: 21-Feb-2002 1:16
Hi Joel,
> Not that I would ever dissent, but... ;-)
Hah! :)
> > Also, CONTEXT has an educational quality about it - it reminds
> > me to think about where/when objects can be used. On this
<<quoted lines omitted: 7>>
> a "shortcut" for MAKE OBJECT! (especially as it saves only five
> keystrokes...)
I suspect, but can't guarantee, that you are mixing contexts here! :)
IIRC Rebol tech. has not used
the word "context" in any official way except for this shortcut
function. That's rather marked I believe. I felt that this was a
deliberate decision as many of RT's decisions seem to be.
I have benefited though from the list participants using the word
context
when discussing their theories on how Rebol carries
out evaluation. Such discussion reasonably uses terms
from computing science. I can appreciate that such discussion
becomes more difficult when a term of the discussed language
has the same name.
So the list has a concept they have called "context" and the
Rebol language has a function that RT has called "context".
Maybe the list should use the word "namespace" to identify
the concept underlying Rebol evaluation in order to avoid
confusion :)
Also, I don't think that a shortcut should be judged soley on
the number of keystrokes saved.
I'm not really trying to defend the decision, more to explain
why I not that fussed. I think your points are valid
particularly to an audience wanting to discuss Rebol from
a computer science perspective (likely much of this list),
but the Rebol audience is larger.
Day to day my mind seems cursed to have to follow through
multiple contexts (not the CS term the English meaning) in
order to do my work or think about writing programs for
the net in Rebol. IMO contexts left compilers and started
swarming over applications particulary when HTML came
out and the internet was discovered. So one more context
is unlikely to twist my mind any more than it is. :)
Now I should go to bed because I'm obviously becoming
delirious :)
> Try having a conversation in which it's important to
> know whether someone has said "a context" or "a CONTEXT", and I
> think the point will be made.
A point well made.
> I learned a very wise saying from my father:
>
> Communicate not so that you CAN be understood, but so
> that you MUST be understood.
I like that.
Thanks,
Brett.
[20/33] from: lmecir:mbox:vol:cz at: 20-Feb-2002 17:37
Hi Brett,
good night to you.
My POV is as follows:
<<Joel>>
...an object has a context, ...
<</Joel>>
I think, that we can safely say: an object *is* a context. (which is the POV
presented by RT too)
<<Brett>>
...IIRC Rebol tech. has not used
the word "context" in any official way except for this shortcut
function...
<</Brett>>
I disagree, have a look at the Bind function. That function (at least for
me) officially defines the meaning of the word "context" in Rebol.
<<Brett>>
...Such discussion reasonably uses terms
from computing science...
<</Brett>>
As far as I am concerned, I am only trying to use the word "context" in the
sense represented by the Bind function, not trying to use any Computer
Science meaning. I would guess, that the Rebol meaning differs slightly from
the usual CS meaning. In this sense it may look unlucky to have one word
meaning a (Bind sense) context as well as a function making objects. It
would be perhaps more logical to call the function Make-context or some such
(?).
> Communicate not so that you CAN be understood, but so
> that you MUST be understood.
Am I approaching that state in this case?
Cheers
Ladislav
[21/33] from: joel:neely:fedex at: 20-Feb-2002 13:59
Hi, Ladislav
Ladislav Mecir wrote:
> <<Joel>>
> ...an object has a context, ...
> <</Joel>>
>
> I think, that we can safely say: an object *is* a context.
> (which is the POV presented by RT too)
>
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", but the discussion of BIND doesn't leave one (me
at least) with the impression that it is limited to objects (even if
the underlying implementation of objects and function contexts is
the same...
> > Communicate not so that you CAN be understood, but so
> > that you MUST be understood.
>
> Am I approaching that state in this case?
>
Clear as ever!
-jn-
[22/33] from: joel:neely:fedex at: 20-Feb-2002 13:53
Brett Handley wrote:
> >
> > The problem I had with the name is that the concept of "a context"
<<quoted lines omitted: 8>>
> believe. I felt that this was a deliberate decision as many of
> RT's decisions seem to be.
Again, I must disagree; the documentation available from the RT
web site *does* refer to the concept in many places.
The word "context" is used throughout the REBOL/Core User Guide,
specifically in the following sections.
http://www.rebol.com/docs/core23/rebolcore-2.html
http://www.rebol.com/docs/core23/rebolcore-4.html
http://www.rebol.com/docs/core23/rebolcore-9.html
http://www.rebol.com/docs/core23/rebolcore-10.html
http://www.rebol.com/docs/core23/rebolcore-15.html
http://www.rebol.com/docs/core23/rebolcore-16.html
http://www.rebol.com/docs/core23/rebolcore-17.html
It also appears in
http://www.rebol.com/core23notes.html
Additionally,
http://www.rebol.com/docs/dictionary.html
contains a section called "Context Functions" which includes
ALIAS, BIND, CONTEXT, GET, IN, SET, UNSET, USE, and VALUE?
The discussion of BIND makes heavy use of the idea of context, and
is the closest to exposing that concept of anywhere I know in the
REBOL documentation.
> I have benefited though from the list participants using the
> word "context" when discussing their theories on how Rebol
> carries out evaluation.
>
Those "theories" also include ideas gained from posts to the list
by RT employees.
> Such discussion reasonably uses terms from computing science.
>
But "context" is *not* the standard term from computing science;
it is specific to REBOL. I am accustomed to seeing the terms
environment
and "activation record" used in computing science
for what RT calls "context".
> So the list has a concept they have called "context" ...
>
Which came from RT.
-jn-
[23/33] from: chalz:earthlink at: 20-Feb-2002 23:52
Cool. Thanks, everyone, for the info! I've stuck the emails in my
'Snippets' folder for future reference.
--Charles
[24/33] from: chalz:earthlink at: 21-Feb-2002 0:09
> "Use the SOURCE, Luke!" ;-)
> Try copying the following into your interpreter window:
<<quoted lines omitted: 5>>
> source has
> Too much thinking in c? ;-)
Heh. Actually, it's things like..... okay, um... the language in help
makes more sense now than it did, so I can't figure out why I was confused.
*grimaces* But, I usually only get to use this phone line to which my
computer is connected after 10pm. And by the time I get to sorting through
the 70-some messages on the REBOL list, it's usually closer to midnight, and
my mind is befuddled. Maybe I should just download my mail and read it the
following afternoon :/ Now I feel dumb. Oh well. ;)
[25/33] from: brett:codeconscious at: 21-Feb-2002 18:35
Hmm. The objective evidence indicates that I need to re-read the doc because
I've obviously forgotten it (or never learnt it well the first time). I
think I've gone through the cycle below and I am firmly at step 0 again.
0. Unconscious Incompetence
1. Conscious Incompetence
2. Conscious Competence
3. Unconscious Competence
4. --> 0.
Brett.
[26/33] from: g:santilli:tiscalinet:it at: 20-Feb-2002 23:55
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", but the discussion of BIND doesn't leave one (me
Well, I'd say that an OBJECT! is a wrapper around a CONTEXT! (which is not
exposed at the language level). 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?
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[27/33] from: lmecir:mbox:vol:cz at: 21-Feb-2002 11:29
<<Brett>>
...
Hmm. The objective evidence indicates that I need to re-read the doc because
I've obviously forgotten it (or never learnt it well the first time). I
think I've gone through the cycle below and I am firmly at step 0 again.
0. Unconscious Incompetence
1. Conscious Incompetence
2. Conscious Competence
3. Unconscious Competence
4. --> 0.
Brett.
<</Brett>>
<<Joel>>
...
> The word "context" is used throughout the REBOL/Core User Guide,
> specifically in the following sections.
<<quoted lines omitted: 14>>
> is the closest to exposing that concept of anywhere I know in the
> REBOL documentation.
...snip
> But "context" is *not* the standard term from computing science;
> it is specific to REBOL. I am accustomed to seeing the terms
> "environment" and "activation record" used in computing science
> for what RT calls "context".
>
<</Joel>>
Context
looks like being mixed with "scope" in the documentation. It might
be useful to discern them.
Cheers
Ladislav
[28/33] 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-
[29/33] from: joel:neely:fedex at: 21-Feb-2002 9:47
Hi, Ladislav,
Ladislav Mecir wrote:
> "Context" looks like being mixed with "scope" in the documentation.
> It might be useful to discern them.
>
I agree.
-jn-
[30/33] from: g:santilli:tiscalinet:it at: 22-Feb-2002 23:54
At 16.31 21/02/02, Joel wrote:
>I can think of at least two simple ways:
>
> >> use [counter] [
[...]
This does not give you a direct reference to the context; you'll need to
reference it indirectly via a bound word. (That might be less intuitive...)
It also requires you to know the "local words" in advance.
>It seems to me that these are equally simple to write and use as long
The differences are very minor, but IMHO they justify the choice of MAKE OBJECT! versus
USE for CONTEXT.
>Minor differences in simplicity aside, each of these cases creates
>a context and provides an interface to manipulate the state of that
>context.
So, if you were to write a mezzanine to create a context, which would you
choose? Objects look like the most obvious choice IMHO...
>1) ask for the context of a specific word;
That would be useful, but mainly only if you were able to ask CONTEXT! what
other words it has, and things like these; i.e. only if it behaved like
OBJECT!. (Which is like asking RT to turn every CONTEXT! into an OBJECT! ---
pretty ironic conclusion for a thread that started with "'CONTEXT is a
confusing name for a function that makes OBJECT!s". :)
>2) use a context as the explicit second argument to BIND;
If you already have a word bound to it... (Well, that said, I'd like to have
BIND accept at least OBJECT!s, to avoid that extra IN, but even more to
accept functions etc. to avoid all the magic needed to get to it...)
>4) be able easily to ask whether two words belonged to the
> same context;
That's a point. :)
>5) ask whether a specific word belonged to a specific context;
Two points. ;)
>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.
I agree here. (I second Ladislav in his desire to have all REBOL types as
first-class.)
>A nice notation for (1) would be
>
> context some-word
I'd say CONTEXT-OF, or GET/CONTEXT (this looks pretty consistent and clean
--- with GET you have the value, with GET/CONTEXT you have the context; you
could even replace BIND with SET/CONTEXT... :).
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[31/33] from: lmecir:mbox:vol:cz at: 23-Feb-2002 19:00
Hi Gabriele,
<<Joel>>
1) ask for the context of a specific word;
<</Joel>>
<<Gabriele>>
That would be useful, but mainly only if you were able to ask CONTEXT! what
other words it has, and things like these; i.e. only if it behaved like
OBJECT!. (Which is like asking RT to turn every CONTEXT! into an OBJECT! ---
pretty ironic conclusion for a thread that started with "'CONTEXT is a
confusing name for a function that makes OBJECT!s". :)
<</Gabriele>>
I am not missing such a function badly...
<<Joel>>
>2) use a context as the explicit second argument to BIND;
<</Joel>>
<<Gabriele>>
If you already have a word bound to it... (Well, that said, I'd like to have
BIND accept at least OBJECT!s, to avoid that extra IN, but even more to
accept functions etc. to avoid all the magic needed to get to it...)
<</Gabriele>>
Yes, I think, that there are no reasons why BIND shouldn't accept an object
or a function, or why IN shouldn't accept a function?
<<Joel>>
4) be able easily to ask whether two words belonged to the
same context;
<</Joel>>
I am quite satisfied with what I am able to do now.
<<Joel>>
>5) ask whether a specific word belonged to a specific context;
<</Joel>>
Not very important for me.
<<Joel>>
>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.
<</Joel>>
<<Gabriele>>
I agree here. (I second Ladislav in his desire to have all REBOL types as
first-class.)
<</Gabriele>>
What I really ask for is first class properties for all Rebol values (see
the example of ERROR! type values or UNSET! type value or circular blocks
regularly crashing the interpreter, etc.). I am not asking for a datatype
called CONTEXT!. (although some Rebol programmers might find that useful
...)
<<Joel>>
>A nice notation for (1) would be
>
> context some-word
<</Joel>>
<<Gabriele>>
I'd say CONTEXT-OF, or GET/CONTEXT (this looks pretty consistent and clean
--- with GET you have the value, with GET/CONTEXT you have the context; you
could even replace BIND with SET/CONTEXT... :).
<</Gabriele>>
I admit, that It might be useful sometimes...
Cheers
L
[32/33] from: joel:neely:fedex at: 23-Feb-2002 11:06
Hi, Gabriele,
Gabriele Santilli wrote:
> At 16.31 21/02/02, Joel wrote:
> >I can think of at least two simple ways:
<<quoted lines omitted: 7>>
> which would you choose? Objects look like the most obvious
> choice IMHO...
Well, perhaps I understood the original question. I took
create a context
to mean constructing an environment with
one or more words not in the global contxt, not in the sense
of obtaining a "direct reference to the context"; I think
we've both stated in various ways that REBOL doesn't really
give a way to access contexts (per se) directly.
As for your commeonts on the numbered list of things one
could do with a first-class context, perhaps I didn't express
sufficiently clearly that I considered them all to be inter-
related. For example...
> >1) ask for the context of a specific word;
>
> That would be useful, but mainly only if you were able to
> ask CONTEXT! what other words it has, and things like these;
> i.e. only if it behaved like OBJECT!...
>
No, sorry, I wasn't asking for object-like behavior.
> (Which is like asking RT to turn every CONTEXT! into an
> OBJECT! --- pretty ironic conclusion for a thread that
> started with "'CONTEXT is a confusing name for a function
> that makes OBJECT!s". :)
>
The very fact that I was unable to make the difference clear
in what I was asking for demonstrates (to me at least) that
the confusion/damage is already done.
> >2) use a context as the explicit second argument to BIND;
>
> If you already have a word bound to it... (Well, that said,
> I'd like to have BIND accept at least OBJECT!s, to avoid that
> extra IN, but even more to accept functions etc. to avoid all
> the magic needed to get to it...)
>
If contexts were first class, one *wouldn't* need a word that
is already bound to it. That was my whole point. Let's put
items (1) and (2) together and consider the following
(imaginary) bit of REBOL:
use [ini mini meini mo] [
ini: mini: meini: mo: none
;
; some functions that do interesting things, using
; those four "private" words to maintain state
;
immm-namespace: func [] [get-the-context-of ini]
]
Now I could say things like this:
a-context-var: immm-namespace
;
; time passes...
;
flarp a-context other-args...
where
flarp: func [ctxt [context!] ...] [
;
; and somewhere down inside FLARP or the body of a
; function that FLARP evaluates...
;
bind [ini] ctxt
; or
if equal? ctxt get-the-context-of word-ref [...]
; or
if defined-in-context ctxt some-word-ref [...]
;...
> >4) be able easily to ask whether two words belonged to the
> > same context;
<<quoted lines omitted: 8>>
> I agree here. (I second Ladislav in his desire to have all REBOL
> types as first-class.)
Being able to do (1) and keep the result, pass it as an argument,
or whatever else one does with a first-class value, provides a
simple way to do (4) and (5) in terms of the context itself,
rather than having to keep around some specific word within the
context.
Therefore, I'm puzzled that we agree on the value of (4), (5),
and the general issue of first-class-hood, and yet don't see
(1) and (2) alike...
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[33/33] from: g:santilli:tiscalinet:it at: 24-Feb-2002 12:10
At 18.06 23/02/02, you wrote:
>Well, perhaps I understood the original question. I took
>"create a context" to mean constructing an environment with
>one or more words not in the global contxt, not in the sense
>of obtaining a "direct reference to the context"; I think
I think both are important...
>we've both stated in various ways that REBOL doesn't really
>give a way to access contexts (per se) directly.
Yes. But objects are very close IMHO.
>As for your commeonts on the numbered list of things one
>could do with a first-class context, perhaps I didn't express
>sufficiently clearly that I considered them all to be inter-
>related. For example...
Yes, sorry I think that the one being unclear was me. I just think that 1
and 2 are not useful if not to be able to do 4 and 5.
[1]
>No, sorry, I wasn't asking for object-like behavior.
Then the CONTEXT! value is only useful for 4 and 5, IMHO.
>If contexts were first class, one *wouldn't* need a word that
>is already bound to it. That was my whole point. Let's put
<<quoted lines omitted: 8>>
> immm-namespace: func [] [get-the-context-of ini]
> ]
But you see that you've been using a word bound to the context to be able to
get the context. So imagine I just do this:
use [ini mini meini mo] [
ini: mini: meini: mo: none
; etc.
immm-namespace: func [] ['ini]
]
a-context-var: immm-namespace
; ...
flarp a-context-var other-args...
flarp: func [ctxt [word!] ...] [
; ...
bind [ini] ctxt
; ...
]
The only things I cannot do are 4 and 5.
>Being able to do (1) and keep the result, pass it as an argument,
>or whatever else one does with a first-class value, provides a
>simple way to do (4) and (5) in terms of the context itself,
>rather than having to keep around some specific word within the
>context.
Yes, sorry again if I've been unclear.
>Therefore, I'm puzzled that we agree on the value of (4), (5),
>and the general issue of first-class-hood, and yet don't see
>(1) and (2) alike...
:-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted
Librarian comment
the round function is supplied as standard in REBOL 1.3 and later.