Replies: 4 comments 23 replies
-
That is goal expansion, not attributed variables. They are often used together to create nice interfaces, like in |
Beta Was this translation helpful? Give feedback.
-
Inspired, I was thinking: in Prolog, can I conceptualize a computation in an object-oriented way? At least one aspect, the central aspect of OOP, computation by sending messages? Of course, as I'm a programming and Prolog beginner, I can use only a small subset of Prolog , without low-level predicates, so only very simple and immutable objects... And of course, the concept how to do OOP without an OOP language is not from my head. Edit: It seems that I should not use the words like "low-level predicates" and "only" before "immutable objects"...
|
Beta Was this translation helpful? Give feedback.
-
Is really objects what you are so much interested in? Recall that messages are a slightly more polite form of a command. (Just as the question "Did you get the message?" just means "Objey the command") And a command implies state. It is possible to simulate state somewhat in Prolog, but the dilemma you face is this: Either the state is explicit, then your OO-ish programs look rather awkward or you devise a formalism to hide it, but the you mostly lose the nice algebraic properties. |
Beta Was this translation helpful? Give feedback.
-
My 5 cents, I think that "programming in the large" in Prolog is such a large and highly debated topic that it isn't really possible to answer it in a single post. Prolog already offers the richest form of polymorphism invented. Do you really need object orientedness in Prolog? I personally don't think so. |
Beta Was this translation helpful? Give feedback.
-
Abstractions, Encapsulation, Coupling, and Code Organization in Prolog
Overview
I'm curious what everyone's experience with modularization/organization is with Prolog. I strongly suspect the answer is "DCGs", but allow me to explain my case:
In OO languages, techniques such as inheritance or SOLID principles are used to organize code in such a way that (in theory, if not practice) it is easy and comprehensible to extend, modify, and maintain the code. Python allows for operator overloading and polymorphism, so you can do fun things like
That's because integers, strings, and lists all define the
__add__(self, other)
method, which is what gets invoked when the+
operator is called.Haskell of course really takes this to the next level, and adds a layer of type safety on top of that.
There are a zillion approaches to this, way too many to list, I'm just trying to establish some common understanding of what I'm talking about.
Prolog approaches identified "in the wild"
In exploring Prolog code, I've identified two examples so far of these techniques.
The first is the A* implementation from Prolog Programming for Artificial Intelligence, and the other is from
library(atts)
.The more familiar one (to some) is
probably theloading files, where (credit @bakaq for showing this to me) users are able to definelibrary(atts)
versiongoal_expansion/2
andterm_expansion/2
in their modules and they will be invoked in some way (I don't fully understand the details)in conjunction with whenwhile for attributed variables,atts:term_attributed_variables/2
is invokedattribute_goals//1
and/orverify_attributes/3
are defined (see #2591 (comment)).Module loading
Module loading APIs defined for atts.pl and dgs.pl
And here's how it's used in
library(dcgs)
:A* approach
This A* code takes a different approach.
Client domains are only required to implement
s/3
andh/2
, which are successor functions and the A* heuristic function respectively. Implicit in these definitions is a model of the state, as the successor function relationship is ofs(State0, State, Cost)
, whereCost
is theg(n)
in the heuristic estimator function (f(n) = g(n) + h(n)
).Thus any client of the algorithm need only define those two predicates, then invoke
bestfirst/2
with a valid starting starting state (that is the same as the argument used bys/3
.You can see the details of the configuration technique in the following details sections.
A* code organization examples
A* important "APIs"
Task Scheduling Domain API "implementations"
Eight Puzzle Domain API "implementation"
Using DCGs for Domain Specific Languages(?)
My initial attraction to Prolog was actually from DCGs, because (assuming you are good at Prolog and DCGs, which is turning out to be much harder than I thought!), it should be very possible to quickly write up a domain specific language (provided you understand the domain well) to accomplish good abstractions via syntax directed translation while staying close to the core Prolog abstractions, but that's still pretty hypothetical :)
Wrap-up
Like any other code organization techniques, these have pros and cons. I have a feeling that Prolog suffers from some of the same issues that lisp and Forth/PostScript do -- meaning, there are many (wonderful) ways to write abstractions, but the more you stray from core abstractions and the more "magic" that gets introduced (e.g., lisp macros), there can be some long term consequences for that approach. Likewise, not using enough abstractions results in a lot of highly coupled, repetitive code, codesprawl, and disorganization.
I don't yet know what the trade-offs of using DCGs for DSLs are at scale.
Curious what everyone's thoughts are, here! What did I miss? What did I overlook or get wrong?
Beta Was this translation helpful? Give feedback.
All reactions