46
Differences Haskell / Frege Towards making Frege a better Haskell dialect/subset Ingo Wechsung IT Consultant, contexo GmbH Reutlingen, Germany @iwechsu

FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Embed Size (px)

Citation preview

Page 1: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Differences Haskell / FregeTowards making Frege a betterHaskell dialect/subset

Ingo WechsungIT Consultant, contexo GmbH

Reutlingen, Germany@iwechsu

Page 2: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

State and Vision

GHC

Haskell 2010

Frege

GHC

Haskell2010

Frege

Page 3: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Purpose of this Presentation

● To give a comprehensive overview about really existing differences and what can be done about them.

● Community to ○ discuss if and how to deal with them○ create corresponding GitHub issues, if applicable○ actually work on the issues

Page 4: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Preliminary notes

In the following slides, “Standard” refers to the Haskell 2010 Language Report https://haskell.org/definition/haskell2010.pdf

Suggestions and estimations of importances and efforts are my subjective opinions (well founded ones, of course☺).

Page 5: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Haskell Compatibility Mode?

There are some Frege features that cannot get abandoned without making Frege ● less practical for use on the JVM● less good than it isWhen otherwise unresolvable conflicts with the Standard arise, should we have a “haskell compatibility mode” (abbrev. HCM)?

Page 6: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Variable names

● Frege: allows apostrophes only at the end, no underscores at start

● Standard: “An identifier consists of a letter followed by zero or more letters, digits, underscores, and single quotes.” (2.4, pg. 9)

● Effort: low (simple fix in lexical analyzer)● Importance: low● Suggestions: implement

Page 7: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Operator constructors (1)

● Frege: operator constructors are not supported

● Standard: “An operator symbol starting with a colon is a constructor.” (2.4, pg. 10)data Complex = Double :+ Double

● Effort: medium (parsing)● Importance: high● Suggestion: implement

Page 8: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Operator constructors (2)

Note that GHC extension -XTypeOperators in addition allows infix type constructors: Int :& Int :| Double :& DoubleImplementing this would entail a whole range of changes. The critical point is that types could only get parsed once the fixity of the operators is known. Currently, type parsing is already complete when the parser is done.

Page 9: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Octal integer literals

● Frege: Java literal syntax, e.g. 032 == 26● Standard: octal literals 0o32 (2.5, pg. 11)● Effort: low, rewrite literal in lexer● Importance: low● Suggestion: implement. Interpret 032 as 32

in HCM. Or just get rid of octal literals entirely.

Page 10: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

String and Char literals

● Frege: certain escape sequences and gaps in strings (multi line strings) won’t work

● Standard: 2.6, page 11f● Effort: medium, bikeshedding● Importance: low● Suggestion: Need not be done all at once.

The gaps feature would be worth having.

Page 11: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Meaning of String Literals

● Frege: string literals mean (Java) strings● Standard: “String literals are actually abbreviations

for lists of characters” (2.6, pg. 12)● Effort: medium● Importance: high● Suggestions: overload string literals so that

list functions work, follow standard in HCM.

Page 12: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Layout (1)

● Frege: no insertion of {}● Standard: “If the indentation of the non-brace

lexeme immediately following a where, let, do or of is less than or equal to the current indentation level, then … {} is inserted …” (2.7, pg. 12)

● Effort: medium● Importance: medium● Suggestion: adapt

Page 13: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Layout (2)

● Frege: no “syntactic” insertion of closing brace except before in

● Standard: “... if an illegal lexeme is encountered at a point where a close brace would be legal, a close brace is inserted.” (2.7, pg. 12)

● Effort: high (layout is lexical only)● Importance: low● Suggestions: try to cover some cases

Page 14: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Overloaded Integer literals

● Frege: numeric literals are not overloaded● Standard: “An integer literal represents the

application of the function fromInteger to the appropriate value of type Integer” (3.2, page 17)

● Effort: low, possibly breaks existing code● Importance: medium● Suggestions: slightly in favor, but should be

