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:

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.

This page is powered by Blogger. Isn't yours?