Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.forth

Reply
 
Thread Tools Display Modes
  #16 (permalink)  
Old 10-29-2011, 10:47 PM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 29, 4:06*pm, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
wrote:
> On 28/10/2011 23:40, Krishna Myneni wrote:
>
>
>
>
>
>
>
> > I've posted an example of the type of modular code I had in mind,
> > including the modules interface (v. 0.3.1), at

>
> >ftp://ccreweb.org/software/kforth/ex...ental/modules/

>
> > The main application is

>
> > term.4th

>
> > It relies on the following modules,

>
> > serial.4th
> > serial-comm.4th
> > dummy-comm.4th
> > terminal.4th

>
> > The terminal module allows for different communications interfaces to
> > be used. Here, in the application loader, term.4th, either the serial
> > comm interface can be used or the dummy comm interface can be used.

>
> > The serial port code is specific to kForth because of a requirement
> > for non-blocking I/O. The main purpose of the example is to show how
> > different modules can implement words with the same names in their
> > public interfaces, and this does not create a problem in writing code
> > that is reusable, and also loadable at the same time. Examples of
> > public words which are reused are OPEN CLOSE WRITE GET PUT , etc.

>
> [..]
>
> ISTM that applications like this are begging to be implemented in OO
> Forth. e.g in rough outline using Mini-oof syntax and the hierarchy is
> probably wrong:
>
> object class
> * * method open
> * * method close
> * * method write
> * * method get
> * * method put
> end-class DummyComm
>
> :noname *( code for dummy open ) *; DummyComm defines open
> :noname *( code for dummy close ) ; DummyComm defines close
> etc
>
> DummyComm class
> * * \ any additional methods
> end-class Serial
>
> :noname ( ... ) ; Serial defines open
> :noname ( ... ) ; Serial defines close
> etc
>
> Serial class
> * * ( ... )
> end-class SerialComm
>
> :noname ( ... ) ; SerialComm defines open
> :noname ( ... ) ; SerialComm defines close
> etc
> etc
>
> \ Code for methods can call that for the parent class where appropriate
>
> \ Define objects which will then be used to call the methods.
> Serial new constant serial
> SerialComm new constant serial-comm
>
> \ Use these objects to call the methods
>
> Sorry this isn't a helpful discussion of your modules code but I thought
> it worth pointing out an alternative. Whether one technique is better
> than the other is, I suppose, just a matter of taste.
>


Thanks, Gerry. I think it is actually useful to contrast object
oriented code with the modular example I gave. OOF may indeed be more
appropriate for this case. Depends on the complexity of the
application, I suppose. There are also cases where OOF is likely to be
of negligible benefit, e.g. the FSL . Past experiments with C++ and
numerical computing suggest this.


> Classes are a sort of module anyway and, in addition, you could
> modularise an OOF version if so desired. Having classes inside a module
> is one reason I would like to see modules nestable.
>


The particular modules scheme proposed here encourages name reuse in
the public interfaces of modules -- this is different from modules in
C, and closer to classes in C++.

> Of course the same sort of thing can be done using deferred words
> instead of an OOF.
>


Multiple instances of a module can coexist by using separate
vocabularies/modules. It shouldn't be hard to give an example of
having a co-existing dummy comm terminal and a serial comm terminal,
within the application. Of course, in OOF, it's fairly trivial to do
that.

> --
> Gerry


Krishna

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #17 (permalink)  
Old 10-29-2011, 11:51 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 29, 6:40*pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> Ok. At this point, it's not clear to me how object-oriented code
> should be mixed with my proposed module scheme. Need to try to use
> mini-oof within a module, to see what makes sense.


One issue, since mini-oof is used in pairs, the [] operator might be
extended to include phrases from inside a vocabulary, perhaps:
[{ foo open widget }]

> Thanks for the rev. I will try it.


4 typos in that one ~ PUBLIC instead of PUBLIC: , a stray >IN ! with
its matching >IN @ already factored out, a "0=" missing before an
ABORT"

