FregeDay: Design and Implementation of the language (Ingo Wechsung)
13. Sep 2015•0 gefällt mir
3 gefällt mir
Sei der Erste, dem dies gefällt
Mehr anzeigen
•1,406 Aufrufe
Aufrufe
Aufrufe insgesamt
0
Auf Slideshare
0
Aus Einbettungen
0
Anzahl der Einbettungen
0
Downloaden Sie, um offline zu lesen
Melden
Technologie
Talk by Ingo Wechsung at the FregeDay 2015, Sept 11th, Basel, Switzerland, covering general characteristics of the language, history, and important design decisions.
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
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.
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
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
Background Information
Haskell 2010 Report https://www.haskell.
org/definition/haskell2010.pdf
Implementation of FP-Languages http://research.
microsoft.com/en-
us/um/people/simonpj/papers/slpj-book-1987/slpj-
book-1987.pdf
Calling Frege Code from Java https://github.
com/Frege/frege/wiki/Calling-Frege-Code-from-Java