On Wednesday 18 July 2007 04:42, Slava Pestov wrote:

Since yesterday, I've had time to recode a few things and think more about 
what I'm proposing. It's actually very conseravative.

  * TUPLE: generates a default <foo> constructor (done)

  * Remove C:

In my experience, custom constructors are often easily defined in terms of the 
BOA constructor. For exceptional cases where it's not convenient to line 
things up BOA, what you're proposing below would help.

However, my original thought was to name the default constructor <foo*>, so 
that we can easily tell which are the BOA constructors versus others that may 
actually do some initialization. Initialization is very common so I thought 
we could reserve the <foo> name for those. They just wouldn't get the special 
C: treatment.

That alone would help. In some of my code, I'm changing things to no longer 
use C:. I'm leaving the <foo> words as BOAs and defining new make-foo words 
to do the initialization. This is my workaround convention.

The other idea is:

        set-delegate ( object delegate -- delegate )

And lastly, slot setters with effect:

        set-player-foo ( object value -- object )

The first item is good because it's actually removing code, i.e. the C: form.

The second item I believe is not too controversial and would help in the 
majority of uses I think.

The last, I recognize, is controversial.

Here's another example. It's the label widget constructor from x.widgets:

TUPLE: label text gc ;

C: label ( text -- label )
tuck set-label-text
<gc> over set-label-gc
<window> over set-delegate
dup add-to-window-table
{ ExposureMask } over select-input ;

The new version is:

: make-label ( text -- label )
<gc> <label> <window> set-delegate add-to-window-table
{ ExposureMask } select-input ;

* In terms of the BOA
* set-delegate is a "pipe"
* add-to-window-table and select-input changed to be "pipe" words

The set-slots word is cool, I'm going to see if it can help clean things up in 
other places.

> Chris Double's ogg player code uses a pair of words, slots and set-
> slots to read/write multiple slots:
>
> { player-foo player-bar } slots
>
> is the same as
>
> [ player-foo ] keep player-bar

> There's a set-slots which reads inputs from the stack too:
>
> { set-player-foo set-player-bar } set-slots
>
> this becomes
>
> set-player-bar [ set-player-foo ] keep

Hmm. Perhaps thats:

[ set-player-foo ] keep set-player-bar

> As for custom constructors, how about this - its not coded but would
> be easy to cook up:
>
> : <funny-player> { set-player-foo set-player-bar } player construct ;
> :
> : empty-tuple 1array >tuple ;
> : construct empty-tuple [ swap set-slots ] keep ;

This is good if you want to set a subset of the tuple slots in a certain 
order. If you can line things up for a BOA, it's probably better to go that 
route. However, in cases where you have a very large tuple and you only need 
to set a couple of items, set-slots and construct are good. ... Let's look at 
that actual player tuple. Well golly gee:

TUPLE: player stream temp-state 
       op oy og 
       vo vi vd vb vc vorbis
       to ti tc td yuv rgb theora video-ready? video-time video-granulepos
       source buffers buffer-indexes start-time
       playing? audio-full? audio-index audio-buffer audio-granulepos 
       gadget ;

'very large tuple'? Check. 'Need to set a couple of items'? Check. :-)

Hmmm. I found get-slots in ogg.player.utils. Where is set-slots?

Anyways, I rewrote some of that code:

----------------------------------------------------------------------

TUPLE: player stream temp-state 
       op oy og 
       vo vi vd vb vc vorbis
       to ti tc td yuv rgb theora video-ready? video-time video-granulepos
       source buffers buffer-indexes start-time
       playing? audio-full? audio-index audio-buffer audio-granulepos 
       gadget ;

! changed to a 'pipe' effect

: init-vorbis ( player -- player )
    dup player-oy ogg_sync_init drop
    dup player-vi vorbis_info_init 
    dup player-vc vorbis_comment_init ;

! changed to a 'pipe' effect

: init-theora ( player -- player )
    dup player-ti theora_info_init 
    dup player-tc theora_comment_init ;

! changed to a 'pipe' effect
! uses 'pipe' style setters

: init-sound ( player -- player )
    init-openal check-error
    1 gen-buffers check-error       set-player-buffers
    2 "uint" <c-array>              set-player-buffer-indexes
    1 gen-sources check-error first set-player-source ;

! versus:

! : init-sound ( player -- player )
!     init-openal check-error
!     1 gen-buffers check-error over set-player-buffers
!     2 "uint" <c-array> over set-player-buffer-indexes
!     1 gen-sources check-error first swap set-player-source ;