So try this one instead:
----------------------
\ modules031-revA.4th
( Title: Modular programming in Forth
File: modules.4th
Version: 0.3.1 - Revision A
Revised: October 28, 2011
Revision: A, October 29 2011 BRM


Description:
-----------

This library provides a facility for modular programming in
Forth. It supports both named and unnamed modules, and allows
for private definitions in a module to be made accessible.
The library uses design features from several sources:
David N. Williams' root-module.fs [v 0.8.2], Bruce McFarling's
suggested module facility for the Forth Scientific Library [FSL],
the original module facility in the FSL's fsl-util auxiliary files,
and Neal Bridges' anonymous modules code.


Design elements:
---------------

1. The layout of a module is determined by the following words:

MODULE: BEGIN-MODULE PUBLIC: PRIVATE: END-MODULE

Here, BEGIN-MODULE is where the module begins, and END-MODULE
is where it ends. The code area between the two is "inside" the
module. The words PUBLIC: and PRIVATE: control the visibility
of the module code to external code and to the user. Assigning
a name to the module with MODULE: is optional, but highly
encouraged to avoid name clash problems.

1A. An alternate layour it:

PRIVATE-MODULE: BEGIN-MODULE PUBLIC: PRIVATE: END-MODULE

Here, PRIVATE-MODULE names a private module but compiles PUBLIC
words into the present compilation target

2. A module contains two types of words: "public" and "private".
The word PUBLIC: declares that subsequent definitions are
public words, while the word PRIVATE: declares subsequent
definitions to be private words. The public words of a
module constitute the API or application programming
interface to the module. Private words are not intended
to be used by the module user.


3. A module may or may not be named:

a] For an unnamed module, the public definitions are compiled
into the current compilation wordlist.

b] For a named module, the public definitions are compiled
into a new wordlist, the module's public wordlist. Invoking
the module name replaces the top wordlist id on the search
order with the public wordlist of the module. To add the
public wordlist to the search order, use

ALSO <module_name>

c] For both a named and an unnamed module, a new private
wordlist is created. For named modules, the private
wordlist id can be retrieved using >PRIVATE on the
module xt. The private wordlist of an unnamed module
is not accessible outside the module.

4. PRIVATE: and PUBLIC: should occur only inside a module, and may
be invoked any number of times there, in any order. Definitions
inside a module usually go into its public or private
wordlist.

5. The module layout is not nestable.

6. The search order depth and compilation wordlist just before either
MODULE: or PRIVATE-MODULE: or, if the module is anonymous,
BEGIN-MODULE are restored by END-MODULE. The part of the search
order present before this point may not be changed inside the
module.

[This could be made safer by actually saving and restoring
the initial search order. This implementation does not do
that.]

7. The module name reference operator, [] , allows direct
referencing of a word inside of a named module, using the
syntax,

[] <module_name> <word>

The reference operator [] may be used in either compilation
or interpretation state.
)


\ *** GENERAL USE

[UNDEFINED] drops [IF] \ BMcF
: drops ( +n -- ) 0 ?DO drop LOOP ; [THEN]

[UNDEFINED] order-drops [IF]
: order-drops ( +n -- ) ( o: wid_n ... wid_1 -- )
0 ?DO previous LOOP ; [THEN]

[UNDEFINED] order-depth [IF]
: order-depth ( -- n ) get-order dup >r drops r> ; [THEN]

[UNDEFINED] >order [IF] \ same as BMcF's ADD-WORDLIST
: >order ( wid -- order: wid )
>r get-order r> swap 1+ set-order ; [THEN]


[UNDEFINED] order> [IF] \ not used in this module
: order> ( o: wid -- ) ( -- wid )
get-order swap >r 1- set-order r> ; [THEN]

[UNDEFINED] order@ [IF] \ not used in this module
: order@ ( o: wid -- ) ( -- wid )
get-order over >r drops r> ; [THEN]


