Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Preventing further Brainwash by Logtalk

360 views
Skip to first unread message

burs...@gmail.com

unread,
Sep 12, 2018, 3:28:29 PM9/12/18
to
Paulo Moura posted the following fairy tale
in connection with his take on my interpolate
solution for Samers problem, which in my
mixes static and dynamic methods.

His take on the problem is here:
https://gist.github.com/pmoura/c04dedc03ce4e0e820e82bd1afc56dc8

His additional response was here and is given below:
https://groups.google.com/d/msg/swi-prolog/cUDGgAju5dw/D18d2FMjCAAJ

> On 12 Sep 2018, at 11:54, Proof Easel <janb...@easel.ch> wrote:
>
> There are a lot of loose ends that need to be tied together.
> The problem is that the Prolog community is brain washed
> by Log-Nonsense-Talk, which can even not mix
>
> static and dynamic definitions in the same code.

You call Logtalk repeatedly (here and in other public
forums) nonsense, a fraud, useless, and now with brain
washing powers. You seem unable to write about your
alternative without trashing Logtalk. For anyone
wondering why so much hate for Logtalk, it seams to
have started after I informed Jan Burse back in 2016
that I was unable to support his Prolog system,
Jekejeke, until several standards compliance issues
were fixed. Or maybe something else triggered it. My
brain washing powers don't seem to extend to mind
reading. Thankfully.

Here's some facts:

1. The existence of Logtalk doesn't affect in any
way what your alternative solution can and
cannot do.

2. Any alternative should be able to stand
on its own.

3. Alternatives are a good thing. They embed
different design decisions. They give users choices.

4. Anyone serious about using the best tool for
a job does due diligence on alternatives.

5. Giving examples where your alternative doesn't
work, or doesn't appear to work, is valid criticism.
Nothing prevents you from showing a solution and
proving that it can be done in a sensible way.
Examples also help understand any limitations
of different alternatives.

6. Claiming that the community is brain washed is
seeing the people in the community in lesser terms.

7. Logtalk respect by the community results notably
from (1) people recognizing continuous hard work
freely shared for anyone to benefit; (2) people
recognizing the role Logtalk played in the
convergence of Prolog systems and on official
and de facto standardization. No brain washing
involved.

8. Repeatedly making strong but baseless claims
that Logtalk doesn't support basic functionality
found in most OO languages only backfires. There's
plenty of documentation and examples. Questions
can always be asked. But I confess that I have
long lost patience for your ramblings.

9. Repeatedly insulting people and their work only
results in a toxic environment and serves no
purpose other than killing any chance of
enlightening and fruitful discussions. Btw, I
didn't get you (temporarily) banned from this
mailing list. You did it to yourself. Apparently
you have learned nothing as you continue to
do it elsewhere.

As a last note, thanks for all your publicity
on Logtalk. There's true in the saying that
there isn't such thing as bad publicity!

burs...@gmail.com

unread,
Sep 12, 2018, 3:29:59 PM9/12/18
to
Here is my latest response, a plead for more
transparency of Logtalk:

In my opinion, one Brainwashi thing, is that one cannot
do listing of the code that Logtalk generates. At least the
last time I used the Logtalk pillow command line for

SWI-Prolog. If one checks the SWI-Prolog adapter
one sees that there some special $hide directive in the
code of this adapter.

So for a "community" it is really difficult to understand what
Logtalk does and to give feedback where Logtalk could
improve. For example this code from Paulo Moura (see
link below) here:

:- object(vector, imports(math)).
add(X, Y, Z) :- apply:maplist(plus, X, Y, Z).
plus(X, Y, Z) :- Z is X+Y.
mul(X, Y, Z) :- apply:maplist(times(X), Y, Z).
times(X, Y, Z) :- Z is X*Y.
:- end_object.

It would be very interesting to see what it EXACTLY
does. Does it have a "this" somewhere. Yes or no. If not,
its just a module no Logtalk needed, and its not the
same code as my first take on the Samer example.

If yes, can we do the following:
- mix static and non-static

If there is a "this" somewhere, how does the code
know that plus/3 and times/3 is static, and that add/[?3,4,5?]
and mul[?3,4,5?] are dynamic.

This is what I mean by brainwash. The brainwash is not that
some members of the community are lesser. The brainwash is
that Logtalk is not transparent,

makes it not easy for the end-user to see what is going
on. On the other hand SWI-Prolog 7 Prolog dicts, and
functions on Prolog dicts are fairly transparent,

listing works, and its much easer to deal with them. Even
Picat is better in this respect. I recently asked whether they
can show the B-Prolog compile. And the answer was

yes this and that command. How do I list the above example?
What is the resulting code? What are the Open Source measures,
against Brainwash here?

Am Mittwoch, 12. September 2018 15:48:31 UTC+2 schrieb Paulo Moura:
https://gist.github.com/pmoura/c04dedc03ce4e0e820e82bd1afc56dc8

burs...@gmail.com

unread,
Sep 12, 2018, 3:30:38 PM9/12/18
to
Hi,

If Logtalk were more transparent, it would more count as
a honorable contribution to the community, by the efforts
of one person. At the moment its not clear what your code

does, and whether it has anything to do with my example.
For example if the code had really a "this", they the
call from dynamic to stattic would be, thats how you call

so called plain code:

{maplist(plus, X, Y, Z)}

but instead I see something like:

apply:maplist(times(X), Y, Z).

So I guess its either plain-plain, or the non-plain-non-plain.
Neither is what my example did. non-plain-non-plain could
give a an unwanted performance penalty.

Currently I see 10-20 downloads of your Logtalk pack,
and its a one man show. If it would be more transparent,
with a listing/[0,1] that works, and is also recommended

and explained, then there would be maybe more downloads,
and maybe more contributions. A system doesn't get
more transparent and more collaborators by providing

more examples. In the age of open source, a system gets
more transparent and more collaborators by showing
each and every artefact that is consumed or generated.

Hope this helps...

burs...@gmail.com

unread,
Sep 13, 2018, 6:21:12 PM9/13/18
to
No reply, still?

I guess Logtalk is still mulling over how to do
the polymoprhic datatypes example, so that function
cohesion is shown.

Here is a suggestion: Why use {}/1 only for plain
body goals, why not use {}/1 also for plain clause
terms inside a Logtalk text?

With this extension we could finally do in Logtalk:

:- object(vector(X)).

add(Y, Z) :- {maplist(plus, X, Y, Z)}.

{plus(X, Y, Z) :- Z is X+Y}.

mul(Y, Z) :- {maplist(times(Y), X, Z)}.

{times(X, Y, Z) :- Z is X*Y}.

:- end_object.

Copyright J.Burse, 2018

burs...@gmail.com

unread,
Sep 13, 2018, 6:34:05 PM9/13/18
to
Adding an idea from Picat, the (@)/2 operator
in head unification, we could maybe do the following:

:- object(X@[H|T]).

Basically we want a term object with functor
'.' and parameters H and T, but nevertheless

we want to refer to it by one variable. This would
already give the desired result I guess for

this small example and the vector datatype.

Copyright J.Burse, 2018

burs...@gmail.com

unread,
Sep 14, 2018, 9:52:48 PM9/14/18
to
Ok, I have clarified the public license terms, and
added a paragraph, so that it is 100% clear, that
Logtalk is not a permitted usage of Jekejeke Prolog:

* Restrictions
* Only to be distributed with programs that add
* significant and primary functionality to the library.
* Not to be distributed with additional software intended
* to replace any components of the library.

https://github.com/LogtalkDotOrg/logtalk3/issues/67

burs...@gmail.com

unread,
Sep 14, 2018, 10:45:32 PM9/14/18
to
The easiest would be probably to provide a module
"param", that allows to make some parameterized modules
inside the ISO core standard and the ISO module standard.

Shouldn't be that difficult. Either it gets that
simple as the module "func" now, which has only a
(:=)/2 to define methods, or it needs a little bit

more syntactic machinery. Either way similar like the
module "func" it would not try to build a pillow and
replace everything on the top-level, in that it would

not try to provide its own load and make commands, and
go for a new language with a zoo of new nonsense terminology
for the existng ISO modules and their reexport/1. The

module "param" would be rather small add-on that is
subjungated to the rest of the system, but nevertheless
adds an aspect to a module, namely these parameters.

Tabling, co-induction, DCG, whaever can co-exist, no
need for some Log-Nonsense-Talk. And all these things
can come from different authors. There would be only one

visible marker that we have a parameterized module at
hand, in that we import the module "param" in the present
location, and that we use the predicates and operators

provided by this new module "param". So no more brainwash
and nonsense that listing/[1,2] is a convenience that we
can dispise with. Since the module "param" is now just a

subjungate feature that can be used or not used, there is
not need to buy into some new nonsense environment. So
far in the past Prolog has championed this approach in

many domains. DCG is a typical example, where a simple
new operator like (-->)/2 and some on the fly transformation
does the magic. No need for a transpiler that ask for

nonsense such as change directory command whatever...

burs...@gmail.com

unread,
Sep 14, 2018, 11:00:54 PM9/14/18
to
A new module "param" would also run under the
category cleaning past sins. This time not some
minor sins of SWI-Prolog 7, but rather the bigger

blunder of Log-Nonsense-Talk. Its relatively easy
to sketch the idea of a new module "param" what it
would need to do. There are two approaches for

parameterized modules I guess:

a) First Approach: Double delegate. I guess what
is already seen in Logtalk as this/1 and self/1
could be simply modelled as a double delegate,
and some chaining, thats what one might be
first thinking of.

b) Second Approach: Some lazy computation of the
projection. So there would be a single delegate,
and by special method names and a self message could
figure out the projection. The module "param" would
do a rewriting for these extra method names.

Ha Ha

Works probably easiest with robost Prologs such as
SWI-Prolog 7 and Jekejeke Prolog, that don't go bonkers
if a meta_predicate declaration is missing, and that
have some truth maintenance, so that the module "param"

can create its code, even if it has forward references,
like it is the case for the module "func". Just enjoy
the funky capabilities of your module system. How about
some recursive parametric modules, would be the result?

Ha Ha

burs...@gmail.com

unread,
Sep 14, 2018, 11:06:21 PM9/14/18
to
Lets not forget that we have also variable_names/1
available during consult. Through some prolog
context access, so its not extremly difficult to

give extra interpretation of variables in a clause.
For example we could interpret SELF in a clause.
Just lookup whether SELF is in variable_names/1

and then do something with it. I don't think Logtalk
has the SELF. SmallTalk had it, there was alwas a
variable self. So maybe the module "param" would be

even more funky than Logtalk itself. The
variable_names/1 lookup trick works also for
parameter names. You can lookup variables, and then

redirect them to something else, by simply
instantiating them, before asserting the rewritten
clause. Works splendidly....

burs...@gmail.com

unread,
Sep 16, 2018, 9:23:44 AM9/16/18
to
Ok, I made an experiment with a user module "param",
that provides some new directives, and does everything
on the fly, based on the ISO module standard.

In my language, lets call this language Log-Not-Some-
Nonsense-Talk, I defined point and colorpoint as follows.
The module "param" provides all the necessary rewriting,
so that the below text is accepted.

File point.p:

:- object(point(X,Y)).

:- public get_x/2.
get_x(_,X).

:- public get_y/2.
get_y(_,Y).

:- end_object.

Everything is rewritten to the ISO module standard, and
the usual module/2 and reexport/1 directives are used.
The usual colorpoint/point already works:

?- colorpoint(1,2,red)::get_x(X).
X = 1
?- colorpoint(1,2,red)::get_y(Y).
Y = 2

Provided and missing features so far:

- I do not yet have some way to distinguish static and
dynamic, so inside the object/1 and end_object/0 parenthesis
everything is viewed as dynamic. Not yet sure what
the marker could be, really {}/1 around a clause?

- I do not touch the body or head of a clause. The head
needs to use Pythonesk call convention extra parameter,
and the body, in case it would call itself or another module
would need to use (::)/2.

For more information see:

Preview: Parametric modules via ISO Prolog modules. (Jekejeke)
https://plus.google.com/+JekejekeCh/posts/EK9JGPvivpm

Have Fun!

Am Samstag, 15. September 2018 05:00:54 UTC+2 schrieb burs...@gmail.com:

burs...@gmail.com

unread,
Sep 16, 2018, 9:26:55 AM9/16/18
to
Oops, I forgot one file. Somthing thats more simpler
and versatile in Log-Not-Some-Nonsense-Talk, compared
to Log-Nonsense-Talk:

File colorpoint:

:- object(colorpoint(X,Y,_)).

:- extends(point(X,Y)).

:- end_object.

As can be seen, I splitte object/2 into object/1
and extends/1. So multiple inheritance will just have
multiple extends/1 directives.

The extends/1 directive will know about the variable
names of the object/1 directive. So X and Y are in
correspondence. Its all open source:

Open Source: Parametric Modules
https://gist.github.com/jburse/1969445303128fb77ea91090138f64d2#file-param-p

burs...@gmail.com

unread,
Sep 16, 2018, 9:38:41 AM9/16/18
to
The listing/[0,1] predicate is not blocked. Its very
easy to understand what the rewriting does. If one
understands Pythoneks OO and its Prolog variant (::)/2
as provided by Jekejeke Prolog:

The (::)/2 operator is based on the ISO module standard
(:)/2. See also my other posts "Best Kept Secret". As
can be seen the rewriting uses module/2 and reexport/1
directive, the later from the ISO module standard.

Rewritten File point:
==============================================
:- module(point, []).

:- public as/3.
as(point(X,Y), point, A) :- !,
A = point(X,Y).

:- public get_x/2.
get_x(A, X) :-
A::as(point, point(X,_)).

:- public get_y/2.
get_y(A, Y) :-
A::as(point, point(_,Y)).

Rewritten File colorpoint:
==============================================
:- module(colorpoint, []).
:- reexport(library(point)).

:- public as/3.
as(colorpoint(X,Y,A), colorpoint, B) :- !,
B = colorpoint(X,Y,A).
as(colorpoint(X,Y,_), A, B) :-
point(X,Y)::as(A, B).

In this approach no rewritten files are written on
some medium. The rewriting is all done on the fly
through term expansion and the simplification pipeline.
No transpiler needed, that would be based on files,

only the interleaved combination of a end-user
extensible expansion pipeline and an also end-user
extensible simplification pipeline, as featured
by Jekejeke Prolog by the experimental module "simp".

Am Sonntag, 16. September 2018 15:26:55 UTC+2 schrieb burs...@gmail.com:
> The extends/1 directive will know about the variable
> names of the object/1 directive. So X and Y are in
> correspondence. Its all open source:
>
> Open Source: Parametric Modules
> https://gist.github.com/jburse/1969445303128fb77ea91090138f64d2#file-param-p

burs...@gmail.com

unread,
Sep 16, 2018, 9:46:36 AM9/16/18
to
Disclaimer: I don't say this is an optimal
rewriting. It serves only some conceptual considerations,
the second approach, to dig deeper into the

functional requirements. Non-function requirements,
concerning performance etc.. need possibly a different
rewriting. In this rewriting we have also "O(1)"

access to parameters, if we allow the vague classification
from Log-Nonsense-Talk as O(1) for accessing logical
variable inside a Prolog clause.

But as can be seen, there is some projection overhead
to get into the Prolog clause of a dynamic object
method. The ISO module standard, through reexport/1

will help in finding the predicate, and thus the
Prolog clause of dynamic object methods, but we might
want to compute the projection only once for multiple

Prolog clauses, so there is room for all kinds of
optimizations. Possibly Log-Nonsense-Talk has also found
some ways to do the rewriting better, but still

it might be the case that Log-Nonsense-Talk does not
take advantage of ISO module system, since it targets
all kind of "back-end" Prolog systems. The test here

concerns the question what can we get out of the
ISO Prolog module standard for parametric modules.
Is/was there something in it for parametric modules?

burs...@gmail.com

unread,
Sep 16, 2018, 11:30:40 AM9/16/18
to
Interestingly the auto loader also works for parameterized
modules. Since the used Prolog system had an auto loader,
we even didn't have to do much of Prolog text loading.

All that was needed was a path to the sources. A porting to
SWI-Prolog is pending, need to figure out variable name access
and the blocking implication rewriting trick.

Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland

?- ensure_loaded('<location1>/param.p').
% 1 consults and 0 unloads in 16 ms.
Yes
?- sys_add_path('<location2>/animals/').
Yes

?- bloodhound::bark.
ruff
Yes
?- bassethound::bark.
woof
Yes

See also: Objected Oriented Programming in SWI-Prolog
https://stackoverflow.com/a/52355552/502187

j4n bur53

unread,
Jan 7, 2019, 10:26:13 AM1/7/19
to
Ha Ha,

Logtalk now selling Logtalk via abolish_object/1.
But abolish_object/1 is very weak. Its a forced
removal. What if other objects still depend on it?

Here is a better more clean solution:

Jekejeke Prolog 3, Development Environment 1.3.4
(c) 1985-2019, XLOG Technologies GmbH, Switzerland

?- use_module(library(automata/binlog)).
% 2 consults and 0 unloads in 19 ms.
Yes

?- current_module(X), write(X), nl, fail; true.
...
standard/dcg
automata/binlog

So a module binlog was loaded, which was dependent
on a module dcg. Now watch out:

?- unload_file(library(automata/binlog)).
% 0 consults and 2 unloads in 0 ms.
Yes

?- current_module(X), write(X), nl, fail; true.
...

binlog is gone, and dcg is also gone, since it
is not anymore used.

To be continued ...

j4n bur53

unread,
Jan 7, 2019, 10:31:59 AM1/7/19
to
Whats the algorithm behind? Well very simple,
the modules form a graph, by their dependency.
The usual ISO core standard dependencies,

import and reexport. Now use_module/1 and
unload_file/1 are primarily graph manipulation
operations. use_module/1 adds a new link from

its current call-site to the module argument.
And unload_file/1 removes a module link. Both
predicates then preform a graph garbage

collection, removing unused modules. So the
implementation of the two predicates is roughly:

use_module(M) :-
create new M if necessary
establish link from current call-site to M
load M if necessary
perform graph garbage collection

unlink_file(M) :-
remove link from current call-site to M
perform graph garbage collection

Now where does abolisth_object/1 happen. Well only
inside the graph garbage collection. The graph
garbage collection is primitively implemented as follows:

graph garbage collection :-
mark all reachable modules, reachable from user
then scan all modules and remove the modules that
were not reachable via abolish_object/1.

Pros and cons. Actually I have a multi thread solution
which should more or less work for concurrent use_module/1
and unload_file/1. But this is not yet extensively

tested and should be further scrutinized.

j4n bur53

unread,
Jan 7, 2019, 10:34:37 AM1/7/19
to
Why should a Log-Nonsense-Talk glee deliver such
a functionality, when it is also useful for ordinary
modules? And when we can anyway bootstrap object

orientation from ISO modules? Why have an abolish_object/1,
when every module system has somewhere such a function
most likely? Because of the joy of duplicate work?

Welcome to the brainwash of reinventing the wheel.

j4n bur53

unread,
Jan 7, 2019, 10:39:20 AM1/7/19
to
P.S.: Whats the idea behind this module garbage
collection. Well the idea is a little bit that the
Prolog system can work like a perpetual Smalltalk

image. We do not load and store an image like in
Smalltalk, we only load files. Maybe we write also
some. But these files and their dependency can

change, and the Prolog system should keep up with
such changes. Such changes can be quite complex,
like during development a developer might decide

to add a few files AND remove a few files. The idea
is that the make utility can also keep up with such
removals, and replay the removal as well.

The unload_file/1 predicate is to notify the system,
that the end-user is not anymore interested in a
module, but if the end-user is not interested in a

module, also not indirectly, the module becomes
unreachable and will be removed.

j4n bur53

unread,
Jan 7, 2019, 11:25:45 AM1/7/19
to
What I didn't manage is to leave the module
GC to the Java GC. So there is some duplicate
work here. I think there are possibly some

means to do it, like weak pointers etc.. Also
some Java virtual machines have class garbage
collection, this would be a further possibility

to hook into such a mechanism.

Mostowski Collapse

unread,
May 6, 2020, 8:28:47 AM5/6/20
to
Amazingly slow SWI-Prolog community. LoL
By Jan W., some experimental (::)/2:

> Here is a demo of the idea to manage self on the stack. Start as
>
> swipl oo.pl facts.pl
> ?- facts::rule(X).
> X = yip.

For the file oo.pl see SWI Prolog discourse
thread, Threaded queries? Rulebase independence?

Mostowski Collapse

unread,
May 6, 2020, 8:30:49 AM5/6/20
to
In last call optimization exactly the
right frame is missing. Therefor might
prevent last call optimization. Thats
why you need to do it this way, from
your file oo.pl:

M::G :-
call(M:G),
no_lco(M).

no_lco(_).

no_lco means no last call optimization.
If you want (::)/2 that can also have
last call optimization, you could try
passing the receiver object in the
first argument, like Python programming
language does it:

O::G :-
G =.. [F|L],
H =.. [F,O|L],
functor(O,M,_),
M:H.

There are not much problems with last
call optimization, since M:H is a last
call again. This way you can even do term
objects like in Logtalk, without the parameter
variables. You only need the ISO module standard
and would instead use accessors.

:- module(point, [x/2]).
x(point(X,_), X).

Example run:

?- point(3,1)::x(X).
X = 3.

I posted on comp.lang.prolog about that, and
suggested on pushing the ISO module standard
back into the focus of Prolog system development.
But other solutions with more system support
like prolog_current_frame/1, etc… could of
course also provide valuable insight.

About Python:

Class methods have only one specific difference from ordinary
functions - they must have an extra first name that has to be
added to the beginning of the parameter list
https://python.swaroopch.com/oop.html

Mostowski Collapse

unread,
May 6, 2020, 1:59:49 PM5/6/20
to
It should be noted, that in this oop.pl one doesn't
loose LCO completely. It still happens when call(M:G)
exists and when you enter no_lco(M) I guess. But it
blocks garbage collection of the parent frame.

So for example:

p(Y) :- s(X), Y::t(X).

So if s(X) produces a very large term, this term stays
until Y::t(X) has completed. With (::)/2 capable LCO
the large term can go away while processing Y::t(X).
LCO does drop frames not only to allow deep recursion.
LCO also enables enviroment trimming.

But situation might be different from Prolog system
to Prolog system. But generally the more LCO the less
transient garbage. Also since you are most often only
interested in self, the first argunent of (::)/2,
using a frame which stores the full (::)/2
goal is overkill.

A parameter seems to be more economic. You see that
you have too much information on the stack, since oop.pl
does the unpacking here:

::Goal :-
prolog_current_frame(Fr),
prolog_frame_attribute(Fr, parent_goal, ::(Self,_)),
call(Self:Goal).

Python probably delegates optimization of this parameter
to the backend compiler. Backend compilers might
designated a special register to hold self, and this
register then doesn’t need to be pushed/poped in the
event of self calls.

Your self call doesn’t work, if it does a self call
again. Because I don’t see how you deal with the
additional frame that arises from previous self call.
So its not that powerful as Logtalk currently. Maybe
you would need to do Self::Goal instead
of call(Self:Goal).

Logtalk has some interesting optimization for self
calls. Which you can also do with the Python convention
of first argument. If you don’t need late binding,
like for a private predicate, you can of course call
it directly with the extra argument.

So in Python convention you can replace this:

rule(X) :-
::fact(X).

By this here, if you dont need late binding,
making it a direct call:

rule(Self, X) :-
fact(Self, X).

This is useful when fact is a private helper
that is not overridden.

Mostowski Collapse

unread,
May 7, 2020, 6:01:23 AM5/7/20
to
No, no, although amusing, but not very
helpful. Somebody suggested this on SWI
discourse for inheritance.

:- module(facts, []).
:- use_module(rules).

You cannot emulate inheritance by use_module/1.
Just indicate inheritance by the ISO module
reexport/1 directive, and not by the use_module/1
directive. And you need of course also declare
the overridden predicate fact1/1:

:- module(facts, [fact1/1]).
:- reexport(rules).

If you only use use_module/1, then the
module facts will not export what is inside
the module rules. You need to use reexport/1,
and then you shouldn’t get the error Unknown
procedure: facts:fact2/1 anymore. At least

this works like a charm with my (::)/2:

?- facts::rule(X, Y).
X = 3,
Y = 2

For screenshot and code of oo.pl, facts.pl
and rules.pl see here:

https://gist.github.com/jburse/e1a79d40a1ec45f1d96074623beb6a02

Mostowski Collapse

unread,
May 7, 2020, 7:00:14 AM5/7/20
to
You can also use reexport/1 for multiple inheritance:

:- module(child, []).
:- reexport(parent1).
:- reexport(parent2).
..
:- reexport(parentn).

Pitty Logtalk is offended by reexport/1. It could
also see it as an opportunity. Like trying to write
a version of Logtalk that uses reexport/1 in its
backend. reexport/1 together with the Python approach:

Class methods have only one specific difference
from ordinary functions - they must have an extra
first name that has to be added to the beginning
of the parameter list
https://python.swaroopch.com/oop.html

Will simply equate modules and classes. What reexport/1
does, it builds the virtual function table of the class.
Whereby from Prolog system to Prolog system it might be
different how the virtual function table is built, or
whether its even materialized.

For example SWI-Prolog shows a warning (Warning: Local
definition … overrides) when an entry in the virtual
function table is changed through overriding. Maybe a
closer cooperation with Prolog vendors would make such
a Logtalk backend take off the ground.

The possible benefits:

- Maybe faster execution?
- Maybe faster debugging execution?
- What else?

Mostowski Collapse

unread,
May 7, 2020, 8:52:18 AM5/7/20
to
I made a test, how Java checks the override,
i.e. whether it also shows a warning like SWI-Prolog.
Java shows only an error when the visibility
is down graded, like for example:

Parent Child
public public No error
public package Error
public private Error

If the child is in the same package as parent it
also shows this error:

Parent Child
package public No error
package package No error
package private Error

For a private parent there is no such check. In
the fact1 example fact1 is both public aka exported
in rules and facts, so in Java it would not show a
warning or an error.

Currenly in my system similar like in SWI-Prolog,
I show as well a warning. And I have a directive
override/1 to disable the warning. If I would
implement the Java error I would less often show a
warning and

not anymore need the directive override/1. The Java
error indicates that a virtual function table entry
will not be executable, since the overriden
table entry has less visibility. So could even turn
it from warning into error.

Its strange that pmoura has found so many problems
in half-broken hacks https://logtalk.org/blog.html?tag=half+broken+hacks
It could also be that case that a) not properly tested
or b) that the systems have indeed kind of bugs,

unlogical warnings or too strict warnings.

Mostowski Collapse

unread,
May 7, 2020, 8:56:20 AM5/7/20
to
Not sure whether I can already implement the
more elaborate override check as found in Java
already for the upcoming release.

It is basically the same check I already have,
with some extra. Also checking for downgrade,
in the two scenarios same package or not.

And then could drop the override directive, make
it useless, dispose of it. Which will make a few
old examples throw directive errors.

Wao!

But getting rid of the directive override/1 is
also due, since the end user can now use the directive
wrongly on situations that Java completely

forbids. So the directive override/1 was inherently
unsafe, since it also allowed to suppress the warning
where there must be an error.

Mostowski Collapse

unread,
May 7, 2020, 9:26:28 AM5/7/20
to
Also not yet sure whether the new check should only
be applied to reexported stuff. Currently
my override check also barks on use module stuff.

Would need to make a Java test about some
import static examples. Well this Java test
was quickly made, I find:

Java doesn't bark at all on overridden
static imports. All combinations allowed.

Oki Doki. So the new business rule must be also
discriminative about reexported versus use module,
and in the case of use module we would

simply tollerate everything?!

Mostowski Collapse

unread,
May 21, 2020, 5:58:39 AM5/21/20
to
We see a first chasm between Logtalk and
SWI-Prolog. Maybe you have noticed that Logtalk
has quit SWI-Prolog discourse.

And from twitter we can learn that Logtalk
has been hired by a new start-up, http://graphstax.ai/
https://twitter.com/LogtalkDotOrg/status/1260956171999105025

Whats behind graphstax.ai. Arun Majumdar is founder
of new stealth AI startup, GraphStax, according to
his LinkedIn profile. Making it not so stealth. LoL

Arun Majumdar is also co-founder and fellow of
Kindy. I guess the chasm will persist somehow,
in case graphstax goes into competition with

ClioPatria: the SWI-Prolog RDF toolkit. Why Prolog
Hub is gone I don't know. It had a lot of LogTalk
content. Even its twitter account is gone.

Mostowski Collapse

unread,
May 21, 2020, 6:04:06 AM5/21/20
to
Maybe Prolog Hub was hired by graphstax.ai
as well? Anyway, if Logtalk wastes another
20 years, maybe we see OWLTalk? LoL

Mostowski Collapse

unread,
Jul 17, 2020, 8:25:34 AM7/17/20
to
Maybe Logtalks complaining is unfounded.
Paulo Moura wrote on SWI-Prolog discourse:

> Meanwhile, every single time I provide a simple,
> elegant, and working solution to a user in
> trouble trying to twist modules into something
> that they are not designed for, we get this
> barrage of half-broken hacks . How is that
> helpful? How is keeping users writing non-trivial
> applications frustrated with the module system and
> writing more and more convoluted code the way forward?

I am currently reviewing OO and Prolog. One thing that the
half+broken+hacks complains about, is the “overrides weak import”
warning of SWI-Prolog. Apparently there is no way to switch off

this warning. But this isn’t true. Meanwhile I found a way
to switch it off:

Mostowski Collapse

unread,
Jul 17, 2020, 8:27:37 AM7/17/20
to
I get a warning when using:

:- module(rottweilerswi, [barking/2]).
:- reexport(dogswi).
barking(_, ruff).

I don’t get a warning when using:

:- module(rottweilerswi, [barking/2]).
:- reexport(dogswi, except([barking/2])).
barking(_, ruff).

What is overridden is barking/2 from dogswi (not shown)
where it is woof. But in both cases overriding works
correctly, namely I get:

/* works for both */
?- rottweilerswi:barking(_,X).
X = ruff.

The difference is only that I am now able to switch
off the warning by using reexport/2 in the
second variant.

Mostowski Collapse schrieb:

Mostowski Collapse

unread,
Jul 17, 2020, 8:39:13 AM7/17/20
to
Now I am wondering how my override/1 relates
to the except/1 option. What I see directly from
the way the option is available:

- except/1 orients along the corresponding module that
is subject of the use_module/2 or reexport/2. Whereas
my override/1 orients along the current module.

- my override/1 implicitly creates a predicate, whereas
I guess except/1 can be also used without creating
a predicate inside the current module.

- my override/1 is rather agnostic from where something
is overridden, where except/1 could have further uses
cases like resolving import ordering issues.

Oki Doki. Interesting.

Mostowski Collapse

unread,
Jul 17, 2020, 8:48:20 AM7/17/20
to
Addendum PMs complains are here:

Half-broken hacks: reexport/1 as inheritance
https://logtalk.org/blog.html?tag=half+broken+hacks

I really don't know where there is "hack" or
where there should be "half-broken".
Seems to be more a RTFM problem. But strangely

I even don't remember Jan W. mentioning
the except/1 option as a solution to the probem.
Thats like the russians spying on a vaccine,

and then manifactoring and using the vaccine,
and not knowing that it has a side effect, like
green toe nails.

LoL

Mostowski Collapse

unread,
Jul 17, 2020, 8:56:33 AM7/17/20
to
Unfortunately not all Prolog systems seem to provide
the except/1 option. I don't find one in SICStus Prolog:

https://sicstus.sics.se/sicstus/docs/latest4/html/sicstus.html/mpg_002dref_002duse_005fmodule.html

The solution there would be maybe to compute the set
R = [all] \ [except(L)], and then use R. But this
could be a little annoying. Also unfriendly to separate

compilation, would need to recompute R and update the
code, if a base module introduces something new.

Mostowski Collapse

unread,
Jul 18, 2020, 4:09:51 AM7/18/20
to
The SWI-Prolog except/1 could have something in
common with Eiffel undefine. I did a quick survey
which programming language has something

like an override/1 directive. Basically I was
looking at data whether a programming language has
a silent or non-slient override. A non-silent override

can mean a lot, like my override/1 directive semantics
or more stronger or more weaker semantics. Here
are my findings, non-silent override seems to

be more common than I think, but also often optional:

Language Slient Non-Silent
ADA Yes Yes
C# No Yes
C++ Yes Yes
Delpi No Yes
Eiffel No Yes
Java Yes No*
Kotlin No Yes
Python Yes No*
Ruby Yes No

The asterix indicates programming languages where a
non-silent overriding is provided through other means
than the language itself, like annotations or pragmas.

See also:
https://en.wikipedia.org/wiki/Method_overriding

Mostowski Collapse

unread,
Jul 19, 2020, 9:45:15 AM7/19/20
to
I recently got facinated by the new Python
__slots__ . They can replace the __dict__
object state, or a Python object can even

have bot __slots__ and __dict__ . I am not
working very intensly on bringing Python state
to Prolog. Its rather that I have recently

discontinued the SWI-Prolog dicts. But then
I did something new recently. I had already
these two predicates:

arg/3: ISO core standard
set_arg/4: Not ISO core standard, could
be bootstrapped from (=..)/2, but natively
in Jekejeke Prolog for more speed.

There was one big obstacle. My Prolog term
objects could have a package prefix. So an
object could be example02/dog(coco), and

not only example02/dog(coco). And things
don't work as expected for arg/3 and set_arg/4
then. I get these undesired results:

?- arg(1, example02/dog(coco), X).
X = example02

?- set_arg(1, example02/dog(coco), sally, X).
X = sally/dog(coco)

Mostowski Collapse

unread,
Jul 19, 2020, 9:52:52 AM7/19/20
to
So what was the work around? Well there
is a rather straight forward work around, enlarging
the functionality of arg/3 and set_arg/4.

I did this with a little twist. Namely
the new predicates do not have a new names,
I used overriding the standard predicates.

The same overriding techique was already
used while providing rational numbers. I
forget about this overriding technique,

not an object oriented overriding technqique
really, but rather a way to replaced a
user: predicate by some module: predicate,

and make the module: predicate visible
through import. But I recalled the technique
from my recent rational number implementation,

So all you have to do now is
import library(basic/proxy):

Jekejeke Prolog 4, Runtime Library 1.4.5

?- use_module(library(basic/proxy)).
% 0 consults and 0 unloads in 0 ms.
Yes

?- arg(1, example02/dog(coco), X).
X = coco

?- set_arg(1, example02/dog(coco), sally, X).
X = example02/dog(sally)

I made a blog post about it:

Preview: arg/3 and set_arg/4 convenience for
object oriented Prolog. (Jekejeke)
https://gist.github.com/jburse/d10fe7ad2988892c70b9f57638fe0521#gistcomment-3381934

Mostowski Collapse schrieb:

Mostowski Collapse

unread,
Jul 19, 2020, 10:07:20 AM7/19/20
to
Overall I dunno yet whether there is some feasible
way to bring __slots__ to Prolog. I had an old idea to
compress dicts as follows. Currently SWI-Prolog uses

this representation for dicts:

?- X = foo{bar:1,baz:2}, X =.. L.
X = foo{bar:1, baz:2},
L = [C'dict', foo, 1, bar, 2, baz].

But you could also use this representation:

?- X = foo{bar:1,baz:2}, X =.. L.
X = foo{bar:1, baz:2},
L = [C'dict', [foo, bar], 1, 2].

Putting the list of slots into the first argument.
This would open up that different dicts could
share the same slot list, making the representation

more memory savy like in Python. But I guess
it doesn’t give necessarely some speed advantage.
Unless you can compile something like:

Y = X.bar

Into this here:

arg(3, X, Y)

But the compilation problem into arg/3 for example
would be more or less the same for compressed and
none compressed dicts. You would need some reliable

inference of the class of X and you need single
inheritance, wouldn’t work anymore for multiple
inheritance. Here is a SO post detailing the

new Python __slots__ .

Usage of __slots__?
https://stackoverflow.com/a/28059785

Mostowski Collapse

unread,
Jul 19, 2020, 10:24:11 AM7/19/20
to
Corr.:

?- X=foo{bar:1,baz:2}, X=..L.
X = foo{bar:1, baz:2},
L = [C'dict', [foo, bar, baz], 1, 2].

Mostowski Collapse

unread,
Jul 20, 2020, 10:29:21 AM7/20/20
to
I made a little test, using the new
except/1 discovery, a SWI-Prolog
feature I have overlooked so far. And

I could let dicts do method dispatch and
inheritance/overriding without warnings:

File “dog”:

:- module(dog, [barking/2]).
_.barking() := woof.

File "beagle"

:- module(beagle, []).
:- reexport(dog).

File “rottweiler”:

:- module(rottweiler, [barking/2]).
:- reexport(dog, except([barking/2])).
_.barking() := ruff.

Mostowski Collapse

unread,
Jul 20, 2020, 10:33:08 AM7/20/20
to
The trick was loading all Prolog modules and
bypassing the trouble maker pseudo Prolog module
“user”. So I wrote a Prolog text “main” and

used except/1 again:

File “main”:

:- module(main, []).
:- use_module(beagle).
:- use_module(rottweiler, except([barking/2])).

You only need to consult “main”. It wont show any warnings.
Then a query works like a charm:

?- X = beagle{}.barking().
X = woof.

?- X = rottweiler{}.barking().
X = ruff.

It has to do with that fact that a qualified
call M:G has some special rights, that bypass all
import tightenings. So although main wants barking/2

uniquely and forces me once again to use except/1.
This is irrelevant when qualified calls M:G
are used, which are used under the hood in the

implementation of functions on dict. In SWI-Prolog,
as soon as a module M is loaded, it is globally visible
for all qualified calls M:G.

Mostowski Collapse

unread,
Jul 20, 2020, 10:42:00 AM7/20/20
to
I don’t know whether modules are also visible
across pengines? Or what SWISH would do with it.
Didn’t test yet. In Java this can be solved via

class loaders. The example I was using was:
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/10_docu/06_advanced/04_examples/03_default.html

But I adapted it so that insted a binary barking
predicate is defined, I used function on dicts
notation via (:=)/2 to define something, also

instead of message sending, I used the dict dot
operator to call something.

Mostowski Collapse

unread,
Jul 20, 2020, 10:50:23 AM7/20/20
to
Anybody who wants to see how brainwash works,
like Logtalk brainwash, I recommend this film:

A Cure for Wellness (2016)
Reg.: Gore Verbinski

Enjoy

Mostowski Collapse

unread,
Sep 9, 2021, 8:48:08 AM9/9/21
to
It becomes more and more evident that the Logtalk transpiler
is utter nonsense. Because it doesn't solve the dynamic meta
space problem so well. In Dogelog runtime I have now proof

that it is possible to have a dynamic meta space mostly
written in Prolog itself dealing with both static predicates and
dynamic predicates access and modification. I also use transpiler

technology, bot only for bootstrapping a small part of the
Prolog systems. Unfortunately Dogelog runtime is not yet
object oriented. So there is no proof of concept yet, that

we can do a dynamic meta space for an object oriented
Prolog system as well. But I am working on it. So big question
is, am I yet allowed to call Logtalk nonsense?

Mostowski Collapse

unread,
Sep 9, 2021, 8:53:38 AM9/9/21
to
As usual SWI-Prolog discourse does censor my "nonsense".
So they have not yet grown up? Well there are also only
like 3 participants now on SWI-Prolog discourse. LoL

Maybe if they would allow the word "nonsense" they would
have a larger crowd? One discourse that is quite active, is
users.rust-lang.org, they have so many posts each day, I

cannot keep up in any way. Thats nearly impossible, so if I
am lucky I randomly pick up something interesting. And it
seems they don't censor "nonsense", there are currently:

50+ results for nonsense
https://users.rust-lang.org/search?q=nonsense

LAMO!

Mostowski Collapse

unread,
Sep 9, 2021, 10:49:15 AM9/9/21
to
I feel insulted that people think I insulted Logtalk. Whereby they
simple dont understand my argument. But I can easily explain it,
its the same like 10 years ago. In my opinion, Paulo Moura made

a scene back then, to discredit my opinion. Thats maybe his only
negative personal trait. But the according discussion should be
simpler now than 10 years ago, since there are many dynamic

OO (sic!) languages around, like Python, JavaScript etc…

Dislcaimer I am not advocating to use always dynamic languages.
Don’t take me wrong, my interest in dynamic languages is not tied
to a dictum to always use dynamic languages.

Mostowski Collapse

unread,
Sep 9, 2021, 10:52:00 AM9/9/21
to
Take instead the word unreasonable.
Now what I wanted to express was:

- It is unreasonable to have a source to source transpiler
for a dynamic language. I have posted about dynamic
languages already elsewhere. Prolog can or cannot be
a dynamic language. SWI-Prolog has more traits
of being dynamic.

https://de.wikipedia.org/wiki/Dynamische_Programmiersprache

- It is reasonable to have a source to source transpiler for
a static language. Thats what Logtalk does. But do we
want to have a OO-Prolog system that works that way?
It doesn’t make any sense, so its “nonsense”.
You could directly use C++?

You are only believe I insult the creator because in the past
the creator told you so. But my intention in critizising Logtalk
is never to insult Paulo Moura, although he insulted me
many times.

Its about a technical matter. Dang! If I had an opinion
about Paulo Moura I would call him directly idiotic.
But he surely is not an idiot.

Mostowski Collapse

unread,
Sep 10, 2021, 5:24:40 AM9/10/21
to
I wonder how Logtalk runs test cases towards it back-ends. For
example the Trealla back-end. Please Logtalk nonsense try this:

% echo $LANG
de_CH.UTF-8

% trealla/tpl

Trealla Prolog (c) Infradig 2020-2021, v1.13.4-2-g266e8
?- X is float(30000000000000)-30000000000000000.
X = -2.0,997e+16.

?- X = -2.0,997e+16.
Error: syntax error parsing number, line 0, ''

LoL

Mostowski Collapse

unread,
Sep 10, 2021, 8:53:31 PM9/10/21
to
Logtalk nonsense can always be topped by other Logtalk
nonsense. Interesting test case:

test(lgt_unbounded_sqrt_01, error(evaluation_error(float_overflow))) :-
_ is sqrt(7^7^7).

How long does it take to compute 7^7^7 in Trealla?

?- time(_ is 7^7^7).
Time elapsed 0,325 secs
true.

How long does it take in SWI-Prolog:

?- time(_ is 7^7^7).
% 1 inferences, 0.013 CPU in 0.014 seconds (87% CPU, 79 Lips)
true.

LoL

Mostowski Collapse

unread,
Sep 10, 2021, 9:02:35 PM9/10/21
to
Here is an easier test case for overflow. If you know IEEE floats
a little bit, and your Prolog system provides them, try this:

In Trealla, yeah the float display bug is gone:

Trealla Prolog (c) Infradig 2020-2021, v1.13.5-1-g36f32
?- X is float(1<<1023).
X = 8.98846567431158e+307.

?- X is float(1<<1024).
uncaught exception: error(evaluation_error(float_overflow),float/1)
true.

Unfortunately there is still a parsing error:

?- X = 8.98846567431158e+307.
Error: syntax error parsing number, line 0, ''
true.

So cannot close this ticket.

The Logtalk nonsense with 7^7^7 is from here:
https://github.com/LogtalkDotOrg/logtalk3/blob/09e996f53e561e8f2cfacb7ccf73562a60d319e9/tests/prolog/unbounded/tests.lgt#L260

I would expect testing parsing/unparsing before testing overflow.

Mostowski Collapse

unread,
Sep 10, 2021, 9:04:54 PM9/10/21
to

Feeling bored, want a laugh. Just google Logtalk, and see what
is cooking the last days, you will surely find some splendid nonsense.

Mostowski Collapse

unread,
Sep 10, 2021, 9:19:01 PM9/10/21
to
Interesting find the Chrome JavaScript arithmetic is quite
fast, it is between Traella and SWI-Prolog. I get:

Dogelog Runtime, Prolog to the Moon, 0.9.5
?- time(_ is 7^7^7).
% Wall 36 ms, trim 0 ms
https://www.dogelog.ch/

And as a bonus I can also display it, using X is 7^7^7 instead
of _ is 7^7^7. Using the browser as output is quite robust. On the
other hand, the Mac Console for SWI-Prolog crashes on my side:

The Dogelog Runtime can compute 7^7^7 quite fast AND can display it:
https://gist.github.com/jburse/f4e774ebb15cac722238b26b1a620f84#gistcomment-3889281

SWI-Prolog can compute 7^7^7 ultra fast but CANNOT display it:
https://gist.github.com/jburse/f4e774ebb15cac722238b26b1a620f84#gistcomment-3889282

Mostowski Collapse schrieb am Samstag, 11. September 2021 um 02:53:31 UTC+2:

Mostowski Collapse

unread,
Sep 10, 2021, 9:34:21 PM9/10/21
to
Ever seen Logtalk sandboxed? Ha Ha, it has so many loop
holes, you can just call whatever you want from the
target Prolog system, like for example exec('rm -R /'). On
the other hand Dogelog runtime is not a source to source

translator, but a dynamic Prolog system, it takes a Prolog
text and prepares it for execution from within a host
language. If the host language is a sandbox, like a browser
web page with JavaScript, it will execute there and

profit from the existing sandbox there. listing/[0,1] works
also, it will not show the world, only the user predicates
and user clauses. On the other hand listing/[0,1] in SWISH
is broken, this example doesn't work anymore for

some reasons. Maybe a form of bit rot?

listing(apple_stock_price/2).
Unknown procedure: apple_stock_price/2 (DWIM could not correct goal)
https://swish.swi-prolog.org/example/data_source.swinb

Mostowski Collapse

unread,
Sep 10, 2021, 9:36:05 PM9/10/21
to

Logtalk testing framework would be useful if it could
test SWISH notebooks. How do you assure that they
always do what the authors intended them to do?

Mostowski Collapse

unread,
Apr 4, 2023, 4:05:18 AM4/4/23
to
Ha Ha, LogNonsenseTalk at its best:

> Future work
> Arm–twist Prolog implementers for better
> support for rational terms and tabling
> https://logtalk.org/papers/colp2012/coinduction_colp2012_slides.pdf

Ok, here is a suggestion. Propose a (@<)/2 for rational terms.

Then talk again.

Mostowski Collapse

unread,
Apr 4, 2023, 4:10:56 AM4/4/23
to
(@<) can be useful for tabling tries. So I guess LogNonsenseTalk
work about co-induction was highly influenced by the following
seminal paper in logic programming dating back to the 70s:

How to Levitate
https://www.youtube.com/watch?v=z2I5J1ArmeM

LMAO!

Mostowski Collapse

unread,
Apr 4, 2023, 4:20:01 AM4/4/23
to
Other Levitating experts on the scene: Ulrich Neumerkel
and Markus Triska. It is now the year 2023, and they
still discuss number_chars/3:

number_chars/2 sometimes yields wrong results
https://github.com/mthom/scryer-prolog/issues/1773

Whereas their Scryer Prolog cannot do correctly
(@<) on rational trees aka cyclic terms. It even never
comes to their mind, to apply KISS principle

to the number_chars/3 problem, and instead
read the requirement for what number_chars/3
accepts to read it as "integer" where:

integer (* 6.4 *)
= [ layout text sequence (* 6.4.1 *) ] ,
integer token (* 6.4.4 *) ;

Why not simply strip down the relevant production
requirement for number_chars/3 "integer token" only,
or maybe something even simpler, and forget about

all the layout nonsense? Most programming languages
do it this way. Just checkout parseInteger() or parseFloat()
across languages such as Java, JavaScript, Python etc..

No language designer is so debilated to include in the integer
or float syntax layout or comments. This happens only when
you have Levitating experts on the scene.

LoL

Mostowski Collapse

unread,
Apr 4, 2023, 4:33:44 AM4/4/23
to
About the KISS principle:

KISS, an acronym for "Keep it simple, stupid!",
https://en.wikipedia.org/wiki/KISS_principle

Hope this Helps!

Mostowski Collapse

unread,
Apr 22, 2023, 9:26:19 AM4/22/23
to
This blog post has a nice easter egg at the end.
https://www.philipzucker.com/harrop-checkpoint/
Elaborating on it I get the following:

/* File comvars2.p */
:- op(1200, xfy, =>).
:- op(1150, fx, hypo).

term_expansion((:- hypo(F/N)), (H :- shift(in(H)))) :-
functor(H, F, N).

(A => B) :-
reset(B, in(C), Cont),
(Cont == 0 -> true; (C = A; shift(in(C))), Cont).

Here is test case of embedded implication backtracking:

:- hypo p/1.

?- reset((p(1) => p(2) => p(X)), in(_), Cont), Cont==0.
X = 2,
Cont = 0 ;
X = 1,
Cont = 0 ;
false.

Mostowski Collapse

unread,
Apr 22, 2023, 9:28:20 AM4/22/23
to
When I try the same with Scryer Prolog:

/* File comvars2sc.p */
:- use_module(library(cont)).

:- op(1200, xfy, =>).
:- op(1150, fx, hypo).

term_expansion((:- hypo(F/N)), (H :- shift(in(H)))) :-
functor(H, F, N).

(A => B) :-
reset(B, in(C), Cont),
(Cont = none -> true; Cont = cont(G) -> (C = A; shift(in(C))), G).

I get a segmentation fault during backtracking:

?- reset((p(1) => p(2) => p(X)), in(_), Cont), Cont==none.
X = 2, Cont = none
; Segmentation fault

Mostowski Collapse

unread,
May 11, 2023, 9:43:49 AM5/11/23
to
I always thought these new type systems only provide gradual
typing. But a keyword here seems to be flow sensitive typing(**). And
there are more players in town:

Microsoft: Typescript
Facebook: Flow(***)
What else?

Flow has funny things like an exact object type {| .. |}. A straight
forward Prolog “linter”(*) isn’t flow sensitive, since it wouldn’t validate
different types along disjunction or if-then-else branches?

(*) Logtalk even barks on disjunctions?
Clauses whose body is a disjunction
https://logtalk.org/manuals/devtools/linter.html

(**)
Flow-sensitive typing
https://en.wikipedia.org/wiki/Flow-sensitive_typing

(***)
Flow vs TypeScript: Which is Better in 2023?
https://www.scalablepath.com/javascript/flow-vs-typescript

Mostowski Collapse schrieb am Mittwoch, 12. September 2018 um 21:28:29 UTC+2:
> As a last note, thanks for all your publicity
> on Logtalk. There's true in the saying that
> there isn't such thing as bad publicity!

Mostowski Collapse

unread,
May 13, 2023, 9:52:02 AM5/13/23
to
Ha Ha, twice nonsense doesn't give something Ok.
Now Logtalk has this implemention:

variant(Term1, Term2) :-
\+ \+ subsumes_term(Term1, Term2),
\+ \+ subsumes_term(Term2, Term1).
https://github.com/LogtalkDotOrg/logtalk3/blob/master/library/types/term.lgt#L102

Spot the 2 errors. Here are the errors:

Error 1: There is no need for garbage collection \+ \+ in
subsumes_term/2. It does already undo its bindings.
Thats the difference between subsumes/2 and subsumes_term/2,

that subsumes_term/2 does not leave some bindings,
is only a test predicate.
See also here:

On success, the bindings are undone.
https://www.swi-prolog.org/pldoc/man?predicate=subsumes_term/2

Error 2: According to Ulrich Neumerkels account
here this is only half correct. There is a copy_term/2
missing:

variant_correct(A, B) :-
copy_term(A, AC),
subsumes_term(AC, B),
subsumes_term(B, AC).
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/built-in_predicates

Mostowski Collapse

unread,
May 13, 2023, 9:54:46 AM5/13/23
to
In as far this Quintus adapter is nonsense:

subsumes_term(General, Specific) :-
subsumes(General, Specific).
https://github.com/LogtalkDotOrg/logtalk3/blob/master/adapters/quintus.pl#L255

SICStus Prolog tells me it should be either:

subsumes_term(General, Specific) :-
subsumes_chk(General, Specific).

Or then this here:

subsumes_term(General, Specific) :-
\+ \+ subsumes(General, Specific).
https://quintus.sics.se/isl/quintus/html/quintus/lib-tma-subsumes.html

Mild Shock

unread,
Jul 28, 2023, 7:58:06 AM7/28/23
to
Thats probably the most brain damaged nonsense I
have ever seen. Whats the programming pattern?
Inverted control, which inverted again?

Printing messages and asking questions
https://logtalk.org/manuals/userman/printing.html

Nobody uses such nonsense in practice. Neither
Python, nor JavaScript, provide something as absurd
as this "framework". Its kind of a perverted logging

framework, that lacks Internationalization/Localization.
And the bad news is, it goes really back to Quintus Prolog,
you find it here in this documentation:

Quintus Prolog User’s Manual
https://quintus.sics.se/isl/quintus/pdf/quintus.pdf

But its not something that somebody would use in a
modern application. The most horrible section in the
Quintus Prolog User's Manual is the idea to

translate DCG. What can go wrong? You need to
understand the syntax and semantics of DCG to do that.
Ever found a translator that can massage DCGs?

Mild Shock

unread,
Jul 28, 2023, 8:06:11 AM7/28/23
to
The Quintus Prolog User's Manual describes a method that predates
the idea of resource bundles, as found for example Java. It not only
predates that idea, it also shows a different idea. It goes on:

"By default, generate_message/3 sends the
message term through the English message
generator, messages(’english/QU_messages’)."

The misery is then this advice:

To have all messages printed in another language, the basic steps are as follows
1. Take a copy of ‘QU_messages.pl’ and translate all the messages.
2. Test the translated ‘QU_messages.pl’ and then install it
in the Quintus Prolog directory hierarchy.
3. Install or re-install Quintus Prolog to get a version that uses the translated messages.

So there is no locale parameter in the runtime? And there is
no extension mechanism, you need to go into the system folders
and change them? And you cannot build applications, libraries

or systems that offer multiple languages, have bundled multiple
languages. Why, is there not enough memory on the disk
and in the RAM? LoL

Mild Shock

unread,
Jul 28, 2023, 8:12:45 AM7/28/23
to
Now I have added the power of resources bundles, through
a very simple new 100% pure Prolog solution to Dogelog Player,
which I am currently backporting to formerly Jekejeke Prolog.

One can try the following in Example 02: Website Sandbox:

?- X is 1/0.
Error: Division by zero.
user:1

?- set_prolog_flag(sys_locale, de_CH).
true.

?- X is 1/0.
Fehler: Nulldivision.
user:2

Very beautiful and very simple! Not the brainless Quintus
copypasta of Logtalk. Whats the competence behing Logtalk?
Is it a demonstration of how to be stupid, dumb and uninspired?
0 new messages