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