1<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 2<!-- BEGIN LICENSE BLOCK 3 - Version: CMPL 1.1 4 - 5 - The contents of this file are subject to the Cisco-style Mozilla Public 6 - License Version 1.1 (the "License"); you may not use this file except 7 - in compliance with the License. You may obtain a copy of the License 8 - at www.eclipse-clp.org/license. 9 - 10 - Software distributed under the License is distributed on an "AS IS" 11 - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 12 - the License for the specific language governing rights and limitations 13 - under the License. 14 - 15 - The Original Code is The ECLiPSe Constraint Logic Programming System. 16 - The Initial Developer of the Original Code is Cisco Systems, Inc. 17 - Portions created by the Initial Developer are 18 - Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 19 - 20 - Contributor(s): 21 - 22 - END LICENSE BLOCK --> 23<html> 24<head> 25 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 26 <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; SunOS 5.7 sun4u) [Netscape]"> 27 <title>ECLiPSe Internal Documents</title> 28</head> 29<body text="#000000" bgcolor="#CCFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> 30 31<h1> 32Module System Cleanup</h1> 33Author: Joachim Schimpf 34<br>Last update: 02/2003 35<p>This information describes changes to the module system that were implemented 36in release 5.0. 37<h2> 38Topics</h2> 39 40<ol> 41<li> 42Simplify the implementation and semantics of tools</li> 43 44<li> 45sort out some problem related to "lazy import" and clashes</li> 46 47<li> 48implement reexport</li> 49 50<li> 51implement better semantics for :/2, i.e. specifying lookup module rather 52than definition module</li> 53 54<li> 55related change is to get rid of the null-module descriptors that are used 56currently for :/2</li> 57 58<li> 59allow [m1,m2]:Goal as a shorthand for m1:Goal, m2:Goal</li> 60 61<li> 62Possibly split procedure descriptors into</li> 63 64<ul> 65<li> 66definition descriptor (at most 1 per module)</li> 67 68<li> 69visibility descriptor (at most 1 per module)</li> 70 71<li> 72qualified reference descriptor (possibly many per module)</li> 73</ul> 74 75<li> 76Get rid of protected-property, declared-flag</li> 77 78<li> 79Simplify the module system by removing the interface/body separation</li> 80 81<li> 82Change default visibility for containers (record,setval) to local</li> 83 84<li> 85Towards a multi-language system</li> 86 87<li> 88Get rid of "global" visibility</li> 89</ol> 90 91<h2> 92Differences for the user</h2> 93 94<ul> 95<li> 96:/2 specifies the visibility module, and accepts a list of modules on the 97left hand side</li> 98 99<li> 100visibility changes are not allowed (except local->export and import->reexport)</li> 101 102<li> 103export in module-interface and body are no longer treated differently - 104in fact the interface-body separation is made obsolete</li> 105 106<li> 107lazy import does not cause visibility clashes, these occur only when an 108ambiguously imported name is actually used. Ambiguity is resolved via explicit 109import.</li> 110 111<li> 112globals are deprecated and replaced by exports that are imported automatically 113when used</li> 114 115<li> 116setting a handler now automatically exports the handler</li> 117 118<li> 119Definition before use: When an exported predicate is being used, it (or 120the whole module that defines it) has to be imported first (via import, 121use_module, reexport or import/from).</li> 122</ul> 123 124<h2> 125The implementation of :/2</h2> 126Originally, :/2 was called call_explicit and defined as referring to the 127definition module. This does not fit well into the overall scheme since 128otherwise everything is based on the notion of visibility. 129<br>The original implementation used non-standard procedure descriptors 130that did not belong to a module ("null" module) and were never deallocated. 131Several bugs were due to these "null"-module descriptors. 132<p>The main problem with letting :/2 specify the lookup module instead 133of the definition module is that this could potentially create lookup chains, 134which are costly to implement. However, when only exported predicates can 135be accessed this way, the visible predicate is the same as the defined 136one, therefore the problem of chains does not occur. It is also possible 137and potentially useful to make the exported/global restriction only for 138compiled calls, while allowing unlimited access for metacalls: this creates 139no problems with chains (since visibility is resolved at call time) and 140simplifies precise metaprogramming using :/2 and @/2. 141<p>New implementation: The "null" descriptors are replaced by qualified-access-descriptors. 142They refer from a use in one module to a definition in another module. 143This is similar to an import-descriptor, but while there can be only one 144import descriptor for a particular name (specifying the visible one), there 145may be many qualified-access-descriptors. 146<h2> 147Simplifying consistency/redefinition</h2> 148The original implementation allowed certain dynamic redefinitions, e.g. 149tool->nontool. The requirement for a redefinition to be allowed is that 150a call compiled under the original assumption is still valid in the redefined 151case. As a fortunate side effect, this policy also solved the following 152problem that occurs when recompiling a module that exports a predicate 153to which a call has already been compiled elsewhere: 154<pre>:- module_interface(m).</pre> 155 156<pre>:- export p/1.</pre> 157 158<pre>% at this point p/1 is exported but not yet known as a tool</pre> 159 160<pre>:- tool(p/1, p/2).</pre> 161 162<pre>:- begin_module(m).</pre> 163 164<pre>p(X,Y) :- ...</pre> 165Assume m was compiled, then a call to p/1 was compiled with the tool-calling 166-convention. When module m is now recompiled, the export-directive exports 167a non-tool which fortunately is compatible with the tool-call, but this 168is just a lucky special case. 169<h3> 170Inter-module consistency checks</h3> 171To solve the above problem, the actual export (i.e. the updating of the 172corresponding import descriptors and the consistency check) can be delayed. 173Actual export is done: 174<ol> 175<li> 176at export time only if already code-defined</li> 177 178<li> 179at code-definition time otherwise</li> 180</ol> 181Note that we introduce a new descriptor state here (descriptor exported 182but corresponding imports not checked or updated) that didn't exist before. 183An additional flag TO_EXPORT is introduced to indicate this state, which 184is halfway between LOCAL and EXPORT. 185<h3> 186Intra-module consistency checks</h3> 187Once the local descriptor has been referenced, every single declaration 188must make a consistent change. The following table indicates what changes 189are allowed. 190<br> 191<table BORDER COLS=3 WIDTH="100%" NOSAVE > 192<tr> 193<td><b>Predicate property</b></td> 194 195<td><b>Change when already referenced (call compiled)</b></td> 196 197<td><b>Change when already code defined</b></td> 198</tr> 199 200<tr> 201<td>code</td> 202 203<td>yes</td> 204 205<td>yes</td> 206</tr> 207 208<tr BGCOLOR="#FFCCCC" NOSAVE> 209<td NOSAVE>modes & uniftype</td> 210 211<td>no</td> 212 213<td>no</td> 214</tr> 215 216<tr BGCOLOR="#FFCCCC" NOSAVE> 217<td NOSAVE>inline trans</td> 218 219<td>no</td> 220 221<td>yes</td> 222</tr> 223 224<tr BGCOLOR="#FFCCCC" NOSAVE> 225<td NOSAVE>adding tool property</td> 226 227<td>no</td> 228 229<td>no</td> 230</tr> 231 232<tr NOSAVE> 233<td>debugged</td> 234 235<td>yes</td> 236 237<td BGCOLOR="#FFCCCC" NOSAVE>no</td> 238</tr> 239 240<tr> 241<td>spy,trace,skip,start</td> 242 243<td>yes</td> 244 245<td>yes</td> 246</tr> 247 248<tr NOSAVE> 249<td>parallel</td> 250 251<td>yes</td> 252 253<td BGCOLOR="#FFCCCC" NOSAVE>no</td> 254</tr> 255 256<tr NOSAVE> 257<td>demon</td> 258 259<td>yes</td> 260 261<td BGCOLOR="#FFCCCC" NOSAVE>no</td> 262</tr> 263 264<tr> 265<td>waking prio</td> 266 267<td>yes</td> 268 269<td>yes</td> 270</tr> 271 272<tr BGCOLOR="#FFCCCC" NOSAVE> 273<td NOSAVE>calling convention</td> 274 275<td>no</td> 276 277<td>no</td> 278</tr> 279 280<tr NOSAVE> 281<td>dynamic</td> 282 283<td>yes</td> 284 285<td BGCOLOR="#FFCCCC" NOSAVE>no</td> 286</tr> 287</table> 288 289<h3> 290Protected procedures</h3> 291In the previous implementation, the protect-mechanism was used to enforce 292that redefinitions of predicates that were treated specially by the compiler 293were made beforehand, i.e. before any calls had been compiled. This should 294now be taken care of by the general mechanism, i.e. the restrictions on 295changes of the calling convention when calls have already been compiled. 296The protected-property has therefore been removed. 297<br>For a small number of control constructs i.e. 298<pre>,/2 ;/2 ->/2 -?-> :/2 true/0</pre> 299it would be good to forbid redefinition altogether otherwise all code that 300analyses goals would have to check whether those have been redefined. We 301are talking here about the compiler, tr_goals/3 and the like. It simply 302means that these goals can be relied upon even without explicit sepia_kernel-qualification. 303<h2> 304Import/lazy import</h2> 305It probably makes sense to have both, lazy and immediate import, with the 306following meaning: 307<ul> 308<li> 309When a module is (lazily) imported (use_module(m) or import(m)) no checks 310are done, the fact is just memorized. In particular, it is not an error 311(or warning) when two imported modules export the same names.</li> 312 313<li> 314Only when the name is referenced for the first time does the import link 315get established: it is checked whether there is a unique import, and ambiguity 316is an error</li> 317 318<li> 319Explicit import (e.g. <tt> import p/3 from m</tt>) immediately creates 320the import link.</li> 321 322<li> 323Import links could previously be removed by abolish. This is now no longer 324be necessary to resolve ambiguous imports. This allows to restrict the 325functionality of abolish and get rid of unwanted dynamicity in the interfaces.</li> 326 327<li> 328When a predicate is referenced before having been imported in any way:</li> 329 330<ul> 331<li> 332we assume a default calling convention and default properties for the predicate. 333If a later import proved not to be compatible with these assumptions, this 334is an error.</li> 335 336<li> 337consequently, imports should always textually precede any call of a predicate.</li> 338 339<li> 340the same applies to a use->local sequence (to allow one-pass processing)</li> 341</ul> 342</ul> 343Necessary changes: 344<ul> 345<li> 346when module interface is imported, exports must no longer be mapped into 347import-froms. I.e. get rid of the distinction between exporting in the 348interface or in the body.</li> 349 350<li> 351ambiguity must be reported when it happens during lazy import (make/will_lazy_import), 352but not already at the import-module directive,</li> 353 354<li> 355former notion of global can be treated as lazy import from sepia_kernel 356(actually now eclipse_language)!</li> 357</ul> 358 359<h2> 360Getting rid of globals</h2> 361In ECLiPSe prior to 5.0, predicates could be declared <i>global</i>. 362This visibility class has been removed in order to simplify things. 363The main use of global predicates was for the ECLiPSe built-in predicates, 364which were automatically visible everywhere (unless hidden by a local or 365imported definition - this was used in compatibility packages). The new 366scheme is as follows: 367<ul> 368<li> 369By default, the module <tt>eclipse_language</tt> is implicitly (lazy) 370imported into every new module. This is the way the built-ins are provided.</li> 371 372<li> 373The set of predicates reexported from eclipse_language defines the set 374of builtins (previously this was the set of global declarations).</li> 375 376<li> 377Local redefinitions still hide this (lazy) import.</li> 378 379<li> 380Compatibility packages that provide alternative implementations of builtins: 381the import from eclipse_language and the import from a compatibility module 382are now equivalent. Possible solutions:</li> 383 384<ul> 385<li> 386The importer has to resolve the conflict</li> 387 388<li> 389The compatibility library has to be used <b>instead</b> of the kernel (via 390module/3, create_module/3)</li> 391</ul> 392Alternative ways to deal with this problem (not implemented): 393<ul> 394<li> 395The kernel-exports are somehow declared "weak", the library exports "strong" 396- but this approach doesn't nest</li> 397 398<li> 399Partial ordering: if something is visible via one import and hidden via 400another, it should be hidden (see algorithm below)</li> 401</ul> 402What is implemented in 5.0 is: no automatic resolution, except arithmetic 403comparisons, which are explicitly resolved in favour of eclipse_language 404by the ambiguity-handler. Compatibility packages should be used instead 405of eclipse_language rather than in addition.</ul> 406Resolution of some import-ambiguities (not implemented): 407<blockquote><tt>vis := next_imported()</tt> 408<br><tt>while (clash := next_imported())</tt> 409<br><tt>{</tt> 410<br><tt> if (vis visible in definition module of clash) 411% hidden</tt> 412<br><tt> vis := clash</tt> 413<br><tt> else if (clash visible in definition module 414of vis)</tt> 415<br><tt> ;</tt> 416<br><tt> else</tt> 417<br><tt> error(ambiguous_import)</tt> 418<br><tt>}</tt></blockquote> 419 420<h2> 421Tools</h2> 422Tools are predicates which get a caller module argument added when called. 423<br>The current implementation allows all kinds of redefinitions which 424is probably exaggerated. 425<p>Suggested changes, not all done in release 5.0 yet: 426<ul> 427<li> 428disallow tool/1, always require to specify the tool body when declaring 429a tool. This will allow to do the tool->body mapping at compile time, making 430it possible to inline the calls properly.</li> 431</ul> 432 433<pre>% tool definition in module tm:</pre> 434 435<pre>:- tool(t/3, tb/4).</pre> 436 437<pre>% Called in module cm:</pre> 438 439<pre>t(a,b,c) -----> tm:tb(a,b,c,cm)</pre> 440 441<pre>t(a,b,c)@xm -----> tm:tb(a,b,c,xm)</pre> 442The qualification with :/2 is necessary because the tool body might not 443be visible in module cm. 444<br>Note that this transformation can, for compiled calls, be done by inlining: 445<pre>:- inline(t/3, t_t/3).</pre> 446 447<pre>t_t(t(A,B,C), tm:tb(A,B,C,M), M).</pre> 448For metacalls, the same transformation must be done, probably in the emulator. 449<br>For delay/waking, the mapping should happen at delay time (i.e. the 450tool body is delayed instead of the original call), so the waking code 451does not have to deal with this complication and can be simpler and more 452efficient. 453<br>Also, the compiler does not have to deal with tool calls, they are 454all removed (replaced by body calls) by inlining. 455<br>All this means that tool interfaces can never get called, and therefore 456do not need any code generated. The code field in the procedure descriptor 457can be used to hold a pointer to the descriptor of the tool body. 458<p>To do: define restrictions on visibility of tool body. 459<ul> 460<li> 461Does it have to be <u>defined</u> in the same module as the tool interface, 462or just visible? (just visible from an implementation standpoint, but the 463restriction may make sense for programming discipline?)</li> 464 465<li> 466Is it automatically exported/imported with the interface? (exported probably 467yes, imported probably no).</li> 468 469<li> 470Most (all?) flag settings on the interface should be propagated to the 471body.</li> 472 473<li> 474The tool-to-body link cannot be changed (after the tool has been referenced), 475ie. the tool interface cannot be redefined, however the body can.</li> 476 477<li> 478For debugging etc, it would be nice if there was a one-to-one mapping between 479tool interface and body, so that body calls could be mapped back to interface 480calls, and the body predicates would almost never be visible.</li> 481</ul> 482 483<h2> 484Restrictions on redefinition</h2> 485In the previous implementation lots of dynamic redefinitions were allowed. 486This is problematic when calls are compiled and properties of the callee 487are used in the process, like 488<ul> 489<li> 490modes</li> 491 492<li> 493tool property</li> 494 495<li> 496inlining</li> 497 498<li> 499external calling convention</li> 500</ul> 501It is safer not to allow redefinitions and require forward declarations 502for everything: 503<ol> 504<li> 505Within a module, forward declarations can be avoided by going to multipass 506compilation, at least within a single file.</li> 507 508<li> 509For interactive, incremental compilation it might be enough to have a simple 510default assumption (prolog convention, local, general mode, no tool, no 511inlining, etc).</li> 512 513<li> 514For references across module boundaries, the exporting module interface 515must provide all the information and must be known at compile time.</li> 516</ol> 517 518<h3> 519Abolish</h3> 520That leaves the problem of the abolish-primitive: There is no way to inform 521the possibly inlined calls of the abolishment. Maybe the semantics could 522be restricted to a removal of the clauses while keeping all other properties. 523This is tantamount to allowing redefinition with all the other properties 524being kept the same. This is implemented in release 5.0. 525<h3> 526Erase_module</h3> 527Recompiling a module: Currently erase+compile. This leaves all the referencing 528descriptors around and they are updated when the module is recompiled and 529the predicate reappears. 530<h3> 531Time of visibility resolution</h3> 532What about metacall-access and non-call access (property lookup etc)? In 533other words, should the first metacall to a (unambiguously, lazily) imported 534predicate fix the import link, or should it be resolved afresh on every 535metacall? Since metacalls contribute to the semantics, they should freeze 536the visibility, but in order to keep the ease of the interactive toplevel 537that is not necessarily desirable. In 5.0, the first metacall freezes the 538visibility, i.e. they behave like compiled calls. 539<h2> 540Procedure Descriptors</h2> 541 542<h4> 543Current pri descriptor fields and their usage:</h4> 544 545<ul> 546<li> 547code</li> 548 549<ul> 550<li> 551wam code address, or emulator builtin index</li> 552</ul> 553 554<li> 555next_proc</li> 556 557<ul> 558<li> 559finding visible pred in a module</li> 560 561<li> 562dict-gc</li> 563 564<li> 565to copy the fields to all with a certain mod_ref</li> 566 567<li> 568unlinking in erase_module</li> 569 570<li> 571lazy import</li> 572</ul> 573 574<li> 575next_in_mod</li> 576 577<ul> 578<li> 579to import all exported ones to free in erase_module</li> 580 581<li> 582current_predicate</li> 583</ul> 584 585<li> 586mod_def</li> 587 588<ul> 589<li> 590the module where the descriptor belongs</li> 591</ul> 592 593<li> 594mod_ref</li> 595 596<ul> 597<li> 598the module that the descriptor refers to, ie. where the definition is</li> 599</ul> 600 601<li> 602did</li> 603 604<ul> 605<li> 606functor of the predicate (name/arity)</li> 607</ul> 608 609<li> 610flags</li> 611 612<ul> 613<li> 614various property flags</li> 615</ul> 616 617<li> 618mode</li> 619 620<ul> 621<li> 6223 bits per argument in a 32 bit word, modes for higher arguments ignored</li> 623</ul> 624 625<li> 626trans_function</li> 627 628<ul> 629<li> 630did of the transformation predicate (inlining)</li> 631</ul> 632</ul> 633 634<h4> 635Descriptor types</h4> 636Defined in that module: 637<blockquote>LOCAL 638<br>EXPORT</blockquote> 639Defined elsewhere (exported or reexported there): 640<blockquote>IMPORT 641<br>IMPEXP</blockquote> 642Unknown 643<blockquote>DEFAULT</blockquote> 644Qualified access (exported or reexported elsewhere) 645<blockquote>QUALI</blockquote> 646Descriptor states: 647<br> 648<table BORDER COLS=6 WIDTH="100%" NOSAVE > 649<tr> 650<td>scope</td> 651 652<td>module_ref</td> 653 654<td>TO_EXPORT</td> 655 656<td>NOREFERENCE</td> 657 658<td>CODE_DEFINED</td> 659 660<td>other properties</td> 661</tr> 662 663<tr> 664<td>DEFAULT</td> 665 666<td>D_UNKNOWN</td> 667 668<td>0</td> 669 670<td>0/1</td> 671 672<td>0</td> 673 674<td>any</td> 675</tr> 676 677<tr> 678<td>LOCAL</td> 679 680<td>== module_def</td> 681 682<td>0/1</td> 683 684<td>0/1</td> 685 686<td>0/1</td> 687 688<td>any</td> 689</tr> 690 691<tr> 692<td>EXPORT</td> 693 694<td>== module_def</td> 695 696<td>0</td> 697 698<td>0/1</td> 699 700<td>0/1</td> 701 702<td>any</td> 703</tr> 704 705<tr> 706<td>IMPEXP</td> 707 708<td>home module</td> 709 710<td>0</td> 711 712<td>0/1</td> 713 714<td>0/1</td> 715 716<td>any</td> 717</tr> 718 719<tr> 720<td>IMPORT</td> 721 722<td>home module</td> 723 724<td>0</td> 725 726<td>0/1</td> 727 728<td>0/1</td> 729 730<td>any</td> 731</tr> 732 733<tr> 734<td>QUALI</td> 735 736<td>home module</td> 737 738<td>0</td> 739 740<td>0</td> 741 742<td>0/1</td> 743 744<td>any</td> 745</tr> 746</table> 747 748<h4> 749State changes - previous situation</h4> 750 751<table BORDER COLS=6 WIDTH="100%" NOSAVE > 752<tr BGCOLOR="#66FFFF" NOSAVE> 753<td NOSAVE>from\to</td> 754 755<td>LOCAL</td> 756 757<td>EXPORT</td> 758 759<td>GLOBAL</td> 760 761<td>IMPORT</td> 762 763<td>DEFAULT</td> 764</tr> 765 766<tr> 767<td>DEFAULT</td> 768 769<td>ok</td> 770 771<td>ok</td> 772 773<td>ok</td> 774 775<td>ok</td> 776 777<td>-</td> 778</tr> 779 780<tr> 781<td>LOCAL</td> 782 783<td>-</td> 784 785<td>ok</td> 786 787<td>ok</td> 788 789<td>error</td> 790 791<td></td> 792</tr> 793 794<tr> 795<td>EXPORT</td> 796 797<td>ok</td> 798 799<td>-</td> 800 801<td>ok</td> 802 803<td>error</td> 804 805<td></td> 806</tr> 807 808<tr> 809<td>GLOBAL</td> 810 811<td>ok</td> 812 813<td>ok</td> 814 815<td>-</td> 816 817<td>ok</td> 818 819<td></td> 820</tr> 821 822<tr> 823<td>IMPORT</td> 824 825<td>error</td> 826 827<td>error</td> 828 829<td>error</td> 830 831<td></td> 832 833<td></td> 834</tr> 835</table> 836 837<h4> 838State changes - new behaviour</h4> 839We accept repeated (or weaker) declarations silently 840<table BORDER COLS=6 WIDTH="100%" NOSAVE > 841<tr BGCOLOR="#66FFFF" NOSAVE> 842<td NOSAVE>from\to</td> 843 844<td>LOCAL</td> 845 846<td>EXPORT</td> 847 848<td>IMPEXP</td> 849 850<td>IMPORT</td> 851 852<td>DEFAULT</td> 853</tr> 854 855<tr> 856<td>DEFAULT</td> 857 858<td>ok</td> 859 860<td>ok</td> 861 862<td>ok</td> 863 864<td>ok</td> 865 866<td></td> 867</tr> 868 869<tr> 870<td>LOCAL</td> 871 872<td>nop</td> 873 874<td>ok</td> 875 876<td>error</td> 877 878<td>error</td> 879 880<td></td> 881</tr> 882 883<tr> 884<td>EXPORT</td> 885 886<td>nop</td> 887 888<td>nop</td> 889 890<td>error</td> 891 892<td>error</td> 893 894<td></td> 895</tr> 896 897<tr> 898<td>IMPEXP</td> 899 900<td>error</td> 901 902<td>error</td> 903 904<td>nop(s)</td> 905 906<td>nop(s)</td> 907 908<td></td> 909</tr> 910 911<tr> 912<td>IMPORT</td> 913 914<td>error</td> 915 916<td>error</td> 917 918<td>ok(s)</td> 919 920<td>nop(s)</td> 921 922<td></td> 923</tr> 924</table> 925(s) - if imported from same module as before 926<h2> 927Note on reexport</h2> 928reexport could be handled by inlined indirection: 929<pre>:- reexport p/3 from m1.</pre> 930 is functionally equivalent to 931<pre>:- export p/3.</pre> 932 933<pre>p(A,B,C) :- m1:p(A,B,C).</pre> 934which can be made efficient by adding inlining 935<pre>:- inline(p/3,t_p/2).</pre> 936 937<pre>t_p(P3, m1:P3).</pre> 938This is also related to having use_module in a module interface, which 939is similar to re-exporting. The difference between that and reexport is 940the definition module of the indirectly imported predicate. 941<h2> 942Removal of the module_interface section</h2> 943Pre-5.0, modules could be partiotioned into module_interface and module 944body (begin_module). This static sectioning has been dropped. Without the 945module_interface section, the following queries effectively comprise a 946module's interface: 947<ul> 948<li> 949:- export</li> 950 951<li> 952:- reexport</li> 953</ul> 954These directives record themselves as the interface of the module that 955contains them. They do not have to appear in any particular section. 956<p>For backward compatibility, we interpret certain directives in an old-style 957module_interface by transformation into an equivalent export/reexport/global 958directive. Unfortunately, this is not exactly possible for occurrences 959of use_module,lib,import in module_interfaces: they almost map to the new 960reexport directive, but the semantics is subtly different. We therefore 961support having use_module and import in recorded interfaces, although it 962is only possible to create them by using obsolete features. 963<br> 964<table BORDER COLS=2 WIDTH="100%" NOSAVE > 965<tr> 966<td><b>Directive in old :- module_interface</b></td> 967 968<td><b>Occurs in recorded interface as</b></td> 969</tr> 970 971<tr> 972<td>op(A,B,C)</td> 973 974<td>export op(A,B,C)</td> 975</tr> 976 977<tr> 978<td>set_chtab(A,B)</td> 979 980<td>export chtab(A,B)</td> 981</tr> 982 983<tr> 984<td>define_macro(A,B,C)</td> 985 986<td>export macro(A,B,C)</td> 987</tr> 988 989<tr> 990<td>set_flag(syntax_option, X)</td> 991 992<td>export syntax_option(X)</td> 993</tr> 994 995<tr> 996<td>meta_attribute(A,B)</td> 997 998<td>global meta_attribute(A,B)</td> 999</tr> 1000 1001<tr> 1002<td>use_module(M)</td> 1003 1004<td>use_module(M) - almost reexport(M)</td> 1005</tr> 1006 1007<tr> 1008<td>lib(M)</td> 1009 1010<td>use_module(library(M)) - almost reexport(library(M))</td> 1011</tr> 1012 1013<tr> 1014<td>import(Preds from M)</td> 1015 1016<td>import(Preds from M) - almost reexport(Preds from M)</td> 1017</tr> 1018 1019<tr> 1020<td>import(M)</td> 1021 1022<td>import(M) - almost reexport(M)</td> 1023</tr> 1024</table> 1025 1026<p>For any other directives in a module_interface, we issue a warning. 1027<h3> 1028The source-processor problem</h3> 1029How do we solve the source-processor problem? We execute certain export/local 1030directives, ie. the ones that affect the syntax: 1031<ul> 1032<li> 1033op/3</li> 1034 1035<li> 1036struct/1</li> 1037 1038<li> 1039macro/3</li> 1040 1041<li> 1042chtab/2</li> 1043 1044<li> 1045syntax_option/1</li> 1046 1047<li> 1048meta_attribute/2</li> 1049</ul> 1050Apart from that, we also have to do all imports (since they may define 1051necessary syntax). For more details, see library(source_processor). 1052<h2> 1053Autoload</h2> 1054The existing autoload feature is messy because 1055<ol> 1056<li> 1057It requires the autoloaded predicates to be global</li> 1058 1059<li> 1060It creates the module where the autoloaded predicates are defined</li> 1061</ol> 1062Only one of these two things should be done, and globality should not be 1063used at all. I think there are two conceptually different features that 1064could be called "autoloading": 1065<ul> 1066<li> 1067A <u>development environment tool</u> that comes into action when an undefined 1068predicate is called. It could find (possibly multiple) libraries that define 1069the missing predicate and offer the programmer to load and import one of 1070these libraries. This might not work when a call is already compiled (calling 1071convention).</li> 1072 1073<li> 1074A <u>runtime mechanism</u> that lazily loads bulky libraries (or individual 1075predicates) only when called. Here, the programmer has clearly specified 1076what definition is wanted.</li> 1077</ul> 1078 1079<br> 1080</body> 1081</html> 1082