[UNDEFINED] MODULE: [IF]

: NAMEDLIST: ( "name" -- ) \ F83 style vocabulary
WORDLIST CREATE , DOES> order> drop @ >order ;

GET-CURRENT
NAMEDLIST: Module-System
ALSO Module-System DEFINITIONS

\ *** PRIVATE DEFINITIONS

VARIABLE prior-defs DUP prior-defs !
VARIABLE public-defs public-defs !
VARIABLE prior-depth order-depth 1- prior-depth !
VARIABLE private-defs order@ private-defs !

: PRIVATE: ( -- ) private-defs @ SET-CURRENT ;
: PUBLIC: ( -- ) public-defs @ SET-CURRENT ;

: END-MODULE ( o: <extras> -- )
(
Restore the initial search order depth and compilation wordlist. An
ambiguous condition exists if the initial search order has been
clobbered. Reset the named-module flag.
)
prior-defs @ SET-CURRENT
order-depth prior-depth @ - order-drops
0 prior-depth ! ;

: NAMEDLIST&ID: ( "name" -- wid ) \ create namedlist & return wid
>IN @ NAMEDLIST: >IN ! ALSO ' EXECUTE order> ;


\ *** PUBLIC DEFINITIONS

PUBLIC:

\ Conditional compilation test for whether module
\ definition is already in progress

: Default-Module? ( -- flag ) prior-depth @ 0= ;

\ Create a named private module and store information
\ for BEGIN-MODULE

: PRIVATE-MODULE: ( "name" -- )
order-depth prior-depth !
GET-CURRENT DUP prior-defs ! DUP public-defs !
ALSO Module-System DEFINITIONS NAMEDLIST&ID: private-defs !
SET-CURRENT PREVIOUS ;

\ Create named public module and store information
\ for BEGIN-MODULE

: MODULE: ( "name" -- )
>IN @ PRIVATE-MODULE:
>IN ! NAMEDLIST&ID: public-defs ! ;


\ Add private wordlist to search order
: ALSO-PRIVATE: ( "module" -- wid )
BL WORD COUNT ALSO Module-System order> SEARCH-WORDLIST 0= ABORT"
Module not found."
ALSO EXECUTE ;

\ BEGIN-MODULE and END-MODULE are not to be nested.

: BEGIN-MODULE ( -- ) ( o: -- public private )
(
Save information that allows END-MODULE to restore the initial
search order and compilation wordlist, assuming the initial
order has remained unchanged. If a module definitions is not
already in process, set up the private and public wordlist.
Push the public and private wordlists onto the search order,
and set the private wordlist to be the current compilation
wordlist.
)
prior-depth @ 0= IF
order-depth prior-depth !
WORDLIST private-defs !
GET-CURRENT public-defs !
THEN ALSO Module-System
public-defs @ >order
private-defs @ >order
DEFINITIONS ;