! uses 'pipe' style setters

: <player> ( stream -- player )
    <player~> swap set-player-stream
    0 set-player-vorbis
    0 set-player-theora 
    0 set-player-video-time 
    0 set-player-video-granulepos 
    f set-player-video-ready?
    f set-player-audio-full?
    0 set-player-audio-index    
    0 set-player-start-time
    audio-buffer-size "short" <c-array> set-player-audio-buffer
    0 set-player-audio-granulepos
    f set-player-playing?
    "ogg_packet" malloc-object       set-player-op
    "ogg_sync_state" malloc-object   set-player-oy 
    "ogg_page" malloc-object         set-player-og
    "ogg_stream_state" malloc-object set-player-vo
    "vorbis_info" malloc-object      set-player-vi
    "vorbis_dsp_state" malloc-object set-player-vd
    "vorbis_block" malloc-object     set-player-vb
    "vorbis_comment" malloc-object   set-player-vc 
    "ogg_stream_state" malloc-object set-player-to
    "theora_info" malloc-object      set-player-ti
    "theora_comment" malloc-object   set-player-tc
    "theora_state" malloc-object     set-player-td 
    "yuv_buffer" <c-object>          set-player-yuv
    "ogg_stream_state" <c-object>    set-player-temp-state
    init-sound
    init-vorbis 
    init-theora ;

----------------------------------------------------------------------

In that version of the constructor, there's only one shuffle word left.

Here's more data supporting 'pipe' style setters. Let's look at all the places 
where a setter is used. There are 48 calls to setters. 45 of them are 
preceded by 'over'. 2 of them are preceded by 'swap'. Those two are cases 
where the player didn't need to be kept on the stack. The 1 of them was 
wrapped in a keep.

    $ grep 'set-player-' player.factor

    1 gen-buffers check-error over set-player-buffers
    2 "uint" <c-array> over set-player-buffer-indexes
    1 gen-sources check-error first swap set-player-source ;
    [ set-player-stream ] keep
    0 over set-player-vorbis 
    0 over set-player-theora 
    0 over set-player-video-time 
    0 over set-player-video-granulepos 
    f over set-player-video-ready?
    f over set-player-audio-full?
    0 over set-player-audio-index    
    0 over set-player-start-time    
    audio-buffer-size "short" <c-array> over set-player-audio-buffer
    0 over set-player-audio-granulepos
    f over set-player-playing?
    "ogg_packet" malloc-object over set-player-op
    "ogg_sync_state" malloc-object over set-player-oy 
    "ogg_page" malloc-object over set-player-og
    "ogg_stream_state" malloc-object over set-player-vo
    "vorbis_info" malloc-object over set-player-vi
    "vorbis_dsp_state" malloc-object over set-player-vd
    "vorbis_block" malloc-object over set-player-vb
    "vorbis_comment" malloc-object over set-player-vc 
    "ogg_stream_state" malloc-object over set-player-to
    "theora_info" malloc-object over set-player-ti
    "theora_comment" malloc-object over set-player-tc
    "theora_state" malloc-object over set-player-td 
    "yuv_buffer" <c-object> over set-player-yuv
    "ogg_stream_state" <c-object> over set-player-temp-state
        millis over set-player-start-time    
    dup player-buffers 1 gen-buffers append over set-player-buffers 
    t over set-player-playing? t ;
    copy-to-theora-state 1 over set-player-theora ;
    copy-to-vorbis-state 1 over set-player-vorbis ;
    dup player-vorbis 1+ over set-player-vorbis ;
    dup player-theora 1+ over set-player-theora ;
    4 * * "uchar" <c-array> over set-player-rgb ;
    dup player-audio-index 1+ swap set-player-audio-index ;
        t over set-player-audio-full?
        pick - over set-player-audio-granulepos
        pick + over set-player-audio-granulepos
            dup player-td theora_state-granulepos over
                set-player-video-granulepos
            over set-player-video-time
            t over set-player-video-ready?
            f over set-player-audio-full?
            0 over set-player-audio-index
            f over set-player-video-ready?
    dup <theora-gadget> over set-player-gadget

> We could have it so that TUPLE: foo ... ; doesn't define a <foo> at
> all; C: foo <foo> defines a default <foo> "BOA" constructor, but any
> number of custom constructor words with any name can be defined to
> call 'construct' just by using :.

That could work too.

> Note that the above would be more pleasant if slot words did not
> contain the tuple class name in them!

Right!

Ed


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Factor-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to