Hello world

From Dyna
Jump to: navigation, search

Contents

Hello, world!

Welcome to the Dyna tutorial! It is traditional to start by writing and running a program that prints hello world. Put the following text in a file called helloworld.dyna:

% My first Dyna program (helloworld.dyna)
:- item(item, double, 0).   % says that values are double-precision real numbers
goal += hello*world.        % an inference rule for deriving values
hello := 6.                 % some initial values
world := 7.

This does not print hello world. It was the closest we could come. Dyna is a "pure" language. It focuses on computation, and sniffs haughtily at mundane concerns like input and output.

Compiling with a Standard Driver Program

Once you have downloaded and installed the dyna compiler, you can compile the above program with

dynac helloworld.dyna --driver=goal

This produces an executable program called helloworld or helloworld.exe. (It translates your dyna code into C++ and then calls a C++ compiler, usually g++.)

The --driver=goal command-line option tells dynac what is to be done with the Dyna program's pure computation: namely, print the value of the goal item and exit. (There are several other standard --driver options that can be passed to dynac; they are documented in dynac's manpage.)

Running

Now run ./helloworld to get the following output. (On Cygwin, you may have to run ./helloworld.exe.)

42

When you run the executable, it outputs 42, because goal now has a value of 42, and the --driver=goal option has asked dynac for an executable that prints the value of goal.

The word goal is not a reserved word in Dyna. But it is often used, so some of the standard driver programs treat it as special.

Custom Driver Programs

Now, what if you want to do something more interesting than just print the value of goal?

If you aren't going to use one of the standard driver programs, you will need to write your own in C++ (or perhaps another language) to make your Dyna program talk to the outside world.

Here's a custom C++ driver program, helloworld_driver.cpp, that prints the value of goal with a little explanatory text.

 // C++ driver program (helloworld_driver.cpp)
 #include <iostream>            // lets you use standard C++ I/O libraries
 using namespace std;    

 #include "helloworld_dyna.h"   // interface with helloworld.dyna
 using namespace helloworld;    // lets you drop helloworld:: prefix
 
 int main() {                  // the actual driver routine
    chart c;
    cout << "hello*world = " << c[goal] << endl;  // print value of goal
 }

The included header file helloworld_dyna.h is produced from helloworld.dyna by the Dyna compiler. It declares the other C++ names that you see above: the class chart and the constants goal, hello, and world. Their full names are actually helloworld::chart, helloworld::goal, etc., but the namespace declaration lets you drop the helloworld:: prefix.

It is recommended that you always put a try/catch block around the code in main, to catch things that might go wrong:

 #include <stdexcept>
 ...
 int main() {
    try{   
        chart c;
        cout << "hello*world = " << c[goal] << endl;  // print value of goal
    }catch(exception& e){
        cerr << e.what() << endl;
        return(EXIT_FAILURE);
    }
 }

Compiling with a Custom Driver Program

To compile your Dyna program with the custom driver helloworld.cpp that we just wrote, use the same command as before, but specify helloworld_driver.cpp in place of --driver=goal:

dynac helloworld.dyna helloworld_driver.cpp

The dynac compiler is a drop-in replacement for the C++ compiler (usually g++). The main difference is that you can include .dyna files in the list of files to compile and link together.

Now run ./helloworld to get the following output:

hello*world = 42

The relation between Dyna and C++

Notice that ./helloworld just called the C++ main() function in the usual way. If you are a C++ programmer, Dyna won't try to take over your life. It will just generate some C++ classes that your C++ program can rely on for hard jobs, like multiplying 6*7. Your "driver" program might actually be a big, multi-file C++ system that does a lot more than just "drive" Dyna:

dynac life.cpp universe.cpp helloworld.dyna 
       everything.cpp -o deepthought
       # the -o option says what to call the executable

Even if your .dyna file really is the centerpiece of your application, you will still need a driver program to make it talk to the outside world. Like C, Dyna is a small language that has no built-in functions beyond arithmetic. It has to get I/O and other functions from external libraries. There would have been no point in reinventing those wheels: you can simply use C or C++'s perfectly good libraries.

A variation: Hello hello hello, world!

This variation shows a slightly more interesting computation of goal, and shows that goal automatically changes when hello does.

% My second Dyna program.  This time it doesn't specify any
% initial values.  All values will come from the driver program.

:- item(item, double, 0).  
goal += hello*hello.
goal += hello*world.
 // A fancier C++ driver program.
 #include <iostream>
 #include <stdexcept>
 #include "helloworld_dyna.h"    
 using namespace std;        
 using namespace helloworld;

 int main(int argc, char** argv) {
    try{

        chart c;     // Dyna object that holds all item values

        cout << "default value of goal = " << c[goal] << endl;

        // set some values
        c[hello]=2;   
        c[world]=5;
        // goal's value is magically computed from them
        cout << "hello*hello + hello*world = " << c[goal] << endl;

        // now change hello to 3 and watch goal change too
        c[hello]=3;   
        cout << "no, wait!  hello*hello + hello*world = " 
             << c[goal] << endl;

    } catch(exception& e){        // everyone's favorite C++ exception handler
        cerr << e.what() << endl;
        exit(EXIT_FAILURE);
    }
 }

This produces

default value of goal = 0
hello*hello + hello*world = 14
no, wait!  hello*hello +  hello*world = 24

The first line of your Dyna program said that all of the program's "items" (goal, hello, world) should have double-precision values that default to 0. That is why goal was initially 0.

The rest of your Dyna program ensured that goal would update as hello or world changed. The program defines goal to be the sum of hello*hello and hello*world.

Now let's see a more powerful form of such definitions.

Continue tutorial by finding the shortest path in a graph

Personal tools
Namespaces

Variants
Actions
Navigation
Tools