done together with floating point literals (next slide).

Page 15: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Overloaded Floating Point Literals

● Standard: “The floating point literal f is equivalent to fromRational (n Ratio.% d ), where fromRational is a method in class Fractional and Ratio.% constructs a rational from two integers, as defined in the Ratio library. The integers n and d are chosen so that n/d = f.” (3.2, pg. 17)

● Effort: high, Fractional and Ratio don’t exist yet● Importance: high● Suggestions: first implement needed classes and types.

Overloading itself can be done later, or just in HCM.

Page 16: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Lambda abstractions

● Frege: only single pattern allowed● Standard: “Lambda abstractions are written \p1 . . .

pn -> e, where the pi are patterns.” (3.3, pg. 18)● Effort: high● Importance: medium● Suggestion: would break existing programs

that have smth. like: \x:xs -> x

Page 17: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Field Labels as Selectors

● Frege: field labels (selectors) not top level● Standard: “Selectors are top level bindings ...”

(3.15.1, pg. 26)● Effort: depending on solution● Importance: low● Suggestion: implement in HCM only

Page 18: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Construction using Field Labels

● Frege: all field labels must be mentioned● Standard: Fields not mentioned are initialized to ⊥.

(3.15.2, pg. 26)● Effort: low● Importance: low● Suggestions: HCM only

Page 19: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Updates Using Field Labels

● Frege: slightly different syntax● Standard: “aexp<qcon> { fbind1 , . . . , fbind n }”

(3.15.3, pg. 27)● Effort: low● Importance: medium● Suggestions: implement, retire Frege dot-

syntax

Page 20: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Pattern syntax

● Frege: uses expression syntax● Standard: defines extra syntax for patterns

(3.17.1, page 28), makes @ and ~ reserved symbols

● Effort: surprisingly high, breaks Frege code● Importance: high● Suggestion: ???

Page 21: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Negative Patterns

● Frege: not supported● Standard: allows them with numeric literals

(3.17.1, page 28)● Effort: medium● Importance: medium● Suggestions: implement

Page 22: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Irrefutable pattern

● Frege: not supported● Standard: ~apat (3.17.1, page 28)● Effort, Importance, Suggestions: see

“Pattern syntax”

Page 23: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Context in Data Declaration

● Frege: not allowed● Standard: data [context =>] simpletype [= constrs]

(4.2.1, page 40)● Effort: medium● Importance: very low● Suggestion: don’t implement, as it is

considered bad practice anyway

Page 24: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

“deriving” clause in data defs

● Frege: has separate derive definition● Standard: optional deriving clause on data

declarations (4.2.1, page 40)● Effort: medium● Importance: high, though GHC now also has

separate deriving declaration● Suggestion: implement

Page 25: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Datatype renamings

● Frege: can be achieved with data● Standard: uses newtype for renaming, data

has slightly different semantics. (4.2.3, page 43)

● Effort: low/medium● Importance: high/low● Suggestion: support syntax, ignore corner

data case except in HCM

Page 26: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Context in Class/Instance Declarations

● Frege: class name first● Standard: context first (4.3.1, 4.3.2, pages

44ff)● Effort: small● Importance: high● Suggestion: this stupid error on my side

should long have been fixed. Requires adaption of most existing code, though.

Page 27: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Numeric Type Defaulting

Frege: not doneStandard: specifies default declarationEffort: mediumImportance: ?Suggestion: In a first step, just the syntax could be implemented.

Page 28: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Fixity Declarations

● Frege: top level only● Standard: has them as nested declarations, they can

appear in class declarations and let/where (4.4.2, page 50)

● Effort: medium● Importance: low● Suggestions: follow standard

Page 29: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Mutually Recursive Modules

● Frege modules form a directed acyclic graph

● Standard: “allowed to be mutually recursive” (5, page 62)

● Effort: quite high● Importance: low? ● Suggestions: don’t touch for now.

Page 30: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Optional Module Header

