Hi, folks! I somehow managed to get Self 4.0 to run on a SPARCstation here at my workplace. Now I can understand better a lot of things that I knew in theory, but couldn´t feel in practice. I am experimenting a little with the empty Self world, that is the bare VM. I tried to do the following: self _AddSlots: ( | prims = _PrimitiveList . credits = _Credits | ) This was successful and added the two slots to the lobby (strangely one cannot access the lobby with the "lobby" selector, but with "self" because the VM# prompt evaluation context is the lobby). Unfortunately, what I wanted to do was to invoke the credits slot as a method slot, so that it would print the credits. Instead, the result was that it only kept the returned object (´Thanks!´) on the slot. Then I tried another idea: self _AddSlots: ( | prims = _PrimitiveList . credits = [ _Credits ] | ) Yes, a block. Perhaps I could invoke the primitive with "self credits value". Unfortunately it didn´t work. It only complained about non-lifo blocks invocation after the block´s enclosing scope has returned. Does anyone know a workaround to really INVOKING a primitive from a slot of the lobby (or generically any object)?
Regards, Douglas
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interest http://www.egroups.com - Simplifying group communications
I somehow managed to get Self 4.0 to run on a SPARCstation here at my workplace. Now I can understand better a lot of things that I knew in theory, but couldn´t feel in practice.
It is great to use this list to talk about using Self instead of just implementing it. While I found Self just what I had expected from reading about it, it seems that most people are very surprised by the difference between practive and theory.
I am experimenting a little with the empty Self world, that is the bare VM. I tried to do the following: self _AddSlots: ( | prims = _PrimitiveList . credits = _Credits | )
This would have worked just as well if you eliminated the initial "self" in the expression. When a receiver is missing in a Self expression, self is implied. There is a difference when this is used inside a method: "x: 2" will send "x:" to self but start the message lookup with the method's local slots, while "self x: 2" will also send "x:" to self but will look it up starting the with receiver's slots. Note that the message receiver is always a parent of the executing method (through the "self*" slot).
This was successful and added the two slots to the lobby (strangely one cannot access the lobby with the "lobby" selector, but with "self" because the VM# prompt evaluation context is the lobby).
This is because the "lobby" slot is only added to lobby when you file in "init.self" to create a non empty world.
Unfortunately, what I wanted to do was to invoke the credits slot as a method slot, so that it would print the credits. Instead, the result was that it only kept the returned object (´Thanks!´) on the slot.
You created a constant slot which has as its value the result of evaluating the expression "_Credits" in the context of the lobby. I found it strange that sending _Credits to the lobby just returned the string 'Thanks', but I tried it and you are right - it has a side effect of printing a lot of stuff on the terminal, but the result is just this short string.
Then I tried another idea: self _AddSlots: ( | prims = _PrimitiveList . credits = [ _Credits ] | ) Yes, a block. Perhaps I could invoke the primitive with "self credits value". Unfortunately it didn´t work. It only complained about non-lifo blocks invocation after the block´s enclosing scope has returned.
This is a limitation that Self has but Smalltalk doesn't. After the expression that created a block has finished executing, you can no longer use that block because that doesn't make sense with a simple stack implementation. Smalltalk uses a linked list of context objects, this isn't a problem (except for the Smalltalk implementor ;-)
Note that what Smalltalk does with non LIFO (last in, first out) blocks you can do in Self just as well by creating lots of anonymous little objects (something you can't do in Smalltalk).
Does anyone know a workaround to really INVOKING a primitive from a slot of the lobby (or generically any object)?
Please note that your problem has nothing to do with primitives. Try:
_AddSlots: ( | credits = ( _Credits ) | )
Now credits is a constant slot that has a method that invokes the primitive as its value, instead of the result of invoking the primitive. You can type "self credits" or simply "credits" and get what you want.
Please compare the following:
_AddSlots: ( | cvec = vector _Clone: 3 Filler: 9 | )
_AddSlots: ( | nvec = (vector _Clone: 3 Filler: 9) | )
cvec _At: 1 Put: 5
nvec _At: 1 Put: 5
It sure looks like they are the same so far, doesn't it? But this
VM# cvec <20>: ( | parent* = <1>. | object array: {9, 5, 9} ) VM# nvec <22>: ( | parent* = <1>. | object array: {9, 9, 9} ) VM#
shows that there is a difference. nvec is a method which returns a new vector every time it is invoked, while cvec is a constant slot which returns the same vector every time it is invoked. I was going to do this without a primitive to show that it is a different issue, but in the empty world there are no non-primitive methods...
-- Jecel
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interest http://www.egroups.com - Simplifying group communications
One quick comment: _AddSlots: ( | lobby = 0 _AsObject | ) (N.B.: the ObjectID of the lobby is not necessarily 0, remarkably if the first expression you type returns an error. To find out the ObjectID of the lobby type: self on the VM# prompt.) and _AddSlots: ( | lobby = self | ) can make the lobby selector visible in the empty world. Also see my comments below. Regards, Douglas
jecel@lsi.usp.br wrote:
I somehow managed to get Self 4.0 to run on a SPARCstation here at my workplace. Now I can understand better a lot of things that I knew in theory, but couldn´t feel in practice.
It is great to use this list to talk about using Self instead of just implementing it. While I found Self just what I had expected from reading about it, it seems that most people are very surprised by the difference between practive and theory.
That is, I guess, because most people aren´t used to the object-oriented style of thinking and acting. I wasn´t, and I hadn´t got the slightest Smalltalk background when I first heard of Self.
I am experimenting a little with the empty Self world, that is the bare VM. I tried to do the following: self _AddSlots: ( | prims = _PrimitiveList . credits = _Credits | )
This would have worked just as well if you eliminated the initial "self" in the expression. When a receiver is missing in a Self expression, self is implied. There is a difference when this is used inside a method: "x: 2" will send "x:" to self but start the message lookup with the method's local slots, while "self x: 2" will also send "x:" to self but will look it up starting the with receiver's slots. Note that the message receiver is always a parent of the executing method (through the "self*" slot).
Perhaps that is because I was adding slots to the lobby, which coincidently is the evaluation context of the VM# prompt (anything one types on the VM# promptis evaluated as if it were a slot of the lobby, right? Or else, anything one types on the VM# prompt turns into a message sent to the lobby).
This was successful and added the two slots to the lobby (strangely one cannot access the lobby with the "lobby" selector, but with "self" because the VM# prompt evaluation context is the lobby).
This is because the "lobby" slot is only added to lobby when you file in "init.self" to create a non empty world.
I suspected. So the only reason we can get to the lobby is that it is hardwired in the VM implementation as the evaluation context of the empty world. Of course, there are some objects that are returned by some primitives (like _PrimitiveList, for example, which returns a vector).
Unfortunately, what I wanted to do was to invoke the credits slot as a method slot, so that it would print the credits. Instead, the result was that it only kept the returned object (´Thanks!´) on the slot.
You created a constant slot which has as its value the result of evaluating the expression "_Credits" in the context of the lobby. I found it strange that sending _Credits to the lobby just returned the string 'Thanks', but I tried it and you are right - it has a side effect of printing a lot of stuff on the terminal, but the result is just this short string.
Perhaps this is the reason why the credits are not returned into an object that "the hand" can grab and manipulate. Only the Thanks! string is an object.
Then I tried another idea: self _AddSlots: ( | prims = _PrimitiveList . credits = [ _Credits ] | ) Yes, a block. Perhaps I could invoke the primitive with "self credits value". Unfortunately it didn´t work. It only complained about non-lifo blocks invocation after the block´s enclosing scope has returned.
This is a limitation that Self has but Smalltalk doesn't. After the expression that created a block has finished executing, you can no longer use that block because that doesn't make sense with a simple stack implementation. Smalltalk uses a linked list of context objects, this isn't a problem (except for the Smalltalk implementor ;-)
Note that what Smalltalk does with non LIFO (last in, first out) blocks you can do in Self just as well by creating lots of anonymous little objects (something you can't do in Smalltalk).
Does anyone know a workaround to really INVOKING a primitive from a slot of the lobby (or generically any object)?
Please note that your problem has nothing to do with primitives. Try:
_AddSlots: ( | credits = ( _Credits ) | )
Now credits is a constant slot that has a method that invokes the primitive as its value, instead of the result of invoking the primitive. You can type "self credits" or simply "credits" and get what you want.
Yeah, it works! So the difference between what I did and your suggestion is that I assigned **the result of evaluating** _Credits to my constant credits slot while you put the primitive **inside the code for an object**, so that whenever you send a credits message to the lobby it will **execute** the primitive again. Great! This is the kind of thing I would never understand without running Self and doing the experiment myself.
Please compare the following:
_AddSlots: ( | cvec = vector _Clone: 3 Filler: 9 | )
_AddSlots: ( | nvec = (vector _Clone: 3 Filler: 9) | )
cvec _At: 1 Put: 5
nvec _At: 1 Put: 5
It sure looks like they are the same so far, doesn't it? But this
VM# cvec <20>: ( | parent* = <1>. | object array: {9, 5, 9} ) VM# nvec <22>: ( | parent* = <1>. | object array: {9, 9, 9} ) VM#
shows that there is a difference. nvec is a method which returns a new vector every time it is invoked, while cvec is a constant slot which returns the same vector every time it is invoked. I was going
to do this without a primitive to show that it is a different issue, but in the empty world there are no non-primitive methods...
-- Jecel
Tired of waiting for your stock quotes and charts to load? StockMaster is super-fast for quotes, charts, news, and portfolios. Markets don't wait, why should you? http://clickhere.egroups.com/click/69
eGroups.com home: http://www.egroups.com/group/self-interest http://www.egroups.com - Simplifying group communications
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interest http://www.egroups.com - Simplifying group communications
I'm glad you have a SPARC to play with Self on, and it sounds as though Jecel has already answered your questions.
Have your tried either of the UIs yet? They offer more visual ways to explore than in the empty world.
- Dave
At 9:09 AM -0300 5/20/99, Douglas Atique wrote:
Hi, folks! I somehow managed to get Self 4.0 to run on a SPARCstation here at my workplace. Now I can understand better a lot of things that I knew in theory, but couldn´t feel in practice. I am experimenting a little with the empty Self world, that is the bare VM. I tried to do the following: self _AddSlots: ( | prims = _PrimitiveList . credits = _Credits | ) This was successful and added the two slots to the lobby (strangely one cannot access the lobby with the "lobby" selector, but with "self" because the VM# prompt evaluation context is the lobby). Unfortunately, what I wanted to do was to invoke the credits slot as a method slot, so that it would print the credits. Instead, the result was that it only kept the returned object (´Thanks!´) on the slot. Then I tried another idea: self _AddSlots: ( | prims = _PrimitiveList . credits = [ _Credits ] | ) Yes, a block. Perhaps I could invoke the primitive with "self credits value". Unfortunately it didn´t work. It only complained about non-lifo blocks invocation after the block´s enclosing scope has returned. Does anyone know a workaround to really INVOKING a primitive from a slot of the lobby (or generically any object)?
Regards, Douglas
@Backup - The #1 Online Backup Service Automatic, Safe, Reliable Backup and Restores. FREE for 30 Days. INSTALL Now and have a chance to win a Palm Pilot V! http://clickhere.egroups.com/click/218
eGroups.com home: http://www.egroups.com/group/self-interest http://www.egroups.com - Simplifying group communications
David Ungar Sun Microsystems Laboratories (650) 336-2618
------------------------------------------------------------------------
eGroups.com home: http://www.egroups.com/group/self-interest http://www.egroups.com - Simplifying group communications
self-interest@lists.selflanguage.org