How many of you realize that SWI-Prolog is an excellent, genuinely excellent language?

There it is. That’s it, 95% of what I want to say is in the title—Prolog is great! What follows is just commentary. All those of have contributed to SWI-Prolog or any other Prolog in any way, you all have my accolades, and my deep appreciation. I’ll explain briefly why.

A couple of years ago, I decided to start upgrading my computer science and my programming knowledge to the new status quo. Yes, I decided to learn functional programming! And I loved it. Then later, curious of new paradigms, I decided to try this strange thing called “logic programming”. I felt right at home from the get-go. Prolog, in my mind, is a sister to the functional programming languages. Functional-style recursion is the way you usually write your routines—imperative-style loops are off the menu. So, skills gained in writing one translate very well to the other.

I’ve tried so many functional languages, and yet there’s none that covers all the bases I need covered for it to be a compelling proposition both for everyday scripting and serious projects.

Haskell is excellent, (and I’ve spent so much time becoming proficient in it!) but the shocking state of package documentation means that, whenever I want to try something new and exciting from the packages, I’m back to square one. I’m a total newb again, desperately struggling to figure out what obscure combination of unusual operators will produce the program I want, in the syntactical style that was intended. Starting with a new package is an incredibly stressful experience.

Clojure has excellent syntax—it’s a really crisp, clear and beautiful take on LISPs—but the Java-spawned error messages are baffling, making the simplest of debugging attempts into pure psychological torture, and the runtime overhead of the JVM makes me regret using it every time.

I could go on and on.

But let’s talk about SWI-Prolog. Here’s a language that has never, ever let me down. It’s not a functional language, it’s not the hot, cool new kid on the block, but I don’t care one bit. Everything I want to do with Prolog, the language and the engine just gets out of my way and lets me do it.

  • Package and language documentation is incredibly easy to read.

  • It has one the best command-line debugging environments I’ve ever come across, and the little window that pops up to help with your profiling is fantastic, too.

  • Solving your problems is often as easy as formulating an elegant description of them.

  • Sysadmin tasks are aided by straightforward IO predicates and some excellent libraries, making it easy to do all your daily scripting tasks in Prolog.

  • It interfaces easily, and excellently, with other languages when you need more specialized functionality.

  • The community is one of the friendliest going, and people’s passion for the project is very much visible.

  • Extensions like DCGs, CHRs and CLP are focused, first and foremost, on increasing the number of problems you can easily solve in Prolog, greatly adding to the power of the language.

  • Once you know SWI-Prolog, you can capably handle just about any other logical programming environment. You can compile logic programs to C using Mercury, meaning you can use them with WebAssembly, or you can use Tau Prolog to run logic programs directly in transpiled JavaScript. Or you can just take your program written in a more low-level language and plug your Prolog program into it.

There are valid criticisms to make, for sure. The unification system can seem like magic to the uninitiated, and it takes a certain level of skill to learn how to coax searches to go exactly where you need them to, and no further. That’s why there is such an element of “craft” to Prolog, with classic books on the language deservedly owning names like “The Art of Prolog”. The error messages may be mystifying for beginners, and it’s not helped by how you can’t annotate your predicates with type or mode information.

But I’ll leave others to do the grouching (and I’d like to hear it, make no mistake!). But for me, at least, errors have never taken too long to debug, because there’s such a powerful arsenal available to you when it comes to debugging.

As an example of how Prolog’s helped me out lately, I’m using Probabilistic Logic Programming with Prolog to generate believable, internally consistent worlds for a video game project. You’ll start by choosing random facts about your world, for example “This world is powered by ice energy”, and the system will go on to decide “Well then, 50-100% of terrain should be cold terrain”, and from there to “This north-eastern peninsula of land has an 85% chance to be tundra”, and from there to “There are 0-3 ice dragons living in this tundra region” and so on and so on.

I won’t write the whole game in Prolog, but the fact I don’t need to is an asset, not a downside to Prolog! It just plugs in and solves the problems I want solving without effort.

Prolog is an incredible tool to have in your toolbelt, and one you start with it, creative ideas on what you can do with it start to come flooding in.

So thanks to you all, and keep it up!

Comments, corrections and/or advice are welcome :grin:. Thanks!

11 Likes

In my mind, Prolog once used in earnest, is the kind of language that makes it very hard to go back to other languages …

I felt a lot of “cognitive pain” when I rewrote some code in C …

Dan

2 Likes

I heartily agree! Most of my “day job” work is in Clojure, which I do love…but SWI-Prolog makes me even happier to use. It’s not only incredibly powerful but so delightful to work with that it makes me seek out problems which I can use Prolog to solve.

The beauty of SWI-Prolog - hotloading code

Just along the lines of what has been posted, recently I had a long running process (hours and hours) and I needed to correct a small issue. I couldn’t stop the process. Well…SWI-Prolog came to the rescue: it is able to hot load code on the fly!

Here is a little example.

:- use_module(library(prolog_server)).
:- prolog_server(4333,[]).

longrunning :-
    flag(counter,C,C+1),
	format('~w blippy blops so far~n',[C]),
	sleep(3),
	longrunning.

Run this in one terminal window:

26 ?- longrunning.
...
232306 blippy blops so far
232307 blippy blops so far
232308 blippy blops so far
232309 blippy blops so far
232310 blippy blops so far
232311 blippy blops so far

Now, those numbers are getting hard to read, wouldn’t it be nice if I could just fix the output, printing easier to read numbers, without stopping the process?

Well, SWI-Prolog does it!
In your favorite editor fix the format/2 statement changing this:

	format('~w blippy blops so far~n',[C]),

to this:

	format('~D blippy blops so far~n',[C]),

Save the file, and now we can hotload the code! In another terminal, run this:

$ telnet localhost 4333   % yes, ssh is supported with the libssh addon
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to the SWI-Prolog server on thread client@localhost.localdomain

1 ?- make.
...

Now look at the output in the first terminal :grin: :

26 ?- longrunning.
...
232306 blippy blops so far
232307 blippy blops so far
232308 blippy blops so far
232309 blippy blops so far
232310 blippy blops so far
232311 blippy blops so far
232312 blippy blops so far
232313 blippy blops so far
232,314 blippy blops so far      % right here the code was hotloaded
232,315 blippy blops so far
232,316 blippy blops so far
232,317 blippy blops so far
232,318 blippy blops so far
232,319 blippy blops so far

I have only been able to do this with erlang in the past.
Certainly, SWI-Prolog is a gem.


EDIT

By @EricGT

This reply and its replies were moved to a new topic.

3 Likes

3 posts were merged into an existing topic: Hotloading code