some questions about context in r2

96 views
Skip to first unread message

pd

unread,
Feb 26, 2014, 6:57:09 AM2/26/14
to re...@googlegroups.com
Hello,

I have some doubts about my (mis)understanding of contexts and objects in R2

my first assumption is object and context are synonyms:

>> ob: make object! [a: 1 b: 2]
>> o: context [a: 1 b: 2]
>> probe o
make object! [
    a: 1
    b: 2
]
>> probe ob
make object! [
    a: 1
    b: 2
]
>> type? o
== object!
>> type? ob
== object!

but

>> equal? o ob
== false

shouldn't it be true?

I've read internally R2 stores contexts as two tables, one for words and the other for values, so you can ask for them:

o: context [a: 1 b: 2]
>> first o
== [self a b]
>> second o
== [make object! [
        a: 1
        b: 2
    ] 1 2]

in any way...

>> pick o 1
== [self a b]
>> pick o 2
== [make object! [
        a: 1
        b: 2
    ] 1 2]

but there's a third "table" (a block) which seems to be undocumented and this one is only accesible using third function

>> third o
== [a: 1 b: 2]

>> pick o 3
** Script Error: Out of range or past end
** Near: pick o 3

what is supposed to be this third block?

something similar seem to occur in functions but this time both third and pick perform well:

>> f: func [a] [print a]
>> first :f
== [a]
>> second :f
== [print a]
>> third :f
== [a]
>> pick :f 1
== [a]
>> pick :f 2
== [print a]
>> pick :f 3
== [a]

first block is params, second block is body but what does this third block represents in a function?

Another weird behaviour about contexts is dynamically adding code:

>> append third o [c: 3]
== [a: 1 b: 2 c: 3]

but...

>> first o
== [self a b]
>> second o
== [make object! [
        a: 1
        b: 2
    ] 1 2]
>> third o
== [a: 1 b: 2]

the append is missing!   same if appending to first o or second o

this do not occur using "common" blocks:

>> m: [a [b] c]
== [a [b] c]
>> append m 3
== [a [b] c 3]
>> m
== [a [b] c 3]
>> append second m 1
== [b 1]
>> m
== [a [b 1] c 3]

why is this?

About bindology in contexts, you are supposed to bind any block to any context, in particular you can bind a global context block to a local context:

