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

Links ? Pointers ?

 [1/14] from: gchillemi::aliceposta::it at: 23-Aug-2009 12:00


Hello, I whish to ask a question to REBOL professional developers: If we have: A: [1 2 3] B: C: :A B and C would share the same list of A If we set A A: ["something"] B and C would point to the list [1 2 3] and A to ["something"] I am thinking about introducing a new notation for indirect links. Look at this: A: [1 2 3] B: C: ::A ;(please notice the double colon) B and C now would have a link to whatever A is pointing to. If we change A A: ["something" 1 2 3] Then PROBE B and PROBE C should return ["something" 1 2 3] It would be usefull for objects. When you create a new object you should be able to link values/functions/lists to the previous object or copy them. What about this ? Giuseppe Chillemi

 [2/14] from: carl:cybercraft at: 25-Aug-2009 12:41


Hi Giuseppe, On Sunday, 23-August-2009 at 12:00:52 Giuseppe Chillemi wrote,
>I am thinking about introducing a new notation for indirect links. Look at >this:
<<quoted lines omitted: 8>>
>PROBE C >should return ["something" 1 2 3]
To achieve that currently, I'd do something like this...
>> a: [1 2 3]
== [1 2 3]
>> b: c: :A
== [1 2 3]
>> probe a
[1 2 3] == [1 2 3]
>> probe b
[1 2 3] == [1 2 3]
>> insert a "something"
== [1 2 3]
>> probe a
["something" 1 2 3] == ["something" 1 2 3]
>> probe b
["something" 1 2 3] == ["something" 1 2 3] Is this not enough? -- Carl Read.

 [3/14] from: semseddinm:bircom at: 25-Aug-2009 9:23


> Hello, I whish to ask a question to REBOL professional developers: > If we have:
<<quoted lines omitted: 4>>
> A: ["something"] > B and C would point to the list [1 2 3] and A to ["something"]
This is because you created a new variable, not changed value(s) of A. If you use insert/replace/remove/clear and other series functions then A, B and C will point to the same variable.

 [4/14] from: izkata:g:mail at: 25-Aug-2009 2:09


He's talking about the possibility of multiple variables pointing at an immutable value:
>> X: make object! [Name: {Spock}] >> A: B: :X
Then, say, changing the object entirely:
>> X: make object! [Species: {Human}]
and having A and B now also point to the new object. Here's a way to simulate it:
>> X: reduce [make object! [Name: {Spock}]] >> A: B: X >> X/1: make object! [Species: {Human}]
Now, A/1 and B/1 also point at the new object. 2009/8/25 Semseddin Moldibi [ Bircom ] <semseddinm-bircom.com>:
>> >> Hello, I whish to ask a question to REBOL professional developers:
<<quoted lines omitted: 17>>
> To unsubscribe from the list, just send an email to > lists at rebol.com with unsubscribe as the subject.
-- =E5=A5=8F=E3=81=A7=E3=81=A6=E5=A4=A2

 [5/14] from: ryan:practicalproductivity at: 25-Aug-2009 9:08


A: [1 2 3]B: C: does [A] Personally I would rather not see real pointers. --Ryan PracticalProductivity.com 707-367-9230 On Tue, Aug 25, 2009 at 12:09 AM, Izkata <izkata-gmail.com> wrote:

 [6/14] from: gchillemi:aliceposta:it at: 26-Aug-2009 20:02


> He's talking about the possibility of multiple variables > pointing at an immutable value: > > >> X: make object! [Name: {Spock}] > >> A: B: :X
You are right !
> Then, say, changing the object entirely: > >> X: make object! [Species: {Human}] > and having A and B now also point to the new object.
You have interpreted correctly my message.
> Here's a way to simulate it: > >> X: reduce [make object! [Name: {Spock}]] > >> A: B: X > >> X/1: make object! [Species: {Human}] > Now, A/1 and B/1 also point at the new object.
I whish a more direct way able to be able to link to a function and have many object point to that function and reuse the code. Giuseppe Chillemi

 [7/14] from: carl:cybercraft at: 27-Aug-2009 17:53