\ Module targeted word reference operator
: []
state @ if bl word find 0= ABORT" Unknown Module!"
else ' then also execute
state @ if postpone ['] postpone execute else ' execute then
previous
; immediate

END-MODULE

[THEN]
\ --------------------------------------------
Reply With Quote
  #18 (permalink)  
Old 10-30-2011, 02:11 AM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 29, 5:47*pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> On Oct 29, 4:06*pm, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
> wrote:


>
> > ISTM that applications like this are begging to be implemented in OO
> > Forth.

....
> Multiple instances of a module can coexist by using separate
> vocabularies/modules. It shouldn't be hard to give an example of
> having a co-existing dummy comm terminal and a serial comm terminal,
> within the application. Of course, in OOF, it's fairly trivial to do
> that.
>


Below is shown a way to have multiple instances of a terminal. I have
both a dummy terminal and a serial terminal coexisting in the Forth
environment, and the user may interactively choose his comm interface.
It's a little messier than what would be required in OOF, but far less
messier, I believe, than doing the same thing without a modules
implementation. Irrelevant portions of the revised term.4th are not
shown. Incidentally, in doing this whole exercise, I found a bug in
kForth which does not allow me to tick a created structure and execute
it. That will be fixed ASAP.

Krishna

--
\ term.4th

\ include statements ...

\ Load multiple communications interfaces, and allow user
\ to select the comm interface to use within a terminal.

Defer Comm

\ Create a dummy terminal module
include dummy-comm \ Dummy Asynchronous Communications Interface
' dummy-comm IS Comm
include terminal
: dummy-term terminal ;

\ Create a serial terminal module
include serial \ Serial Port I/O Module
include serial-comm \ Serial Communications Interface
' serial-comm IS Comm
include terminal
: serial-term terminal ;

\ Other terminals ...


: term ( -- | start a terminal )
cr ." Select a terminal, a) dummy b) serial: "
key
case
[char] a OF :: dummy-comm config
:: dummy-term start ENDOF
[char] b OF :: serial-comm config
:: serial-term start ENDOF
endcase
;

ALSO Forth

cr .( Type 'term' to start the terminal.)


Reply With Quote
  #19 (permalink)  
Old 10-30-2011, 09:42 AM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 28, 5:40*pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> I've posted an example of the type of modular code I had in mind,
> including the modules interface (v. 0.3.1), at
>
> ftp://ccreweb.org/software/kforth/ex...ental/modules/
>

....
> The terminal module needs a little better factoring. ...


The terminal module, terminal.4th, is better factored now. In
particular the logic of the module word START is more easily
comprehensible.

There's also one new feature to allow echo toggling.

Krishna
Reply With Quote
  #20 (permalink)  
Old 10-30-2011, 11:34 AM
Andrew Haley
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

Krishna Myneni <krishna.myneni@ccreweb.org> wrote:

> The main purpose of the example is to show how different modules can
> implement words with the same names in their public interfaces, and
> this does not create a problem in writing code that is reusable, and
> also loadable at the same time. Examples of public words which are
> reused are OPEN CLOSE WRITE GET PUT , etc.


But isn't the disadvantage of this scheme that it actually
*encourages* people to use names that will collide in public words? I
admit that it's not an overwhelming problem because the user of a
module can create unique aliases for the public words, but it's not
ideal.

Look at this:

: open ( aconfig -- )
dup port @ :: serial open com !
dup params com @ swap :: serial set-params
baud @ com @ swap :: serial set-baud ;

which could be

: comm-open ( aconfig -- )
dup port @ serial-open com !
dup params com @ swap serial-set-params
baud @ com @ swap serial-set-baud ;

which is simpler, easier to read, and uses just "vanilla" Forth.
Better in every way, IMO.

Maybe it's just that a serial port is just too small an example to
show the advantages of the modules approach. Serial comms in Forth is
usually just a matter of a couple of dozen lines, although I admit
that the rather complex UNIX-style interface doesn't help.

Andrew.
Reply With Quote
  #21 (permalink)  
Old 10-30-2011, 12:39 PM
Elizabeth D. Rather
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On 10/30/11 8:34 AM, Andrew Haley wrote:
> Krishna Myneni<krishna.myneni@ccreweb.org> wrote:
>
>> The main purpose of the example is to show how different modules can
>> implement words with the same names in their public interfaces, and
>> this does not create a problem in writing code that is reusable, and
>> also loadable at the same time. Examples of public words which are
>> reused are OPEN CLOSE WRITE GET PUT , etc.

>
> But isn't the disadvantage of this scheme that it actually
> *encourages* people to use names that will collide in public words? I
> admit that it's not an overwhelming problem because the user of a
> module can create unique aliases for the public words, but it's not
> ideal.


Open Firmware has "packages" for each device it supports, with a
standardized set of commands such as OPEN CLOSE READ WRITE etc. for
which there's a version for each device. These packages are structured
as wordlists. You name a device, and then get access to the API for that
device. Within a package, certain words are public, some private
(actually, headless), and some have heads or not depending on a switch
set at compile time. If you SEE a definition that references headless
words, you get the address for that word, and (if you wish) you can feed
that address to (SEE) and look at it.

That works very well for OF's purposes, though I'm not sure it's
appropriate for generalized code management, where you don't have the
conceptual parallelism that characterizes OF's device support.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================
Reply With Quote
  #22 (permalink)  
Old 10-30-2011, 01:43 PM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 7:34*am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> > The main purpose of the example is to show how different modules can
> > implement words with the same names in their public interfaces, and
> > this does not create a problem in writing code that is reusable, and
> > also loadable at the same time. Examples of public words which are
> > reused are OPEN CLOSE WRITE GET PUT , etc.

>
> But isn't the disadvantage of this scheme that it actually
> *encourages* people to use names that will collide in public words? *I
> admit that it's not an overwhelming problem because the user of a
> module can create unique aliases for the public words, but it's not
> ideal.
>
> Look at this:
>
> : open ( aconfig -- )
> * * * * dup port @ :: serial open com !
> * * * * dup params com @ swap :: serial set-params
> * * * * * * baud @ com @ swap :: serial set-baud ;
>
> which could be
>
> : comm-open ( aconfig -- )
> * * * * dup port @ serial-open com !
> * * * * dup params com @ swap serial-set-params
> * * * * * * baud @ com @ swap serial-set-baud ;
>
> which is simpler, easier to read, and uses just "vanilla" Forth.
> Better in every way, IMO.
>
> Maybe it's just that a serial port is just too small an example to
> show the advantages of the modules approach. *Serial comms in Forth is
> usually just a matter of a couple of dozen lines, although I admit
> that the rather complex UNIX-style interface doesn't help.
>
> Andrew.



I think the best answer to your question will come from going through
the exercise of implementing a terminal, using just vanilla Forth,
that can be reused either with a serial port, or which talks to
another (dummy) interface.

Krishna
Reply With Quote
  #23 (permalink)  
Old 10-30-2011, 02:30 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 9:39*am, "Elizabeth D. Rather" <erat...@forth.com> wrote:
> On 10/30/11 8:34 AM, Andrew Haley wrote:


>> Krishna Myneni<krishna.myn...@ccreweb.org> *wrote:
>>> The main purpose of the example is to show how different modules can
>>> implement words with the same names in their public interfaces, and
>>> this does not create a problem in writing code that is reusable, and
>>> also loadable at the same time. Examples of public words which are
>>> reused are OPEN CLOSE WRITE GET PUT , etc.


>> But isn't the disadvantage of this scheme that it actually
>> *encourages* people to use names that will collide in public words?
>> I admit that it's not an overwhelming problem because the user of a
>> module can create unique aliases for the public words, but it's not
>> ideal.


As per Ms. Rather's description of OF, in the scenario illustrated,
the choice of actual function is early bound at compile time by what
specific module that Comm points to ~ and the *point* of the exercise
is that all the modules that can be used for Comm *have* the same name
for the parallel function (you could also, eg, have one communicating
with an program that has a terminal backend, that implemented the
backend protocol for that program).

> Open Firmware has "packages" for each device it supports, with a
> standardized set of commands such as OPEN CLOSE READ WRITE etc. for
> which there's a version for each device. *These packages are structured
> as wordlists. You name a device, and then get access to the API for
> that device. Within a package, certain words are public, some private
> (actually, headless), and some have heads or not depending on a switch
> set at compile time.


> If you SEE a definition that references headless words, you get the
> address for that word, and (if you wish) you can feed that address to
> (SEE) and look at it.


The question I have is the same as Ms Rather's, below, whether that is
the general case, or a special case. If the latter, then there should
be a version of module available in the system that does *not* do
that, but instead places the "PUBLIC" words directly into the original
compilation wordlist.

> That works very well for OF's purposes, though I'm not sure it's
> appropriate for generalized code management, where you don't have the
> conceptual parallelism that characterizes OF's device support.

Reply With Quote
  #24 (permalink)  
Old 10-30-2011, 03:09 PM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 10:30*am, BruceMcF <agil...@netscape.net> wrote:
> On Oct 30, 9:39*am, "Elizabeth D. Rather" <erat...@forth.com> wrote:
>
> > On 10/30/11 8:34 AM, Andrew Haley wrote:
> >> Krishna Myneni<krishna.myn...@ccreweb.org> *wrote:
> >>> The main purpose of the example is to show how different modules can
> >>> implement words with the same names in their public interfaces, and
> >>> this does not create a problem in writing code that is reusable, and
> >>> also loadable at the same time. Examples of public words which are
> >>> reused are OPEN CLOSE WRITE GET PUT , etc.
> >> But isn't the disadvantage of this scheme that it actually
> >> *encourages* people to use names that will collide in public words?
> >> I admit that it's not an overwhelming problem because the user of a
> >> module can create unique aliases for the public words, but it's not
> >> ideal.

>
> As per Ms. Rather's description of OF, in the scenario illustrated,
> the choice of actual function is early bound at compile time by what
> specific module that Comm points to ~ and the *point* of the exercise
> is that all the modules that can be used for Comm *have* the same name
> for the parallel function (you could also, eg, have one communicating
> with an program that has a terminal backend, that implemented the
> backend protocol for that program).
>
> > Open Firmware has "packages" for each device it supports, with a
> > standardized set of commands such as OPEN CLOSE READ WRITE etc. for
> > which there's a version for each device. *These packages are structured
> > as wordlists. You name a device, and then get access to the API for
> > that device. Within a package, certain words are public, some private
> > (actually, headless), and some have heads or not depending on a switch
> > set at compile time.
> > If you SEE a definition that references headless words, you get the
> > address for that word, and (if you wish) you can feed that address to
> > (SEE) and look at it.

>
> The question I have is the same as Ms Rather's, below, whether that is
> the general case, or a special case. If the latter, then there should
> be a version of module available in the system that does *not* do
> that, but instead places the "PUBLIC" words directly into the original
> compilation wordlist.
>
>
>
>
>
>
>
> > That works very well for OF's purposes, though I'm not sure it's
> > appropriate for generalized code management, where you don't have the
> > conceptual parallelism that characterizes OF's device support.


There are (at least) two different cases in general code development
which benefit from the module concept:

1. Developing different applications which can reuse the same set of
procedures.

2. Developing an application or module that uses a generalized set of
procedures, for which different external modules may be substituted
either at load time or during run time.

For 1) The module provides common code for internal data (possibly
different from app to app). It can isolate names only intended for
internal use by the module, to lessen the chance of name clashes.
These type of name clashes are typically not a worry in Forth.
However, in Forth, we can do better with this concept, compared to C,
by allowing full name reuse, even for the interface words. As an
example, different applications which need to communicate via the
serial port can simply drop-in the serial.4th module, without worrying
about name clashes, even though no prefixes were used to name the
words.