>> a: context [ print: does [rebol/words/print "yeah!"] f: func[b] [do bind b 'print]]
>> a/f [print "hello"]
yeah!
== "hello"

so it must be possible to bind a local context block to the global context too, but my attempts were unsuccessful:

>> b: context [ b: [print "hello"] print: does [rebol/words/print "yeah!"] f: func[] [do bind b 'system]]
>> b/b
== [print "hello"]
>> do b/b
yeah!
== "hello"
>> b/f
hello
>> do b/b
hello

it seems I made it but:

>> equal? bind? 'system bind? in b 'b
== false
>> same? bind? in b 'f bind? in b 'b
== true

What is my error here?

thanks in advance

regards

Hostile Fork

unread,
Feb 26, 2014, 9:51:45 AM2/26/14
to re...@googlegroups.com
On Wednesday, February 26, 2014 6:57:09 AM UTC-5, pd wrote:
I have some doubts about my (mis)understanding of contexts and objects in R2

There's a lot of doubt to be had, as Rebol2 is not open source, and won't be.  I'd like to emphasize that these are "backwards-looking" questions, and I think it's better to look ahead to Rebol3 and Red.  With those, if you have a question, you can just go look at the code.  :-)

You have asked at *least* four separate questions here.  Each of which could wind up spawning comments, clarifications, and further discussion.  It would be FAR easier to talk about if they were posted individually as Q&A posts on StackOverflow:


So rather than ending up in a hard-to-follow intermingled discussion on a relatively-low-tech newsgroup, please consider creating an account there (if you don't already have one) and re-post each question I've labeled separately.  Then I'll re-post each answer separately, and people can chime in from there.


#### QUESTION 1: "Are OBJECT and CONTEXT synonyms in Rebol2?"

my first assumption is object and context are synonyms:

>> ob: make object! [a: 1 b: 2]
>> o: context [a: 1 b: 2]
>> probe o
make object! [
    a: 1
    b: 2
]
>> probe ob
make object! [
    a: 1
    b: 2
]
>> type? o
== object!
>> type? ob
== object!

but

>> equal? o ob
== false

You did a context-to-object comparison, but you didn't do an object-to-object comparison.  Would they test equal in Rebol2?

    >> equal? (make object! [a: 1]) (make object! [a: 1])
    == false

Nope; equal? does not work in Rebol 2 on objects.  For mysterious internal reasons we have no code for.  :-/  In Rebol3 they do test equal, however:

    >> equal? (make object! [a: 1]) (make object! [a: 1])
    == true

Contexts will also test as equal to their corresponding object:

    >> equal? (context [a: 1]) (object [a: 1])      
    == true

I first found out about the distinction between object and context in Rebol3 when I noticed object was a mezzanine that modified its input block.  This puzzled me.

    >> source object
    object: make function! [[
        "Defines a unique object."
        blk [block!] "Object words and values (modified)"
    ][
        make object! append blk none
    ]]

    >> source context
    context: make function! [[
        "Defines a unique object."
        blk [block!] "Object words and values (modified)"
    ][
        make object! blk
    ]]

It still puzzles me.  The obvious consequence is that you can make an object which has no terminal value, like "object [a: b: c:]" whereas with a context you would have to write "context [a: b: c: none]" to keep it from being an error.  I'm not sure why having that be an error case for context is so important, or alternately why having it not be an error case for object is so important.  It seems to me that "make object!" could just pick one internal expectation and stick to it--then get rid of the CONTEXT word and everyone is a little less confused.

But this isn't the place to discuss that.  Design discussions for Rebol3 and Red are open and spirited, so please join us in chat (if you haven't already under a different alias):


 
### QUESTION 2: "What is the undocumented block you get from THIRD on object/function in Rebol2?"

I've read internally R2 stores contexts as two tables, one for words and the other for values, so you can ask for them:

o: context [a: 1 b: 2]
>> first o
== [self a b]
>> second o
== [make object! [
        a: 1
        b: 2
    ] 1 2]

in any way...

>> pick o 1
== [self a b]
>> pick o 2
== [make object! [
        a: 1
        b: 2
    ] 1 2]

but there's a third "table" (a block) which seems to be undocumented and this one is only accessible using third function

>> third o
== [a: 1 b: 2]

>> pick o 3
** Script Error: Out of range or past end
** Near: pick o 3

what is supposed to be this third block?

It seems in Rebol2 that THIRD was not purely synonymous with PICK of 3, for some edge cases.  :-/  In Rebol3 this is no longer the case.

Your third value is what Rebol3 calls the BODY-OF.  What I can tell you about Rebol3 is that positional picking isn't available for objects or functions:

    >> pick object [a: 1 b: 2] 1
    ** Script error: pick does not allow object! for its aggregate argument

Instead you have WORDS-OF, VALUES-OF, and BODY-OF:

    >> words-of object [a: 1 b: 2]
    == [a b]

    >> values-of object [a: 1 b: 2]
    == [1 2]

    >> body-of object [a: 1 b: 2]
    == [
        a: 1
        b: 2
    ]

These have been backported to Rebol2 in R2/Forward, so you can (and should) use these functions in place of positional pick.
 
something similar seem to occur in functions but this time both third and pick perform well:

>> f: func [a] [print a]
>> first :f
== [a]
>> second :f
== [print a]
>> third :f
== [a]
>> pick :f 1
== [a]
>> pick :f 2
== [print a]
>> pick :f 3
== [a]

first block is params, second block is body but what does this third block represents in a function? 

Your example was too simple to notice that the distinction of the third was that it was the SPEC-OF, because your spec only contained words.  So SPEC-OF was equal to WORDS-OF.  Adding a type constraint to your spec reveals the difference.

    >> f: func [a [integer!]] [print a]
    >> first :f
    == [a]
    >> third :f
    == [a [integer!]]

Once again, Rebol2 via R2/Forward offers you WORDS-OF, SPEC-OF, and BODY-OF for functions.  And once again, avoid using positional picks for these properties.


### QUESTION 3: "Why doesn't dynamically adding code to object take effect in Rebol2?"

[A] weird behaviour about contexts is dynamically adding code:

When you ask for the body, spec, or words of a function... you receive a *copy* of the data.  So your append was not acting on the object itself... but a copy.

Rebol2 prohibits adding to objects themselves with append:

    >> append make object! [a: 1 b: 2] [c: 3]
    ** Script Error: append expected series argument of type: series port
    ** Near: append make object! [a: 1 b: 2] [c: 3]
 
But Rebol3 allows it:

    >> append make object! [a: 1 b: 2] [c: 3]
    == make object! [
        a: 1
        b: 2
        c: 3
    ]

I'm the wrong person to ask about the precise implications of allowing series-style modification on live objects.  But there you go.


### QUESTION 4: "How to bind local context block to global context in Rebol2?"

About bindology in contexts, you are supposed to bind any block to any context, in particular you can bind a global context block to a local context:

>> a: context [ print: does [rebol/words/print "yeah!"] f: func[b] [do bind b 'print]]
>> a/f [print "hello"]
yeah!
== "hello"

so it must be possible to bind a local context block to the global context too, but my attempts were unsuccessful:

>> b: context [ b: [print "hello"] print: does [rebol/words/print "yeah!"] f: func[] [do bind b 'system]]
>> b/b
== [print "hello"]
>> do b/b
yeah!
== "hello"
>> b/f
hello
>> do b/b
hello

it seems I made it but:

>> equal? bind? 'system bind? in b 'b
== false
>> same? bind? in b 'f bind? in b 'b
== true

What is my error here?

I'm not even going to look at this one, as it involves both Binding *and* Rebol2... I'll let someone else on StackOverflow field it.  :-)

So please repost these as StackOverflow questions--it is a much better medium!  You'll like it better!  Tag them with **rebol** and **rebol2**.

Best,
--Brian 

pd

unread,
Feb 26, 2014, 4:49:07 PM2/26/14
to re...@googlegroups.com
On Wed, Feb 26, 2014 at 3:51 PM, Hostile Fork <hosti...@gmail.com> wrote:

You have asked at *least* four separate questions here.  Each of which could wind up spawning comments, clarifications, and further discussion.  It would be FAR easier to talk about if they were posted individually as Q&A posts on StackOverflow:

So rather than ending up in a hard-to-follow intermingled discussion on a relatively-low-tech newsgroup, please consider creating an account there (if you don't already have one) and re-post each question I've labeled separately.  Then I'll re-post each answer separately, and people can chime in from there.

So please repost these as StackOverflow questions--it is a much better medium!  You'll like it better!  Tag them with **rebol** and **rebol2**.


ok, thanks for your replies and advices, I'm asking the four question (as you formulated them) in stackoverflow.
 
regards

Hostile Fork

unread,
Feb 26, 2014, 6:41:47 PM2/26/14
to re...@googlegroups.com

On Wednesday, February 26, 2014 4:49:07 PM UTC-5, pd wrote:
ok, thanks for your replies and advices, I'm asking the four question (as you formulated them) in stackoverflow.


Nice.  And a more modern means of doing Q&A, as I think you'll soon agree...

AND as a side-effect of learning the system, now you have enough points to speak in the chat!  Please do:


Best,
    \V/
    oo
     | 

pd

unread,
Feb 26, 2014, 7:17:49 PM2/26/14
to re...@googlegroups.com
On Thu, Feb 27, 2014 at 12:41 AM, Hostile Fork <hosti...@gmail.com> wrote:


Nice.  And a more modern means of doing Q&A, as I think you'll soon agree...

AND as a side-effect of learning the system, now you have enough points to speak in the chat!  Please do:



I've followed the link and created an account in trello.com but I'm not used to trello and don't understand it, the link brings me to a site for rebol in trello (I suppose that is the chat) I find very interesting but don't know how to add myself to the comunity (the chat), the only thing I could do was to suscribe and even that seems not to be recognized in my profile

thanks

Hostile Fork

unread,
Feb 26, 2014, 7:28:47 PM2/26/14
to re...@googlegroups.com
On Wednesday, February 26, 2014 7:17:49 PM UTC-5, pd wrote:

I've followed the link and created an account in trello.com but I'm not used to trello and don't understand it, the link brings me to a site for rebol in trello (I suppose that is the chat) I find very interesting but don't know how to add myself to the comunity (the chat), the only thing I could do was to suscribe and even that seems not to be recognized in my profile


Trello is not the chat; it's a separate service from StackOverflow.

I like to go through some indirection as "Rebol and Red" chat may not always use StackOverflow, but to give you a direct link if you were confused:

    http://chat.stackoverflow.com/rooms/291/rebol-and-red 

If you are logged into StackOverflow that link should work just fine, and we can discuss from there.

Best,
--Brian
Reply all
Reply to author
Forward
0 new messages