Re: [m-users.] Creating an interface module
"Zoltan Somogyi" <[email protected]>
| Newsgroups | gmane.comp.lang.mercury.general |
|---|---|
| Message-ID | <[email protected]> |
On 2023-07-14 10:02 +02:00 CEST, "Volker Wysk" <[email protected]> wrote: > I can think of a solution that looks easy to implement. Everything is simple and easy when you don't have to do it. Obligatory example: Dilbert's boss. > In a module there > could be some statement ":- import_as_well(...)", which tells the compiler > to import some other modules as well, when the module with the statement is > being imported. This means that the set of modules your code says to import (e.g. module A and B) is not the set of modules you *will* import (which will be A, B, C, D, E and F if B contains an import_as_well for C, C contains one for D etc). This can reduce compiler performance more than people may expect, and it will definitely add extra complication to the build system. It also means that the set of modules that a module imports can now include itself, if module X imports Y, and Y contains an import_as_well for X. What is the semantics of *that*? All of this is begging the questions: what problem does reexport solve, and is it the best solution of that problem? I have never seen a thorough attempt at answering those questions. Most answers amount to "this is the approach I am used to, and I don't want to learn another". The one use case people always bring up is that it allows several modules in a library to be presented to users as a single unified entity. However, I don't see how reexport makes an useful difference in that case. Without reexport, users of the library have access to library.module1.pred1 library.module1.pred2 library.module2.pred1 and so on. With reexport, they have access to library.module1_pred1 library.module1_pred2 library.module2_pred1 and so on. Without reexport, the module structure within the library is visible. With reexport, it is technically not visible, but the renaming required to prevent name clashes *makes* it visible anyway, at least in some cases. For example, the Mercury compiler has a gazillion functions named "init": map.init, set.init and so on, and the same is true for predicates named insert, remove, map, foldl, foldr etc. If the module structure is exposed, the module qualifiers on calls can be optional if the right choice is dictated by the types of the arguments. With the reexport with renaming approach, the module qualifiers must become part of the name, and are no longer optional. This means that *even in a language that supports reexport*, there is a good argument for not using it. Peter said that Mercury's module system is pretty basic. That is a statement of fact, but it is not a value judgement. Among the languages I know about, the most powerful module system belongs to the ML family of languages. Everyone acknowledges that it allows people to do things with modules that other languages can't support. However, to a first approximation, no newer langage has copied its approach to module system design. I am pretty sure that this means that language designers don't consider the extra power to be worth the extra cost. Your post considers cost in the form of implementation effort (in a somewhat cavalier fashion), but does not consider cost in the form of extra conceptual complexity for users of the language, which can be even more significant, and which (unlike implementation effort) has to be paid over and over, whenever a new person learns the language. Zoltan. _______________________________________________ users mailing list [email protected] https://lists.mercurylang.org/listinfo/users