For 2) A generalized set of interface words can be provided by
multiple modules, each of which carries out different actions. In
Forth, we have shown that an application can simultaneously load
multiple modules which provide the same API, but for different uses.
Thus, the application can not only choose which of the available iso-
API modules to use, but also do so at run time. The example already
shown is that of the terminal which allows the user to choose which
communication interface to use (serial-comm or dummy-comm).

I'll submit that 2) is not that rare of a situation, even when we are
not dealing with hardware interfaces. Consider a numerical application
that requires a function to be integrated. The integrator may be
implemented by different methods. It's not hard to imagine devising a
common API for different integrator methods. The application can be
written assuming a general interface and can do one of the following:
a) load a specific integrator module at load time, b) load multiple
integrators and set one at load time, or c) load multiple integrators
and dynamically select its integration method during runtime.

Another example of 2) is to use a generalized display interface in the
terminal module. Currently, the terminal module is hardwired to output
its display on an ansi console. But, using a generalized display
interface, just like using the generalized Comm interface, one could
imagine using not only an ansi console, but an X Window or some other
display hardware as well. The main application can load the required
module(s) and "plug them" into the terminal module.

Krishna

Reply With Quote
  #25 (permalink)  
Old 10-30-2011, 03:41 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 12:09*pm, Krishna Myneni <krishna.myn...@ccreweb.org>
wrote:

