Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 3, the unsupported old release. You're almost certainly looking for [[/eggref/4/lexmod|the CHICKEN 4 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-4.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags: egg]] [[toc:]] == lexmod === Introduction The name 'lexmod' is short for 'lexical module'. -- This module system is based on Lexical Capture -- === Documentation ==== lexmod [syntax] (lexmod NAME EXPORT-LIST [NOT-FOUND-HANLDER] BODY) -> lexmod Create a lexmod with the given {{NAME}}, {{EXPORT-LIST}}, and {{BODY}}. [procedure] (NOT-FOUND-HANLDER NAME EXPORT) -> object {{NAME}} is a module-name symbol and {{EXPORT}} is an unexported symbol. The return value is the default value for not-found situations. An exception may also be raised. As for {{hash-table-ref}}. The {{EXPORT-LIST}} should have a form of: <enscript highlight=scheme> (export EXPORT-CLAUSE ...) </enscript> Each {{EXPORT-CLAUSE}} should have a form of: SYMBOL : Export {{SYMBOL}} as defined from {{BODY}} or (as EXPORTED INTERNAL) : Export {{EXPORTED}} as what {{INTERNAL}} was defined as in {{BODY}}. The definitions in {{BODY}} are evaluated as in a {{lambda}} body. Qualified module names have the form: (LEXMOD 'NAME) Modules within modules are perfectly possible. Qualified names in nested modules can end up becoming a little hairy though -- ((LEXMOD 'SUBLEXMOD) 'SUBLEXMOD--BINDING) --. In a later version, this might be made nicer. ==== define-lexmod [syntax] (define-lexmod NAME EXPORTS BODY) Convenience for <enscript highlight=scheme> (define NAME (lexmod NAME EXPORTS BODY)) </enscript> ==== lexmod-exports? [procedure] (lexmod-exports? LEXMOD NAME) -> boolean Takes a {{LEXMOD}} and a symbol {{NAME}} and returns {{#t}} iff the lexmod exports the symbol, or {{#f}} otherwise. ==== let-imports ==== let*-imports [syntax] (let-imports ((LEXMOD IMPORT-CLAUSE ...) ...) BODY) [syntax] (let*-imports ((LEXMOD IMPORT-CLAUSE ...) ...) BODY) Import names from lexmods in a local context. Each {{IMPORT-CLAUSE}} should have a form of: SYMBOL : Import {{SYMBOL}} from the corresponding module exactly or (as IMPORTED EXPORTED) : Import {{EXPORTED}} from the corresponding module, but rather bind {{IMPORTED}} to its value. {{let*-imports}} is like {{let-imports}}, but it binds each {{LEXMOD}} clause sequentially, whereas {{let-imports}} binds in an order such that each {{LEXMOD}} is evaluated in the environment of the context of the {{let-imports}} form. That is, {{let-imports}} might be defined to expand <enscript highlight=scheme> (let-imports ((MOD1 A (as B Z) C) (MOD2 D (as E Y) F)) BODY) </enscript> to <enscript highlight=scheme> (let ((A (MOD1 'A)) (B (MOD1 'Z)) (C (MOD1 'C)) (D (MOD2 'D)) (E (MOD2 'Y)) (F (MOD2 'F))) body) </enscript> and {{let*-imports}} might expand <enscript highlight=scheme> (let*-imports ((MOD1 A (as B Z) C) (MOD2 D (as E Y) F)) BODY) </enscript> to <enscript highlight=scheme> (let-imports ((MOD1 A (as B Z) C)) (let-imports ((MOD2 D (as E Y) F)) BODY)) </enscript> ==== define-imports [syntax] (define-imports (LEXMOD IMPORT-CLAUSE ...) ...) Like {{let-imports}}, but expand to a set of {{define}}, rather than bind locally a bunch of variables. Each {{IMPORT-CLAUSE}} has the same syntax & semantics as with {{let-imports}}. ==== interface [syntax] (interface NAME EXPORT ...) -> interface Create an interface with the given {{EXPORT ...}} and {{NAME}} symbol. ==== define-interface [syntax] (define-interface NAME EXPORT ...) Convenience for <enscript highlight=scheme> (define NAME (interface EXPORT ...)) </enscript> ==== interface-exports? [procedure] (interface-exports? INTERFACE NAME) -> boolean Does {{INTERFACE}} contain {{NAME}} in its export list? ==== lexmod-satisfies? [procedure] (lexmod-satisfies? LEXMOD INTERFACE) -> boolean Does {{LEXMOD}} export everything that {{INTERFACE}} demands it to? ==== functor [syntax] (functor NAME ((LEXMOD INTERFACE) ...) EXPORT-LIST BODY) -> procedure [syntax] (functor ((LEXMOD INTERFACE) ...) EXPORT-LIST BODY) -> procedure Functors are functions that take lexmods and return lexmods. The functor macro ensures that the lexmods satisfy the interfaces. EXPORT-LIST is like the list of exports in lexmod. {{NAME}} will be the name of the lexmod the functor returns; it defaults to the symbol {{_anonymous_}}. The functor takes a parameter list (PARAM-NAME ...) and each {{PARAM-NAME}} is checked to satisfy its respective interface when the functor is applied. Functor application is ordinary function application. ==== lexmod-fulfills? [procedure] (lexmod-fulfills? LEXMOD [INTERFACE | NAME | LIST-OF-NAME] ...) -> boolean Performs both 'lexmod-exports?' and 'lexmod-satisfies?'. The export criteria consists of one or more of an {{INTERFACE}}, a {{NAME}}, or a {{LIST-OF-NAME}}, where {{INTERFACE}} is an interface object, {{NAME}} is a symbol, and {{LIST-OF-NAME}} is a list of symbols. ==== lexmod? [procedure] (lexmod? OBJECT [INTERFACE | NAME | LIST-OF-NAME] ...) -> boolean Is the {{OBJECT}} a lexmod, that also fulfills the optional export criteria? The export criteria is as for {{lexmod-fulfills?}}. ==== lexmod-open [procedure] (lexmod-open [LEXMOD | (lexmod-export ...)] ...) [syntax] (lexmod-export LEXMOD IMPORT-CLAUSE ...) Binds the top-level variables from the {(lexmod-export LEXMOD IMPORT-CLAUSE ...)}} specification. Each {{IMPORT-CLAUSE}} has the same syntax & semantics as with {{let-imports}}. Each individual {{LEXMOD}} parameter is treated as having an export specification with the complete list of exports. Similar to {{define-imports}} at top-level scope in action but a runtime interface. ==== compound-lexmod [procedure] (compound-lexmod [NAME] [NOT-FOUND-HANLDER] LEXMOD ...) -> lexmod Returns a new lexmod, exporting the union of the {{LEXMOD}} parameter's exports. The set of exports must be dis-joint otherwise an error is raised. Unless a name is provided the name of the new lexmod is the symbol with printname "+<lLEXMOD-1 name>+...+<LEXMOD-N name>". When {{NAME}} missing the symbol {{_anonymous_}} is used. Similar to {{functor}} in that it combines lexmods. ==== define-compound-lexmod [syntax] (define-compound-lexmod NAME [(default NOT-FOUND-HANLDER)] LEXMOD ...) -> lexmod Sugar for {{compound-lexmod}}. ==== compound-lexmod? [procedure] (compound-lexmod? OBJECT) -> boolean Is the {{OBJECT}} a compound-lexmod? ==== compound-lexmods [procedure] (compound-lexmods LEXMOD) -> list Returns the components of a compound-lexmod as a list-of {{LEXMOD}}, or {{'()}}. === Conventions ; modules : @{{LEXMOD-NAME}} ; interfaces : {{INTERFACE-NAME}}-interface ; functors : @make-{{NAME}} === Known problems There are only four (known) problems with this module system: 1. It doesn't support macros; this module system is purely run-time, while macros are macro-expand- or compile-time-only. 2. There can be no initialization code scattered throughout the module, so you can't do, for instance: <enscript highlight=scheme> (lexmod @foo (export bar baz quux) (define bar #f) (define (baz stuff) body) (set! bar (baz mumble)) (define quux (zot bar))) </enscript> because then the {{set!}} expression unsets the fact that it's a definition context in the rest of the lexmod expression, and so that define expression below it is in an expression context, not a definition context, which won't work very well. Instead put all initialization after all definition -- for example: <enscript highlight=scheme> (lexmod @foo (export bar baz quux) (define bar #f) (define (baz stuff) body) (define quux #f) (set! bar (baz mumble)) (set! quux (zot bar))) </enscript> (The syntax-case module system exhibits this problem as well, so hah!) Riastradh has written a macro for giving top-level semantics to local scopes, but it has one problem: those local bodies can't contain macros that expand to define and work right, which is why he hasn't put it in the lexmod distribution yet. 3. Because each subform is wrapped inside a single let, the definitions are ordinary internal defines, so they're equivalent to a {{letrec}} -- i.e. they aren't evaluated sequentially, and they don't have _all_ the properties of top-level defines (for example, they're not equivalent to {{set!}} if the variable is already defined) --. These two could be fixed by wrapping every form in a lexmod expression with let, but that would cons a closure for every expression, which would be rather annoying. 4. The export list should be able to be an interface as created with the interface macro, not just with {{(export ...)}}. Due to this problem, I'll probably change interfaces to use macro magic that lets them be both macro-expand-time and run-time values so that the lexmod macro can use them, and they can also be used as ordinary run-time values. === Author Taylor Campbell, packaged for CHICKEN by [[/users/felix winkelmann|felix winkelmann]] Kon Lovett, extensions === History ; 1.0 : added compound queries, made interface object type disjoint, lexmod-open accepts import-clause, faster lexmod? predicate ; 009 : extensions ; 008 : initial release as a CHICKEN extension === License Copyright (C) 2003, 2004 Taylor Campbell All rights reserved. You may use and redistribute this in source code or binary form as you like, as long as in redistribution you include the above copyright notice, this licence, and the following disclaimer. Modifications are requested, but not required, to be sent back to the author. Any modification must give credit to the original author, however, and be licensed under this licence. You may NOT distribute the author's email address in any way, shape, or form, except in a list of credits, where the email address AS DISPLAYED ABOVE may be used. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 15 from 15?