fregeday: roadmap for resolving differences between haskell and frege (ingo wechsung)
TRANSCRIPT
Differences Haskell / FregeTowards making Frege a betterHaskell dialect/subset
Ingo WechsungIT Consultant, contexo GmbH
Reutlingen, Germany@iwechsu
State and Vision
GHC
Haskell 2010
Frege
GHC
Haskell2010
Frege
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
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☺).
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)?
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
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
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.
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.
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.
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.
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
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
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).
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.
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
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
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
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
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: ???
Negative Patterns
● Frege: not supported● Standard: allows them with numeric literals
(3.17.1, page 28)● Effort: medium● Importance: medium● Suggestions: implement
Irrefutable pattern
● Frege: not supported● Standard: ~apat (3.17.1, page 28)● Effort, Importance, Suggestions: see
“Pattern syntax”
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
“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
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
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.
Numeric Type Defaulting
Frege: not doneStandard: specifies default declarationEffort: mediumImportance: ?Suggestion: In a first step, just the syntax could be implemented.
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
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.
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
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
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
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
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
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
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
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
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
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.
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.
IO Exception Handling
● Frege uses Java Exceptions● Standard: IO Exception Handling (7.3, page
90)● Importance: none● Effort: N/A● Suggestion: don’t change
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?
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
Conclusion
● we have a long way to go● much work to be done● much can be done to enhance “Haskellnes”
Background, Pointers & Links
● Haskell 2010 Language Report● GHC Language System● Frege Wiki
○ https://github.com/Frege/frege/wiki/GHC-Language-Options-vs.-Frege
○ https://github.com/Frege/frege/wiki/Differences-between-Frege-and-Haskell
I need a break!