> For 1) The module provides common code for internal data (possibly
> different from app to app). It can isolate names only intended for
> internal use by the module, to lessen the chance of name clashes.
> These type of name clashes are typically not a worry in Forth.
> However, in Forth, we can do better with this concept, compared to C,
> by allowing full name reuse, even for the interface words. As an
> example, different applications which need to communicate via the
> serial port can simply drop-in the serial.4th module, without worrying
> about name clashes, even though no prefixes were used to name the
> words.


"Even though no prefixes were used to name the words" is framing the
question as if it was technical issue, rather than an established
practice of many Forth programmers backed up as useful by long
experience of naming specialized words in full. I personally prefer
natural English naming rather than C-style mechanical prefix naming,
but the effect on likelihood of name clashes is the same if the
natural English name is specific.

You not sharing that preference does not suffice to establish that
preference as a special case that should require an extra step versus
words choices that are only clear when the context in which they are
defined is kept in mind.

> For 2) A generalized set of interface words can be provided by
> multiple modules, each of which carries out different actions. In
> Forth, we have shown that an application can simultaneously load
> multiple modules which provide the same API, but for different uses.
> Thus, the application can not only choose which of the available iso-
> API modules to use, but also do so at run time. The example already
> shown is that of the terminal which allows the user to choose which
> communication interface to use (serial-comm or dummy-comm).


