• The joy of OO

    From albert@spenarnc.xs4all.nl@21:1/5 to All on Sat May 24 15:33:57 2025
    There are some good criticisms on OO on youtube. Check out Brian Will.
    (He took on, to rewrite a 3800 line Java program.)
    The idea to combine data and code is good, and recent posts of Will
    reflects that, softening his earlier views a bit.

    We bring onto remembrance how create/does> construct
    "objects with one methods" work in Forth:

    : ARRAY CREATE ALLOT DOES> + ;

    Usage:
    12 ARRAY myname
    3 myname C@ \ third character
    0 myname C! \ store it at the zeroth character,

    In other words "myname" is the single default method, in OO-speak.
    Actually "myname" is a horrible name to call an indexing method;
    that's what it is.

    This holds Forth back. We absolutely need more than one method to get
    anywhere.
    The proper way to do it, is having methods that works on what
    one used to call fields, but note that we from now on we need the
    term field hardly anymore.
    While allocating space we define methods that work on HERE so to
    speak.

    class ARRAY
    M: [] + M; \ Works on HERE.
    ALLOT
    endclass

    An object is made current by stating its name. Right! Just one
    object of the type at the same time available, normally.

    Usage:
    12 ARRAY name
    name 3 [] C@ \ third character
    0 [] C! \ name is still current,store it at the zeroth character,

    Now an array with size.
    class ARRAYS
    M: _size @ m;
    DUP ,
    M: [] + M;
    ALLOT
    endclass

    Usage is the same.
    But now you can do
    12 ARRAYS myname2
    myname2
    0 [] H. \ fetches the address of the zeroth character
    0000,0000,0041,1170 OK
    _size .
    12 OK

    A slight improvement:

    class ARRAYS
    M: _size @ m;
    DUP ,
    M: []
    OVER 0 _size WITHIN 0= 1001 ?THROW
    + M;
    ALLOT
    endclass


    You can also have a pointer to an object on the stack and
    use methods defined as
    M:r _size @ m;

    So far so good. Look how it helps in defining the memory wordset:
    ALLOCATE FREE RESIZE
    This is an implementation of this wordset that was presented by me before traditionally, without Object Orientation.

    The current block idea works well.
    The current block pointer serves as an allocation pointer, but
    it is clear that for FREE and RESIZE we have to resort to M:r style methods.

    The following is stylized for pedagogical purposes.
    Actually the memory set is practical, iron-clad and tested fully.
    This means special cases for speed and exceptions for running out of
    space are left out.

    \ ------------- data structure -----------------------------
    \ Implementation of the memory wordset.
    \ The whole (!) memory space is considered circular, and consists of
    \ blocks. The first cell of a block points to the next block.
    \ The second cell points to the end of the occupied space of the block,
    \ or zero if the space till the next block is totally available.
    \ Naturally Forth and its stacks must be part of the occupied space of some
    \ block.
    2 CELLS CONSTANT overhead \ Administration at start of each block.
    \ ------------- basic structure & basic operations --------------------------- \ Note ^AB contains a pointer to the current block.
    class AB
    M: _bump @ ^AB ! M; \ Make the next block current.
    M: _split DUP 2@ SWAP ALIGNED >R R@ ! R> SWAP ! M; \ Split into alloc and free. M: _avail DUP @ SWAP - overhead - M; \ total AVAILABLE to use as payload. M: _remain 2@ SWAP ALIGNED - overhead - M; \ freely AVAILABLE as payload.
    _ ,

    M: _alloc_f >R R@ CELL+ + SWAP ! M; \ Fill in the allocation SIZE .
    M:r _nonfree? @ M; \ "it IS not free" Dirty flag
    M:r _free 0 SWAP ! M; \ Free the block.
    M:r _size_alloc @+ SWAP - M; \ Return ALLOCATED size, byte granularity.
    _ ,

    M: payload M;
    endclass

    \ Declare a single block, containing the world, including Forth itself.
    HERE DUP , DUP , ^AB !
    : _AH ^AB @ ; \ Current block.


    Once the one-line methods are established and tested,
    note how the Forth code is near the ideal by Chuck Moore
    that the code is its own comment.

    \ ------------- adorned operations -------------

    \ merge free blocks.
    : _merge DUP BEGIN @ DUP _nonfree? UNTIL SWAP ! ;

    \ Search for SIZE . From non-free block to block with enough space.
    : _search BEGIN _merge DUP _remain > WHILE _bump REPEAT DROP ;

    \ From here all addresses are user addresses (as used by Forth.)

    \ Allocate SIZE, return ADDRES.
    : _allocate _merge _bump DUP _search _split _bump _alloc_f payload ;

    \ Resize at ADDRESS to allocated SIZE. Return ADDRES with size.
    : _resize DUP _allocate SWAP CMOVE payload ;

    An occasional DUP, no OVER, and certainly no ROT's and -- heaven forbid --
    no LOCAL's.

    \ ---------------- Forth operations -------------------------
    : ALLOCATE _allocate 0 ; \ ISO
    : FREE overhead - _free 0 ; \ ISO
    : RESIZE _resize 0 ; \ ISO

    \ Practical usage demands:
    \ Return the actual size of an allocated block, byte granularity.
    : SIZE overhead - _size_alloc ;
    ( Set aside X bytes for allocation )
    : INIT-ALLOC HERE ^AB ! ALLOT 0 HERE _AH 2! _AH , _AH , ;

    \ --------------------------------------------------------
    --
    Temu exploits Christians: (Disclaimer, only 10 apostles)
    Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
    Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
    And Gifts For Friends Family And Colleagues.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to albert@spenarnc.xs4all.nl on Sun May 25 18:37:01 2025
    albert@spenarnc.xs4all.nl writes:
    There are some good criticisms on OO on youtube. Check out Brian Will.
    (He took on, to rewrite a 3800 line Java program.)

    If you mean this, the program was in Go rather than Java, though in an
    OO style. After the rewrite, it had fewer functions and files than
    before, but about the same amount of LOC. I watched only a minute or so
    of the video.

    https://www.youtube.com/watch?v=V6VP-2aIcSc

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to no.email@nospam.invalid on Mon May 26 12:36:25 2025
    In article <874ix82lvm.fsf@nightsong.com>,
    Paul Rubin <no.email@nospam.invalid> wrote:
    albert@spenarnc.xs4all.nl writes:
    There are some good criticisms on OO on youtube. Check out Brian Will.
    (He took on, to rewrite a 3800 line Java program.)

    If you mean this, the program was in Go rather than Java, though in an
    OO style. After the rewrite, it had fewer functions and files than
    before, but about the same amount of LOC. I watched only a minute or so
    of the video.

    https://www.youtube.com/watch?v=V6VP-2aIcSc

    Indeed this example is a Golang program. Java promises to be even more
    verbose.

    Groetjes Albert
    --
    Temu exploits Christians: (Disclaimer, only 10 apostles)
    Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
    Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
    And Gifts For Friends Family And Colleagues.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From sjack@21:1/5 to albert@spenarnc.xs4all.nl on Mon May 26 17:19:39 2025
    albert@spenarnc.xs4all.nl wrote:

    This holds Forth back. We absolutely need more than one method to get anywhere.

    A generation ago I explored using defining word to create object
    with multiple methods; not an OO attempt, no class but just a useful
    object. Such an object was "FPAD:" :

    [r] Object Definition
    fpad: ( type buffer size --) \ defining word for file pad object
    \ type =0, line type
    \ type =1, block type
    \ buffer =0, use Pad for buffer
    \ buffer !=0, use buffer

    File Operations (methods)
    read ( -- f) \ read to buffer
    write ( --) \ write from buffer
    wstr ( a u --) \ write from string
    clear ( --) \ clear buffer
    type ( --) \ print string
    dump ( --) \ dump buffer
    id ( -- u) \ file id
    bfr ( -- a u) \ buffer address and count
    $ ( -- a u) \ string address and count
    open ( a u atr --) \ open file
    stdin ( --) \ open /dev/stdin
    create ( a u atr --) \ create file
    close ( --) \ close file
    pos ( -- du) \ position file
    rpo ( du --) \ reposition file

    Structure Maintenance
    ^ ( -- a) \ structure address
    @ ( n1 -- n2) \ fetch word at structure cell n
    ! ( n2 n1 --) \ store word at structure cell n
    ? ( n1 --) \ print word at structure cell n

    [r] Auxiliary words

    Example offset usage:

    foo ^ ^cnt ? \ Print count value

    foo ^ \ returns the pfa of foo
    ^cnt \ adds the count offset
    ? \ prints the value

    ^cnt ( a -- a') add offset to string cnt value +0
    ^str ( a -- a') add offset to string address +4
    ^sz ( a -- a') add offset to bfr cnt value +8
    ^bfr ( a -- a') add offset to bfr address +12
    ^id ( a -- a') add offset to file id value +16
    ^off ( a -- a') add offset to pad offset value +20
    ^read ( a -- a') add offset to read xt +24
    ^write ( a -- a') add offset to write xt +28
    ^blank ( a -- a') add offset to erase xt +32
    ===
    Such object was a defining word with case statement for methods.
    Method names were just labels (an address for id only) thus
    method names could be shared among objects thereby saving memory used
    by method naming.
    Case statement (of ... endof) contains string of code for the
    method. After the case structure, the chosen method was evaluated at
    compile time when the method was used. So an object with its method
    was a macro that compiled code.
    ===
    [r] Example use of FPAD:
    --
    -- wb1 is some work buffer
    -- fp1 will be a line type file object created by fpad:
    --
    0 wb1 wb1.len fpad: fp1

    readit
    It's convenient to create higher level file word that
    need only a filepath as an argument:
    : readit ( filePath --)
    bl parse r/o fp1 open
    begin fp1 read while
    cr fp1 type
    repeat
    fp1 close
    ;

    sh ls>/tmp/ipc \ system shell to create some data
    readit /tmp/ipc \ Forth read the data
    --.

    --
    me

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to sjack on Tue May 27 11:16:31 2025
    In article <10127r9$23us0$1@dont-email.me>, sjack <sjack@dontemail.me> wrote: >albert@spenarnc.xs4all.nl wrote:

    This holds Forth back. We absolutely need more than one method to get
    anywhere.

    A generation ago I explored using defining word to create object
    with multiple methods; not an OO attempt, no class but just a useful
    object. Such an object was "FPAD:" :

    I don't advocate classes with the huge implication of inheritance
    and polyformism either.
    You can reasonably call a defining word to create object with multiple methods a "class". I certainly wouldn't refrain from that.

    <SNIP>

    me

    --
    Temu exploits Christians: (Disclaimer, only 10 apostles)
    Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
    Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
    And Gifts For Friends Family And Colleagues.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)