FregeDay: Design and Implementation of the language (Ingo Wechsung)

24
Frege: Design & Implementation A short Overview Ingo Wechsung IT Consultant, contexo GmbH Reutlingen, Germany

Transcript of FregeDay: Design and Implementation of the language (Ingo Wechsung)

Frege: Design & Implementation

A short Overview

Ingo WechsungIT Consultant, contexo GmbH

Reutlingen, Germany

Topics

• History

• Language Design

• Runtime

• Compiler Architecture

History

• Frege1

• Frege2

• Frege3

see http://www.infoq.com/news/2015/08/frege-haskell-for-jvm

Design Goals

• pure functional, statically typed, non-strict– essentially Haskell 2010

– plus higher ranked types

– more GHC features to be implemented on top

• easy integration in JVM ecosystem– a practical JVM language

– a (more funny) way to write (better) Java code

– be as familiar as possible for JVM programmers

Reminder: Haskell means Laziness

… not now, please! I can do that later ….

Principles for Design Decisions

• when in doubt, do it like Haskell 2010– unless it makes no sense in JVM

• module system, FFI, exceptions, C-ish/POSIX-ish APIs

– unless outdated (Functor/Applicative/Monad)– maybe a bit simpler in certain cases– subsetting (e.g. standard/prelude libraries)

• add nice JVM stuff– regexes out of the box– long, java.lang.String– types as name spaces (makes records possible)

To err is human …

• class/instance syntax:class Eq a => Ord a / instance Eq a => Eq (Maybe a)

class Ord Eq a => a / instance Eq Eq a => Maybe a

thought it would be easier to parse, read and understand, but really is major annoyance.

• Java comment syntax, package/module

• Underestimation of how important source code compatibility would be.

Unintended Consequences

• for interoperability and speed: support and use primitive JVM types, hence

data Bool = pure native boolean

• requires literals

– familiarity concerns suggest true, false

• Haskell users [Confused .. Annoyed]

• Yet can‘t fix this easily without „cheating“ in the compiler.

Too bad your compiler doesn’t know what “True” and “False” is!

Native Interface (aka FFI)

• not only functions, but also data types• JVM types appear as abstract data types

– need functions (i.e. JVM methods) too– (watch out: ADT abbreviates abstract as well as

algebraic data types.)– primitives, interfaces, classes, arrays– almost no knowledge about „basic types“ hardwired

in the compiler: it‘s all in the Prelude

• Haskell FFI not fit for JVM, replaced with NI– code that uses C functions is not portable anyway

Ru

ntim

e

Runtime

• do as much as possible in the NI

• minimalist

• no dependencies

Runtime Concerns

• provide Java methods where • synchronized { … }

• try { … } catch … finally { … }

would be needed.

• interfaces and classes for representation of

Frege ADT and functions

• thunks & lazy evaluation

Runtime System Overview (to be changed soon)

interface Applicable

interface Value

abstract Algebraic

abstract Lambda

abstract Delayed

function types

algebraic data types

interface Lazy

Created by applied

functions

Current vs. Upcoming Function Handling

● A FunN, when applied, creates a FunN-1, and Fun1 a Delayed.

● designed to minimize class files, because it covers partial applications.

● Create FunN “function pointers” for functions as needed.

● Re-use function pointers across modules.

● Higher order functions do not care about type/arity of passed functions.

● no partial application implemented in Java anymore

● thunks/lazy values are Callable<X>

● higher order functions expect functional arguments with exact arity

● should reduce number of intermediate instances drastically

● will create less class files in Java 8, more in Java 7

● more type safe calling from Java into Frege

Example

map (1+) list

map ((+) 1) list

List.map(plus123.apply(1),list)

Fun2 plus123 = new Fun2() {public Integer eval(Object a1,

Object a2) {return Delayed.<Integer>forced(a1) +

Delayed.<Integer>forced(a2); }}

map (1+) list

map (\x -> 1+x) list

List.map((Func1)(x -> 1 +

Thunk.<Integer>forced(x)), list)

Encoding of Product Types

data P a b = C a b

data R = Pair { !a, !b :: Int }

final class TP {final Object m1;final Object m2;

TP(Object a, Object b) {m1 = a; m2 = b;

}}

final class TR {final int mema, memb;…

}

Encoding of Sum Types

data S a b = S1 a | S2 b interface TS {

static class DS1 implements TS { DS1 _S1() { return this; }DS2 _S2() { return null; }…

}static class DS2 implements TS

{ … }

public DS1 _S1();public DS2 _S2();

}

See the REPL!

● There are no secrets in Frege.

● Just type an example in the REPL and use :java

command!

● Caveat: REPL tells you only how things are today.

● JVM evolution may offer opportunities we cannot

refuse.○ JVM8: lambdas

○ JVM?: value types

Three classes of values

● Immutable ○ All Frege types and pure native types

○ can be used everywhere

● Mutable only○ JVM types defined mutable native

○ native functions that use them must be IO actions

● Mutable○ JVM types defined native

○ can appear in ST actions or pure functions

Marshalling in the NI

● no arguments for static method: () -> ST s R

● nullable arguments of type X:

Maybe X or Maybe (Mutable s X)

● void method: ST s () or IO ()

● let return type be X in Frege○ mutable? Mutable s X

○ nullable? Maybe (...)

○ exceptions? (Ex1 | Ex2 | …)

○ side effects? ST s (...)

Compiler facts

● multi pass

● pass :: StateT Global IO a

● records information about compiled module in the

form of Java annotations

● creates and compiles Java source code

● concurrent -make option

● IDE friendly

Important Compiler Passes

● Lexer :: String -> [Token]

● Parser :: [Token] -> Maybe [Definition]

● Import

● Name resolution

● Type Check

● Transformations & Optimizations

● Strictness

● generate meta data and code