This is precisely the OpenForth packages scenario, where the API words
have to be generic because the whole API is a system that can be
implemented in multiple ways, and I recognize that as an entirely
valid thing to support as a first-class citizen, with a module
specification that makes the creation of packages with a parallel
system of generic API names a reasonable thing to support.

Setting it up so that a cross-compiler can compile library source into
a single target device compilation wordlist without necessarily having
to edit the module specification out of the base source code will
require a little bit more infrastructure, but not much.

> I'll submit that 2) is not that rare of a situation, ...


The question I am raising here is not whether that should be
supported, but whether that should be the *sole* model that is
supported.

Especially as I think that *in* that model it is preferable to have
the public namespace as an actual F83 style vocabulary rather than as
a structure that emulates the F83 vocabulary. This "namespace wid
hiding in the second cell of the body of the vocabulary word" is
guaranteed to only integrate with host vocabulary handling that is
written knowing that some but not all of the vocabularies in the
namespace have this special attribute. Placing the private namespace
inside a "Module-System" vocabulary allows much more straightforward
integration with pre-existing namespace management tools.

And under that alternate approach, the "open" PUBLIC API model is a
*factor* of the "closed" PUBLIC API model.

Reply With Quote
  #26 (permalink)  
Old 10-30-2011, 05:51 PM
Andrew Haley
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

Krishna Myneni <krishna.myneni@ccreweb.org> wrote:

> I think the best answer to your question will come from going through
> the exercise of implementing a terminal, using just vanilla Forth,
> that can be reused either with a serial port, or which talks to
> another (dummy) interface.


But that's something that is done easily in Forth with a vectored
execution table.

Andrew.
Reply With Quote
  #27 (permalink)  
Old 10-30-2011, 06:09 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 2:51*pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> > I think the best answer to your question will come from going through
> > the exercise of implementing a terminal, using just vanilla Forth,
> > that can be reused either with a serial port, or which talks to
> > another (dummy) interface.


> But that's something that is done easily in Forth with a vectored
> execution table.


And while someone assuming that one should use a close public API
wordlist for that might use generic names for the offsets, relying on
the module name to discriminate between different uses of the same
offset name ...

