Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #30596 > unrolled thread
| Started by | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| First post | 2014-05-22 19:29 -0700 |
| Last post | 2014-05-27 06:19 -0500 |
| Articles | 20 on this page of 34 — 11 participants |
Back to article view | Back to comp.lang.forth
A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-22 19:29 -0700
Re: A slightly longer mini-oof2.fs example. albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-23 11:22 +0000
Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-23 09:38 -0700
Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-23 12:11 +0000
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-23 10:26 -0500
Re: A slightly longer mini-oof2.fs example. Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-23 19:59 +0200
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-24 04:23 -0500
Re: A slightly longer mini-oof2.fs example. Hans Bezemer <the.beez.speaks@gmail.com> - 2014-05-24 15:47 +0200
Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-26 12:46 -0700
Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-24 15:35 +0000
Re: A slightly longer mini-oof2.fs example. Alexander Skobelev <al.skobelev@gmail.com> - 2014-05-24 20:45 +0400
Re: A slightly longer mini-oof2.fs example. Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-24 21:46 +0200
Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-25 15:03 +0000
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-25 15:16 -0500
Re: A slightly longer mini-oof2.fs example. Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-26 00:47 +0200
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-25 18:55 -0500
Re: A slightly longer mini-oof2.fs example. albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-26 11:44 +0000
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 05:25 -0500
Re: A slightly longer mini-oof2.fs example. albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-27 11:56 +0000
Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-26 12:18 -0700
Re: A slightly longer mini-oof2.fs example. Paul Rubin <no.email@nospam.invalid> - 2014-05-26 12:46 -0700
Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-26 13:43 -0700
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 05:28 -0500
Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-23 09:39 -0700
Re: A slightly longer mini-oof2.fs example. mhx@iae.nl - 2014-05-23 10:29 -0700
Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-23 17:16 +0000
Re: A slightly longer mini-oof2.fs example. andraszsoter@gmail.com - 2014-05-26 10:23 -0700
Re: A slightly longer mini-oof2.fs example. Mark Wills <markwills1970@gmail.com> - 2014-05-27 02:09 -0700
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 06:07 -0500
Re: A slightly longer mini-oof2.fs example. andraszsoter@gmail.com - 2014-05-28 10:17 -0700
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 05:39 -0500
Re: A slightly longer mini-oof2.fs example. Mark Wills <markwills1970@gmail.com> - 2014-05-27 04:02 -0700
Re: A slightly longer mini-oof2.fs example. Mark Wills <markwills1970@gmail.com> - 2014-05-27 04:04 -0700
Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 06:19 -0500
Page 1 of 2 [1] 2 Next page →
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2014-05-22 19:29 -0700 |
| Subject | A slightly longer mini-oof2.fs example. |
| Message-ID | <70a9649b-29ee-43f8-a1f8-af2581dafab8@googlegroups.com> |
Hello clf,
mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs (an object
system in a screen) plus something called a "current object". If you search
clf, mini-oof2.fs is mentioned a few times in passing and then there's a long
thread where Bernd supports object systems having a "current object" while
others are skeptical of this. There is also an example of a 'point' class.
Please take a look at this longer example:
\ ------------------------------------------------------------
require mini-oof2.fs
object class
method :unshift ( x -- )
method :shift ( -- x )
method :each ( xt -- )
method .list ( -- )
method nil? ( -- f )
end-class nil-class
nil-class class
field: cdr
field: car
end-class cons-cell
' true nil-class to nil?
' false cons-cell to nil?
nil-class new constant nil
: cons ( car cdr -- list )
cons-cell new >o cdr ! car ! o o> ;
[: nil? if o> nil cons >o exit then
o cons-cell new o> >o cdr ! car ! ;] nil-class to :unshift
[: nil? if nil exit then
car @ cdr @ dispose o> >o ;] nil-class to :shift
[: { xt } o >o begin nil? 0= while car @ xt execute cdr @ o> >o repeat o> ;] nil-class to :each
[: ['] . :each ;] nil-class to .list
\ totally unnecessary -- see below.
nil-class >methods
dup cell+ swap @
cell - \ don't copy 'nil?'
cons-cell >methods cell+ swap move
: upto ( n -- list )
nil >o 0 swap -do i :unshift 1 -loop o o> ;
10 upto value a-list
: bump ( -- ) a-list >o [: drop 1 car +! ;] :each .list o> ;
: chop ( -- ) a-list >o :shift . :shift . :shift . o to a-list o> ;
\ ------------------------------------------------------------
Why does this use a nil class? Because you can't invoke methods on 0. If
nil is 0, you can't ever say NIL >o 1 :UNSHIFT o o> to produce the list (1).
Incidentally, you *can* 'invoke' fields on 0. You get the offset.
gl-helper.fs in the Android distribution has a use of this in VERTEX-INIT .
Why does this manually copy method XTs from nil-class to cons-cell ? Because
methods are only copied on class creation, but these methods need to be able to
refer to NIL as well as CONS-CELL . ... although, come to think of it, they
don't need that: the NIL? IF .. EXIT THEN behaviors should just be NIL-CLASS's
own method definitions.
Why does :EACH have that [: o >o ... o> ;] pattern? So that it can walk through
the list's cells and then restore the list as the active object. Otherwise
BUMP would display nothing, because .LIST would always be invoked on NIL
Meanwhile, :SHIFT and :UNSHIFT deliberately replace the active object, so that
you can chain these operations as seen in UPTO and CHOP .
How can BUMP mutate the list? Because :EACH, originally intended to only
provide the value of CAR to the xt, also happens to leave the cons-cell it's at
as the active object. The presense of an active object means that :EACH
actually shouldn't provide the value of CAR at all -- it should just let the xt
grab whatever it wants.
What's all this >o o> o stuff again?
: >o ( o -- ) pushes the object at the top of the data stack to the top of the
object stack ;
: o> ( -- ) performs a DROP on the object stack. ;
: o ( -- o ) copies the top of the object stack to the top of the data stack ;
Other unfactored operations:
: o-dup ( -- ) ( obj: o -- o o ) o >o ;
: o-replace ( o2 -- ) ( obj: o1 -- o2 ) o> >o ;
: o>d ( -- o ) ( obj: o -- ) o o> ;
Methods are applied to the top of the object stack.
What's with these weird names? :SHIFT :UNSHIFT ? Why doesn't NIL? also have a
preceeding colon? Let's not get distracted by the small stuff.
When I CHOP more than a few times I start seeing this weird number? That's the
address of NIL.
I said A-LIST >O .LIST to gforth and it complained about an Invalid memory
address? Seems that gforth uses the current object as well, so you should use
the same discipline about the current object that you would use in a
definition, and write: A-LIST >O .LIST O>
--
So what do you think? My initial reaction to the current object stuff was "why
would you want all that noise?" and "I never missed something like this when
using other object systems." And in the longer thread that you can search for
(Google only finds four references to mini-oof2.fs in clf) there are complaints
like "I expect that matching the >O and O> operations will be difficult."
But the object no longer needs to be managed on the data stack, and it's easy
to change the current object within a method, or to leave the current object as
part of the environment for an XT. For all the extra 'noise', the code is
cleaner and is easier to write. And it's not actually difficult to keep track
of >o and blah; it's a super shallow stack (as far as you ever care) with few
operations, and this is Forth, so managing it does not feel unnatural.
And the 'mini' of mini-oof2 is an advantage. In the example above, the unnamed
COPY-METHODS ( class1 class2 -- ) was easily written even though it wasn't a
good idea. If I'd faced some problem like this in SWOOP, I would've sat back,
re-read the documentation, agonized for a bit, and then would've done the right
thing of changing my classes rather than messing with the object system :-)
-- Julian
[toc] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl (Albert van der Horst) |
|---|---|
| Date | 2014-05-23 11:22 +0000 |
| Message-ID | <537f2f6e$0$3031$e4fe514c@dreader35.news.xs4all.nl> |
| In reply to | #30596 |
In article <70a9649b-29ee-43f8-a1f8-af2581dafab8@googlegroups.com>, Julian Fondren <ayrnieu@gmail.com> wrote: >Hello clf, > >mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs (an object >system in a screen) plus something called a "current object". If you search >clf, mini-oof2.fs is mentioned a few times in passing and then there's a long >thread where Bernd supports object systems having a "current object" while >others are skeptical of this. There is also an example of a 'point' class. > >Please take a look at this longer example: Example of what? Please add one line to a program at the front to explain what its purpose is. My first guess is your program is for calculating primes (all my programs are) , but I have no idea how it works ;-) <SNIP> > >So what do you think? My initial reaction to the current object stuff was "why >would you want all that noise?" and "I never missed something like this when >using other object systems." And in the longer thread that you can search for >(Google only finds four references to mini-oof2.fs in clf) there are complaints >like "I expect that matching the >O and O> operations will be difficult." About the current object thing. I made my own objects to implement manx2 and replace both structs and fields from Marcel Hendrix. I decided that current object is better over ( object data method ) and (data object method ) and never looked back. I published the two screener here a couple of times. Recently it has become a one screener. A host of applications I did, confirm it, such as ciasdis, an assembler/disassembler. In particular my implementation of ALLOCATE that would never have done with objects if my objects required an extra object id on the stack. > >But the object no longer needs to be managed on the data stack, and it's easy >to change the current object within a method, or to leave the current object as >part of the environment for an XT. For all the extra 'noise', the code is >cleaner and is easier to write. And it's not actually difficult to keep track >of >o and blah; it's a super shallow stack (as far as you ever care) with few >operations, and this is Forth, so managing it does not feel unnatural. Huh? > >And the 'mini' of mini-oof2 is an advantage. In the example above, the unnamed >COPY-METHODS ( class1 class2 -- ) was easily written even though it wasn't a >good idea. If I'd faced some problem like this in SWOOP, I would've sat back, >re-read the documentation, agonized for a bit, and then would've done the right >thing of changing my classes rather than messing with the object system :-) > > >-- Julian Groetjes Albert -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
[toc] | [prev] | [next] | [standalone]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2014-05-23 09:38 -0700 |
| Message-ID | <9e3ce38a-2ea9-4157-8fb2-ac2c7978d7a7@googlegroups.com> |
| In reply to | #30603 |
On Friday, May 23, 2014 6:22:22 AM UTC-5, Albert van der Horst wrote: > Example of what? Please add one line to a program at the front to > explain what its purpose is. My first guess is your program is for > calculating primes (all my programs are) , > but I have no idea how it works ;-) You've correctly intuited that it calculates primes, though. Right now it only counts 1.5 primes. You just need to add a length method: [: 0 [: drop 1+ ;] :each ;] nil-class to length Then, getting the length of a-list and CHOPping it yields a "not a prime / a prime" alternating pattern: 10 7 4 1 > About the current object thing. I made my own objects to implement > manx2 and replace both structs and fields from Marcel Hendrix. I > decided that current object is better over ( object data method ) and > (data object method ) and never looked back. I published the two > screener here a couple of times. Recently it has become a one > screener. A host of applications I did, confirm it, such as ciasdis, > an assembler/disassembler. In particular my implementation of ALLOCATE > that would never have done with objects if my objects required an > extra object id on the stack. Cool. A search for 'washing-oo' finds a self-contained example. -- Julian
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2014-05-23 12:11 +0000 |
| Message-ID | <2014May23.141134@mips.complang.tuwien.ac.at> |
| In reply to | #30596 |
Julian Fondren <ayrnieu@gmail.com> writes:
>Hello clf,
>
>mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs (an object
>system in a screen) plus something called a "current object". If you search
>clf, mini-oof2.fs is mentioned a few times in passing and then there's a long
>thread where Bernd supports object systems having a "current object" while
>others are skeptical of this.
IIRC the only one sceptical was Andrew Haley. Most people working on
this have a current object (THIS, SELF or O). The main discussion was
about how the current object should be set. Bernd Paysan sets and
restores it explicitly with >O O>, or WITH END-WITH or somesuch,
whereas most others set it implicitly on method call. As a
consequence, the others put the object that is to become the current
object on the data stack on a method call, while Bernd Paysan makes it
the current object explictly at some earlier point, and then just uses
that for the dynamic dispatch.
This results in the following syntactic differences:
Calling a method FOO for the current object (THIS):
Bernd Paysan: foo
Anton Ertl: this foo
Callingt a method FOO for a different object BAR
Bernd Paysan: bar >o foo o>
Anton Ertl: bar foo
Bernd Paysan's argument was that he usually calls the method with the
current object and that he changes the current object much less
frequently. Given your experiment, what do you think? There are 9
>O, 9 O>, and 5 O in your example, in 8 definitions.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2014: http://www.euroforth.org/ef14/
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2014-05-23 10:26 -0500 |
| Message-ID | <zLCdnQlJo9IW9eLOnZ2dnUVZ8tCdnZ2d@supernews.com> |
| In reply to | #30605 |
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: > Julian Fondren <ayrnieu@gmail.com> writes: >>Hello clf, >> >>mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs >>(an object system in a screen) plus something called a "current >>object". If you search clf, mini-oof2.fs is mentioned a few times >>in passing and then there's a long thread where Bernd supports >>object systems having a "current object" while others are skeptical >>of this. > > IIRC the only one sceptical was Andrew Haley. Most people working on > this have a current object (THIS, SELF or O). Gosh, just me, really? The only thing I was skeptical about was having THIS as a hidden argument passed to all routines, even colon definitions. I don't think doing that is a good idea: Forth should pass arguments, including THIS, on the stack. As far as I'm aware, most (non-Forth) OOP languages do that. So, I have no objection to the idea of a current object, I just think it should be passed in the normal way. Andrew.
[toc] | [prev] | [next] | [standalone]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2014-05-23 19:59 +0200 |
| Message-ID | <llo2ag$i0l$1@online.de> |
| In reply to | #30614 |
Andrew Haley wrote: > Gosh, just me, really? The only thing I was skeptical about was > having THIS as a hidden argument passed to all routines, even colon > definitions. I don't think doing that is a good idea: Forth should > pass arguments, including THIS, on the stack. As far as I'm aware, > most (non-Forth) OOP languages do that. So, I have no objection to > the idea of a current object, I just think it should be passed in the > normal way. "the normal way" is more pragmatic in Forth. First of all, we don't have just *the* stack. We have a data stack, a floating point stack, and a return stack; Gforth has a separate locals stack. A number of string packages offer a string stack, we have a vocabulary stack, there's a recognizer stack in Gforth. Having more than one stack is natural in Forth. As it quickly turned out with packages like mini-oof.fs, having the object on the data stack is too much of an obstacle. Mini-OOF is barely usable, especially for accessing the instance variables. So you will soon have a current object. Now what? Use it only for instance variables? This results in inconsistent use: instance variables are relative to the current object, methods take it from the stack. Inconsistent interfaces clutter the mind, and therefore should be avoided. Result: Use a stack (shared with the return stack) for the current object, with the top of stack in a user variable or register, passed implicitely to other methods. BTW: Mini-OOF2 has a "plugin system" for how methods and instance variables work, so you can make them whatever you want (including explicit object passing for methods and implicit for instance variables). One of the ways to plug into that system is to have specific "current objects" for different classes. E.g. the IO vectors in Gforth use that: There's a current output object and a current input object. KEY and EMIT call through that objects, they are really just methods. It wouldn't work if these methods would require a current object on the stack. -- Bernd Paysan "If you want it done right, you have to do it yourself" http://bernd-paysan.de/
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2014-05-24 04:23 -0500 |
| Message-ID | <_4udnQIXGsmE-B3OnZ2dnUVZ_vednZ2d@supernews.com> |
| In reply to | #30620 |
Bernd Paysan <bernd.paysan@gmx.de> wrote: > Andrew Haley wrote: >> Gosh, just me, really? The only thing I was skeptical about was >> having THIS as a hidden argument passed to all routines, even colon >> definitions. I don't think doing that is a good idea: Forth should >> pass arguments, including THIS, on the stack. As far as I'm aware, >> most (non-Forth) OOP languages do that. So, I have no objection to >> the idea of a current object, I just think it should be passed in the >> normal way. > > "the normal way" is more pragmatic in Forth. First of all, we don't > have just *the* stack. We have a data stack, a floating point > stack, and a return stack; Gforth has a separate locals stack. A > number of string packages offer a string stack, we have a vocabulary > stack, there's a recognizer stack in Gforth. Having more than one > stack is natural in Forth. > > As it quickly turned out with packages like mini-oof.fs, having the > object on the data stack is too much of an obstacle. Mini-OOF is > barely usable, especially for accessing the instance variables. OK, why? Let's assume that you put THIS into a local at the start of a method, and that instance variables use the local THIS, and that if you want to call a PRINT method you say THIS PRINT or somesuch. (I know that you can't portably tick and COMPILE locals, but let's ignore that for a moment.) Python was a real revelation for me: I am used to Smalltalk and Java style, where "this" (aka "self") is usually implicit, but in Python you say "self.blah" if you want to access instance variable blah, and people using Python don't seem to mind having to do that. AFAIK The reason they don't mind is that they got used to it, and the advantage is that you can see easily at the point of use what is an instance variable. And also, there is nothing special about "self" in Python: it's just a local variable, and the name "self" is no more than a convention. What you get in return is simplicity and consitency. > BTW: Mini-OOF2 has a "plugin system" for how methods and instance > variables work, so you can make them whatever you want (including > explicit object passing for methods and implicit for instance > variables). One of the ways to plug into that system is to have > specific "current objects" for different classes. E.g. the IO > vectors in Gforth use that: There's a current output object and a > current input object. KEY and EMIT call through that objects, they > are really just methods. > > It wouldn't work if these methods would require a current object on > the stack. No, it wouldn't, but that's rather obscure. Andrew.
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-05-24 15:47 +0200 |
| Message-ID | <5380a2bd$0$2830$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #30620 |
Bernd Paysan wrote: > Result: Use a stack (shared with the return stack) for the current object, > with the top of stack in a user variable or register, passed implicitely > to other methods. Agreed. I came to the same conclusion. The only difference is that in FOOS there is the word "this" which is an alias for "r@". If you can't stand the return stack being "taken", never use DO..LOOP again, I thought. Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2014-05-26 12:46 -0700 |
| Message-ID | <27c05757-4f87-48ec-b6e6-f932872cc34d@googlegroups.com> |
| In reply to | #30640 |
On Saturday, May 24, 2014 8:47:19 AM UTC-5, The Beez wrote: > Bernd Paysan wrote: > > Result: Use a stack (shared with the return stack) for the current object, > > with the top of stack in a user variable or register, passed implicitely > > to other methods. > Agreed. I came to the same conclusion. The only difference is that in FOOS > there is the word "this" which is an alias for "r@". If you can't stand the > return stack being "taken", never use DO..LOOP again, I thought. > > Hans Bezemer Wow, I hadn't realized that there was any interaction with the return stack. In mini-oof2.fs: ( output: 0 ) 0 >o 1 >r o . rdrop o> ( output: 0 !) 1 >r 0 >o r@ . o> rdrop ( output: 0 ) 0 >o 1 >r 2 >o o> o . rdrop o> ( output: 3 !) 0 >o 1 >r 2 >o 3 >r o> o . rdrop rdrop o> : x ( -- ) \ print 0 ten times 0 >o 10 0 do o . loop o> ; : x ( -- ) \ break horribly -- which is probably for the best 10 0 do i >o loop 10 0 do o> loop ; : start 0 >o ; : stop o> ; : invalid-memory-address ( -- ) start o . stop ; : continue o 1+ o> >o ; : x ( -- ) \ output: 1 0 >o continue o . o> ; I, uh, look forward to the documentation :-) -- Julian
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2014-05-24 15:35 +0000 |
| Message-ID | <2014May24.173516@mips.complang.tuwien.ac.at> |
| In reply to | #30620 |
Bernd Paysan <bernd.paysan@gmx.de> writes:
>As it quickly turned out with packages like mini-oof.fs, having the object
>on the data stack is too much of an obstacle. Mini-OOF is barely usable,
>especially for accessing the instance variables. So you will soon have a
>current object. Now what? Use it only for instance variables? This
>results in inconsistent use: instance variables are relative to the current
>object, methods take it from the stack. Inconsistent interfaces clutter the
>mind, and therefore should be avoided.
I did not find that inconsistent when I wrote Gray. After all,
methods are not instance variables. E.g., methods are bound
dynamically, instance variables not. Do you also think that this is
an inconsistency that should be avoided?
One interesting observation in the Java part of my introductory
programming course is that many students write "this.bla" where "bla"
would be sufficient. I did not teach them that, and in what I show
them I use "bla" instead (at least for instance variables). I guess
they learned it elsewhere and there is someone teaching that style.
Which may be a good idea, it's more consistent with the access to the
instance variables of other objects.
Anyway, the problem with mini-oof.fs is that there is no current
object at all.
Once we have a current object, the question is whether to set it
implicitly on method call (as happens in most OO languages and most
Forth OO packages), or whether to set it explicitly. Or we might also
do both: set it implicitly on method calls, and also allow explicit
setting.
The actual difference is: When you set it implicitly on method calls,
you pass this object on the stack. When you don't set it on method
calls, but only explictly, you do not pass the object on the stack,
you only pass it through the current object.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2014: http://www.euroforth.org/ef14/
[toc] | [prev] | [next] | [standalone]
| From | Alexander Skobelev <al.skobelev@gmail.com> |
|---|---|
| Date | 2014-05-24 20:45 +0400 |
| Message-ID | <m2r43jrupt.fsf@gmail.com> |
| In reply to | #30644 |
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes: > […] > > One interesting observation in the Java part of my introductory > programming course is that many students write "this.bla" where "bla" > would be sufficient. I did not teach them that, and in what I show > them I use "bla" instead (at least for instance variables). I guess > they learned it elsewhere and there is someone teaching that style. > Which may be a good idea, it's more consistent with the access to the > instance variables of other objects. When I write C++ code I usually use this->bla and in Objective-C it is _bla. It just a convention to designate instance variables to make the code more readable. So from this point THIS BLA may be preferable to BLA.
[toc] | [prev] | [next] | [standalone]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2014-05-24 21:46 +0200 |
| Message-ID | <llqsu1$ivh$1@online.de> |
| In reply to | #30644 |
Anton Ertl wrote: > Bernd Paysan <bernd.paysan@gmx.de> writes: >>As it quickly turned out with packages like mini-oof.fs, having the object >>on the data stack is too much of an obstacle. Mini-OOF is barely usable, >>especially for accessing the instance variables. So you will soon have a >>current object. Now what? Use it only for instance variables? This >>results in inconsistent use: instance variables are relative to the >>current >>object, methods take it from the stack. Inconsistent interfaces clutter >>the mind, and therefore should be avoided. > > I did not find that inconsistent when I wrote Gray. After all, > methods are not instance variables. E.g., methods are bound > dynamically, instance variables not. Do you also think that this is > an inconsistency that should be avoided? No, because that is not an invocation inconsistency - invocation is your public interface, how you implement it is a private decision of the implementer. In Forth, all things are first of all *words*. And then you put them into bins like "variable" or "colon definition", usually classified by their stack effect. In mini-oof2, you can have instance variables (they are defined with field: or friends, but actually relate to the current object; that choice was made because there is a large set of words already there with field: and a central place where to hook into to change the behavior), you can have methods, and you can factor your definitions into ordinary colon definitions, which would be "early bound methods" or non-virtual methods in C++. And when you refactor your code, you can concentrate on the essence of refactoring, instead of going through your entire code base. E.g. let's say foo was first an instance variable, holding a cell. After a while, you discover that your object really has two states in which it has two different foos, and you now define : foo ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ; After a while, you discover furthermore that, well, this distinction is only necessary for 20% of your classes, and the other do well with having just one foo, so you declare foo as a method, and define that with ' foo1 my-baseclass to foo or, for those who needs two states :noname ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ; my-sublass to foo The invocation never changed, and therefore, you never had to dig through your entire code base for all invokations of foo. This sort of consistency makes maintaining code easy. The thing you need to maintain consistently is the signature of the word (the way it is invoked), not the way it is implemented. > One interesting observation in the Java part of my introductory > programming course is that many students write "this.bla" where "bla" > would be sufficient. I did not teach them that, and in what I show > them I use "bla" instead (at least for instance variables). I guess > they learned it elsewhere and there is someone teaching that style. Yes, probably. > Which may be a good idea, it's more consistent with the access to the > instance variables of other objects. Well, you shouldn't access instance variables of other objects... > Anyway, the problem with mini-oof.fs is that there is no current > object at all. > > Once we have a current object, the question is whether to set it > implicitly on method call (as happens in most OO languages and most > Forth OO packages), or whether to set it explicitly. Or we might also > do both: set it implicitly on method calls, and also allow explicit > setting. > > The actual difference is: When you set it implicitly on method calls, > you pass this object on the stack. When you don't set it on method > calls, but only explictly, you do not pass the object on the stack, > you only pass it through the current object. Yes. The thing I want to make is a *consistent* minimalistic set of operations, which all do *exactly one thing*. And do that right. And once there is a current object, the only way to manipulate that current object is the >o o> stuff, and it's orthogonal to all other operations, i.e. no other operation has a hidden side-effect which manipulates the current object. The good thing for people like you is that the "do one thing right" for METHOD is to take a template and produce a method invocation from that template (that is to be consistent with +FIELD, which is the central place to define instance variables, and it is malleable - it will always add the offsets the same way, but what kind of FIELD stuff it implements can change). You can change the template. And if you like to, you can change that template to contain >O and O> around the actual invocation, so the variant of mini-oof2 you are using will require a THIS (or O as it is called in mini-oof2, as this is more consistent with the >O O> stuff) for invoking methods of the same object. The default method invocation doesn't do this, because it is always easier to add things than to take them away. Perfection is only reached when there's nothing left to take away. Consistency is reached when things have the same interface to the outside. Flexibility is reached when you can change all those things to suit your needs. Mini-oof2 came into life, because I started to experiment with a Forth Meta Object Protocol. The intention is to have something that is so basic that nobody can refuse to add the basics. And that you can extend it the way you want. The basics are there to provide with essential stuff, and that means all this essential stuff is then somewhat compatible between different OOP systems that base on the same foundation. Somewhat, because people do have incompatible method invocation, and that can't be fixed. But what can be fixed is that these method invocations consist of core components which are the same, and the only difference is how to glue them together. This allows a system implementer to implement a fast and efficient set of primitives, which he has the duty to maintain, and leave all the other stuff to the OOP package implementers, and there, he doesn't have to maintain things. If you don't like foo >o bar o> in mini-oof2, add a dot-parser recognizer which will transform foo.bar into foo >o bar o> foo->bar into foo @ >o bar o> with any number of . and -> in the string (just replace all "." with " >o " and all "->" with " @ >o " and count the number of occurances, and then add that number of " o>" to the end - and reevaluate). That stuff is probably a good idea to do, and improves readability. It works consistently for accessing instance variables and methods from other classes. This is the sort of consistency I'm aiming at. -- Bernd Paysan "If you want it done right, you have to do it yourself" http://bernd-paysan.de/
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2014-05-25 15:03 +0000 |
| Message-ID | <2014May25.170321@mips.complang.tuwien.ac.at> |
| In reply to | #30653 |
Bernd Paysan <bernd.paysan@gmx.de> writes:
>And when you refactor your code, you can concentrate on the essence of
>refactoring, instead of going through your entire code base.
Given that, as you write, one should only access an instance variable
in its class (and maybe descendent classes), you don't need to go
through the entire code base. Sure, if I don't control the code base
that would need to be changed, keeping the interface the same is the
way to go, but if I do, it may be better to actually change it
(although keeping the interface the same may be good for the
intermediate step). Anyway, you also have both options with
objects.fs.
E.g. let's say
>foo was first an instance variable, holding a cell. After a while, you
>discover that your object really has two states in which it has two
>different foos, and you now define
>
>: foo ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ;
This works in objects.fs, too; THIS is global, and is not changed when
you call a colon definition. One may discuss whether this is a
feature, or just an artifact of the implementation; it was not
intended as a feature, but maybe you can convince me that it is one
(better, convince Andrew Haley!-).
>After a while, you discover furthermore that, well, this distinction is only
>necessary for 20% of your classes, and the other do well with having just
>one foo, so you declare foo as a method, and define that with
>
>' foo1 my-baseclass to foo
>
>or, for those who needs two states
>
>:noname ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ; my-sublass to foo
In objects.fs I can define
selector foo-s
: foo this foo-s ; \ used global this
\ in my-baseclass
m: foo1 ;m overrides foo-s \ could be made more efficient
\ in some classes
m: ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ;m overrides foo-s
>The invocation never changed, and therefore, you never had to dig through
>your entire code base for all invokations of foo.
>
>This sort of consistency makes maintaining code easy. The thing you need to
>maintain consistently is the signature of the word (the way it is invoked),
>not the way it is implemented.
As I demonstrated, explicit setting of the current object is not
needed for this.
>> One interesting observation in the Java part of my introductory
>> programming course is that many students write "this.bla" where "bla"
>> would be sufficient. I did not teach them that, and in what I show
>> them I use "bla" instead (at least for instance variables). I guess
>> they learned it elsewhere and there is someone teaching that style.
>
>Yes, probably.
>
>> Which may be a good idea, it's more consistent with the access to the
>> instance variables of other objects.
>
>Well, you shouldn't access instance variables of other objects...
That's what I thought when I started working with Java. now I am no
longer convinced of that, at least for Java.
Anyway, back to our discussion: Yes, that was the idea behind the way
instance variables and methods are handled in objects.fs:
Only instance variables of the current object should only be accessed,
so instance variables are only visible in their class, and they always
are accessed through the current objects.
In contrast, methods should be callable everywhere, for arbitrary
objects, so the method selector has a global name, and you pass the
object on which it dispatches explicitly.
As demonstrated, you can emulate the instance variable interface with
colon definitions or methods, so that's no reason to change that.
>Yes. The thing I want to make is a *consistent* minimalistic set of
>operations, which all do *exactly one thing*. And do that right. And once
>there is a current object, the only way to manipulate that current object is
>the >o o> stuff, and it's orthogonal to all other operations, i.e. no other
>operation has a hidden side-effect which manipulates the current object.
>
>The good thing for people like you is that the "do one thing right" for
>METHOD is to take a template and produce a method invocation from that
>template (that is to be consistent with +FIELD, which is the central place
>to define instance variables, and it is malleable - it will always add the
>offsets the same way, but what kind of FIELD stuff it implements can
>change). You can change the template. And if you like to, you can change
>that template to contain >O and O> around the actual invocation, so the
>variant of mini-oof2 you are using will require a THIS (or O as it is called
>in mini-oof2, as this is more consistent with the >O O> stuff) for invoking
>methods of the same object. The default method invocation doesn't do this,
>because it is always easier to add things than to take them away.
Now you just need to document it so we can all see the light:-).
The other thing is whether you want to keep it dependent on Gforth
features.
>If you don't like foo >o bar o> in mini-oof2, add a dot-parser recognizer
>which will transform
>
>foo.bar into foo >o bar o>
>foo->bar into foo @ >o bar o>
>
>with any number of . and -> in the string (just replace all "." with " >o "
>and all "->" with " @ >o " and count the number of occurances, and then add
>that number of " o>" to the end - and reevaluate).
I have been thinking about something like that, too:
Have .BAR take the current object from the TOS, and BAR keep it as it
is (although "." is taken as a prefix in Forth, so we should probably
use something else, maybe ":" or "~"; I'll leave that discussion to
someone else, my names are generally disliked:-). This could be
implemented in standard Forth by defining two words, or in
sufficiently capable systems with a dot-parser. So we would have
foo .bar
foo @ .bar
for your examples.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2014: http://www.euroforth.org/ef14/
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2014-05-25 15:16 -0500 |
| Message-ID | <fO-dneT_-M4Y0h_OnZ2dnUVZ_u2dnZ2d@supernews.com> |
| In reply to | #30693 |
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: > This works in objects.fs, too; THIS is global, and is not changed > when you call a colon definition. One may discuss whether this is a > feature, or just an artifact of the implementation; it was not > intended as a feature, but maybe you can convince me that it is one > (better, convince Andrew Haley!-). THIS is thread-local, surely? A USER variable. Andrew.
[toc] | [prev] | [next] | [standalone]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2014-05-26 00:47 +0200 |
| Message-ID | <lltrum$vf2$1@online.de> |
| In reply to | #30693 |
Anton Ertl wrote: > Bernd Paysan <bernd.paysan@gmx.de> writes: >>And when you refactor your code, you can concentrate on the essence of >>refactoring, instead of going through your entire code base. > > Given that, as you write, one should only access an instance variable > in its class (and maybe descendent classes), you don't need to go > through the entire code base. That could be a variable in a base class... used in a lot of places. > Sure, if I don't control the code base > that would need to be changed, keeping the interface the same is the > way to go, but if I do, it may be better to actually change it > (although keeping the interface the same may be good for the > intermediate step). Anyway, you also have both options with > objects.fs. Changing an interface in a sufficiently large code base is always a problem, even if you control the codebase. > E.g. let's say >>foo was first an instance variable, holding a cell. After a while, you >>discover that your object really has two states in which it has two >>different foos, and you now define >> >>: foo ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ; > > This works in objects.fs, too; THIS is global, and is not changed when > you call a colon definition. One may discuss whether this is a > feature, or just an artifact of the implementation; it was not > intended as a feature, but maybe you can convince me that it is one > (better, convince Andrew Haley!-). I think it's just an artefact of the implementation. >>After a while, you discover furthermore that, well, this distinction is >>only necessary for 20% of your classes, and the other do well with having >>just one foo, so you declare foo as a method, and define that with >> >>' foo1 my-baseclass to foo >> >>or, for those who needs two states >> >>:noname ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ; my-sublass to >>:foo > > In objects.fs I can define > > selector foo-s > : foo this foo-s ; \ used global this > > \ in my-baseclass > m: foo1 ;m overrides foo-s \ could be made more efficient > > \ in some classes > m: ( -- addr ) mystate @ IF foo1 ELSE foo2 THEN ;m overrides foo-s Yes, the global this makes this possible... >>The invocation never changed, and therefore, you never had to dig through >>your entire code base for all invokations of foo. >> >>This sort of consistency makes maintaining code easy. The thing you need >>to maintain consistently is the signature of the word (the way it is >>invoked), not the way it is implemented. > > As I demonstrated, explicit setting of the current object is not > needed for this. You have demonstrated that you can produce a workaround by accidentially having a global current object, and that you can therefore create a wrapper that supplies the selector with an object on the stack. In Mini-OOF2, this is by design. >>> Which may be a good idea, it's more consistent with the access to the >>> instance variables of other objects. >> >>Well, you shouldn't access instance variables of other objects... > > That's what I thought when I started working with Java. now I am no > longer convinced of that, at least for Java. I'm not convinced of this rule, either, but at least it should be easier to access the own instance variables (that's why having a current object is so useful). > Anyway, back to our discussion: Yes, that was the idea behind the way > instance variables and methods are handled in objects.fs: > > Only instance variables of the current object should only be accessed, > so instance variables are only visible in their class, and they always > are accessed through the current objects. > > In contrast, methods should be callable everywhere, for arbitrary > objects, so the method selector has a global name, and you pass the > object on which it dispatches explicitly. > > As demonstrated, you can emulate the instance variable interface with > colon definitions or methods, so that's no reason to change that. Mini-OOF2 doesn't handle limited visibility (yet), it will quite likely become another thing that you can have when you want it, but not as essential feature. > Now you just need to document it so we can all see the light:-). Yes. > The other thing is whether you want to keep it dependent on Gforth > features. One of the ideas is that there are a few essential things a system needs to provide to implement OOP with good performance, and these things aren't portable yet. >>If you don't like foo >o bar o> in mini-oof2, add a dot-parser >>recognizer which will transform >> >>foo.bar into foo >o bar o> >>foo->bar into foo @ >o bar o> >> >>with any number of . and -> in the string (just replace all "." with " >o >>" and all "->" with " @ >o " and count the number of occurances, and then >>add that number of " o>" to the end - and reevaluate). > > I have been thinking about something like that, too: > > Have .BAR take the current object from the TOS, and BAR keep it as it > is (although "." is taken as a prefix in Forth, so we should probably > use something else, maybe ":" or "~"; I'll leave that discussion to > someone else, my names are generally disliked:-). This could be > implemented in standard Forth by defining two words, or in > sufficiently capable systems with a dot-parser. So we would have > > foo .bar > foo @ .bar > > for your examples. Yes, that would work, too, making the parser even easier (does it start with a dot? Is the rest found in the dictionary - use word-recognizer for that)? Interpret and compile it wrapped in >o o>. . is indeed "taken", so there can be conflicts. The original suggestion makes the dot parser way more complicated, but then, foo.bar doesn't conflict. -- Bernd Paysan "If you want it done right, you have to do it yourself" http://bernd-paysan.de/
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2014-05-25 18:55 -0500 |
| Message-ID | <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com> |
| In reply to | #30644 |
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: > > Once we have a current object, the question is whether to set it > implicitly on method call (as happens in most OO languages and most > Forth OO packages), or whether to set it explicitly. I don't think that Java and C++ really have a current object: "this" is really just the name given to the first argument that was passed to a (virtual or non-static) method. There is the syntactic convenience that "this" is implicit at the point of call when no receiver is specified, but "this" is entirely transient: it exists only for the duration of a method and is only visible in the scope of that method. Andrew.
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl (Albert van der Horst) |
|---|---|
| Date | 2014-05-26 11:44 +0000 |
| Message-ID | <5383293b$0$4943$e4fe514c@dreader35.news.xs4all.nl> |
| In reply to | #30725 |
In article <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>, Andrew Haley <andrew29@littlepinkcloud.invalid> wrote: >Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: >> >> Once we have a current object, the question is whether to set it >> implicitly on method call (as happens in most OO languages and most >> Forth OO packages), or whether to set it explicitly. > >I don't think that Java and C++ really have a current object: "this" >is really just the name given to the first argument that was passed to >a (virtual or non-static) method. There is the syntactic convenience >that "this" is implicit at the point of call when no receiver is >specified, but "this" is entirely transient: it exists only for the >duration of a method and is only visible in the scope of that method. My take of a current object is apparently totally different. There is one current object for each class, so a method belonging to a class automatically uses that object, without any special care. The current object is changed by executing it. class APE .. endclass APE ian APE jane ian \ Ian is on eat \ Ian eats jane \ Jane is on. eat \ Jane eats Moreover an object has no fields. It has data, and getter and setter methods that are just ordinary methods. Possibly it has a getter for a pointer to a field, which amounts to the dreaded global visibility (as if getters and setters are any different.). Anton Ertl wants invisibility for some things. Well Forth knows namespaces, they are called wordlists. This is an orthogonal concept and can be retrofitted. (In the following CURRENT and CONTEXT are kept the same throughout). PREVIOUS ( order : FORTH ) NAMESPACE %ape% %ape% DEFINITIONS ( order : %ape% FORTH ) class APE .. endclass FORTH DEFINITIONS ( order : FORTH %ape% FORTH ) \ There are the only words exported from %ape% into the forth wordlist 'APE ALIAS APE 'eat ALIAS eat \ There is no need for eat2 to be in %ape% : eat2 eat eat ... accessing private parts of APE .... ; PREVIOUS ( order : %ape% FORTH ) PREVIOUS ( order : FORTH ) \ visible here are : APE eat eat2 Groetjes Albert > >Andrew. Groetjes Albert -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2014-05-27 05:25 -0500 |
| Message-ID | <y8Wdnfz9Hta29RnOnZ2dnUVZ_uGdnZ2d@supernews.com> |
| In reply to | #30749 |
Albert van der Horst <albert@spenarnc.xs4all.nl> wrote: > In article <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>, > Andrew Haley <andrew29@littlepinkcloud.invalid> wrote: >>Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: >>> >>> Once we have a current object, the question is whether to set it >>> implicitly on method call (as happens in most OO languages and most >>> Forth OO packages), or whether to set it explicitly. >> >>I don't think that Java and C++ really have a current object: "this" >>is really just the name given to the first argument that was passed to >>a (virtual or non-static) method. There is the syntactic convenience >>that "this" is implicit at the point of call when no receiver is >>specified, but "this" is entirely transient: it exists only for the >>duration of a method and is only visible in the scope of that method. > > My take of a current object is apparently totally different. > There is one current object for each class, so a method belonging > to a class automatically uses that object, without any special care. > The current object is changed by executing it. > > class APE .. endclass > > APE ian APE jane > ian \ Ian is on > eat \ Ian eats > jane \ Jane is on. > eat \ Jane eats I don't really understand this. Let's say that you have a word FORMAT which does some formatting, and internally it uses OOP. And, you have a word PRINT to print an object. Then (objects called layout and ian) : formatted-print ( obj) layout format print; ian formatted-print wouldn't work, would it? Andrew.
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl (Albert van der Horst) |
|---|---|
| Date | 2014-05-27 11:56 +0000 |
| Message-ID | <53847d84$0$4720$e4fe514c@dreader36.news.xs4all.nl> |
| In reply to | #30826 |
In article <y8Wdnfz9Hta29RnOnZ2dnUVZ_uGdnZ2d@supernews.com>, Andrew Haley <andrew29@littlepinkcloud.invalid> wrote: >Albert van der Horst <albert@spenarnc.xs4all.nl> wrote: >> In article <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>, >> Andrew Haley <andrew29@littlepinkcloud.invalid> wrote: >>>Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: >>>> >>>> Once we have a current object, the question is whether to set it >>>> implicitly on method call (as happens in most OO languages and most >>>> Forth OO packages), or whether to set it explicitly. >>> >>>I don't think that Java and C++ really have a current object: "this" >>>is really just the name given to the first argument that was passed to >>>a (virtual or non-static) method. There is the syntactic convenience >>>that "this" is implicit at the point of call when no receiver is >>>specified, but "this" is entirely transient: it exists only for the >>>duration of a method and is only visible in the scope of that method. >> >> My take of a current object is apparently totally different. >> There is one current object for each class, so a method belonging >> to a class automatically uses that object, without any special care. >> The current object is changed by executing it. >> >> class APE .. endclass >> >> APE ian APE jane >> ian \ Ian is on >> eat \ Ian eats >> jane \ Jane is on. >> eat \ Jane eats > >I don't really understand this. Let's say that you have a word FORMAT >which does some formatting, and internally it uses OOP. And, you have >a word PRINT to print an object. Then > >(objects called layout and ian) > >: formatted-print ( obj) layout format print; >ian formatted-print > >wouldn't work, would it? Apparently you missed something, or I wasn't clear. There is a current object for each class. If I have a `` print '' that prints the current object of class PAIR, it does so regardless of who else is using OOP. A small test example : ------------------------- WANT class WANT SEE 0 0 class PAIR M: two @ M; , M: one @ M; , endclass : print one . two . ; 4 5 PAIR jan 1 2 PAIR piet WORDS ." Expect 4 5 :" jan print CR SEE PAIR SEE BUILD-PAIR SEE one ------------------------- <other output of WORDS snipped> ... SEE ^PAIR two one BUILD-PAIR PAIR print jan piet Expect 4 5 :4 5 : PAIR CREATE BUILD-PAIR ^PAIR ! DOES> ^PAIR ! ; : BUILD-PAIR HERE >R , , R> ; : one ^PAIR @ 8 + @ ; ------------------------- > >Andrew. -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
[toc] | [prev] | [next] | [standalone]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2014-05-26 12:18 -0700 |
| Message-ID | <a5ebce86-6efb-421e-b885-33f99888975f@googlegroups.com> |
| In reply to | #30725 |
On Sunday, May 25, 2014 6:55:12 PM UTC-5, Andrew Haley wrote:
> I don't think that Java and C++ really have a current object: "this"
> is really just the name given to the first argument that was passed to
> a (virtual or non-static) method.
You've said this a few times, but always tentatively like this, or with
reference to a language where the passed object is explicitly an argument of
the method, like Python [or Perl or CL].
If you have a current object, then you can write a non-method that grabs the
current object out of the air:
: .cons ( -- )
." (" car @ . cdr @ 0 .r ." ) " ;
: debug ( -- )
cr ." DEBUG: <other debugging information>. Current class: " o .class ;
And invoke it in the middle of a method or an >o .... o> sequence without
taking any effort to pass anything to it.
If you don't have a current object, then you can't do that. There's nothing to
grab. So Java and C++, and certainly the explicit-passing languages, don't
have this feature at all. objects.fs has it by accident -- if TO-THIS isn't to
be used, then isn't it just an implementation choice to have a VALUE instead of
having methods secretly s" { this }" EVALUATE when defined?
Incidentally, there's no .CLASS in mini-oof2, but when I thought of that as an
example I found that it was easy to graft on:
require mini-oof2.fs
variable classes \ list of (cdr, class, name)
align here classes ! 0 , object , ' object >name ,
: end-class ( class methods vars "name" -- ) end-class
align here classes @ , classes !
lastxt execute , lastxt >name , ;
: .classes ( -- )
classes @ begin dup while
dup cell+ cell+ @ cr .name
@ repeat drop ;
: .class ( o -- )
cell- @ classes @ begin dup while
2dup cell+ @ = if nip cell+ cell+ @ .name exit then
@ repeat 2drop ." <unknown> " ;
-- Julian
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.forth
csiph-web