Lessons/Hello World!

From wiki.visual-prolog.com

Revision as of 13:21, 25 September 2018 by Thomas Linder Puls (talk | contribs) (initial)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

In this lesson we will where we just write some code disregarding the finer details.

Exercise Create a console project.

Double-click the main.pro file in the project tree to open it in an editor, and update the run clauses to look like this:

clauses
    run() :-
        stdio::write("Hello World!\n").
Run the program using Build -> Run in window Alt+F5.

The main.pro file contains other stuff, which we will currently disregard, and focus solely on the run clauses you just wrote.

First we have the keyword clauses, which simly indicates that what comes after are clauses. Clauses is where the actual running code is written.

In this text I will use words like "clause" and "predicate", which all have their origin in formal logic, but for the moment we will simply treat them as the names that happens to be chosen for things in a Prolog program.

clauses are used to define predicates, where a predicate is a Prolog routine/subroutine/function/procedure (dear child has many names)

This particular clause defines a predicate run which takes no arguments (indicated by the empty parentheses ()).

After the :- token we have the code that will be executed when run is invoked/called.

In this case we call a predicate named write which is defined in the class named stdio. We will discuss classes later for now we will just consider stdio::write as "a long compound name".

We supply one argument, i.e. the string literal "Hello World!\n", to the stdio::write predicate. Notice that \n in the string literal represents a line shift.

The clause is terminated by a period (i.e. .). Period is used as terminator for many kinds of entities in Visual Prolog.

The predicate run is called when the program is run, and acts as our entry point to the program. Actually, the real entry point is the goal a further down in the main.pro file, but that entry point is used to make varous initializations, corresponding clean-up, etc and will call the run predicate in the right spot, so run can act like your entry point.

So when the program is run the predicate run in main.pro will be called and this will (here) call stdio::write with the argument "Hello World!\n", as a result Hello World! and a line shift will be written to the console window.

Actually, stdio::write writes to the standard output stream, which in a console program is initialized to be the console window. In a default GUI program the standard output stream will write to a message window, but the standard output stream is under programmer control, so what happens when you call stdio::write will depend of what has taken place in the program.

To summarize:

  • The actal runnign code is in clauses
  • predicates is the Visual Prolog name for routines/subroutines/functions/procedures.
  • Predicates are organized in classes, and predicates from other classes is referenced using <class>::<predicate>.
  • The run predicate in main.pro is the (effective) entry to a program.
  • stdio::write can write to the standard output stream

Now let us extend the program with an extra predicate.

Exercise Add this code below the run clauses:
class predicates
    advancedHello : (string Name).
clauses
    advancedHello(Name) :-
        stdio::writef("Hello %!\n", Name).
Build the project using Build -> Build Ctrl+Shift+B

When you build the project you will get a warning stating that the predicate main::advancedHello is an unused local predicate. Which is completely correct; we haven't used it for anything. But let us "decipher" it before we go any further.

We notice that we again have a clause in a clauses section. The clause is for a predicate named  advancedHello that takes one argument called Name. Name is a variable, a variable starts with an uppercase letter and will be green in the editor (variables can also start with an underscore, but we will discuss that later).

Name acts as a formal parameter representing the actual argument used in the call to advancedHello. In this clause we call stdio::writef which is a more advanced "writer" predicate. The first argument to writef is a format string, which contains a %-character, what happens when writef is called is that the actual value of Name is substituted into the format string in the place where the %-character is and then the resulting string is written to the standard output.

This time we also have a class predicates section containing a declaration of the advacedHello predicate. This perticular declaration declares advancedHello as a class predicate which takes one argument which must be a string.

In the predicate declaration the argument also have the name Name but in the declaration the name is mainly intended for documentation purposes. The variable name in teh declaration and in the clauses can be different, or you can remove it completely. I reccoment that you always have names here and that you use names that will make it clearer for the user of the predicate what the arguments represents.

What it means to be a class predicate and what else a predicate can be is discussed elsewhere/later. But before we leave the subject try this little experiement:

Exercise Remove the word class from class predicates in the delcaration of advancedHello. And then build the project.

Notice the error message and remember that you get this message when you have forgotten to write class in front of predicates.

Then insert class again and build the project again.

Now that we have the advancedHello predicate we can use it in our run predicate.

Exercise Update the run clause to look like this:
clauses
    run() :-
        advancedHello("Dear"),
        advancedHello("World").
Run the project in a window.

The clause should be understandable, I just want to highlight that we have used comma to separate the two invocations of advancedHello: comma" to separate, period to terminate. I will give a little prediction: Later when you are familiar with Visual Prolog you will from time to time make syntax errors and (the prediction) 9 out of 10 times the syntax error will concern comma and/or period.