.... one can with less fuss just use situation-specific offset names
and then use them without interfering with specifically-named vectored
execution offsets for other offset tables for other situations.
Reply With Quote
  #28 (permalink)  
Old 10-30-2011, 06:25 PM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 1:51*pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> > I think the best answer to your question will come from going through
> > the exercise of implementing a terminal, using just vanilla Forth,
> > that can be reused either with a serial port, or which talks to
> > another (dummy) interface.

>
> But that's something that is done easily in Forth with a vectored
> execution table.
>
> Andrew.


Show me your code. I've already posted mine.

Krishna
Reply With Quote
  #29 (permalink)  
Old 10-30-2011, 06:29 PM
Krishna Myneni
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 2:09*pm, BruceMcF <agil...@netscape.net> wrote:
> On Oct 30, 2:51*pm, Andrew Haley <andre...@littlepinkcloud.invalid>
> wrote:
>
> > Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> > > I think the best answer to your question will come from going through
> > > the exercise of implementing a terminal, using just vanilla Forth,
> > > that can be reused either with a serial port, or which talks to
> > > another (dummy) interface.

> > But that's something that is done easily in Forth with a vectored
> > execution table.

>
> And while someone assuming that one should use a close public API
> wordlist for that might use generic names for the offsets, relying on
> the module name to discriminate between different uses of the same
> offset name ...
>
> ... one can with less fuss just use situation-specific offset names
> and then use them without interfering with specifically-named vectored
> execution offsets for other offset tables for other situations.


Same reply as I gave to Andrew, ... show me the code so we can debate
relative merits and disadvantages of the suggested approaches. I have
no debate with the simple assertion that the same thing can be done
through other means.

Krishna
Reply With Quote
  #30 (permalink)  
Old 10-30-2011, 08:30 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: example modular code (experimental)

On Oct 30, 3:29*pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
> On Oct 30, 2:09*pm, BruceMcF <agil...@netscape.net> wrote:


>> On Oct 30, 2:51*pm, Andrew Haley <andre...@littlepinkcloud.invalid>
>> wrote:


>>> But that's something that is done easily in Forth with a vectored
>>> execution table.


>> And while someone assuming that one should use a close public API
>> wordlist for that might use generic names for the offsets, relying on
>> the module name to discriminate between different uses of the same
>> offset name ...


>> ... one can with less fuss just use situation-specific offset names
>> and then use them without interfering with specifically-named vectored
>> execution offsets for other offset tables for other situations.


> Same reply as I gave to Andrew, ... show me the code so we can debate
> relative merits and disadvantages of the suggested approaches.


There are two distinct arguments that may be taking place, and
proceeding with the argument without understanding which argument it
is can only lead to confusion.

(a) this approach should be supported with a first class type of
module; and

For (a), "show me the code" is not something I have to pay attention
to, since I am not interested in disputing (a).

(b) this approach should be the only approach supported with a first
class type of module.

For (b), "show me the code" isn't supported by the example you've
present so far. (b) requires a claim that the approach is the across
the board superior way to accomplish this type of objective, and since
the approach you demonstrated performs its switch at compile time and
so to support switching at execution time has to be have the same
source compiled again for each different version of the API, which
means that for some number of distinct implementations, your approach
loses to an execution table approach in terms of dictionary size,
which is on occasion a binding constraint.

> I have no debate with the simple assertion that the same thing can
> be done through other means.


Concluding that no other approach merits support with a first class
type of module, rather than ad hoc patches on top of the sole first
class type of module provided, seems to demand winning a superiority
argument, and the burden of proof for a superiority claim is normally
with the person advancing the claim.

OTOH, concluding that your approach merits support with a first class
type of module, without contesting the right of other approaches to a
first class type of module better suited to those approaches, does not
require a superiority claim. It only requires a utility claim, which
has a much lower burden of proof.

I don't know which claim you are making, since sample experimental
code need not be complete.
Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 07:22 AM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.