On Wednesday, 26-August-2009 at 20:02:39 Giuseppe Chillemi wrote,
>> He's talking about the possibility of multiple variables >> pointing at an immutable value:
<<quoted lines omitted: 13>>
>I whish a more direct way able to be able to link to a function and have >many object point to that function and reuse the code.
Ok. Try ALIAS...
>> alias 'x "aa"
== aa
>> alias 'x "bb"
== bb
>> x: make object! [name: "Spock"] >> probe x
make object! [ name: "Spock" ]
>> probe aa
make object! [ name: "Spock" ]
>> probe bb
make object! [ name: "Spock" ]
>> aa: make object! [species: "human"] >> probe x
make object! [ species: "human" ]
>> probe bb
make object! [ species: "human" ]
>> probe aa
make object! [ species: "human" ] ALIAS only works if the words haven't already been used though. So this doesn't work...
>> alias 'bb "cc"
** Script Error: Alias word is already in use: cc ** Near: alias 'bb "cc" -- Carl Read.

 [8/14] from: ryan:practicalproductivity at: 27-Aug-2009 9:27


Interesting! And, I thought *alias* was a lame function this whole time. But one slight problem I have is that I can't actually figure out how this is useful yet. Can anyone offer any pointers? : ) --Ryan PracticalProductivity.com 707-367-9230 On Wed, Aug 26, 2009 at 10:53 PM, Carl Read <carl-cybercraft.co.nz> wrote:

 [9/14] from: moliad:g:mail at: 27-Aug-2009 22:00


