Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Frege is a pure functional programming language for the JVM in the spirit of Haskell.
Frege Java Bison Perl Other

README.md

What is Frege? Build Status

Frege is a pure functional programming language for the JVM in the spirit of Haskell. It enjoys a strong static type system with powerful type inference and non-strict - also known as lazy - evaluation.

Frege programs are compiled to Java and run on the JVM.

The similarity to Haskell is actually strong enough that many users call it "a Haskell for the JVM".

A Taste of Frege

1. Hello World

This is the classic starter with a slight extension to show the fluent usage from Java and the benefits of having a type system that can recognize purity.

module Hello where

greeting friend = "Hello, " ++ friend ++ "!"

main args = do
    println (greeting "World")

This code will compile to Hello.class and Hello.java with a regular Java main method that one can start the usual Java way.

Moreover, the Hello.class will have a method

public static String greeting(String ...) {...}

that one can call from Java or any other JVM language.

The greeting function is pure, meaning it is stateless and free of side effects. Therefore, it is threadsafe and its results may be automatically cached since given the same argument, the result will always be the same.

The main function is impure. It takes a list of Strings and does not return just "void" as in most other JVM languages but the type IO (), telling that it may produce side effects like printing to the console. The Frege type system guarantees that any caller of main must also be of some IO type and is thus also marked as impure. That way, the lack of purity percolates up the whole call chain.

"Hello World" already shows the tenet of "islands of purity" (greeting) in a "sea of imperative code" (main).

Since the purity information is carried through the type system, the compiler can potentially use it for many optimizations such as pre-calculation, deferred execution, parallel execution, caching, and elimination of common subexpressions.

Frege is strongly and statically typed, even though we haven't declared any types in the code above. If not declared, the types are inferred. When declared, the given types are checked against the inferred ones.

2. No mutable state

Much can be achieved in Frege in one line of code and here is an example that you can paste into the Online REPL. It calculates the fixpoint of the cosine function, i.e. the value where cos(x) == x.

Implementations in imperative languages usually involve introducing local mutable state. Not so in Frege:

import frege.prelude.Math (cos)
(fst . head . dropWhile (uncurry (!=))) (zip cs (tail cs)) where cs = iterate cos 1.0

After execution it should show you the value

 0.7390851332151607

The code is most likely incomprehensible for a Frege/Haskell newcomer at first but you would not believe how obvious and straightforward it is once you know the parts.

  • cs is an infinite list (a stream in Java terms) of cosine values that starts with cos 1.0 and then iterates to cos(cos(1.0)), cos(cos(cos(1.0))), and so forth.
  • zip cs (tail cs) produces an infinite list of pairs of any two adjacent values in cs.
  • uncurry holds onto each element of a given pair and the (!=) function compares these elements for in-equality.
  • dropWhile reads from the infinite list as long as the cosine values in each pair are not equal.
  • The remaining list (the infinite list of pairs of equal cosine values) has a first pair called head and fst returns the first element of that pair, which yields the final result.

This code is pure. The inferred type is Double. The code does not rely on any mutable state (not even internally). Therefore it is threadsafe and the result can be automatically cached.

What's in for me?

For the Java programmer

Frege offers you the opportunity to learn and use a new programming paradigm that shines with

  • a solid mathematical foundation,
  • pure functions,
  • immutability by default,
  • side-effects only when declared,
  • robustness under composition and concurrency,
  • and a type system that is unparalleled on the JVM with its combination of power, simplicity and expressiveness.

You can still reuse your existing knowledge of the Java platform and its vast set of libraries. Frege interoperates with Java such that you can easily call Frege from Java code and vice versa. But unlike other approaches, calling Java from Frege doesn't undermine the language guarantees.

When calling Java from Frege, you have to declare the Java types in rigid Frege terms in order to preserve the Frege language characteristics, especially purity, thread safety, and lazy evaluation.

Learning Frege essentially means that you will also learn Haskell and thus your effort pays off twice, since you also get to know a very popular non-JVM language with 25+ years of development, a great community, many (free) books, publications, tutorials, online courses, and considerable industry demand.

For the Haskell programmer

Frege gives you the opportunity to use your skills on the JVM. Most idiomatic Haskell code will run in Frege unmodified or with only minimal, obvious adaptions. Even more important: you can bring your purely functional problem solution strategies to your Java projects.

From now on you can also enjoy on the JVM:

  • the terse Haskell syntax
  • pure functions and lambdas
  • algebraic data types and typeclasses with parametric polymorphism
  • powerful type inference
  • higher rank types
  • lazy evaluation on infinite data structures
  • pattern matching, list comprehensions, do-notation, point-free style, operators, modules
  • functors, monoids, semigroups, monads, and all your other beloved mathematical abstractions.

The Name

The Frege programming language is named after and in honor of Gottlob Frege who published the ideas of higher-order functions, partial function application, and many more concepts of formal logic that we now take for granted back in the 19th century.

If you are curious how this name is pronounced, you can use this translator page to get it right. Just click the audio symbol in the left (german) part.

Project State

The compiler, an Eclipse plugin and a provisional version of the documentation can be downloaded. Note that Frege requires at least JDK 7 to compile and run programs.

A number of tools are written in Frege:

The documentation is provisional and the library supports almost all of the Haskell 2010 standard library with the remaining known differences being there for good reason.

See the Getting Started page for getting started at the command-line or read the Eclipse plugin page. You can develop Frege inside Intellij IDEA and there is build automation support for Maven, Gradle, and Leinigen.

The awesome QuickCheck library for advanced unit testing comes bundled with the language.

Related Projects

Contributions

If you are interested in contributing, here are some hot topics:

  • Write Frege code to support more of the Java API.
  • Port Haskell libraries or tools.
  • Open issues in the issues tracker if you find bugs, errors in documentation, etc.
  • Help make Frege popular by writing code for projects like Rosetta Stone or Computer Language Shootout.
  • Contribute to the related projects mentioned above, or make your own.

Contact

Upcoming talks

Meet Frege friends at JAX 2015, Mainz, and join the Frege Session at April 21st, 9:45.

The breathing code conference will take place May 4th/5th in Frankfurt, Germany. It solely consists of live coding events and a one-hour session will be devoted to the Frege language.

For discussions

You can contact the project members through the discussion group devoted to the Frege programming language.

For questions

Specific programming problems are best solved on Stack Overflow, we check questions tagged "frege" on a regular basis.

For casual chat (and quick questions)

There's a #frege channel on Freenode IRC where some project members and Frege users hang out. You can use any IRC client you like or Freenode's WebChat interface if you don't want to install IRC software.

For issues only

If you find a bug or have an idea for enhancements, please let us know by opening an issue in the issue tracker. (You'll need a GitHub account to do this.) Please keep discussions to the forum and questions to Stack Overflow.

Links

Recommended reading

API Docs

Copyright and License

Copyright (c) Ingo Wechsung, 2011-2015. All rights reserved. The use and distribution terms for this software are covered by the BSD 3-clause license which can be found in the file LICENSE.txt at the root of this distribution. By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software.

Something went wrong with that request. Please try again.