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>&nbsp;
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 &amp; 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.&nbsp;<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>.&nbsp;
362This visibility class has been&nbsp; 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)&nbsp;
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>&nbsp;&nbsp;&nbsp; if (vis visible in definition module of clash)&nbsp;&nbsp;&nbsp;
411% hidden</tt>
412<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vis := clash</tt>
413<br><tt>&nbsp;&nbsp;&nbsp; else if (clash visible in definition module
414of vis)</tt>
415<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;</tt>
416<br><tt>&nbsp;&nbsp;&nbsp; else</tt>
417<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----->&nbsp;&nbsp;&nbsp;&nbsp; tm:tb(a,b,c,cm)</pre>
440
441<pre>t(a,b,c)@xm&nbsp;&nbsp; ----->&nbsp;&nbsp;&nbsp;&nbsp; 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>&nbsp;
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&nbsp;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&nbsp; 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>&nbsp;
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>&nbsp;
1080</body>
1081</html>
1082