I spent a couple of hours playing with Frege (Haskell on the JVM) and not much documentation tutorials seems available. I am trying to help writing this simple Hello World tutorial.

The code is available on Github: https://github.com/ftomassetti/frege-tutorial/tree/01_HelloWorld

Update: Frege has some very useful documentation at http://www.frege-lang.org/doc/… where … represents the package, or module, name. For example, if one needs some reference for the frege.java.util.Regex package, one looks at http://www.frege-lang.org/doc/frege/java/util/Regex.html

Frege Source Code

The code is very simple for our little hello world example. In this tutorial we focus mainly on configuring our environment.

module HelloWorld where

main :: IO ()
main = do putStrLn "Hello world. Frege is a lot of fun!"

We declare the name of module to be HelloWorld. It will affect the name of the Java class produced.

The third line defines the type signature of the main function, while the fourth lines define main as a call to putStrLn using an IO Monad. In practice, you have to do the operations which affect the real world (like reading from a file or writing to the screen) inside a do statement. The reason is that the compiler treat them differently from pure functions, which can be optimized in several ways (lazyness, memoization, etc.) while “realworld operations” cannot.

Writing the POM (Maven configuration file)

First let’s take a look to the whole file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<!-- 
    This POM file was adapted from the on of the github project frege-testing from talios.

    It is availanle here:
    https://raw.githubusercontent.com/talios/frege-testing/master/pom.xml
-->

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.github.ftomassetti</groupId>
    <artifactId>frege-tutorial</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>frege-tutorial</name>
    <url>http://github.com/ftomassetti/frege-tutorial</url>

    <prerequisites>
        <maven>2.3.1</maven>
    </prerequisites>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <frege.plugin.version>1.0.5</frege.plugin.version>
    </properties>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
                <executions>
                    <execution>
                        <id>purge-local-dependencies</id>
                        <phase>process-sources</phase>
                        <goals>
                            <goal>build-classpath</goal>
                        </goals>
                        <configuration>
                            <outputFile>classpath.conf</outputFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.theoryinpractise.frege</groupId>
                <artifactId>frege-maven-plugin</artifactId>
                <version>${frege.plugin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <inline>true</inline>
                    <hints>true</hints>
                    <includeStale>false</includeStale>
                </configuration>
            </plugin>

        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.theoryinpractise.frege</groupId>
            <artifactId>frege</artifactId>
            <version>3.21.586-g026e8d7</version>
        </dependency>
    </dependencies>
</project>

The dependencies contain frege, no surprises here:

        <dependency>
            <groupId>com.theoryinpractise.frege</groupId>
            <artifactId>frege</artifactId>
            <version>3.21.586-g026e8d7</version>
        </dependency>

We then use two plugins, to compile Frege code and Java code:

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.theoryinpractise.frege</groupId>
                <artifactId>frege-maven-plugin</artifactId>
                <version>${frege.plugin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <inline>true</inline>
                    <hints>true</hints>
                    <includeStale>false</includeStale>
                </configuration>
            </plugin>

Finally we save the classpath used by Maven in a file (classpath.conf) by using  the maven-dependency-plugin

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
                <executions>
                    <execution>
                        <id>purge-local-dependencies</id>
                        <phase>process-sources</phase>
                        <goals>
                            <goal>build-classpath</goal>
                        </goals>
                        <configuration>
                            <outputFile>classpath.conf</outputFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

The classpath.conf file will be useful for running the application using the run.sh script.

Running the Application, the run.sh Script

To run the application we need the Frege jar and the classes generated from our Frege source code.

if [ ! -f "classpath.conf" ]
then
  echo "File classpath.conf does not exist, run 'mvn compile'"
  exit 1
fi

MVN_CLASSPATH=`cat classpath.conf`

java -classpath target/classes:$MVN_CLASSPATH HelloWorld

Compile and Running HelloWorld

After cloning the repository, you can simply run:

mvn compile
sh run.sh

The result, should be something like:

[federico@normandie frege-tutorial]$ sh run.sh
Hello world. Frege is a lot of fun!
runtime 0.001 wallclock seconds.