Differences Haskell /
Frege
Towards making Frege a better
Haskell dialect/subset Ingo Wechsung
IT Consultant, contexo GmbH
Reutlingen, Germany
@iwechsu
State and Vision
GHC
Haskell
2010
Frege
GHC
Haskell
2010
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 is
When 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 :&
Double
Implementing 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
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 done
Standard: specifies default declaration
Effort: medium
Importance: ?
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 present
c. 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 portable
support 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!

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

  • 1.
    Differences Haskell / Frege Towardsmaking Frege a better Haskell dialect/subset Ingo Wechsung IT Consultant, contexo GmbH Reutlingen, Germany @iwechsu
  • 2.
  • 3.
    Purpose of thisPresentation ● 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
  • 4.
    Preliminary notes In thefollowing 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☺).
  • 5.
    Haskell Compatibility Mode? Thereare some Frege features that cannot get abandoned without making Frege ● less practical for use on the JVM ● less good than it is When otherwise unresolvable conflicts with the Standard arise, should we have a “haskell compatibility mode” (abbrev. HCM)?
  • 6.
    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
  • 7.
    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
  • 8.
    Operator constructors (2) Notethat GHC extension -XTypeOperators in addition allows infix type constructors: Int :& Int :| Double :& Double Implementing 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.
  • 9.
    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.
  • 10.
    String and Charliterals ● 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.
  • 11.
    Meaning of StringLiterals ● 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.
  • 12.
    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
  • 13.
    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
  • 14.
    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
  • 15.
    Overloaded Floating PointLiterals ● 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.
  • 16.
    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
  • 17.
    Field Labels asSelectors ● 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
  • 18.
    Construction using FieldLabels ● 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
  • 19.
    Updates Using FieldLabels ● 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
  • 20.
    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: ???
  • 21.
    Negative Patterns ● Frege:not supported ● Standard: allows them with numeric literals (3.17.1, page 28) ● Effort: medium ● Importance: medium ● Suggestions: implement
  • 22.
    Irrefutable pattern ● Frege:not supported ● Standard: ~apat (3.17.1, page 28) ● Effort, Importance, Suggestions: see “Pattern syntax”
  • 23.
    Context in DataDeclaration ● 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
  • 24.
    “deriving” clause indata 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
  • 25.
    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
  • 26.
    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.
  • 27.
    Numeric Type Defaulting Frege:not done Standard: specifies default declaration Effort: medium Importance: ? Suggestion: In a first step, just the syntax could be implemented.
  • 28.
    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
  • 29.
    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.
  • 30.
    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
  • 31.
    Modules - ExportLists ● 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 present c. retire private/public/protected
  • 32.
    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
  • 33.
    Comparison Haskell/Frege Imports importA.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
  • 34.
    Qualified Names andModule 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
  • 35.
    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
  • 36.
    Characters ● Frege Charare 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
  • 37.
    Strings ● Frege usesnative 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
  • 38.
    IOERR ● Frege doesn’thave 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
  • 39.
    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.
  • 40.
    Numbers ● Frege doesn’thave 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.
  • 41.
    IO Exception Handling ●Frege uses Java Exceptions ● Standard: IO Exception Handling (7.3, page 90) ● Importance: none ● Effort: N/A ● Suggestion: don’t change
  • 42.
    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 portable support the foreign import/export syntax though?
  • 43.
    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
  • 44.
    Conclusion ● we havea long way to go ● much work to be done ● much can be done to enhance “Haskellnes”
  • 45.
    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
  • 46.