Sunday, March 28, 2010

Modularity within an Operational Grammar

In the previous example, I purposely left a fairly obvious section of "straight HTML" at the bottom of the grammar.

The detail in this section could be turned into a grammar "module", shrinking the "core" grammar, making it more comprehensible.

WikiBase.gx

. start@ :: {{ wiki }}

. wiki@url_name(page) :: {{wiki_page}}
. wiki@url_name(edit) :: {{wiki_edit_page}}
. wiki@ :: {{wiki_page}}

. wiki_page@url_name(page) :: {{ html_page( *page, wiki_content(*page) ) }}
. wiki_page@ :: {{ html_page( "WikiHome", wiki_content("WikiHome") ) }}

. wiki_edit_page@ :: {{ html_page( *edit, wiki_edit ( *edit ) ) }}

. wiki_content@ :: {{ wiki_top ($1) }} {{ wiki_text ($1) }} {{ edit_link ($1)}} {{ wiki_footer }}

. wiki_edit@ :: {{ wiki_top ($1) }} {{ wiki_form ( wiki_text ) }} {{ wiki_footer }}

. wiki_text@url_name(edit) :: {{ wiki_text.value }}
. wiki_text@ :: {{ wiki_strings (wiki_text.value) }}

. edit_link@ :: {{a_link ("/edit="+$1,"Edit "+$1)}}

. wiki_strings@pattern("\<[^<>]*\>") ::
. wiki_strings@pattern("([A-Z][a-z]+)+") :: {{ a_link("/page="+*1,*1) }}
. wiki_strings@pattern("---+") :: {{ hr }}
. wiki_strings@pattern("\*") ::    •

. wiki_top@ :: <div style="font-weight:bold;">{{ a_link( "/page="+$1, $1 ) }}</div>
. wiki_footer@ :: copyright © {{*year}}

. wiki_form@ :: <form action="/page={{*page}}" method="post">{{form_textarea(*page)}}{{form_button}}</form>

. form_textarea@ :: <textarea name="{{*page}}">{{wiki_text}}</textarea>
. form_button@ :: <input type="submit" name="button" value="save">

... html

It seems like the next nearly modular sub-grammar is the wiki_strings section that handles the retrieval of string content. Obviously this section would be much larger in, say, the WikiMedia codebase. So it makes sense to abstract it away from the core grammar.

WikiBase.gx

. start@ :: {{ wiki }}

. wiki@url_name(page) :: {{wiki_page}}
. wiki@url_name(edit) :: {{wiki_edit_page}}
. wiki@ :: {{wiki_page}}

. wiki_page@url_name(page) :: {{ html_page( *page, wiki_content(*page) ) }}
. wiki_page@ :: {{ html_page( "WikiHome", wiki_content("WikiHome") ) }}

. wiki_edit_page@ :: {{ html_page( *edit, wiki_edit ( *edit ) ) }}

. wiki_content@ :: {{ wiki_top ($1) }} {{ wiki_text ($1) }} {{ edit_link ($1)}} {{ wiki_footer }}

. wiki_edit@ :: {{ wiki_top ($1) }} {{ wiki_form ( wiki_text ) }} {{ wiki_footer }}

. wiki_text@url_name(edit) :: {{ wiki_text.value }}
. wiki_text@ :: {{ wiki_strings (wiki_text.value) }}

. edit_link@ :: {{a_link ("/edit="+$1,"Edit "+$1)}}

. wiki_top@ :: <div style="font-weight:bold;">{{ a_link( "/page="+$1, $1 ) }}</div>
. wiki_footer@ :: copyright © {{*year}}

. wiki_form@ :: <form action="/page={{*page}}" method="post">{{form_textarea(*page)}}{{form_button}}</form>

. form_textarea@ :: <textarea name="{{*page}}">{{wiki_text}}</textarea>
. form_button@ :: <input type="submit" name="button" value="save">

... wiki_strings
... html

Although it doesn't shorten the core grammar much, moving the 3 lines of the edit form to its own module makes sense, given how complex an editor can become.

WikiBase.gx

. start@ :: {{ wiki }}

. wiki@url_name(page) :: {{wiki_page}}
. wiki@url_name(edit) :: {{wiki_edit_page}}
. wiki@ :: {{wiki_page}}

. wiki_page@url_name(page) :: {{ html_page( *page, wiki_content(*page) ) }}
. wiki_page@ :: {{ html_page( "WikiHome", wiki_content("WikiHome") ) }}

. wiki_edit_page@ :: {{ html_page( *edit, wiki_edit ( *edit ) ) }}

. wiki_content@ :: {{ wiki_top ($1) }} {{ wiki_text ($1) }} {{ edit_link ($1)}} {{ wiki_footer }}

. wiki_edit@ :: {{ wiki_top ($1) }} {{ wiki_form ( wiki_text ) }} {{ wiki_footer }}

. wiki_text@url_name(edit) :: {{ wiki_text.value }}
. wiki_text@ :: {{ wiki_strings (wiki_text.value) }}

. edit_link@ :: {{a_link ("/edit="+$1,"Edit "+$1)}}

. wiki_top@ :: <div style="font-weight:bold;">{{ a_link( "/page="+$1, $1 ) }}</div>
. wiki_footer@ :: copyright © {{*year}}

... wiki_edit
... wiki_strings
... html

What we're left with is, perhaps, what we'd expect from WikiBase: the large-scale structure of a web service with two dynamic web pages.

I imagine clicking on an ellipsis (or hitting a key when it's highlighted) in order to see the sub-grammar. That sub-grammar of course will have its own module declarations etc.

Note that this makes immediate opportunities for (1) standardized definitions for interaction with modules and (2) standardized modules.

In a way, the grammar rather forced us to do this. It's slightly different from the way it forced us to separate the context from the grammar: the context interface became defined because the context wasn't part of the system derivation we focused on. That is, if you focus on the structure of a system, a context will always emerge that will make it easier to define the system grammatically. Modules are slightly different. In the process of deriving the system grammar, we notice sub-grammars that are quite modularized, even though they may be used pervasively by the grammar. We keep them in the grammar, but we put them aside. This is different from the context interface, which would be difficult to include in the grammar. It's really a matter of where you start. If we wrote a different grammar, with a focus on building a web server, then the context interface would be different -- it would be the operating system. A wiki, or any web service, would be something so far down from a web server grammar, that it would be running inside a standardized module (the application container).

I think it's a strength of this approach that, no matter where you start, it seems like you'll derive a rather similar layering of operational grammars. This is probably because we're focusing so intently on the structure of the functionality: there is no reason to believe that the solutions would be very different.

No comments:

Post a Comment