|
|
|
|
Net Talk
edited
by Roberto Bagnara
Content:Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > Well, I think that it (the prolog module system) has to get rid of the > concept of importing. Well, Partially. In the given example, it should be possible to write a thing like the following: ?- user:import(book:author/1).
and to decide that a simple call such as: ?- author(Author).
has to look in some specified modules (e.g. user). ...I need help. . Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > Well, I think that it (the prolog module system) has to get rid of the > concept of importing. > I think you know what I want to say. Perhaps - but try to be more precise or people will just dismiss what you say, because importing has more than one meaning - and you mean something very specific. > [code] > :- module(book, [author/1]). > author(kafka). > id(1). > [/code] > > I will expect, after module being loaded, suppose "from" module user (NOTE: > I didnt say "into" module user): Use those terms consistently (you don't later). > [code] > ?- book:author(Author). > Author = kafka > [/code] Do you want ?- author(A). to succeed or error ? But before you answer, see later. > and, accidentally, but substantially: > > [code] > ?- book:id(Id). > ERROR: permission_error ... > [/code] > > Evidently: > > [code] > ?- user:author(Author). > ERROR: existence_error > [/code] > > Without the concept of importing, the predicate user:author/1 simply does > not exists. I think I basically agree with you. However, you should take into account that the toplevel of a Prolog system might make life easy for users who type in queries and in this way relax the rules. Trying to specify what a module system should provide by using the toplevel is going to confuse the hell out of yourself and readers, one reason being that "loading a module" from the toplevel doesn't need to have a meaning consistent with the program-as-divided-into-modules, and that the toplevel isn't a module itself (unless you define it to be and then hopefully consistent with the rest of you module concept). So here is a suggestion: try to define modules using programs only. In the style of program1: :- module(book,[author/1]).
author(ecco). id(17). program2: :- module(bib).
:- import book. foo :- author(X), id(Y). gee :- book:author(X), book:id(Y). bla :- user:author(X), user:id(Y). and specify which goals in program2 refer to which defined predicate (in which modules). Then start doing metapredicates. Then worry about the toplevel. Final suggestion: start with getting rid of module user. Subject: Re: Prolog Module System I'd like explicit qualification. In particular, I'd like a different behaviour of these two: system:assert(foo(bar)).
and assert(system:foo(bar)). % or, even badly, whatever:assert(system:foo(bar)).
While now they have an identical effect (i.e. to assert foo(bar) into module system). Yes I know all this has a meaning, but I think the current module system is simply another way to estrange programmers from prolog. But I accept it. I repeat, I am only experimenting... Subject: Re: Prolog Module System > I'd like explicit qualification. In particular, I'd like a different > behaviour of these two: > > system:assert(foo(bar)). > > and > > assert(system:foo(bar)). % or, even badly, whatever:assert(system:foo(bar)). > > While now they have an identical effect (i.e. to assert foo(bar) into module > system). What do you want the above examples to do ? > Yes I know all this has a meaning, but I think the current module system is > simply another way to estrange programmers from prolog. Just so you don't have the wrong idea about me: I think the module system as done in many Prolog systems is quite bad. It is high time someone came up with something better. Subject: Re: Prolog Module System >> >> and >> >> assert(system:foo(bar)). % or, even badly, >> whatever:assert(system:foo(bar)). >> >> While now they have an identical effect (i.e. to assert foo(bar) into >> module system). > > > What do you want the above examples to do ? ?- system:assert(example:foo(bar)).
yes
?- example:assert(foo(bar)). ERROR: existence_error (predicate example:assert/1 does not exists) ?- user:assert(example:foo(bar)). ERROR: existence error ?- context_module(user), import(system:assert(_)). % * SEE LATER yes ?- user:assert(example:foo(bar)). yes According to my view this should be equivalent to: ?- context_module(user), system:import(system:assert(_)).
Id Est: I am not changing the context module when I call system:import(...), but I am simply calling a predicate that belongs to module system. Other ideas I will put in my OOP package in the future. Subject: Re: Prolog Module System > Mauro Di Nuzzo wrote: > >> I'd like explicit qualification. In particular, I'd like a different >> behaviour of these two: >> >> system:assert(foo(bar)). >> >> and >> >> assert(system:foo(bar)). % or, even badly, >> whatever:assert(system:foo(bar)). >> >> While now they have an identical effect (i.e. to assert foo(bar) into >> module system). You may want to have a look at how ECLiPSe does this. It has a clear distinction between _lookup_module_ and _context_module_. The colon- qualification there only affects where the predicate definition is looked up. In your example: :- module(m).
p :- system:assert(foo(bar)). would use the definition of assert/1 which is exported from 'system', but foo(bar) would still be asserted into module m. To assert into a different module, you'd use the @/2 construct, which overrides the context module, e.g. :- module(m).
p :- assert(foo(bar))@othermod. would assert into module 'othermod'. The two annotations can of course be combined. Bart Demoen wrote: > Just so you don't have the wrong idea about me: I think the > module system as done in many Prolog systems is quite bad. > It is high time someone came up with something better. Before reinventing everything, have at least a look at the ECLiPSe module system, which addresses some of the points that get commonly complained about:
Another system that has put a lot of effort into its module system design is Ciao (www.ciaohome.org) Subject: Re: Prolog Module System > Before reinventing everything, have at least a look at the ECLiPSe > module system, which addresses some of the points that get commonly > complained about: > > - it has proper mechanisms to resolve name conflicts > - colon-qualification doesn't cost anything > - it can optionally enforce hiding of local items > - it implements reexport (with a bit of OO flavour) > - it doesn't employ a 'user' module (nor equivalent) > - it controls not only visibility of predicate names, but also > names of records, global variables, syntax settings etc > > What's maybe not so nice is that metapredicates are done quite > differently from the defacto standard. > Also, the module name space is still flat, which starts becoming > a problem when putting together applications with library components > from various origins. > > Another system that has put a lot of effort into its module system > design is Ciao (www.ciaohome.org) I know they departed from the SICStus module system (which is the same as the Quintus module system as far as I know). What are the highlights of their changes? In certainly favour some improvements here. Especially I'd like an efficient implementation of foo:bar(X), something which the SWI-Prolog module system doesn't allow for (based loosely on the Quintus system). I'd welcome a successor of the ISO part-II that is acceptable to all of us. I think that implies that most programs based on the Quintus module system and its decendants can run unmodified (possibly using some emulation mode). If a reasonable level of compatibility can be achieved I'm in for anything upon which we can agree. From: Paulo Moura Subject: Re: Prolog Module System > ... > Just so you don't have the wrong idea about me: I think the > module system as done in many Prolog systems is quite bad. > It is high time someone came up with something better. Done. Logtalk. Available since 1998. It solves every single problem that you find with current Prolog module systems. And no, this is neither the place nor the time for being modest. From: Jan Wielemaker
Subject: Re: Prolog Module System What about these demands in Logtalk?
From: Paulo Moura
Jan Wielemaker wrote:Subject: Re: Prolog Module System > What about these demands in Logtalk? > > * No overhead No overhead is possible in a Logtalk language implementation whenever static binding can be used. Otherwise, you will need to resort to dynamic binding plus a caching mechanism, just like any other OOP language or extension out there (btw, this is a possible answer for the Module:Goal performance question you asked elsewhere in this thread, which is also a binding issue). True, the *current implementation* is sub-optimal in this regard. > * Incremental compilation, also when changing module > imports and exports? The *current implementation* does incremental compilation: each entity is independently compiled. Nice for development but not the way to go for the best possible performance. The *current specification* neither prevents nor mandates support for incremental compilation. Both your questions are concerns about what is possible for an *implementation* of the Logtalk language specification. The current one is just that, one of the possible implementations. Which happens to be sub-optimal due to its portability goal. One thing is writing pure Prolog code that runs everywhere. Taking advantage of a specific Prolog compiler internals is an all different game, key to better performance and better integration with e.g. all the niceties that make SWI-Prolog a great development environment. From: Jan Wielemaker
Subject: Re: Prolog Module System I'd have to study Logtalk in more details. I am interested in somewhat more OO flavour in the module system. I do like something that executes natively though (or at least 99% transparently and with mimimal overhead). Maybe we should have a chat with some people interesting in these topics at the ICLP. From: Paulo Moura
Subject: Re: Prolog Module System Jan Wielemaker wrote: > ... > I'd welcome a successor of the ISO part-II that is acceptable to all > of us. I think that implies that most programs based on the Quintus > module system and its decendants can run unmodified (possibly using > some emulation mode). If a reasonable level of compatibility can be > achieved I'm in for anything upon which we can agree. That should not be difficult as any replacement would likely be more powerful and feature-rich. E.g. Logtalk can compile modules as objects, providing easy access to legacy code and libraries. It works with a common subset of module directives that include module/1-2, module/2, use_module/2, export/1, and meta_predicate/1. From: Paulo Moura
Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > ... > Yes I know all this has a meaning, but I think the current module system is > simply another way to estrange programmers from prolog. We talked a bit about this on the Prolog standardization forums but is worth repeating it here: most current module systems fail at the very basic thing they ought to support: avoiding name conflicts by providing namespaces when defining predicates. Let's assume two common library modules, each one exporting a member/2 predicate: :- module(lists, [member/2]). ... :- module(sets, [member/2]). ... So far, all is well. Both modules define a member/2 predicate, which is a nice, short, descriptive name. Each modules implements the member/2 predicate accordingly to its nature. Both modules are commonly part of Prolog libraries. Now assume the user defines a third module, which happens to call both lists:member/2 and sets:member/2. Two options here. The first one is to use explicit module qualification. This was the advantage of avoiding the name conflict that would arise if both modules are imported. However, there is often (but not always as Joachim pointed out elsewhere) a performance problem in using explicit qualification, up to the point that some Prolog implementers want to get rid of explicit qualification or strongly discouraged its use. The second option is to use implicit qualification. However, this leads to a name conflict. The common solution is to rename the conflicting predicates in the defining modules! (At this point, you may want to take a look at your favorite Prolog compiler libraries.) This is simply the wrong place and the wrong way of solving the problem. When renaming of a predicate is needed to avoid a conflict, the renaming should take place in the importing modules, not in the definition modules. Renaming in the definition modules is equivalent to saying that modules provide namespaces but we still need to rename predicate names to make them unique in order to avoid usage conflicts! Thus, why use modules in the first place? To be able to use short, nice, descriptive names only for private, not exported predicates? People reusing a module care first and foremost about the module interface, not about the module internals. At the very least, modules should support renaming *on importing*. Not only for solving name clashes but also to be able to give an imported name an alias that is more meaningful in the context where is going to be used. Of course, the problem I just described, is just one of the shortcomings of Prolog modules for software engineering tasks. Solving this shortcomings amounts to people reinventing objects. Worse, people are trying or hoping to reinvent objects as an extension and on such a shaky ground as current module systems (look at the issues with e.g. operators or meta-predicates). And this is just a very sad, big waste of time (sorry Mauro to be so blunt). I will end this post with a Prolog dirty secret: there is not support for abstract data types (ADTs) in current module systems. Supporting ADTs implies being able to define different implementations for the same module *interface*. Clever programmers will find a way around this limitation (they always do). However, lack of support for ADTs in current module systems is so embarassing when talking to people using other high-level programming languages... From: Mauro di Nuzzo
Subject: Re: Prolog Module System I agree with you on almost all what you said. But I have two observations:
From: Paulo Moura
Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > I agree with you on almost all what you said. > But I have two observations: > > 1) I do not think I am trying to build something on the "shaky" ground of > the current module system, So far, you're in the realm of a SWI-Prolog-only implementation. Therefore, you don't need to worry for different semantics for e.g. meta-predicates between Prolog compilers. SWI-Prolog provides a meta_transparent/1 directive. Other Prolog compilers provide a meta_predicate/1 directive. ECLiPSE provides a tool/1 directive. Do you think that these are just different names for the same semantics? Think again. I used the term "shaky" to refer to current module systems (PLURAL), not to a specific system. This is "comp.lang.prolog", not "comp.lang.swi-prolog" (which happens to be a Prolog compiler that I love and use daily). > but I think that, if a new architecture has to > come, it has to guarantee compatibility with old stuff; Don't see a problem there. For example, Logtalk can compile a fair number of the library modules found on common Prolog compilers without the need to change a single line of the original code. > 2) I do not think one should feel himself/herself embarrassed because of > comparision among languages, especially when talking of their most > fashionable properties: I think a prolog programmer could, if he/she wants, > to embarrass whoever; Abstract data types are hardly a fashionable property. > Well, I think prolog offers so much freedom that one can build its own > object-oriented extension in less than 300 source code lines, redefining > system procedures, actually doing what he/she wants. Again, so far, you're in the realm of a SWI-Prolog-only implementation. Therefore, you can take advantage of all SWI-Prolog features that allows you to minimize the number of lines needed to implement the features that you want. E.g. "redefining system procedures" is something that is specific (when possible) to a Prolog compiler. > But one should keep in > mind: what all these OOP features really add to prolog? Powerful code encapsulation and code reuse features? > My view is moving > towards minimalism. In this respect, I can only justify an extension to > prolog that does not create another language, adding so many predicates, When you add a *single* feature to a language, you're creating a superset of the original language and, therefore, a new language. I fail to understand what you mean by "adding so many predicates". Are you referring to user-level predicates? You basically need encapsulation and scope directives and a message-sending predicate operator. Implementation-level predicates? Are you having trouble sleeping due to the number of C lines of code and the number of C functions needed to implement e.g. SWI-Prolog? I don't think so. For example, if you're not using DCGs, then you may chose to not support them on your OOP extension. I could have done the same in Logtalk; it would translate to cut down 500 lines of code (includes layout lines) and the total number of predicates. Of course, if I was targeting a single Prolog compiler, I could probably just use the native DCG translator and runtime predicates. Not such luxury when you're targeting wide portability of your code and your applications. > and, above all, not really so useful concepts (now I am blunt ;). I would say that the usefulness of a language feature depends on the applications that you're writing. As you wrote elsewhere, you're writing your OOP extension as an educational experiment. I'm developing and using Logtalk for writing applications with tens of thousands of lines of code. The same goes for some of the Logtalk users. Different goals. Different feature sets. From: Bart Demoen
Subject: Re:Prolog Module System I would just suggest that one doesn't present "my personal habits" as general advice to others. There was a lot of that in the recent "discussion". From: Jan Wielemaker
Subject: Re: Good Examples of Properly Commented Prolog Code Matthew Huntbach wrote: > the annotations and restrictions required to parallelise it means > what you have is better considered as another sort fo logic > programming language rather than "parallel Prolog". Calling it "parallel Prolog" seems to fit the case perfectly (Prolog, possibly augmented with simple annotations, or with transparent parallelism where the restrictions can be deduced automatically). What could legitimately be called "parallel Prolog", if not exactly that. > OR-parallelism brings big efficiency issues, at worst you have to split > the whole programming environment into two every time you hit an > OR-parallel choice. You don't "have to"; the fact that it's possible doesn't make that a viable strategy, nor does it imply its necessity. Also, it's not the worst case in general: Say I have a single OR branch at the start of a program followed by a lengthy deterministic computation. Splitting on every OR-choice (i.e., once) can be the best thing to happen then. > You also hit the whole tricky issue of speculative parallelism and > speedup anomalies. You mean "speedup anomaly" in the usual sense, i.e., "the observed speedup is greater than predicted"? Yes, that can happen. > So while it can be done, it's much trickier than was naively > supposed when the idea of paraleliding Prolog was first raised. That's one correct and concise reply to Simon's question. From: Matthew Huntbach
Subject: Re: Parallel Prolog Markus Triska wrote: > Matthew Huntbach wrote: > > the annotations and restrictions required to parallelise it means > > what you have is better considered as another sort fo logic > > programming language rather than "parallel Prolog". > > Calling it "parallel Prolog" seems to fit the case perfectly (Prolog, > possibly augmented with simple annotations, or with transparent > parallelism where the restrictions can be deduced automatically). What > could legitimately be called "parallel Prolog", if not exactly that. My own feeling is that the word "Prolog" has a good and useful meaning: the sequential logic programming language with depth-first search and backtracking, left-to-right evaluation of goals, full unification (apart perhaps from the occurs check). I think we have another phrase for languages which look like Prolog but behave in a different way, and that phrase is "logic programming language". OK, I'm prepared to accept "parallel Prolog" for something that looks and behaves like sequential Prolog but exploits parallelism transparently. But I'm uneasy about it going further than that, and I think the usage of "parallel Prolog" for what ought to be "parallel logic programming language" is regrettable, though it often happens. One of the reasons I came to this conclusion was that when I was working on parallel logic programming languages I often found people's beliefs that what I was doing was "parallel Prolog" limited what they believed the language could do. That is, they saw it as logic programming with all the restrictions of Prolog plus the additional restrictions and/or annotations required for efficient parallelisation. I would rather they saw it as "logic programming which is more powerful than Prolog due to the additional facilities opened up by the concurrency and paralellism". > > OR-parallelism brings big efficiency issues, at worst you have to split > > the whole programming environment into two every time you hit an > > OR-parallel choice. > > You don't "have to"; the fact that it's possible doesn't make that a > viable strategy, nor does it imply its necessity. Also, it's not the > worst case in general: Say I have a single OR branch at the start of a > program followed by a lengthy deterministic computation. Splitting on > every OR-choice (i.e., once) can be the best thing to happen then. In sequential Prolog you go with your first OR-choice, and if that doesn't work out you backtrack and go with your second OR-choice. With OR-parallelism, you do both computations, one with your first OR-choice, one with your second, and if these also involve choices you split again, and again ... . So I'm not saying it's never useful, just that it's tricky and its effects and usefulness aren't always obvious. > > You also hit the whole tricky issue of speculative parallelism and > > speedup anomalies. > > You mean "speedup anomaly" in the usual sense, i.e., "the observed > speedup is greater than predicted"? Yes, that can happen. Can happen both ways round. If the solution is somewhere to the right in the search tree, but you get to it quickly because a parallel proessor is working on that branch, you get a faster speedup than the number of processors. On the other hand, if the slution is to the left you get no speedup because you don't arrive at it any more quickly with the parallel processors. A slowdown occurs when the solution is to the left but it happens all your parallel processors are given over to searching for solutions in the branches to it sright. From: Bart Demoen
Subject: Re: Prolog Module System Paulo Moura wrote: > I will end this post with a Prolog dirty secret: there is not support > for abstract data types (ADTs) in current module systems. Let me start this post with a Prolog dirty secret: there is no support for types in Prolog I think it would make a lot of sense to give types to Prolog before giving it abstract data types. From: Paulo Moura
Subject: Re: Prolog Module System In the context of module systems (which is the topic of this thread and the context of my comment), ADTs can be translated to being able to define a module *interface* that can be implemented (and therefore reused) by *several* independent modules. I.e. we can interpret a module as representing a type whose operations are the exported predicates. From: Bart Demoen
Subject: Re: Prolog Module System Maybe I should have been more explicit. In the context of module systems (...) ADTs are senseless for Prolog if Prolog doesn't even support concrete data types. From: Paulo Moura
Subject: Re: Prolog Module System I disagree. Consider, for example, the "dictionary" ADT. You can implement dictionaries in Prolog using e.g. different types of trees. With support for separating interface from implementation in a encapsulation mechanism, you can *declare* predicates for working with this ADT (e.g. empty/1, insert/4, lookup/3, keys/2, etc) in a interface/protocol and then provide different *implementations* for these predicates in different modules/objects, each one implementing a dictionary data structure with its own set of trade-offs. Different implementations can then coexist in the same application. Switching implementations is easy as all of them use the same interface. This is common practice in modern OOP languages. You can also do it in Prolog by using Logtalk. While you (may) regard this as senseless, me and others are happily taking advantage of this features :-) From: Jan Wielemaker
Subject: Re: Prolog Module System Paulo Moura wrote: > While you (may) regard this as senseless, me and > others are happily taking advantage of this features :-) I agree this is useful. Only, you don't need Logtalk for it (you do need it for some other things, particulary I sometimes need the ability to refine an interface, which isn't easily achieved using modules). To realise an interface you can simply define multiple modules with the same exports. If you want formal checking that they define the same exports, put the exports in another file and use :- include/1 to share the exports. This trick probably doesn't work in most current Prolog systems (it doesn't work in SWI-Prolog), but it should be easy to support it and it is completely in line with the de-facto standard. From: Paulo Moura
Subject: Re: Prolog Module System Jan Wielemaker wrote: > I agree this is useful. Only, you don't need Logtalk for it (you do need > it for some other things, particulary I sometimes need the ability to > refine an interface, which isn't easily achieved using modules). Refining an interface is simple in most OOP systems that support separation of interface from implementation. For example, in Logtalk you can write: :- protocol(extended_interface, extends(minimal_interface)).
> To realise an interface you can simply define multiple modules with the > same exports. True. And then, when you want to use nice tools such as PlDoc, you single out one of them to contain the documentation. Or you can just duplicate it as well. And when you change something in the "interface" you just need to make sure that you update all the copies. > If you want formal checking that they define the same > exports, put the exports in another file and use :- include/1 to share > the exports. This trick probably doesn't work in most current Prolog > systems (it doesn't work in SWI-Prolog), but it should be easy to > support it and it is completely in line with the de-facto standard. "Trick" is the right word here. Your suggestion fits squarely on the "let's reinvent objects" plan to solve the shortcomings of most current module systems. And the "de-facto standard" needs a formal standard, even if a minimalist one that could be used to test and drive compliance of all these module systems that claim to follow Quintus Prolog (?) take on modules. The lack of such standard is precisely why I used the term "shaky" in a previous post. We both know that there are subtle and not so subtle differences between the implementation of this elusive "de-facto" module standard. If people want to add new features to this de-facto standard, I would see that would be best to first get the foundations right. From: girish
Subject: Re: Prolog Module System Bart Demoen wrote: > Paulo Moura wrote: >> I will end this post with a Prolog dirty secret: there is not support >> for abstract data types (ADTs) in current module systems. > > Let me start this post with a Prolog dirty secret: > > there is no support for types in Prolog > > I think it would make a lot of sense to give types to Prolog > before giving it abstract data types. Is it difficult to add type semantics? Create unique atoms that correspond to types. Code semantics of the types in Prolog? Using the Prolog internal database it is possible to manage constructor behavior. Perhaps I missing something. From: Jan Wielemaker
Subject: Re: Prolog Module System Paulo Moura wrote: > Jan Wielemaker wrote: >> If you want formal checking that they define the same >> exports, put the exports in another file and use :- include/1 to share >> the exports. This trick probably doesn't work in most current Prolog >> systems (it doesn't work in SWI-Prolog), but it should be easy to >> support it and it is completely in line with the de-facto standard. > > "Trick" is the right word here. Your suggestion fits squarely on the Its not that much of a trick. You just share the module declaration, which effectively *is* an interface definition (albeit a bit minimalistic). All I wanted to say is that this specific task is one of the few that doesn't really need anything new, just proper standardization of what is out there. I agree that standardization of what is out there is a bit of a waste of effort as such as standard still leaves too many things uncovered :-) From: Bart Demoen
Subject: Re: Prolog Module System Paulo Moura wrote: >> In the context of module systems (...) ADTs are senseless for Prolog >> if Prolog doesn't even support concrete data types. > > I disagree. Consider, for example, the "dictionary" ADT. You can > implement dictionaries in Prolog using e.g. different types of trees. > With support for separating interface from implementation in a > encapsulation mechanism, you can *declare* predicates for working with > this ADT (e.g. empty/1, insert/4, lookup/3, keys/2, etc) in a > interface/protocol and then provide different *implementations* for > these predicates in different modules/objects, each one implementing a > dictionary data structure with its own set of trade-offs. Different > implementations can then coexist in the same application. Switching > implementations is easy as all of them use the same interface. This is > common practice in modern OOP languages. You can also do it in Prolog > by using Logtalk. While you (may) regard this as senseless, me and > others are happily taking advantage of this features :-) I have seen Jan's replies and I agree with him: one can do this minimalistic ADT thing in Prolog with the current module system with only minimalistic surgery to the module system - I would go with that instead of poluting Prolog with OO concepts. I think that in this (minimalistic) sense I also agree with Mauro. The argument for having types in Prolog - so that ADTs can be properly supported - has not been made properly yet by me, so here it is: it is clear that in a good module system, one wants to make it impossible (or at least very difficult) to abuse it - call predicates that are not made visible for instance. For ADTs, one would like to prevent (amongst others) inspection of the ADT without using the interface predicates. However, Prolog builtins like arg/3, ==/2 and functor/3 allow such inspection of any term, so also of (the data part of) any ADT. am just naming the obvious builtins: clearly user preds can use the builtin =/2 to inspect (and build) stuff. Proper types would make that impossible (it would require some different view on builtins like arg/3 or ==/2 - but [*]): Mercury has shown how to do them in the context of a Prolog like language and also solved [*]. Mercury has a small variant of the Prolog module system that makes ADTs (and much more more and usefull stuff) available to a Prolog like language. My apologies to Mercury designers if the use of "small variant" sounds condescending: I don't mean you did a "least effort job starting from Prolog" - I know you didn't - it just feels like a good way to sell your good ideas in this newsgroup. From: Bart Demoen
Subject: Re: Prolog Module System girish wrote: > Is it difficult to add type semantics? Create unique atoms that > correspond to types. Code semantics of the types in Prolog? Using the > Prolog internal database it is possible to manage constructor > behavior. Perhaps I missing something. I do not understand everything you write and ask. Maybe the Mercury type (and module) system answers your questions. It has been on my list-to-do for many years to build a typed Prolog - it still is, but I lack energy&time. I would name it tProlog :-) tProlog would look a lot like Mercury, and still feel like Prolog - maybe with similarities to Ciao Prolog, but not as PL/1-ish :-) From: Paulo Moura
Subject: Re: Prolog Module System Bart Demoen wrote: > ... > I have seen Jan's replies and I agree with him: one can do this > minimalistic ADT thing in Prolog with the current module system > with only minimalistic surgery to the module system - I would go > with that instead of poluting Prolog with OO concepts. I completely fail to understand your use of the word "polluting" above. Would you say or write that module concepts pollute Prolog? Your comment above seems to carry a scent of prejudice. Am I wrong? Modules provide encapsulation features to plain Prolog. Objects provide encapsulation features to plain Prolog. Module relations define paths and patterns for code reuse. Object relations define paths and patterns for code reuse. Module concepts can be applied to imperative, functional, and logic languages. Object concepts can be applied to imperative, functional, and logic languages. In fact, objects and modules, as encapsulation mechanisms, are orthogonal to the programming paradigm used in the subjacent language. Should I go on? Which module characteristics do you think make it more suitable as an encapsulation mechanism for Prolog when compared with objects? Tradition does not count. Which object characteristics do you think that do not fit well in a logic programming environment? From: A.L.
Subject: Re: Prolog Module System Paulo Moura wrote: > Bart Demoen wrote: >> ... >> I have seen Jan's replies and I agree with him: one can do this >> minimalistic ADT thing in Prolog with the current module system >> with only minimalistic surgery to the module system - I would go >> with that instead of poluting Prolog with OO concepts. > > I completely fail to understand your use of the word "polluting" > above. Would you say or write that module concepts pollute Prolog? > Your comment above seems to carry a scent of prejudice. Am I wrong? Count me second. Some time ago I asked question "where in Prolog is room for OO". Despite long discussion I still don't have the answer. I believe that OO in Prolog is some sort of "mee too" approach, also known in other languages. Adding OO to Perl converted this otherwise nice small scripting language into a monster. Fortunately, nobody is using OO in Perl. Regarding modules and OO - quite long abo Wirth's shool provided arguments that modules and OO are othhogonal conceps and serve different roles. OO is not module and module is not OO. See the most recent reincarnation of With school, namely Oberon language. It has modules and OO. Similarly Ada has both. There are number of publicatioons of Witht school regarding this issue, mostly in ECOOP proceedings. Arguments have been summarized in Klemens Szyperski's book "Component Software". From: Bart Demoen
Subject: Re: Prolog Module System Paulo Moura wrote: > Bart Demoen wrote: >> ... >> I have seen Jan's replies and I agree with him: one can do this >> minimalistic ADT thing in Prolog with the current module system >> with only minimalistic surgery to the module system - I would go >> with that instead of poluting Prolog with OO concepts. > > I completely fail to understand your use of the word "polluting" > above. Would you say or write that module concepts pollute Prolog? Of course not. Module concepts are fine for Prolog. I think I am clearly saying that I prefer Prolog not to become polluted by OO concepts. Let me be very explicit: I think
You can name it a prejudice, I prefer to name it a well-considered opinion :-) I think that people in favour of OO just have a different prejudice. > In fact, objects and modules, as encapsulation mechanisms, are > orthogonal to the programming paradigm used in the subjacent language. > Should I go on? You are doing just fine: what you say is true. But there is no argument in it in favour polluting Prolog with OO. Orthogonality of something (in this case OO) to something (in this case Prolog) often means a form of incompatibility :-) > Which module characteristics do you think make it more suitable as an > encapsulation mechanism for Prolog when compared with objects? > Tradition does not count. That's not fair: for you, hype and fashion are fine, but for me tradition would not count ? Really, not fair :-( > Which object characteristics do you think that do not fit well in a > logic programming environment? I do not know whether some old invited talks by Kowalski are available somewhere: he knew better than me to sell this point. He might have changed his mind in the mean time - everyone is allowed to do so - but I remember his arguments made sense to me then. Also what Parnasse wrote about OO made sense to me. And I do have some personal experience with OO in the Java context ... My first and foremost complaint with OO is: it allows programmers to produce in a short time lots of unmaintainable and crappy code, instead of just a moderate amount of it. From: Paulo Moura
Subject: Re: Prolog Module System Bart Demoen wrote: > Paulo Moura wrote: >> Bart Demoen wrote: >>> ... >>> I have seen Jan's replies and I agree with him: one can do this >>> minimalistic ADT thing in Prolog with the current module system >>> with only minimalistic surgery to the module system - I would go >>> with that instead of poluting Prolog with OO concepts. > >> I completely fail to understand your use of the word "polluting" >> above. Would you say or write that module concepts pollute Prolog? > > Of course not. Module concepts are fine for Prolog. > I think I am clearly saying that I prefer Prolog not to become > polluted by OO concepts. Let me be very explicit: I think > > - module concepts are fine for Prolog > - OO concepts are not So, I would expect you to be able to provide some the arguments backing your position. Cannot find a single one in your post. >> Your comment above seems to carry a scent of prejudice. Am I wrong? > > You can name it a prejudice, I prefer to name it a well-considered > opinion :-) > I think that people in favour of OO just have a different prejudice. Only if you consider using Prolog+objects to solve programming problems that cannot be solved in a reasonable way using Prolog +modules as a form of prejudice. >> In fact, objects and modules, as encapsulation mechanisms, are >> orthogonal to the programming paradigm used in the subjacent language. >> Should I go on? > > You are doing just fine: what you say is true. > But there is no argument in it in favour polluting Prolog with OO. Follows there is also no argument in it in favour of polluting Prolog with modules. > Orthogonality of something (in this case OO) to something (in this > case Prolog) often means a form of incompatibility :-) Orthogonality often means that you can mix-and-match features in order to solve problems. One example, which I expect to be familiar to most readers: state-space search. Is easy to design and implement both state spaces and search methods in an orthogonal way. The advantage of it? You can apply any search method to a single state space. You can apply a single search method to any state space. >> Which module characteristics do you think make it more suitable as an >> encapsulation mechanism for Prolog when compared with objects? >> Tradition does not count. > > That's not fair: for you, hype and fashion are fine, but for me > tradition would not count ? Really, not fair :-( What hype? What fashion? Where? You're just avoiding answering the question. Take the state-space search example above. Implemented it using Prolog+modules. Post your solution. Then we can go talk about hype and fashion. The Logtalk version of the example is available with the current distribution. Want a different problem? Take a look at recent posts on e.g the SWI-Prolog mailing list of people trying and asking for help in using modules to solve programming problems. Guess how many replies with solutions they have received. Guess what they have ended up using. >> Which object characteristics do you think that do not fit well in a >> logic programming environment? > > I do not know whether some old invited talks by Kowalski are available > somewhere: he knew better than me to sell this point. He might have > changed his mind in the mean time - everyone is allowed to do so - but > I remember his arguments made sense to me then. Also what Parnasse > wrote about OO made sense to me. Saying that some well know people would share your point-of-view is fine if you must but does not really provide any argument for this thread discussion. Anyone have references for those talks and writings? > And I do have some personal experience with OO in the Java context ... Java is just one of the existing materializations of OO concepts. And a class-based one. Plenty more exists, far more interesting from the point-of-view of a logic programming practitioner. For example, prototype-based languages. > My first and foremost complaint with OO is: it allows programmers to > produce in a short time lots of unmaintainable and crappy code, > instead of just a moderate amount of it. That's really a critic on the quality of programmers, not on OO concepts. Lousy programmers can write lousy code in any programming language. Any programming feature can be misused. So what? From: A.L.
Subject: Re: Prolog Module System Paulo Moura wrote: >> You can name it a prejudice, I prefer to name it a well-considered >> opinion :-) >> I think that people in favour of OO just have a different prejudice. > > Only if you consider using Prolog+objects to solve programming > problems that cannot be solved in a reasonable way using Prolog > +modules as a form of prejudice. I am not sure that I understand the sentence above, but I don't know about problems that cannot be solved without OO paradigm in "reasonable way". Maybe the definition of "reasonable" is crucial here. It would be great to see example of such problem. From: Zoltan Somogyi
Subject: Re: Prolog Module System Paulo Moura wrote: > Which module characteristics do you think make it more suitable as an > encapsulation mechanism for Prolog when compared with objects? Object-oriented languages brought much that is good and much that is good. I think interface inheritance is a good idea; I think implementation inheritance is a bad idea. Unfortunately, in many object-oriented languages you cannot get the former without the latter. One of the good points of Java is that it made this possible, by separating the notions of interfaces and classes. Mercury programs can use type classes to achieve the benefits of object orientation. Mercury supports its equivalent of interface inheritance. It does not support implementation inheritance, though of course implementations can be reused by the existing code reuse mechanism: putting the code in a predicate or function and calling it from several places. Note that this is not new from us; Mercury's handling of type classes is based on Haskell's, with some tweaks. For more details, I encourage people to read David Jeffery's PhD thesis, available from the Mercury web page. > Which object characteristics do you think that do not fit well in a > logic programming environment? The notions that objects have (a) identity and (b) mutable state run directly counter to the basic notions of declarative programming. From: Paulo Moura
Subject: Re: Prolog Module System A.L. wrote: > Paulo Moura wrote: > >>> You can name it a prejudice, I prefer to name it a well-considered >>> opinion :-) >>> I think that people in favour of OO just have a different prejudice. > >> Only if you consider using Prolog+objects to solve programming >> problems that cannot be solved in a reasonable way using Prolog >> +modules as a form of prejudice. > > I am not sure that I understand the sentence above, but I don't know > about problems that cannot be solved without OO paradigm in > "reasonable way". Maybe the definition of "reasonable" is crucial > here. Prolog is (or aims to be) a declarative language. Reasonable programming solutions would be as close as possible to the original problem specifications. There are whole classes of problems where knowledge is naturally organized in taxonomies or classification hierarchies. For these kind of problems, objects are arguably a better solution than modules. > It would be great to see example of such problem. See Jan post in this thread. He is looking for adding some OO flavour to SWI-Prolog module systems not as an academic exercice but to solve real world problems. Read the rest of the post your are replying to. Let me give you another example. I'm working with a fellow researcher on the implementation of STEP Application Protocols (these are standards for datafiles used for interchanging data models between CAD/ CAM applications and tools). These standards use a specification language, EXPRESS, which makes a OO solution a natural fit, up to a point that you have close to a one-to-one mapping between the specification entities and the corresponding objects in the Logtalk implementation. This is a must, as it makes tasks such as ensuring that the implementation complies with the specification far more easier. A module-based solution would be akward at best. From: Paulo Moura
Subject: Re: Prolog Module System Zoltan Somogyi wrote: > Paulo Moura wrote: >> Which module characteristics do you think make it more suitable as an >> encapsulation mechanism for Prolog when compared with objects? > > Object-oriented languages brought much that is good and much that is good. > I think interface inheritance is a good idea; I think implementation > inheritance is a bad idea. Unfortunately, in many object-oriented languages > you cannot get the former without the latter. One of the good points of Java > is that it made this possible, by separating the notions of interfaces and > classes. The same is possible in D, C#, Logtalk, and a number of other OOP languages. Implementation inheritance may happen as part of the original problem specification or as a part of the problem solution. As such, it shall be supported. Like any other programming feature, it shall be used with care. > Mercury programs can use type classes to achieve the benefits of > object orientation. Mercury supports its equivalent of interface inheritance. > It does not support implementation inheritance, though of course > implementations can be reused by the existing code reuse mechanism: > putting the code in a predicate or function and calling it from several > places. > > Note that this is not new from us; Mercury's handling of type classes > is based on Haskell's, with some tweaks. > > For more details, I encourage people to read David Jeffery's PhD thesis, > available from the Mercury web page. Thanks for the reference. >> Which object characteristics do you think that do not fit well in a >> logic programming environment? > > The notions that objects have (a) identity and (b) mutable state run directly > counter to the basic notions of declarative programming. Is worth noting that, in current Prolog systems, modules have identity and mutable state. Identity provides a way to refer to a set of encapsulated predicates (or to an interface). I don't see how this goes either in favour or against declarative programming. Prolog have mutable state. In plain Prolog, we've a global dynamic database. Using objects and modules, we've local dynamic databases. Logtalk objects *can* have mutable state; they don't *need* to have mutable state. Prolog modules objects *can* have mutable state; they don't *need* to have mutable state. Logtalk objects can be either static or dynamic; they can be defined in a source file or created dynamically at runtime. Logtalk objects can be used as code encapsulation and reuse features without ever touching mutable state. Using Logtalk objects does not imply creating then dynamically at runtime. You can write useful programs in Prolog without ever doing an assert or retract. You can do the same in Logtalk. I'm co-authoring a Logtalk appplication with hundreds of objects that is used to process datafiles with thousands of objects. All objects are static. None of them uses mutable state. Equating objects in Prolog as bringing to logic programming a Java-like programming experience is the same as putting a blindfold and ignoring that objects is a much richer field of programming concepts than classes and and dynamic objects with mutable state. From: A.L.
Subject: Re: Prolog Module System Paulo Moura wrote: > Prolog is (or aims to be) a declarative language. Reasonable > programming solutions would be as close as possible to the original > problem specifications. There are whole classes of problems where > knowledge is naturally organized in taxonomies or classification > hierarchies. For these kind of problems, objects are arguably a better > solution than modules. As I wrote in other message, sentence "objects are better than modules" has little sense. This is like "car is better than cake". Objects and modules are orthogonal concepts, and there are languages that have BOTH. See the paper "Import is Not Inheritance Why We Need Both: Classes and Modules" by Clemens Szyperski http://citeseer.ist.psu.edu/szyperski92import.html Abstract. The design of many popular object-oriented languages like Smalltalk, Eiffel, or Sather follows a certain trend: The class is the only structuring form. In this paper, the need for having modules besides classes is claimed. Modules stem from a different language family and at first glance it seems that they can easily be unified with classes. Among other things, unifying modules and classes carries the danger of unifying the import and inheritance relationships. Constructs in several languages are discussed that indicate that modules and classes should indeed be kept separate. From: Jan Wielemaker
Subject: Re: Prolog Module System Paulo Moura wrote: > A.L. wrote: > >> It would be great to see example of such problem. > > See Jan post in this thread. He is looking for adding some OO flavour > to SWI-Prolog module systems not as an academic exercice but to solve > real world problems. Read the rest of the post your are replying to. I've encountered numerous cases where I would like to be able to pass a collection of predicates and I want to have several implementations of this collection, often these implementations are refinements of other collections. Typicaly of course, you use a module name as handle and put the different collections in a module. There are two issues with this I very much dislike:
From: Paulo Moura
Subject: Re: Prolog Module System A.L. wrote: > Paulo Moura wrote: >> Prolog is (or aims to be) a declarative language. Reasonable >> programming solutions would be as close as possible to the original >> problem specifications. There are whole classes of problems where >> knowledge is naturally organized in taxonomies or classification >> hierarchies. For these kind of problems, objects are arguably a better >> solution than modules. > > As I wrote in other message, sentence "objects are better than > modules" has little sense. This is like "car is better than cake". > Objects and modules are orthogonal concepts, and there are languages > that have BOTH. See the paper "Import is Not Inheritance Why We Need > Both: Classes and Modules" by Clemens Szyperski There are two major types of OO systems: class-based ones and prototype-based ones. You start your sentence by talking about objects (apparently in a broad sense) and end it with a reference to classes. > http://citeseer.ist.psu.edu/szyperski92import.html Thanks for the reference. Appreciated. > Abstract. The design of many popular object-oriented languages like > Smalltalk, Eiffel, or Sather follows a certain trend: The class is the > only structuring form. In this paper, the need for having modules > besides classes is claimed. Modules stem from a different language > family and at first glance it seems that they can easily be unified > with classes. Among other things, unifying modules and classes carries > the danger of unifying the import and inheritance relationships. > Constructs in several languages are discussed that indicate that > modules and classes should indeed be kept separate. Prototypes can fulfill the role of modules. That's way Logtalk supports both prototypes and classes. Prototypes are a much better plug-in replacement for Prolog modules than classes. Logtalk also supports categories (think components, aspects) that provide you with importing semantics. *Classes* are not the only structuring form in Logtalk. From: A.L.
Subject: Re: Prolog Module System Paulo Moura wrote: > There are two major types of OO systems: class-based ones and > prototype-based ones. You start your sentence by talking about objects > (apparently in a broad sense) and end it with a reference to classes. > > [...] > > Prototypes can fulfill the role of modules. That's way Logtalk > supports both prototypes and classes. Prototypes are a much better > plug-in replacement for Prolog modules than classes. Logtalk also > supports categories (think components, aspects) that provide you with > importing semantics. *Classes* are not the only structuring form in > Logtalk. There is a book about prototypes: "Object Oriented Programming with Prototypes" by Guenther Blashek, Springer Verlag 1994 vere the author shows that conceptually prototypes are not diffrent than classes. P.S. By the way, there is also third OO model: types extension. It is used in Oberon and Ada. From: Paulo Moura
Subject: Re: Prolog Module System Jan Wielemaker wrote: > Paulo Moura wrote: > >> A.L. wrote: > >>> It would be great to see example of such problem. > >> See Jan post in this thread. He is looking for adding some OO flavour >> to SWI-Prolog module systems not as an academic exercice but to solve >> real world problems. Read the rest of the post your are replying to. > > I've encountered numerous cases where I would like to be able to pass > a collection of predicates and I want to have several implementations > of this collection, often these implementations are refinements of > other collections. Typicaly of course, you use a module name as handle and > put the different collections in a module. There are two issues with > this I very much dislike: > > * Using Module:Callable I overrule the module's privacy a > bit too easily. > > * It is not trivial to make simple refinements of a collection, > something which is quite often needed. Both problems have trivial solutions using (Logtalk) objects but you already know that :-) > I made a little hack in a project to deal with the second, but the > hack relies heavily on the SWI-Prolog low-level details of modules and > calling `super' and especially `self' is rather clumsy. In a previous post in this thread, Joachim already wrote about the need of making a distinction between "calling context" and "definition context". This is fundamental in order to get meta-predicates right for predicate-based (i.e. not atom-based) modules. For objects, we need to track at runtime the "execution context". The "execution context" needs "self" (i.e. the object that received the original message), "sender" (the object that have sent the message; this is similar to the "calling context" for modules), and "this" (i.e. the object containg the clause under execution; this is needed when using parametric objects in order to access at runtime the actual value of the parameters). The usual solution for implementing the "execution context" is to extend the arguments of the predicate (during program compilation) with extra ones for representing the execution context. Here we pay a small performance price as more arguments usually imply more register push&pop operations (depending on the WAM model used). From: Paulo Moura
Subject: Re: Prolog Module System A.L. wrote: > Paulo Moura wrote: >> There are two major types of OO systems: class-based ones and >> prototype-based ones. You start your sentence by talking about objects >> (apparently in a broad sense) and end it with a reference to classes. > [...] > >> Prototypes can fulfill the role of modules. That's way Logtalk >> supports both prototypes and classes. Prototypes are a much better >> plug-in replacement for Prolog modules than classes. Logtalk also >> supports categories (think components, aspects) that provide you with >> importing semantics. *Classes* are not the only structuring form in >> Logtalk. > > There is a book about prototypes: "Object Oriented Programming with > Prototypes" by Guenther Blashek, Springer Verlag 1994 vere the author > shows that conceptually prototypes are not diffrent than classes. I've not read the book, so I cannot comment on it. You can certainly solve the same problems using either classes or prototypes. Both types of OO systems have their strengths and disadvantages. Maybe that's what the author means by "conceptually not different"? See the folder "examples/shapes" in the current Logtalk distribution for an example of solving the same problem using both prototypes and classes. Classes represent abstractions. Classes are used indirectly through instantiation (and no, instantiation does not necessarily imply creating a dynamic object at runtime). We can think of classes as describing a set and instances as elements of the set. Prototypes can be self-defining objects. I write "can be" because you can derive a prototype from another prototype. We're not longer talking about sets, abstractions, or materializations of those abstractions. That's what makes prototypes a much better replacement for Prolog modules when compared with classes. For example, the equivalent of the module "ordsets" is the prototype "ordesets", not a class that you would have to instantiate before being able to use the "ordsets" predicates. Of course, for other problems, classes are more appropriated than prototypes as a structuring mechanism. That's way Logtalk supports both (categories and protocols/interfaces can be reused by both classes and prototypes as their are orthogonal concepts). From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote: > Jan Wielemaker wrote: >> Paulo Moura wrote: >>> A.L. wrote: >>>> It would be great to see example of such problem. >>> See Jan post in this thread. He is looking for adding some OO flavour >>> to SWI-Prolog module systems not as an academic exercice but to solve >>> real world problems. Read the rest of the post your are replying to. >> I've encountered numerous cases where I would like to be able to pass >> a collection of predicates and I want to have several implementations >> of this collection, often these implementations are refinements of >> other collections. Typicaly of course, you use a module name as handle and >> put the different collections in a module. There are two issues with >> this I very much dislike: >> >> * Using Module:Callable I overrule the module's privacy a >> bit too easily. >> >> * It is not trivial to make simple refinements of a collection, >> something which is quite often needed. > > Both problems have trivial solutions using (Logtalk) objects but you > already know that :-) Both problems also have trival solution in ECLiPSe's module system (which, compared to Logtalk, is a more gentle variant/extension of Quintus and ISO modules): The Module:Goal construct only allows to call exported predicates and therefore doesn't break privacy (this is possible due to the distinction between lookup module and context module). For the sort of refinements you are talking about, I have found that ECLiPSe's reexport directive is as much object orientation as I need. It is an extension of ISO reexport that makes it easy to write modules that are extensions/restrictions/modifications or combinations of other modules (see http://eclipse-clp.org/doc/userman/umsroot043.html#toc43 ) From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote: > Zoltan Somogyi wrote: >> The notions that objects have (a) identity and (b) mutable state run directly >> counter to the basic notions of declarative programming. > > Is worth noting that, in current Prolog systems, modules have identity > and mutable state. But there are very, very few situations where having mutable state in a module is justified. I personally haven't used assert/retract in at least 15 years of Prolog(-like) programming, and I think we all agree that it is not the essence of LP, but rather an unfortunate blemish. My main criticism of Logtalk is that it goes to great lengths to provide features that not only encourage the use of global names and mutable state, but elevate it to its prevalent programming paradigm. > Identity provides a way to refer to a set of encapsulated predicates > (or to an interface). I don't see how this goes either in favour or > against declarative programming. It is fine to have names for your static code or data. It is wrong to have names for dynamic data. > Prolog have mutable state. In plain Prolog, we've a global dynamic > database. Using objects and modules, we've local dynamic databases. > Logtalk objects *can* have mutable state; they don't *need* to have > mutable state. That would be acceptable if Logtalk had support for a kind of object that behaves like a logical data structure. > Logtalk objects can be either static or dynamic; they can be defined > in a source file or created dynamically at runtime. But they can't be anonymous like a Prolog structure or list. That's why I am not really sure they deserve to be called objects at all. They certainly are not "first class". From: Joachim Schimpf
Subject: Re: Prolog Module System Jan Wielemaker wrote: > I agree this is useful. Only, you don't need Logtalk for it (you do need > it for some other things, particulary I sometimes need the ability to > refine an interface, which isn't easily achieved using modules). As I said in another post, the ISO reexport feature goes a long way towards facilitating this. When I implemented it for ECLiPSe, I noticed that something was missing though, and added a variant that reexports everything except an explicitly specified list of items. So you can do thinks like :- module(m_with_better_p).
:- reexport m except p/1. p(X) :- ... <redefinition of p/1, possibly reusing m:p/1 within> ... > To realise an interface you can simply define multiple modules with the > same exports. If you want formal checking that they define the same > exports, put the exports in another file and use :- include/1 to share > the exports. This trick probably doesn't work in most current Prolog > systems (it doesn't work in SWI-Prolog), but it should be easy to > support it and it is completely in line with the de-facto standard. This trick works in ECLiPSe, and I have repeatedly recommended it to users. And a trick that you repeat a few times becomes a method, doesn't it :-) You do get a bit of checking in the form of a warning, when the interface file exports a predicate that you then forget to define. Nevertheless, because the trick isn't so obvious, it may be worth having a more formal module system construct for it. Of course, having the interface consist of just the name/arity specifications is very weak (see the discussion about ADTs). From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > Paulo Moura wrote: >> Zoltan Somogyi wrote: >>> The notions that objects have (a) identity and (b) mutable state run directly >>> counter to the basic notions of declarative programming. > >> Is worth noting that, in current Prolog systems, modules have identity >> and mutable state. > > But there are very, very few situations where having mutable state in > a module is justified. I personally haven't used assert/retract in at > least 15 years of Prolog(-like) programming, and I think we all agree > that it is not the essence of LP, but rather an unfortunate blemish. I was just pointing out that, in this particular point, there is no distinction between modules and objects. So far, all criticism to objects apply equally well to modules. Which, by itself is telling. > My main criticism of Logtalk is that it goes to great lengths > to provide features that not only encourage the use of global names and > mutable state, but elevate it to its prevalent programming paradigm. What "great lengths" you're talking about? Logtalk reinterprets the familiar dynamic database handling standard predicates in terms of objects, as Prolog systems reinterpret the same predicates in terms of modules. Logtalk provides built-in predicates for dynamically create new objects at runtime. Most Prolog systems allows you to defined and create new modules at runtime. So, once again, your (and others) criticism of objects applies equally well to modules. Let me repeat my question: what "great lengths" you're talking about? >> Identity provides a way to refer to a set of encapsulated predicates >> (or to an interface). I don't see how this goes either in favour or >> against declarative programming. > > It is fine to have names for your static code or data. > It is wrong to have names for dynamic data. Then simply don't use dynamic objects. Nothing in Logtalk forces you to do so. >> Prolog have mutable state. In plain Prolog, we've a global dynamic >> database. Using objects and modules, we've local dynamic databases. >> Logtalk objects *can* have mutable state; they don't *need* to have >> mutable state. > > That would be acceptable if Logtalk had support for a kind of object > that behaves like a logical data structure. Logtalk supports parametric objects (which, btw, predate Logtalk and can be found in several other OO extensions and systems). They behave like a logical data structure. With the added bonus of being able to encapsulate the predicates that "work" in the data structure inside itself. >> Logtalk objects can be either static or dynamic; they can be defined >> in a source file or created dynamically at runtime. > > But they can't be anonymous like a Prolog structure or list. Again, Logtalk supports parametric objects. Everytime you instantiate object parameters you get a "variant" of the parametric object term. Just the same as when you instantiate a Prolog structure of list. > That's > why I am not really sure they deserve to be called objects at all. > They certainly are not "first class". Objects are not anonymous in ANY object-oriented language. An object identity can be implicit but is always there. Anyway, thanks for your feedback. It would be more intersting if you had first taking a closer look at Logtalk. From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > ... >> Both problems have trivial solutions using (Logtalk) objects but you >> already know that :-) > > Both problems also have trival solution in ECLiPSe's module system > (which, compared to Logtalk, is a more gentle variant/extension of > Quintus and ISO modules): Logtalk is neither a gentle nor a strong variant/extension of quintus and ISO modules. > The Module:Goal construct only allows to call exported predicates and > therefore doesn't break privacy (this is possible due to the distinction > between lookup module and context module). > > For the sort of refinements you are talking about, I have found that > ECLiPSe's reexport directive is as much object orientation as I need. > It is an extension of ISO reexport that makes it easy to write modules that > are extensions/restrictions/modifications or combinations of other modules > (seehttp://eclipse-clp.org/doc/userman/umsroot043.html#toc43) This is one of the nicest features of ECLiPSe modules, worth implementing in other Prolog module systems. However, I suspect that is does not provide the solution Jan is looking for (judging only from his description) From: A.L.
Subject: Re: Prolog Module System Paulo Moura wrote: > I was just pointing out that, in this particular point, there is no > distinction between modules and objects. So far, all criticism to > objects apply equally well to modules. Which, by itself is telling. I think that this statement is logically incorrct. Module and object IS NOT the same, except according to your view. From: Cesar Rabak
Subject: Re: Prolog Module System A.L. wrote: > There is a book about prototypes: "Object Oriented Programming with > Prototypes" by Guenther Blashek, Springer Verlag 1994 vere the author > shows that conceptually prototypes are not diffrent than classes. > > P.S. By the way, there is also third OO model: types extension. It is > used in Oberon and Ada. More or less... like Blashek's claim that "'conceptually' prototypes are not diffrent than classes", it can be shown that on languages with a well rooted Object hierarchy (like Smalltalk, Self, etc.) it is conceptually extension from the root Class/Object. From: Paulo Moura
Subject: Re: Prolog Module System A.L. wrote: > Paulo Moura wrote: >> I was just pointing out that, in this particular point, there is no >> distinction between modules and objects. So far, all criticism to >> objects apply equally well to modules. Which, by itself is telling. > > I think that this statement is logically incorrct. Module and object > IS NOT the same, except according to your view. Modules and object are not the same. That's not my view. That's nobody's view on this thread. That's not what I wrote. In other words, don't be a troll. From: Jan Wielemaker
Subject: Re: Prolog Module System Paulo Moura wrote: > Joachim Schimpf wrote: >> For the sort of refinements you are talking about, I have found that >> ECLiPSe's reexport directive is as much object orientation as I need. >> It is an extension of ISO reexport that makes it easy to write modules that >> are extensions/restrictions/modifications or combinations of other modules >> (seehttp://eclipse-clp.org/doc/userman/umsroot043.html#toc43) > > This is one of the nicest features of ECLiPSe modules, worth > implementing in other Prolog module systems. However, I suspect that > is does not provide the solution Jan is looking for (judging only from > his description) Looks like a good start, but I often need a `send-self' construct. Can ECLiPSe do that? From: Joachim Schimpf
Subject: Re: Prolog Module System Yes and no. No in the sense that there is no built-in support for it. Yes in the sense that it is not difficult to get the same effect: You can grab the relevant module name and pass it as an extra argument. Then your send-self becomes simply a module-qualified call. Module systems have simple lookup rules: you either call the visible predicate (which is local or imported), or you module-qualify explicitly. OO systems have much more complex built-in lookup rules. One could be bold and say that they effectively hide some module arguments and module qualifications. That doesn't necessarily mean it's a bad idea, but one has to ask whether the increase in language complexity is justified by reduced application complexity. From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote > ... > Anyway, thanks for your feedback. It would be more intersting if you > had first taking a closer look at Logtalk. Lovely. But you have a point: I have indeed made several attempts in the past to have this "closer look" at Logtalk, and to discover what it can do for me. But I must admit I get stuck in the OO-speak, and it is hard for me to see the relevance to the problems I encounter in daily Prolog programming. But let's try to be constructive: I appreciate that the aim of your Logtalk work is to show that you can put every known OO feature into a Prolog-based system. You have shown that, and it is an interesting result and system, and OO fans may well appreciate all the features. But for the purpose of designing a better Prolog, I think we need a minimalist approach: which are the features that have a really good price/value ratio? Can you put Logtalk aside for a moment, but bring your experience to bear on the question: if you could add only 2 new features/concepts to Prolog-with-Modules, what would you choose? From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > Paulo Moura wrote: > >> ... >> Anyway, thanks for your feedback. It would be more intersting if you >> had first taking a closer look at Logtalk. > > Lovely. Sorry Joachim, didn't mean to sound harsh. My apologies. Is just that it gets very tiresome to keep refuting shallow criticisms. Not to mention that all the objections to objects in Prolog apply equally well to current module systems. People seem oblivious that Prolog modules also have e.g. identity and dynamic state! > But you have a point: I have indeed made several attempts in > the past to have this "closer look" at Logtalk, and to discover what > it can do for me. But I must admit I get stuck in the OO-speak, and > it is hard for me to see the relevance to the problems I encounter in > daily Prolog programming. Documentation could certainly be better. Hard to work on implementing, documenting, and developing open source software when all that seems to matter nowadays in academia is the raw number of papers you publish. > But let's try to be constructive: I appreciate that the aim of your > Logtalk work is to show that you can put every known OO feature into > a Prolog-based system. No. That's not my aim. Far from it. In fact, Logtalk includes since is inception features that only now have started to appear in other OO languages (e.g. components). But let's not dwell on that subject for now. > You have shown that, and it is an interesting > result and system, and OO fans may well appreciate all the features. People don't use objects instead of modules because they are OO fans. People use objects because they provide solutions for Prolog programming and software engineering problems that are awkward at best to solve using modules. Using an encapsulation mechanism does not (necessarily) change the underlying programming paradigm, only the way encapsulated code is called and reused. Predicates inside objects are still predicates. > But for the purpose of designing a better Prolog, I think we need a > minimalist approach: which are the features that have a really good > price/value ratio? The ones that you need to write an application? I think we all agree that the current ISO Prolog standard and most current module systems are too minimalistic to allow people to write real-worls applications without constantly resorting to non-portable, proprietary features. > Can you put Logtalk aside for a moment, but bring > your experience to bear on the question: if you could add only 2 new > features/concepts to Prolog-with-Modules, what would you choose? I've already made in previous posts some suggestions. Trying to be minimalistic, I would say:
From: Cesar Rabak
Subject: Re: Prolog Module System Joachim Schimpf wrote: > OO systems have much more complex built-in lookup rules. One could be > bold and say that they effectively hide some module arguments and > module qualifications. That doesn't necessarily mean it's a bad idea, > but one has to ask whether the increase in language complexity is > justified by reduced application complexity. Would you be surprised if the answer were *yes*? From: Cesar Rabak
Subject: Re: Prolog Module System Paulo Moura wrote: > Joachim Schimpf wrote: >> My main criticism of Logtalk is that it goes to great lengths >> to provide features that not only encourage the use of global names and >> mutable state, but elevate it to its prevalent programming paradigm. > > What "great lengths" you're talking about? Global names: all your objects are named and occupy one global name space. Mutable state: the whole design seems based on the idea that the data members of objects are predicates. The inheritance mechanisms are designed with this in mind. The documentation mainly deals with this situation. Correct me if I'm wrong. > Logtalk supports parametric objects (which, btw, predate Logtalk and > can be found in several other OO extensions and systems). They behave > like a logical data structure. With the added bonus of being able to > encapsulate the predicates that "work" in the data structure inside > itself. I'm not quite sure what to think of parametric objects. Your glossary says that they are a way to get the functionality of templates in C++. I would rather like to believe that they were meant to be a way of having objects with logical data members. However, for that purpose they seem not sufficiently well thought though. They do not behave the same as predicate data members. There are serious problems with inheritance, e.g. you can in general not reuse a superclass method because it expects a different object functor as "this". >> That's >> why I am not really sure they deserve to be called objects at all. >> They certainly are not "first class". > > Objects are not anonymous in ANY object-oriented language. An object > identity can be implicit but is always there. There is a difference between a global name and a pointer. There is a difference between the name of a class in C++ and the result of a constructor call. It's the difference between mode create_object(+,...) and create_object(-,...). Logtalk doesn't support the latter, if I'm not mistaken. From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > Module systems have simple lookup rules: you either call the visible > predicate (which is local or imported), or you module-qualify explicitly. > > OO systems have much more complex built-in lookup rules. Much more complex? Hardly. That sounds too much like FUD for me to be quiet :-) It also omits the troubles that implicit qualification can get you into. Is worth noting that the widespread success of OOP languages shows that most people have no problem mastering and using objects to solve everyday problems. Let's take a look to object lookup rules. The first thing one needs to be aware is that, with objects, there is a clear distinction between *declaring* a predicate and *defining* a predicate (this distinction often gets blurred with modules). Therefore, we have two lookup rules: one for finding the predicate declaration (in order to show that a call is legal; e.g. we're not calling a predicate that is out of scope) and one for finding the predicate definition. The lookup rules are different for prototype-based and class-based systems. Logtalk supportd both types of systems. Alomost all (if not all) other OOP systems only supports one of them. Prototype-based systems: Declaration lookup: if the declaration is not local, simply go up on the prototype derivation relationships until you find it. Definition lokup: the same. Class-based systems: Declaration lookup: start in the "self" class, follow specialization relationships until you find it. Definition lokup: can be the same (in most imperative-derived OOP systems) or you can start locally and, if not found, go to the class of "self" and then follow specialization relationships. Inheritance semantics are not the same as import semantics (mind you, Logtalk supports both). Import semantics look simpler until you import several modules, each of them possibly importing other modules with export and reexport directives coming into play, and with conflicting predicate names. Then you start to appreciate the advantages of explicit qualification and the advantages of language mechanisms for solving name conflicts and for renaming (in the *usage* context) inherited predicates. > One could be > bold and say that they effectively hide some module arguments and > module qualifications. That doesn't necessarily mean it's a bad idea, > but one has to ask whether the increase in language complexity is > justified by reduced application complexity. One could be bold and say that one of the troubles of Prolog implementers with objects is lack of familiarity on how to implement them when compared with the accumulated expertise in implementing modules. People usually cling to what they know best and are afraid of change. The idea of replacing deeply encrusted module support in source trees by object support is troublesome, so why not play some smoke screens and talk how objects corrupt declarative and logic programming ideals, conveniently omitting that the alleged corruption is already there in plain Prolog and in Prolog module systems? From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > Paulo Moura wrote: >> Joachim Schimpf wrote: >>> ... >>> My main criticism of Logtalk is that it goes to great lengths >>> to provide features that not only encourage the use of global names and >>> mutable state, but elevate it to its prevalent programming paradigm. > >> What "great lengths" you're talking about? > > Global names: all your objects are named and occupy one global name space. In most Prolog module systems, all your modules are named and occupy one global name space. > Mutable state: the whole design seems based on the idea that the data > members of objects are predicates. The inheritance mechanisms are designed > with this in mind. The documentation mainly deals with this situation. > Correct me if I'm wrong. The whole design of of modules are based on the idea the module data members are predicates. The import mechanisms are designed with this in mind. The documentation mainly deals with this situation. Correct me if I'm wrong. Why are you talking about *data* members? As opposed to what? Leave that concepts for OO systems derived from imperative languages. I'm beggining to understand why you have a hard time getting into Logtalk objects. Objects in Logtalk are about the encapsulation and reuse of predicates, not about bringing to logic programming concepts that are only appropriated for imperative languages. >> Logtalk supports parametric objects (which, btw, predate Logtalk and >> can be found in several other OO extensions and systems). They behave >> like a logical data structure. With the added bonus of being able to >> encapsulate the predicates that "work" in the data structure inside >> itself. > > I'm not quite sure what to think of parametric objects. Your glossary > says that they are a way to get the functionality of templates in C++. The concept of parametric objects is related to the concept of templates in C++ and generics in other OO languages. However, note that C++ templates are used at *compile* time, while parametric objects are used at *runtime*. > I would rather like to believe that they were meant to be a way of having > objects with logical data members. However, for that purpose they seem > not sufficiently well thought though. They do not behave the same as > predicate data members. And rightly so. Please see the examples with parametric objects in the current Logtalk distribution. > There are serious problems with inheritance, > e.g. you can in general not reuse a superclass method because it expects > a different object functor as "this". In the case of Logtalk (and, I believe, other Prolog OO systems) your sentence above is simply meaningless to me. Could you provide us with a simple example? >>> That's >>> why I am not really sure they deserve to be called objects at all. >>> They certainly are not "first class". > >> Objects are not anonymous in ANY object-oriented language. An object >> identity can be implicit but is always there. > > There is a difference between a global name and a pointer. > There is a difference between the name of a class in C++ and > the result of a constructor call. (object) identifiers are global (unless you're using namespaces for objects as it's possible in some OO languages). The result of a constructor call gives you a pointer to an object that simply acts as an implicit identifier that you pass around. Btw, constructors are just a poor workaround for the lack of support for meta-classes :-) > It's the difference > between mode create_object(+,...) and create_object(-,...). > Logtalk doesn't support the latter, if I'm not mistaken. The built-in predicate create_object/4 is just a *low-level primitive* for creating dynamic objects; it's usually use it as a foundation to build more sophisticated behavior (as explained in the documentation and illustrated in the Logtalk examples). Supporting a create_object(-,...) would be trivial as it's easy to generated unique identifiers in Prolog. From: Paulo Moura
Subject: Re: Prolog Module System Cesar Rabak wrote: > Joachim Schimpf wrote: >> OO systems have much more complex built-in lookup rules. One could be >> bold and say that they effectively hide some module arguments and >> module qualifications. That doesn't necessarily mean it's a bad idea, >> but one has to ask whether the increase in language complexity is >> justified by reduced application complexity. > > Would you be surprised if the answer were *yes*? Ditto. This Wikipedia entry comes to mind: http://en.wikipedia.org/wiki/Worse_is_Better From: Mauro di Nuzzo
Subject: Re: Prolog Module System Wow! This discussion is really charming for I am learning much (actually, this sharpens my opinion). In particular, my experiment with oop and modules has almost reach a point of no return. Modules are no suitable to implement even the flavour of object oriented programming. Nevertheless, I think modules (with the related import semantics) are a good and well established part of the Prolog language. I just hope in minor improvements. To name one (for SWI), I would appreciate a SWI version of the "blackboard" of SICStus. I mean that one should be able to define constants per-module (I am going to add this feature to my oop in order to treat attributes). This is really straightforward to implement (see SICStus bb_set/2, bb_get/2, bb_delete/1, bb_update/3 predicates). On the other hand, when I came to Prolog as a logic programming language, I expected a great part of such a language dealing with categories. Objects must have a part in Prolog, but I do not believe that a "standard" oop can improve Prolog (actually I think the contrary). Prolog is based on predicates and unification. Consider the length/2 predicate. Logtalk definition is identical to standard prolog (I cannot see the advantage, sorry). Instead, within my oop, I define a length/1 predicate, the actual list (i.e. data) being stored elsewhere in the instance. But consider now what definition one could use for append/3 (unless using 3 different predicates). [I hope I expressed myself in the latter point]. So, if data must remain into the predicate (as an argument), why oop? These reflections led me to an idea that unfortunately I am unable to master (perhaps I will upload some unuseful code in my site in the future). The core of the idea is to somehow inductively recognize the data arguments of a predicate in order to decide what to do based on some taxonomic rules. Deliriums... From: Cesar Rabak
Subject: Re: Prolog Module System Paulo Moura wrote: > Joachim Schimpf wrote: >> ... >> Module systems have simple lookup rules: you either call the visible >> predicate (which is local or imported), or you module-qualify explicitly. >> >> OO systems have much more complex built-in lookup rules. > > Much more complex? Hardly. That sounds too much like FUD for me to be > quiet :-) It also omits the troubles that implicit qualification can > get you into. Is worth noting that the widespread success of OOP > languages shows that most people have no problem mastering and using > objects to solve everyday problems. Paulo, since I'm an enthusiast of OOP, I feel comfortable to comment that the "widespread" of OO languages is a bit over sold by the media due two aspects:
> implementers with objects is lack of familiarity on how to implement > them when compared with the accumulated expertise in implementing > modules. People usually cling to what they know best and are afraid of > change. The idea of replacing deeply encrusted module support in > source trees by object support is troublesome, so why not play some > smoke screens and talk how objects corrupt declarative and logic > programming ideals, conveniently omitting that the alleged corruption > is already there in plain Prolog and in Prolog module systems? I would add that before implementing even the _use_ is not that mastered! From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote: > Joachim Schimpf wrote: >> Paulo Moura wrote: >>> Joachim Schimpf wrote: >>>> ... >>>> My main criticism of Logtalk is that it goes to great lengths >>>> to provide features that not only encourage the use of global names and >>>> mutable state, but elevate it to its prevalent programming paradigm. >>> What "great lengths" you're talking about? >> Global names: all your objects are named and occupy one global name space. > > In most Prolog module systems, all your modules are named and occupy > one global name space. > >> Mutable state: the whole design seems based on the idea that the data >> members of objects are predicates. The inheritance mechanisms are designed >> with this in mind. The documentation mainly deals with this situation. >> Correct me if I'm wrong. > > The whole design of of modules are based ... You are missing my point. But this is getting tedious, let's move on. >> I would rather like to believe that they were meant to be a way of having >> objects with logical data members. However, for that purpose they seem >> not sufficiently well thought though. They do not behave the same as >> predicate data members. > > And rightly so. Please see the examples with parametric objects in the > current Logtalk distribution. > >> There are serious problems with inheritance, >> e.g. you can in general not reuse a superclass method because it expects >> a different object functor as "this". > > In the case of Logtalk (and, I believe, other Prolog OO systems) your > sentence above is simply meaningless to me. Could you provide us with > a simple example? Sure. If I want to work with logical data structures, and I want to update something, I need In and Out arguments. So, with parametric objects I could write: :- object(person(_Name,_Age)).
and it works as expected::- public(grow_older/1). grow_older(person(Name,Age1)) :- this(person(Name,Age0)), Age1 is Age0+1. :- end_object. ?- person(joe, 25) :: grow_older(P). P = person(joe, 26) But if I now extend this object, e.g. :- object(emp(_Salary,Name,Age),
extends(person(Name,Age))). :- end_object. I get ?- emp(1000, joe, 25) :: grow_older(P). P = person(joe, 26) but obviously I would like emp(1000,joe,26). How do I do it? [I think Mauro is hinting at the same problem in another post] By the way, the example shows another shortcoming: When I define my emp/3 object, I need to know the arity and argument positions of the person object I want to inherit from - which means that parametric objects can hardly be considered abstract data types. >>>> That's >>>> why I am not really sure they deserve to be called objects at all. >>>> They certainly are not "first class". >>> Objects are not anonymous in ANY object-oriented language. An object >>> identity can be implicit but is always there. >> There is a difference between a global name and a pointer. >> There is a difference between the name of a class in C++ and >> the result of a constructor call. > > (object) identifiers are global (unless you're using namespaces for > objects as it's possible in some OO languages). The result of a > constructor call gives you a pointer to an object that simply acts as > an implicit identifier that you pass around. You seem to be saying that it makes no difference whether you have a name or an anonymous handle/pointer. This is remarkable because you have just written in another forum: > When you are done with a dynamic object, you can simply abolish it. which demonstrates one disadvantage of named objects: no garbage collection. There are others, like the problem of privacy: you can just guess someone else's object's name, and access it. From: Jan Wielemaker
Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > Wow! This discussion is really charming for I am learning much (actually, > this sharpens my opinion). > > In particular, my experiment with oop and modules has almost reach a point > of no return. Modules are no suitable to implement even the flavour of > object oriented programming. Nevertheless, I think modules (with the related > import semantics) are a good and well established part of the Prolog > language. I just hope in minor improvements. To name one (for SWI), I would > appreciate a SWI version of the "blackboard" of SICStus. I mean that one > should be able to define constants per-module (I am going to add this > feature to my oop in order to treat attributes). This is really > straightforward to implement (see SICStus bb_set/2, bb_get/2, bb_delete/1, > bb_update/3 predicates). The SICStus blackboard is a set of global variables. The SWI-Prolog implementation thereof is based on hProlog. See nb_setval/2 and friends. Currently global variables are not local to a module. This is likely to change someday. From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > You are missing my point. But this is getting tedious, let's move on. I believe we're looking at (the role of) objects (in logic programming) in two different ways. My view is simply that objects provide a more powerful and flexible alternative to modules for encapsulating and reusing predicates. Nevertheless, I see no reason why objects in logic programming should provide first-class implementations of imperative/procedural features. Logtalk is the result of a set of design decisions (like any other OO logic programming system), which necessarily constrain its scope, advantages, and limitations. If you are looking for a different feature set, or a different interpretation of OO concepts in logic programming, it would be interesting if you could post a brief (or detailed :-) description of which features you would like to see in a OO logic programing extension to Prolog. > Sure. If I want to work with logical data structures, and I want to > update something, I need In and Out arguments. So, with parametric > objects I could write: > > :- object(person(_Name,_Age)). > :- public(grow_older/1). > grow_older(person(Name,Age1)) :- > this(person(Name,Age0)), > Age1 is Age0+1. > :- end_object. > > and it works as expected: > > ?- person(joe, 25) :: grow_older(P). > P = person(joe, 26) You can certainly do that. I should point out that parametric objects (and using parameters for representing backtracable state, including the idea of returning new object identifiers) goes way back in time. See e.g. Markus Fromherz's OL(P) system. Nevertheless, this usage of parameters is mostly a trick. The idea of a *parameter* is something that you set once, not something that you keep updating. In the specfic case of Logtalk, parameters are not a replecement for dynamic state. > But if I now extend this object, e.g. > > :- object(emp(_Salary,Name,Age), > extends(person(Name,Age))). > :- end_object. > > I get > ?- emp(1000, joe, 25) :: grow_older(P). > P = person(joe, 26) > > but obviously I would like emp(1000,joe,26). How do I do it? > [I think Mauro is hinting at the same problem in another post] I believe you question could be rephrased as: How do I do it in an elegant way, with a minimum of code and preferably by reusing a grow_older/1 method? The short and quick answer is: you don't. Now the extended answer. Logtalk provides built-in methods for accessing an object identifier (this/1) and an object parameters (parameter/2); it does not provide any built-in method for updating a parameter (which would be a strange thing to do!). Therefore, a grow_older/1 method would need to be redefined every time you define a new logical data structure as an extension of another logical data structure; no point inheriting a definition where the format of the extended logical data structure is hard-coded. That said, one solution is: :- object(person(_Name,_Age)).
:- protected(age/3). age(Age0, Age1, person(Name,Age1)) :- this(person(Name,Age0)). :- public(grow_older/1). grow_older(New) :- ::age(Age0, Age1, New), Age1 is Age0 + 1. :- end_object. :- object(emp(_Salary,Name,Age), extends(person(Name,Age))). age(Age0, Age1, emp(Salary,Name,Age1)) :- this(emp(Salary,Name,Age0)). :- end_object. | ?- emp(1200, sally, 25)::grow_older(P). P = emp(1200, sally, 26) yes > By the way, the example shows another shortcoming: When I define > my emp/3 object, I need to know the arity and argument positions > of the person object I want to inherit from - which means that > parametric objects can hardly be considered abstract data types. Why are you talking about abstract data types in this context? What's the connection? When you extend, specialize, or instantiate an object, you need to know and use the identifer of the extended, specialized, or instantiated object. That holds both for Logtalk and for any other OO language. >> (object) identifiers are global (unless you're using namespaces for >> objects as it's possible in some OO languages). The result of a >> constructor call gives you a pointer to an object that simply acts as >> an implicit identifier that you pass around. > > You seem to be saying that it makes no difference whether you have > a name or an anonymous handle/pointer. No. I'm just saying that an identifier is an identifier, no matter if it's the programmer or the system naming the object (a name is just an alias to an internal handler/pointer). > This is remarkable because > you have just written in another forum: > >> When you are done with a dynamic object, you can simply abolish it. > > which demonstrates one disadvantage of named objects: no garbage > collection. Garbage collection of objects would be nice. Of course, to do it in the context of the current *portable* Logtalk implementation, it would imply implementing my own garbage collector, completely separated from the back-end Prolog compiler garbage collector. Even in the context of a Prolog specific implementation, with full access to its internals, it would be no trivial task. Moving on, if you want to imply that Logtalk objects are not first-class because they are not garbage-collected, fine by me. Btw, would you also say the same about e.g. C++ objects? It's a disadvantage to not have garbage collection for dynamic objects? Yes. Is it important? Hardly. If you want to code your application around dynamic objects Logtalk may or may not be your best choice. Note that Logtalk *static* objects can have dynamic state; you don't need to use *dynamic* objects in order to get dynamic state. > There are others, like the problem of privacy: > you can just guess someone else's object's name, and access it. Which is only possible by using someone else's object's *public* interface (note that parameters are in a sense public as they are part of the object identifier). From: Paulo Moura
Subject: Re: Prolog Module System Cesar Rabak wrote: > Joachim Schimpf wrote: >> OO systems have much more complex built-in lookup rules. One could be >> bold and say that they effectively hide some module arguments and >> module qualifications. That doesn't necessarily mean it's a bad idea, >> but one has to ask whether the increase in language complexity is >> justified by reduced application complexity. > > Would you be surprised if the answer were *yes*? Ditto. This Wikipedia entry comes to mind: http://en.wikipedia.org/wiki/Worse_is_Better From: Paulo Moura
Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > Wow! This discussion is really charming for I am learning much (actually, > this sharpens my opinion). > ... > On the other hand, when I came to Prolog as a logic programming language, I > expected a great part of such a language dealing with categories. Objects > must have a part in Prolog, but I do not believe that a "standard" oop can > improve Prolog (actually I think the contrary). Prolog is based on > predicates and unification. For non-trivial Prolog applications, you need encapsulation and reuse mechanisms, wence all the variations of Prolog module and object systems developed so far. > Consider the length/2 predicate. Logtalk > definition is identical to standard prolog (I cannot see the advantage, > sorry). Instead, within my oop, I define a length/1 predicate, the actual > list (i.e. data) being stored elsewhere in the instance. You can do the same within Logtalk and write queries such as: | ?- [1, 2, 3]::length(L).
L = 3 yes See the "examples/parametric" example. > But consider now > what definition one could use for append/3 (unless using 3 different > predicates). [I hope I expressed myself in the latter point]. So, if data > must remain into the predicate (as an argument), why oop? Code (i.e. predicates) encapsulation and reuse. From: Mauro di Nuzzo
Subject: Re: Prolog Module System I dont know if this is the right context, but I am interested in how logtalk solves the following problem. Suppose a "parametric" class (object) 'set' specializing (inheriting) a parametric class 'list' redefining method length/1 (e.g. suppose one wants they have different behaviours). When you call: ?- [1,2,3]::length(L).
what is really called? Is it called set::length(L) or list::length(L)? How logtalk solves (or better, decide what to do with) this? From: Mauro di Nuzzo
Subject: Re: Prolog Module System
From: Paulo Moura
Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > I dont know if this is the right context, but I am interested in how logtalk > solves the following problem. Please consider using the Logtalk discussion forums for Logtalk specific questions in the future. Parametric objects are found on several OO extensions to Prolog so both your question and my reply are not Logtalk specific. > Suppose a "parametric" class (object) 'set' specializing (inheriting) a > parametric class 'list' redefining method length/1 (e.g. suppose one wants > they have different behaviours). > When you call: > > ?- [1,2,3]::length(L). > > what is really called? Is it called set::length(L) or list::length(L)? > How logtalk solves (or better, decide what to do with) this? The syntax you use above is Object::Message. Therefore, if you want to have both "set" and "list" parametric objects, you will need different identifiers for each. For example, you could use the standard list notation for "list" objects and choose a different notation for "set" objects. For example: | ?- {1,2,3}::length(L).
You would need to relate the "set" object parameters with the "list" object parameters in order to inherit "list" methods. If you're looking at the parametric object identifiers as logical data structures, then you don't want to use classes for this specific problem; best to use prototypes (you don't have instances, you have instantiations of the parametric object identifiers). From: Paulo Moura
Subject: Re: Prolog Module System Mauro Di Nuzzo wrote: > - About "code reuse" *I think* we already reuse code without having to > instantiate objects. Using objects does not necessarily means instantiating classes... > Prolog supports arbitrarily complex compund terms, so I > cant easily see the benefits of objects. I see, for first, their > expensiveness. Do you mean expressiveness? > - About "encapsulation" *I think* it could be solved partially changing the > actual module system. In which way, among the many ways, I dont know. I can > only propose to separately handle exported and public predicates. Why? Exported predicates *are* public predicates. Non-exported predicates are assumed to be private predicates. > In particular, I would privilege public/private/protected over > imported/exported, although retaining the latter possibility. Wouldn't it be confusing to have two different scope directives/rules for module predicates? From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote: > Joachim Schimpf wrote: >> You are missing my point. But this is getting tedious, let's move on. > > I believe we're looking at (the role of) objects (in logic > programming) in two different ways. My view is simply that objects > provide a more powerful and flexible alternative to modules for > encapsulating and reusing predicates. Agreed, things have become a bit clearer now. So to summarise:
> provide first-class implementations of imperative/procedural features. I expected from a thing called "object" to somehow support the packaging of code with data. This is what procedural OO languages provide, but it is hardly a procedural-specific concept! It's what you need to build abstract data types. When programming in a (procedural or logic) OO language, I expect that the bulk of my values and variables are contained in objects, or are themselves objects. Why, hardcore OO languages even take pride in declaring that "everything is an object"! In Logtalk, I'm still mainly programming with (non-object) lists and structures. > If you are looking for a different > feature set, or a different interpretation of OO concepts in logic > programming, it would be interesting if you could post a brief (or > detailed :-) description of which features you would like to see in a > OO logic programing extension to Prolog. I'd like to see a marriage between parametric objects and ECLiPSe's "declared structures" (http://eclipse-clp.org/doc/userman/umsroot022.html). The ECLiPSe struct-syntax provides a certain degree of data abstraction, and even of structure inheritance. Hmmm, maybe we should have called them objects ;-) From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote: >>> (object) identifiers are global (unless you're using namespaces for >>> objects as it's possible in some OO languages). The result of a >>> constructor call gives you a pointer to an object that simply acts as >>> an implicit identifier that you pass around. >> You seem to be saying that it makes no difference whether you have >> a name or an anonymous handle/pointer. > > No. I'm just saying that an identifier is an identifier, no matter if > it's the programmer or the system naming the object (a name is just an > alias to an internal handler/pointer). Names and handles are similar in the sense that they both are unique things that represent an object. But you are ignoring an important semantic difference: names live forever, they can be constructed and reconstructed by arbitrary means, they can be stored in a person's head or on a piece of paper, and typed back in. When objects are named, it is perfectly ok for a program to do something like ..., write('Please type an object name:'), read(ObjectName), ObjectName::message, ... For garbage collection, this has the consequence that you can never delete any named object in this scope because the program may need to access it again. Handles, on the other hand, can be reliably tracked by the system, and once all handles to an object are lost, it can be deleted. >> This is remarkable because >> you have just written in another forum: >> >>> When you are done with a dynamic object, you can simply abolish it. >> >> which demonstrates one disadvantage of named objects: no garbage >> collection. > > Garbage collection of objects would be nice. My point was: missing GC is not a shortcoming of your implementation, it is conceptually made virtually infeasible by having named objects. From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > Agreed, things have become a bit clearer now. So to summarise: > > 1. Logtalk objects are great a way of structuring code and read-only > data (i.e. things that are commonly represented as predicates). You are not restricted to read-only data. Logtalk supports both static and dynamic objects. Static objects also support dynamic state. > 2. Logtalk objects (not even parametric ones) are not great for > organising/storing/abstracting dynamic data during computation > (i.e. the things that are commonly represented as Prolog structures > and lists). Logtalk objects are not design with that goal in mind. More below. >> Nevertheless, I see no reason why objects in logic programming should >> provide first-class implementations of imperative/procedural features. > > I expected from a thing called "object" to somehow support the > packaging of code with data. This is what procedural OO languages > provide, but it is hardly a procedural-specific concept! > It's what you need to build abstract data types. In procedural OO languages code and data exist independently of each other. You can declare variables of simple types and compound types. You can define functions and procedures. Therefore, objects in those languages allow you to encapsulate both code and data, i.e. the building blocks of procedural languages. In functional OO languages, objects encapsulate functions. In the context of Prolog, variables and data structures do not exist independently of predicates (and predicate calls). Therefore, is reasonable to interpret objects in Prolog as simply encapsulating predicates. Prolog predicates are used to represent both code and data. I find this uniformity of representation refreshing, flexible, and powerful when compared with procedural languges. The role of Logtalk objects is not to bring back to logic programming the procedural split between code and data representations. > When programming in a (procedural or logic) OO language, I expect > that the bulk of my values and variables are contained in objects, > or are themselves objects. Why, hardcore OO languages even take > pride in declaring that "everything is an object"! In Logtalk, > I'm still mainly programming with (non-object) lists and structures. See my comment above. >> ... If you are looking for a different >> feature set, or a different interpretation of OO concepts in logic >> programming, it would be interesting if you could post a brief (or >> detailed :-) description of which features you would like to see in a >> OO logic programing extension to Prolog. > > I'd like to see a marriage between parametric objects and ECLiPSe's > "declared structures" (http://eclipse-clp.org/doc/userman/umsroot022.html). > The ECLiPSe struct-syntax provides a certain degree of data abstraction, > and even of structure inheritance. Hmmm, maybe we should have called > them objects ;-) I was expecting a reference to ECLiPSe "declared structures" since the first mention of parametric objects. What took you so long? :-) Your suggestion is worth exploring and have been on my to-do list for long. Anyway, parametric objects are objects not because of the parameters in their identifiers but because they encapsulate predicates just like any other (Logtalk) object. Several interpretations are possible for parametric objects. For example, you can easily define a "sort" object accepting as a parameter the "type" of elements to be sorted. Or see a parametric object as a way to associate a set of predicates with a compound term (whose template is the object identifier). Or use parameters for representing backtracable state. OL(P), L&O, SICStus Objects, and Logtalk (I'm probably missing some system here) all provide nice examples of parametric objects. From: Mauro di Nuzzo
Subject: Re: Prolog Module System > Why? Exported predicates *are* public predicates. Non-exported > predicates are assumed to be private predicates. > [...] > Wouldn't it be confusing to have two different scope directives/rules > for module predicates? Maybe. But I am moving to consider a semantic which links the concept of importing to that of inheriting. Suppose a module predicate is public (non-protected) by default, and just a protected_predicate/1 directive is used to declare a module predicate as private (protected). :- module(m, [p/1,q/1]). % suppose this list contains what have to be
inherited (default exports) :- protected_predicate q/1. % protected, though exported p(a). p(b). p(c). q(c). Now, from the user (toplevel) module: user: | ?- use_module(m, [q/1]).
Module user imports only q/1 from m (overriding default export list). Now user:q/1 is protected by user. Of course, one should be able to change the "protected" predicate property. Besides, user:p/1 does not exists, m:p/1 is public, m:q/1 is protected by m. A little different, but useful, I think. Surely, OOP needs more. From: Joachim Schimpf
Subject: Re: Prolog Module System Paulo Moura wrote: > Joachim Schimpf wrote: >> Agreed, things have become a bit clearer now. So to summarise: >> >> 1. Logtalk objects are great a way of structuring code and read-only >> data (i.e. things that are commonly represented as predicates). > > You are not restricted to read-only data. Logtalk supports both static > and dynamic objects. Static objects also support dynamic state. I said "a great way". Using assert/retract is not "a great way". I thought we had agreed on that. > In the context of Prolog, variables and > data structures do not exist independently of predicates (and > predicate calls). Eh? Here is a Prolog data structure: [1,2,3]. Here is another one: person(joe,25). No predicate in sight. > Therefore, is reasonable to interpret objects in > Prolog as simply encapsulating predicates. It would be reasonable if your assumpion were correct. > Prolog predicates are used to represent both code and data. Definitely not. You've got things the wrong way round: Prolog *terms* are used to represent both code (predicates) and data (constants, lists, tuples, strings, ...). > I find this uniformity of > representation refreshing, flexible, and powerful The fact that there *exists* a common representation for code and data is one of the great pluses of Prolog (it makes meta- programming easy). But neither does that mean that code and data are conceptually the same thing, nor does it mean that code and data are *always* represented the same way! Let's take a file containing the text p(f(3)).
This could represent simply a data structure, or a predicate p/1 with a
data structure argument. The representation at this syntactic
level is still the same. There is no way to tell the difference -
it depends on your interpretation.If you open this file and call read/2, you choose the pure data structure interpretation: you get a data representation for both p/1 and f/1 (e.g. tagged memory words on a stack). If you compile this file, you choose to interpret p/1 as a predicate, and f/1 as a data structure. The internal representations (e.g. WAM instructions) that your compiler generates are *very* different for the two. > when compared with > procedural languges. The role of Logtalk objects is not to bring back > to logic programming the procedural split between code and data > representations. This has nothing to do with declarative vs procedural (see e.g. Tcl as an example of a procedural language with common representation of code and data). Prolog is very explicit about where data is turned into predicates (call/1, compile/1, assert/1), or predicates are turned into data (clause/2, read/2 on a source file). So Prolog is not lacking a split between code and data, it just makes the transition easy (while explicit). Any OO extension should mirror that somehow. >> When programming in a (procedural or logic) OO language, I expect >> that the bulk of my values and variables are contained in objects, >> or are themselves objects. Why, hardcore OO languages even take >> pride in declaring that "everything is an object"! In Logtalk, >> I'm still mainly programming with (non-object) lists and structures. > > See my comment above. > >>> ... If you are looking for a different >>> feature set, or a different interpretation of OO concepts in logic >>> programming, it would be interesting if you could post a brief (or >>> detailed :-) description of which features you would like to see in a >>> OO logic programing extension to Prolog. >> I'd like to see a marriage between parametric objects and ECLiPSe's >> "declared structures" (http://eclipse-clp.org/doc/userman/umsroot022.html). >> The ECLiPSe struct-syntax provides a certain degree of data abstraction, >> and even of structure inheritance. Hmmm, maybe we should have called >> them objects ;-) > > I was expecting a reference to ECLiPSe "declared structures" since the > first mention of parametric objects. What took you so long? :-) What's the point of discussing a solution to the data representation problem, when you don't believe in data other than predicates? From: Paulo Moura
Subject: Re: Prolog Module System Joachim Schimpf wrote: > Paulo Moura wrote: >> In the context of Prolog, variables and >> data structures do not exist independently of predicates (and >> predicate calls). > > Eh? Here is a Prolog data structure: [1,2,3]. > Here is another one: person(joe,25). No predicate in sight. Ok. Let me rephrase. In the context of a Prolog PROGRAM (you know, the things we write with a text editor or with a pencil and a sheet of paper), variables and data structures do not exist independently of predicates (and predicate calls). Better now? >> Therefore, is reasonable to interpret objects in >> Prolog as simply encapsulating predicates. > > It would be reasonable if your assumpion were correct. Independently of my assumptions being correct or completly wrong, a reasonable interpretation does not imply that it's also the unique possible interpretation, does it? >> Prolog predicates are used to represent both code and data. > > Definitely not. You've got things the wrong way round: > Prolog *terms* are used to represent both code (predicates) > and data (constants, lists, tuples, strings, ...). Uau! That's a revelation! Thanks for the Prolog 101 lesson. Maybe, just maybe, you're taking the phrase above out of context? >> I was expecting a reference to ECLiPSe "declared structures" since the >> first mention of parametric objects. What took you so long? :-) > > What's the point of discussing a solution to the data representation > problem, when you don't believe in data other than predicates? Thanks for telling me what I do and do not believe. Life is less confusing now. |
|
|