● Frege: module header is mandatory● Standard: “An abbreviated form of module,

consisting only of the module body, is permitted.” (5.1, page 62)

● Importance: low● Effort: low● Suggestion: implement

Page 31: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Modules - Export Lists

● tell what can be imported by other modules● in Frege, we have private/public/protected● Effort: medium .. very high● Importance: medium● Suggestions: do this in multiple steps

a. parse them, but ignore them (everything public) b. default to “private” when presentc. retire private/public/protected

Page 32: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Import Declarations

● Frege ○ doesn’t allow qualified names as module aliases○ instead, all module names are mapped to

namespace names○ doesn’t have the (..) syntax for “all sub-items”○ doesn’t have qualified

● Standard: 5.3, pages 64ff.● Suggestion: handle diffs in HCM

Page 33: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Comparison Haskell/Frege Imports

import A.B -- all

import A.B() -- none

import A.B(T(C))

import A.B(T(..))

import A.B(T)

import A.B(T())

import qualified A

import qualified A()

import a.B -- all

import a.B() -- none

import a.B(T(C))

import a.B(T)

import a.B(T())

import a.B(T())

import A()

-- makes no sense

Page 34: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Qualified Names and Module Names

● Frege uses module names only for imports. Thereafter, only the namespace name can be used for qualification.

● Standard: modid.name (5.5.1, page 67)● Importance: low● Effort: impossible● Suggestion: leave as is

Page 35: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Standard Type Boolean

● Frege uses primitive JVM type:data Bool = pure native boolean

Keyword literals true and false are provided.

● Standard: “The boolean type Bool is an enumeration.”data Bool = False | True

● Importance: high● Suggestion: cheat in the compiler

Page 36: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Characters

● Frege Char are UTF-16 values● Standard: “The character type Char is an

enumeration whose values represent Unicode characters” (6.1.2, page 73)

● Importance: low (?)● Effort: hack JVM● Suggestions: hope for JVM evolution

Page 37: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Strings

● Frege uses native java.lang.String type● Standard: “A string is a list of characters” (6.1.2,

page 73)● Importance: medium (beginners!)● Effort: medium● Suggestion: overload string literals

Page 38: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

IOERR

● Frege doesn’t have it● Standard: “IOError is an abstract type representing

errors raised by I/O operations.” (6.1.7, page 75)● Importance: low● Effort: probably low● Suggestions: can we get away with

type IOERR = IOException

Page 39: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

class Read, read

● not implemented● Standard: “The Read ... [class is] used to convert

values ... from strings.” (6.3.3, page 78)● Importance: medium● Effort: medium● Suggestions: Implement at least for basic

types.

Page 40: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Numbers● Frege doesn’t have all the type classes, no

rationals and complex numbers at this time.● Standard: prescribes a complex web of

numeric type classes (6.4, page 81ff)● Importance: medium● Effort: high● Suggestion: needs care. Or a

mathematically sound alternative.

Page 41: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

IO Exception Handling

● Frege uses Java Exceptions● Standard: IO Exception Handling (7.3, page

90)● Importance: none● Effort: N/A● Suggestion: don’t change

Page 42: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Foreign Function Interface

● Frege has its own Native Interface● Standard: (8, page 91ff)● Importance: none● Effort: small● Suggestion: Haskell sources using standard

FFI (i.e. calls into C) are not portablesupport the foreign import/export syntax though?

Page 43: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Haskell 2010 Libraries

● missing, should be done: ○ Data.Array, Data.Complex, Data.Int, Data.Ix, Data.

Ratio, Data.Word, Numeric, System.Environment, System.Exit

● present (may be incomplete) :○ Data.Bits, Data.Char, Data.List, Data.Maybe

● not done:○ Foreign, Foreign.*, System.IO, System.IO.Error

● obsolete: Control.Monad

Page 44: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

Conclusion

● we have a long way to go● much work to be done● much can be done to enhance “Haskellnes”

Page 46: FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo Wechsung)

I need a break!