there is one feature people often forget about rebol..... it has NO syntax. how do you represent/access a variable... hum... x: "some value" print x how do you represent an object.... hum... x: context [v: "some value"] print x how do you represent a function? ... hum x: func [][ "some value"] print x hum.... see any constant? however you define x... in any kind of data... you always USE it the same way... some types just have more accessors... like objects which have path access. now you realize that the function and the "variable" both print the same thing. just the string. this is your secret indirect reference weapon! you can always (almost) replace a value with a function and let the function do some "special trick" ;-) here, what you do is let the function point to some other value.... so if your code needed to do: a: b: "some value" you can ask function to act as a go between. the nice thing is that most of your code won't have to change because REBOL has so little syntax, only the assignment part will have to be updated... which is usually much more confined a task than access to a value everywhere in your app. functions create a context, and that context persists for each call.. so a function actually can store values, here we use a block without copying it at each eval... what some think is a limitation actually now is shown as the feature it is. :-) so let's say this is what your app should be: person: context [ uid: 666 name: "me" ] employee: context [ uid: user/uid title: "Workoholic" ] managers: [ ceo: employee/uid ] now as you know, changing the uid in person won't be reflected in employe or managers... so you're screwed! ---- Look at this modified version using function trick: person: context [ uid: func [/set value][data: [#[none]] either set [data/1: value][data/1]] name: "me" ] employee: context [ uid: get in person 'uid title: "Workoholic" ] managers: context [ ceo: get in employee 'uid ]
>> person/uid/set 222
== 222
>> managers/ceo
== 222
>>
this is one way to use the function hack, but there are many others, and they depend on the application itself. there are a few little details when using the hack, but usually, its pretty invisible. Hope this helps :-) -MAx

 [10/14] from: tim-johnsons:web at: 27-Aug-2009 18:28


* Maxim Olivier-Adlhoch <moliad-gmail.com> [090827 18:07]:
> so let's say this is what your app should be: > > person: context [ > uid: 666 > name: "me" > ] >
Hi Maxim: See employee/uid below:
> employee: context [ > uid: user/uid > title: "Workoholic" > ]
Should that be person/uid ? thanks tj
> managers: [ > ceo: employee/uid
<<quoted lines omitted: 28>>
> To unsubscribe from the list, just send an email to > lists at rebol.com with unsubscribe as the subject.
-- Tim tim-johnsons-web.com http://www.akwebsoft.com

 [11/14] from: moliad:gmai:l at: 31-Aug-2009 2:49


Hi tim, I did this on purpose, to show that they really are the same reference. they both point to the same function which stores the same value. actually, all three objects contain the exact same function, so I could set any of the three and any other would reflect the same value. :-) -MAx On Thu, Aug 27, 2009 at 10:28 PM, Tim Johnson<tim-johnsons-web.com> wrote:

 [12/14] from: gchillemi:aliceposta:it at: 3-Sep-2009 11:38


> person: context [ > uid: func [/set value][data: [#[none]] either set > [data/1: value][data/1]] > name: "me" > ]
.....
> >> person/uid/set 222 > == 222
<<quoted lines omitted: 5>>
> there are a few little details when using the hack, but > usually, its pretty invisible.
Hello Maxim, I have read your interesting post but I want the details. How it works ? What happens underneat (at interpeter and structure details) when you read the value of UID using another object like "managers/ceo" ? Also, I whis to know the notes you have omitted about this approach and eventually which other approach exists... There are a lot of things I still have to know about objects. Giuseppe Chillemi

 [13/14] from: moliad::gmail at: 14-Sep-2009 16:56


Hi Giuseppe, Sorry I didn't check the ML for a few days and yours slipped in the cracks! Here is a long and verbose explanation of most of what happens. If something isn't clear, ask a precise question and I'll do my best to explain it further. so here we go... saddle-in, this is going to be a big ride into the depths of some REBOL Guru level secrets. ;-) I'll start by reposting the original code snippet as a reference: person: context [ uid: func [/set value][data: [#[none]] either set [data/1: value][data/1]] name: "me" ] ....
>> person/uid/set 222
== 222
>> managers/ceo
== 222 about functions as values ------------------------------------ Basically, all rebol datatypes are evaluated when they are encountered by the interpreter. because functions require no more syntax than a normal variable, they can be silently "slipped-in" as if they WHERE a simple variable (cause in fact they are! :-). The 'UID function, when created by the 'FUNC function creates a context for itself. This context persists for as long as the function exists. If you notice the following: data: [#[none]] I assign a block! to 'DATA (I **DON'T** copy it at each function evaluation). This block is actually part of the 'UID function's context when the function is created. So it persists throughout that function's existence... This means every time 'UID is evaluated, 'DATA really is the same block, every time. When I simply ask for the value of 'UID (person/uid), the function is evaluated as normal, and it returns the first data of the persistent block. When I use the function's /SET refinement, I simply stores a new value into this persistent block: data/1: value As a side note, remember that you can use blocks as indirections, a bit like double referencing in C. Its a bit like saying get the first value pointed to by the block pointed to by 'DATA. (I prefer to use the term "refers" and "contains" respectively though). About sharing functions across objects: -------------------------------------------------------- Normally, when you make objects and use another object as the basis, all of the functions are copied to the new object bound and bound to it. This means that any words which are present in the body of the function will now refer to those found in that object, or to those in the arguments of the function. For example, if I had done this: employee: make person [ title: "Workaholic" ] And tried the function trick, the 'UID function inherited from 'PERSON would not be shared because 'EMPLOYEE would contain a New & independent copy of the 'UID function with its own persistent function context. The trick is to tell 'MAKE, what we we explicitly want the 'UID to be: ('CONTEXT is a mezzanine function which simply does: make object!) employee: context [ uid: get in person 'uid title: "Workaholic" ] Here you see that we tell 'EMPLOYEE to use the exact same function as the one in person. We 'GET it from the other object, and 'MAKE will assign it to the new object, at the location referred to by word 'UID in this new object. It won't be bound to the new 'EMPLOYEE object, and 'UID will actually be the same function as person/uid, NOT a copy of it. This is a VERY powerful feature of REBOL. From this point on, employee/uid and person/uid, being the same function, really share the same function context, so will set and get the same value. Function hack level 2 ----------------------------- You said you wanted other examples of the function trick... Here we'll go Fubar weird!!! Lets refer to values of **another** object using 'SELF... :-) ;------------------------ the code ------------------------- person: context [ full-name: ["luke" "skywalker"] first-name: func [/set val][either set [self/full-name/1: val][self/full-name/1]] last-name: func [/set val][either set [self/full-name/2: val][self/full-name/2]] ] employee: context [ first-name: get in person 'first-name last-name: get in person 'last-name full-name: func [][reduce [first-name last-name]] ] ;-------------------------------------------------------------- Within 'PERSON, we create a similar function-as-value trick, but this time, we use 'SELF to refer to the context (object!) the function is bound to, and then interact with another member of that object using path notation. 'EMPLOYEE, if you recognize the pattern explained earlier, simply borrows ('GETs) two of those functions-as-values and stores them in its own context... but notice a HUGE detail. 'SELF in these functions, still refers to the 'PERSON object, because the functions are still bound to 'PERSON !!! 'FULL-NAME within 'EMPLOYEE, is bound normally since it is created by 'EMPLOYEE 's make. Meaning, it will evaluate whatever value is referred to by the words 'FIRST-NAME and 'LAST-NAME within 'EMPLOYEE. BUT!!! These, as we just explained, are values taken from the other object, namely 'PERSON. So basically, you have an object calling methods from another object, directly. This is far beyond the level of control you can achieve with traditional inheritance and polymorphism, IMHO. You could go a step further and if you really wanted to go nuts with this, you could change the person which is assigned to the function-as-value referred by 'EMPLOYEE on the fly (but I won't go there for risk of loosing you for now ;-) All of this is AFAIK, a feature very few, if any, other languages allow you to do so "legally", safely and with so much detail and dynamic control. here are a few lines of console code which play around with the above level 2 function hack:
>> employee/full-name
== ["luke" "skywalker"]
>> employee/first-name/set "bill"
== "bill"
>> employee/full-name
== ["bill" "skywalker"]
>> person/full-name
== ["bill" "skywalker"]
>> same? person/full-name/1 employee/first-name
== true
>> same? person/first-name employee/first-name
== true 'SAME is a mezzanine function that only returns True if its the same string, not just by its text content like equal?... it really is the same string "pointer" in memory. sweet isn't it ? :-D about other uses of the function hack ----------------------------------------------------- you might want to replace a value by an SQL statement function-as-a-value which is executed every time a value is needed... and if you set the value, it is inserted back directly... this way, you are sure that your data is coherent. In VID you can put functions instead of values for some facets... example are colors, texts & effects which change every time the face is shown... with a little tweak in the redraw : example: view layout [ button with [ texts: reduce [ does [to-string counter] does [random "ABCDE"]] colors: reduce [ does [random white] does [random white]] effects: reduce [ does [reduce ['gradient 0x1 color color - 75.75.75]] does [reduce ['gradient 0x-1 color color - 75.75.75]] ] ] feel [ redraw: func [face act pos /local state][ counter: counter + 1 if all [face/texts face/texts/2] [ face/text: either face/state [face/texts/2] [face/texts/1] ] if face/edge [face/edge/effect: pick [ibevel bevel] face/state] state: either not face/state [face/blinker] [true] if face/colors [face/color: either face/state [face/colors/2] [face/colors/1]] if face/effects [face/effect: either face/state [face/effects/2] [face/effects/1]] ] ] ] here face/colors/2 is evaluated each time the face is drawn... so you might want to put an sql statement which checks if an error occurred on the db for example. whenever the face is refreshed it will be up to date... which is pretty useful. the view face is not a normal object so most of the primitive facets (like color) will not respond if they are set to functions because the view engine actually uses the values directly. as an example if you put a function in face/text it will actually display ?function? as the text... but it should give you ideas on other uses... just the same. -MAx On Thu, Sep 3, 2009 at 5:38 AM, Giuseppe Chillemi <gchillemi-aliceposta.it> wrote:

 [14/14] from: moliad:g:mail at: 14-Sep-2009 17:02


oops.. just one little detail... 'SAME? isn't a mezz.. its a native... -MAx On Mon, Sep 14, 2009 at 4:56 PM, Maxim Olivier-Adlhoch <moliad-gmail.com> wrote:

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted