# Recently started woring with prolog and decided to make a text documenting my annoyances

**URL:** <https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900>\
**Category:** General\
**Created:** [October 19, 2023, 1:05pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900 "2023-10-19T13:05:35Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![marceloslacerda](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/marceloslacerda/32/5769_2.png) [@marceloslacerda](https://swi-prolog.discourse.group/u/marceloslacerda)\
**Post date:** [October 19, 2023, 1:05pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/1 "2023-10-19T13:05:35Z")

</div>

This isn’t my first rodeo with prolog but it’s probably the longest time that I’ve been using it so far.

While working on a chess engine written in prolog I’ve come across a few annoyances in the language. Nothing has been bad enough to dissuade me from continuing (it’s a hobby project after all). But coming from other (mostly imperative) languages there I’m starting to notice a few things that I really miss in the language.

I’m posting this here to read the thoughts of the prolog veterans.

> **[Conveniences that I wished prolog had](https://docs.google.com/document/d/1Hlo-aSbqi2Spq8e726V66QhNeYsftY2cE_oOj63sGAM/edit?usp=sharing)**
>
> Conveniences that I wished prolog had Term deconstructor and alias: my\_pred(X=(Part1, Part2)) :- … An elegant (in my opinion) alternative to adding another rule to the body of the predicate; Also easier to understand at a glance what kind of...

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 19, 2023, 1:49pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/3 "2023-10-19T13:49:52Z")

</div>

Thanks for sharing. It is always good to have fresh comments. Several have a work-around.

> column(Table, Column, Info)

As shown by @anon95304481. You can use term\_expansion to make this work. The problem is of course that `f(X=a(Y))` or `f(X@a(Y))` have a meaning as is, and you are changing this. SWI-Prolog handles unifications to head arguments that immediately follow the head efficiently. So code like below uses clause indexing and does not create a copy of X. If you need a lot of that, I’d indeed introduce some abbreviated syntax. Possibly we should have a library for that.

```
f(X, ...) :-
    X = f(Y),
    ....
    g(X).

```

> my\_pred(…) :-  
> rule1,  
> rule2, % This comma is ignored  
> .

The standard trick is to use `true.` as last line. Of have an editor that is smart enough. I’m not aware of such an editor ☹

> my\_pred(…):-  
> rule1,  
> skip,  
> rule2. % Only rule 1 is checked

You can do that. Define a module skip with the code below. The operator precedence causes skip to take the remainder of the clause as argument. Next just just define it to be true. Also works in branches of a disjunction.

```prolog
:- module(skip,
          [ (skip)/1,
            op(1000, fy, (skip))
          ]).

skip(_).

```

> Type hints

Typing is a long debated topic. It probably needs to be reopened. In the old days we had fully typed languages. Now we have typing on dynamically typed languages such as typescript for JavaScript, types for Python, etc. The Ciao system is probably most advanced here. Hopefully something simple and useful will emerge …

.

---

<div class="post-metadata">

**Author:** ![marceloslacerda](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/marceloslacerda/32/5769_2.png) [@marceloslacerda](https://swi-prolog.discourse.group/u/marceloslacerda)\
**Post date:** [October 19, 2023, 6:49pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/4 "2023-10-19T18:49:11Z")

</div>

> The problem is of course that `f(X=a(Y))` or `f(X@a(Y))` have a meaning as is, and you are changing this.

Ah, I see. I’ll keep that in mind as I continue on my journey.

> The standard trick is to use `true.` as last line. Of have an editor that is smart enough. I’m not aware of such an editor

Or maybe I should switch to a better plugin 😁, VSC-Prolog seems to be able to warn me when I forget a trailing comma.

```prolog
:- module(skip,
          [ (skip)/1,
            op(1000, fy, (skip))
          ]).

skip(_).

```

That’s awesome! I’m definitely adding that to my codebase.

```prolog
Typing is a long debated topic. It probably needs to be reopened. In the old days we had fully typed languages. Now we have typing on dynamically typed languages such as typescript for JavaScript, types for Python, etc. The Ciao system is probably most advanced here. Hopefully something simple and useful will emerge …

```

Python first introduced type-hints as comments as to not change the language. I think the same is possible for prolog. Though type is indeed a challenging topic.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 20, 2023, 7:47am UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/5 "2023-10-20T07:47:30Z")

</div>

> [@marceloslacerda](#):
>
> Or maybe I should switch to a better plugin

At least, the VSC plugin, Sweep (for GNU Emacs) and the built-in Emacs clone do active syntax checking. Would be nice to have a simple command to do things such as removing the last line or swapping the last two. It might be more confusing then helpful though …

> [@marceloslacerda](#):
>
> Python first introduced type-hints as comments

We have that as well, as, e.g.

```
%! age(+Name:atom, -Age:integer) is semidet.

```

There is also an extension pack that creates runtime checks from this. As is though, the optional type annotation needs to be a valid Prolog term, but there is no formal type language. There are types as defined by library(error), must\_be/2.

---

<div class="post-metadata">

**Author:** ![oskardrums](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/oskardrums/32/3594_2.png) [@oskardrums](https://swi-prolog.discourse.group/u/oskardrums)\
**Post date:** [October 20, 2023, 8:18am UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/6 "2023-10-20T08:18:21Z")

</div>

> [@jan](#):
>
> Would be nice to have a simple command to do things such as removing the last line or swapping the last two

FWIW, in Sweep, we can remove the last (or any) sub-goal with `C-M-k` (`kill-sexp`), for example:

```prolog
foo :-
    bar(X)-!-,
    baz(Y).

```

With the cursor at `-!-`, typing `C-M-k` gives:

```prolog
foo :-
    bar(X).

```

Similarly we can transpose goals/terms with `C-M-t` (`transpose-sexps`), so we’d get:

```prolog
foo :-
    baz(Y),
    bar(X).

```

I find this one useful also for transposing arguments, etc.

The relevant part of the Sweep manual is [Term-based Editing (Sweep: SWI-Prolog Embedded in Emacs)](https://eshelyaron.com/man/sweep/Term_002dbased-Editing.html)

---

<div class="post-metadata">

**Author:** ![kwon-young](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kwon-young/32/4841_2.png) [@kwon-young](https://swi-prolog.discourse.group/u/kwon-young)\
**Post date:** [October 20, 2023, 11:52am UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/7 "2023-10-20T11:52:47Z")

</div>

```prolog
Term deconstructor and alias:

my_pred(X=(Part1, Part2)) :-
  …

```

So, I had exactly the same experience as you and here is a tale of my thought process about this problem as a prolog beginner:

The begining of this journey is that you want to write a predicate where you manipulate both the argument and a subterm of the argument in a predicate:

```prolog
my_pred(X) :-
  X = a(Y),
  % use X and Y.

```

But then, you learn about First Argument Indexing (FAI) and notice that by pulling the pattern matching in your head you get a lot of benefit like determinism and speed:

```prolog
my_pred(a(Y) :-
  X = a(Y),
  % use X and Y.

```

But then, you notice the pain of having to write the term twice and think: “How nice it would be to have both convienience and speed !”. And so, begin to think of a solution.  
Since FAI is so good, you don’t want to give it up. So the only solution is to do everything inside the head of a clause and come up some special syntax that will unify both the term and subterm inside the head.

```prolog
my_pred(X=a(Y)) :-
  % use X and Y.

```

But then, you learn what Jan said:

> [@jan](#):
>
> [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) handles unifications to head arguments that immediately follow the head efficiently.

And go full circle and come back to the first solution !

---

<div class="post-metadata">

**Author:** ![kwon-young](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kwon-young/32/4841_2.png) [@kwon-young](https://swi-prolog.discourse.group/u/kwon-young)\
**Post date:** [October 20, 2023, 12:10pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/8 "2023-10-20T12:10:23Z")

</div>

Also about type hints.

> [@jan](#):
>
> There is also an extension pack that creates runtime checks from this.

I believe the pack Jan is referring to is the [mavis pack](https://www.swi-prolog.org/pack/list?p=mavis).

I also remember of a pack that did static checking of types but I can’t find it again. Was it [type\_check pack](https://www.swi-prolog.org/pack/list?p=type_check) ?

But, in my experience, I found that type specification is a just a waste of time when you are writing highly experimental code. That time is better spent writing test cases with the excellent [unit test pack](https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/plunit.html%27)) 🙂

One thing I often wonder is: what is the canonical way to define new type with swi-prolog ?  
Is it by using `has_type/2` ?  
I could not find documentation on the swi-prolog website about this topic and only could find the [typedef pack](https://www.swi-prolog.org/pack/list?p=typedef).

By the way, as a prolog beginner, it was an eye opening experience to browse all [swi-prolog packs](https://www.swi-prolog.org/pack/list).  
There are some wonderful gems in there like the [clpBNR](https://www.swi-prolog.org/pack/list?p=clpBNR) pack.

---

<div class="post-metadata">

**Author:** ![marceloslacerda](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/marceloslacerda/32/5769_2.png) [@marceloslacerda](https://swi-prolog.discourse.group/u/marceloslacerda)\
**Post date:** [October 20, 2023, 1:10pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/9 "2023-10-20T13:10:47Z")

</div>

> I believe the pack Jan is referring to is the [mavis pack](https://www.swi-prolog.org/pack/list?p=mavis).

This looks amazing! I’ll check that out later.

> But, in my experience, I found that type specification is a just a waste of time when you are writing highly experimental code. That time is better spent writing test cases with the excellent [unit test pack](https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/plunit.html%27)) 🙂

Right, at the beginning of any project types are kinda useless indeed. However when I settle down on a few data structures and I wanna be consistent across multiple predicates it is nice to know that I’m unpacking `(BeforePoint, AfterPoint)` and not `(CoordinateX, CoordinateY)`.

Maybe I should give up on using tuples and move on to use predicates to describe my arguments to a predicate.

```prolog
% How I'm doing right now
my_pred((BeforePoint, AfterPoint)):-
   ...

% How I should be doing (?)
movement(Before, After):-
  ...

my_pred(Movement):-
  Movement=movement(Before, After),
  ...

```

---

<div class="post-metadata">

**Author:** ![kwon-young](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kwon-young/32/4841_2.png) [@kwon-young](https://swi-prolog.discourse.group/u/kwon-young)\
**Post date:** [October 20, 2023, 1:31pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/10 "2023-10-20T13:31:53Z")

</div>

> [@marceloslacerda](#):
>
> `my_pred((BeforePoint, AfterPoint)):-`

hum, is that a comma list ?  
I believe there is a consensus that comma list are bad.  
As for the reason why, I believe it is because it is confusing with other prolog construct like compound terms.  
Your example seems well suited with pairs, which the functor `-/2` is commonly used:

```prolog
Movement = Before-After.

```

But if you have different kind of pairs like movement pairs and coordinate pairs, you should totally use compound terms like `movement(Before, After)` and `point(X, Y)`.

You can use the library [`record`](https://www.swi-prolog.org/pldoc/man?section=record) to facilitate the use of such compound, although it is kind of useless for nested compounds…

---

<div class="post-metadata">

**Author:** ![kwon-young](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kwon-young/32/4841_2.png) [@kwon-young](https://swi-prolog.discourse.group/u/kwon-young)\
**Post date:** [October 20, 2023, 1:38pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/11 "2023-10-20T13:38:37Z")

</div>

> [@marceloslacerda](#):
>
> However when I settle down on a few data structures and I wanna be consistent across multiple predicates it is nice to know that I’m unpacking `(BeforePoint, AfterPoint)` and not `(CoordinateX, CoordinateY)`.

By the way, I fully aggree with you.  
However, have you ever experienced the situation where you actually made the mistake of calling a predicate that **you** wrote (even a long time ago) with the wrong type of arguments ?

I think I have never experienced this, although maybe it is because I don’t have many types in my own project ?

---

<div class="post-metadata">

**Author:** ![marceloslacerda](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/marceloslacerda/32/5769_2.png) [@marceloslacerda](https://swi-prolog.discourse.group/u/marceloslacerda)\
**Post date:** [October 20, 2023, 2:30pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/12 "2023-10-20T14:30:47Z")

</div>

> However, have you ever experienced the situation where you actually made the mistake of calling a predicate that **you** wrote (even a long time ago) with the wrong type of arguments ?

Only every single day. 🥲

---

<div class="post-metadata">

**Author:** ![marceloslacerda](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/marceloslacerda/32/5769_2.png) [@marceloslacerda](https://swi-prolog.discourse.group/u/marceloslacerda)\
**Post date:** [October 20, 2023, 2:35pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/13 "2023-10-20T14:35:50Z")

</div>

Yeah I was reluctant to change the entire code base but seems like swi is finally had enough of me with my comma lists

```prolog
?- my_pred(_, ((1, a), (2, b))).
   Call: (10) simple_pawn_capture_movement(_, ((1, a), 2, b)) ? abort

```

Notice how the last nested comma list is unpacked on the trace. No idea why that it happening, but regardless I’ll change it to compound terms.

---

<div class="post-metadata">

**Author:** ![kwon-young](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kwon-young/32/4841_2.png) [@kwon-young](https://swi-prolog.discourse.group/u/kwon-young)\
**Post date:** [October 20, 2023, 5:05pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/14 "2023-10-20T17:05:20Z")

</div>

Well, to debug these kind of error, you can use `write_canonical/1`:

```prolog
129 ?- write_canonical(my_pred(_, ((1, a), (2, b)))).
my_pred(_,','(','(1,a),','(2,b)))
true.

130 ?- write_canonical(my_pred(_, ((1, a), 2, b))).
my_pred(_,','(','(1,a),','(2,b)))
true.

```

I believe this is kind of a textbook example of why the use of comma list is discouraged ^^

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [October 20, 2023, 6:20pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/15 "2023-10-20T18:20:27Z")

</div>

I am not a human, I am the tuple warning bot.

Please look at [this post](https://swi-prolog.discourse.group/t/surprising-result-with-equals-dot-dot/4989/9) for an example why comma lists are not tuples.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [October 21, 2023, 2:13pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/16 "2023-10-21T14:13:39Z")

</div>

So I see my tuple warning bot already engaged with you 🙂 Now it is me writing this.

> [@marceloslacerda](#):
>
> Right, at the beginning of any project types are kinda useless indeed. However when I settle down on a few data structures and I wanna be consistent across multiple predicates it is nice to know that I’m unpacking `(BeforePoint, AfterPoint)` and not `(CoordinateX, CoordinateY)`.
> 
> Maybe I should give up on using tuples and move on to use predicates to describe my arguments to a predicate.

And then you give two possible solutions:

> [@marceloslacerda](#):
>
> ```prolog
> % How I should be doing (?)
> movement(Before, After):-
> ...
> 
> my_pred(Movement):-
> Movement=movement(Before, After),
> ...
> 
> ```

what you could be doing instead is:

```prolog
my_pred(movement(Before, After)) :- ...

```

A side note: in this example, `my_pred/1` is indeed a predicate but `movement/2` is a compound term ie a data structure. This is how I understand the statement “Prolog is a homoiconic language”: data and program are not different in their syntax. Your data can become program if interpreted as such, and interpreting a data structure as program is possible and easy.

And Prolog will let you implement types, in a way. The biggest issue is that the typing you can implement with Prolog easily is mostly **run time**.

Your own example from above already demonstrates how you can specialize an algorithm for a specific data structure by using a compound term with its Name/Arity. If you define your predicate only for an argument of type `movement/2` and you give it a `point/2`, it will just fail at run time.

In the same vein, if you implement some algorithm for integers, and you use a built-in like `between/3` in its definition, you will get a run-time exception. Like this:

```prolog
%% some made up implementation
prime(P) :-
    between(2, infinity, P), % this will throw if you
                             % call prime(foo) and fail
                             % if you call prime(-1)
    ...

```

In this example the concepts of data type and value domains get conflated a bit. There is also must\_be/2 which can help you turn failures into exceptions but it depends on the specific use case.

Another limitation is that it isn’t immediately obvious how to model “is a” relationships (inheritance in OOP). For example both `point(X, Y)` and `movement(Before, After)` are pairs; but how would you define a predicate that works on either, or just any pair? There are many ways to solve this depending on the specifics. Built-in predicates like sort/4 are generic in that way: if you wanted to do a stable ascending sort on the second argument of a compound term, you could write:

```prolog
?- sort(2, @=<, [v(x, y), foo(1,2), bar(0,1,2), a-b], Sorted).
Sorted = [bar(0, 1, 2), foo(1, 2), a-b, v(x, y)].

```

The advantage of resolving the type at run time is that you can implement polymorphism as in OOP or generic algorithms without having to fight the type system or templating facilities. But again, your program will fail or throw at run time.

Finally, Prolog does have some notion of types (atoms, numbers, rationals, floats, strings, and so on) but all the considerations from above still apply.

Sorry for the rambling post, I am a programmer and don’t even have formal computer science or math education. My use of terminology is hopefully not too rage-inducing.

PS: if we talk about types it is probably worth pointing towards Logtalk. I haven’t used it but I am under the impression that it supports compile time typing somehow. Hopefully someone knows better and can give further details.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [October 21, 2023, 2:38pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/17 "2023-10-21T14:38:24Z")

</div>

> [@jan](#):
>
> Typing is a long debated topic. It probably needs to be reopened. In the old days we had fully typed languages. Now we have typing on dynamically typed languages such as typescript for JavaScript, types for Python, etc. The Ciao system is probably most advanced here. Hopefully something simple and useful will emerge …

An uninformed opinion on the topic is that a useful/usable type system for Prolog will have to come together with limitations to the the expressiveness of Prolog to a point where it would have to be recognized as a separate language. As long as that language can be compiled to target a Prolog VM this shouldn’t be such a terrible thing. I wish I had the aptitude and time to work on such an interesting project…

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 21, 2023, 3:07pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/18 "2023-10-21T15:07:29Z")

</div>

> [@Boris](#):
>
> come together with limitations to the the expressiveness of Prolog to a point where it would have to be recognized as a separate language.

That seems to be the necessary consequence of a rigid type system, i.e., a type system that allow full compile time checking of all types. I think Prolog needs a type system that first allows defining types and documenting types. Next, this may be used to derive type errors without trying to proof full type correctness and it can be used to allow automatic instrumentation of the code. But, types are complex in Prolog. We also have the notion of _instantiation_ and (closely related) _modes_ and _determinism_. This requires both the notion of a type (e.g., _list_) as well as a term that is _compatible_ with a list, in this case sometimes called a _partial list_.

The Ciao team did a lot of work on this. I always had the, possibly not so well informed opinion, the assertion language is too complicated. Possibly it is not so bad (experiences?), possibly it is possible to find something more lightweight.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [October 21, 2023, 3:30pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/19 "2023-10-21T15:30:43Z")

</div>

> [@jan](#):
>
> The Ciao team did a lot of work on this. I always had the, possibly not so well informed opinion, the assertion language is too complicated.

Where on the [Ciao site](https://ciao-lang.org/documentation.html) should I start reading about this? Is the chapter on [Assertions and auto-documentation](https://ciao-lang.org/ciao/build/doc/ciao.html/AssrtLang.html)?

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [October 21, 2023, 3:59pm UTC](https://swi-prolog.discourse.group/t/recently-started-woring-with-prolog-and-decided-to-make-a-text-documenting-my-annoyances/6900/20 "2023-10-21T15:59:18Z")

</div>

> [@Boris](#):
>
> The advantage of resolving the type at run time is that you can implement polymorphism as in OOP or generic algorithms without having to fight the type system or templating facilities. But again, your program will fail or throw at run time.

Slight correction: “your program _may_ fail or throw at run time _if_ you have a type error.” (I changed “will” to “may” because instead of failing or throwing an error, it might compute the wrong thing).

> [@Boris](#):
>
> Prolog does have some notion of types

People often confuse “strong or weak typing” with “static or dynamic typing”. Prolog has strong typing, as you’ll find out by executing the goal `X is foo+1` – it won’t let you add an atom and an integer. But it doesn’t have static type checking, such as in C. (C/C++, incidentally has somewhat weak typing, for example `union` and `cast` let you subvert the type system in ways that you can’t in Prolog.)
