Thursday, December 07, 2006
Experimental Factor module system
I have criticized the Factor module system in #concatenative as well as on the factor-talk mailing list. I've started to implement some ideas that I have.
A vocabulary name should correspond to a file. Here are some examples:
Right now, Factor modules reside in core/ libs/ and apps/. To experiment with my ideas I made a new directory called vocabs/ in the Factor directory. You can see a copy of the vocabs directory I used for testing here:
One thing to note about my vocabs/ directory is that there are no load.factor files. Also, none of the *.factor files contain any REQUIRES: or PROVIDES: calls.
The code I wrote to implement this experiment is at:
I took some modules from libs/ and apps/ and redressed them a bit. There are 5 vocabularies in the vocabs folder:
vars and alien are independent vocabularies. The other three have dependencies. For example automata depends on vars, slate and opengl.
When you do a USE: foo.bar, Factor should add foo.bar to the search path. If foo.bar is not a vocabulary, it be loaded from a file. If that fails then Factor should report a problem. If you look at the code for USE:, you'll notice a word check-vocab. I implemented my own version of check-vocab that loads a vocabulary from a file if it doesn't yet exist:
Then I replaced the check-vocab word in the parser vocabulary:
Take a look at the header in automata.factor:
There's no REQUIRES: statement. The non-core vocabulary dependencies are listed there: vocabs.vars vocabs.slate vocabs.opengl. If they don't exist, USING: will take care of loading them. <borat>very nice!<borat>.
These vocabulary names should actually be called:
but of course I put them all in vocabs.* to not conflict with the current libs and apps.
A vocabulary name should correspond to a file. Here are some examples:
libs.vars => "libs/vars/vars.factor"
core.collections.arrays => "core/collections/arrays/arrays.factor"
vocab-file
implements this mapping:
: vocab-file ( vocab -- file )
"." split
dup peek ".factor" append add
"/" join
resource-path ;
Right now, Factor modules reside in core/ libs/ and apps/. To experiment with my ideas I made a new directory called vocabs/ in the Factor directory. You can see a copy of the vocabs directory I used for testing here:
http://onigirihouse.com:9000/vocabs/
One thing to note about my vocabs/ directory is that there are no load.factor files. Also, none of the *.factor files contain any REQUIRES: or PROVIDES: calls.
The code I wrote to implement this experiment is at:
http://onigirihouse.com:9000/vocab.factor
I took some modules from libs/ and apps/ and redressed them a bit. There are 5 vocabularies in the vocabs folder:
vocabs.vars
vocabs.alien
vocabs.opengl
vocabs.slate
vocabs.automata
vars and alien are independent vocabularies. The other three have dependencies. For example automata depends on vars, slate and opengl.
When you do a USE: foo.bar, Factor should add foo.bar to the search path. If foo.bar is not a vocabulary, it be loaded from a file. If that fails then Factor should report a problem. If you look at the code for USE:, you'll notice a word check-vocab. I implemented my own version of check-vocab that loads a vocabulary from a file if it doesn't yet exist:
: check-vocab* ( name -- vocab )
{ { [ dup vocab ]
[ vocab ] }
{ [ dup vocab-file exists? ]
[ dup vocab-file run-file
vocab ] }
{ [ t ]
[ <check-vocab> { { "Continue" f } } condition ] }
} cond ;
Then I replaced the check-vocab word in the parser vocabulary:
IN: parser
: check-vocab check-vocab* ;
Take a look at the header in automata.factor:
USING: kernel namespaces hashtables sequences generic math arrays
threads opengl gadgets
vocabs.vars vocabs.slate vocabs.opengl ;
IN: vocabs.automata
There's no REQUIRES: statement. The non-core vocabulary dependencies are listed there: vocabs.vars vocabs.slate vocabs.opengl. If they don't exist, USING: will take care of loading them. <borat>very nice!<borat>.
These vocabulary names should actually be called:
libs.vars
libs.alien
libs.opengl
libs.slate
apps.automata
but of course I put them all in vocabs.* to not conflict with the current libs and apps.