3 Introduction: What? Implementation of Haskell 98 on Rotor/.NET Haskell is one of the worlds most popular functional programming languages.How to compile Haskell for .NET is still a research problemCan it be done “reasonably”?Would IL changes provide “worthwhile” benefit:cost?Reasonably = at appropriate performance/loss of functionality – interpretation would work for all of Glasgow Haskell but wouldn’t be reasonable. Worthwhile = is the cost of IL changes warranted, or do you just take a hit – B:C. IL changes of course require Rotor.
4 Introduction: Haskell Well knownUsed in industry and academiaNon-strictGlasgow Haskell Compiler (GHC)Provides intermediate-level output to support new backendsExtends Haskell 98 – providing future avenues of research
5 Introduction: Why?Different language families are suited to different tasksThis adds a non-strict functional language to the languages available on .NETTo test the extent to which .NET can run many languages.Primarily used by object oriented imperative languages.
6 Prior Art: BridgesThe functional language runs natively on the real machineA software bridge is provided to the VMExamples:Lambada (Haskell for JVM)Hugs.Net (Haskell for .NET)
7 Prior Art: New Languages Designed to work on the VMsReduced featuresMixed compile/interpretive approachesMore OO-like type systemsExamples:Pizza (JVM)StrictIntroduced parametric polymorphism to JVMMondrian (.NET)OO-like type systemUsed a mixed compiled/interpretive approachTargeted at scripting applications
8 Haskell 98 on .NET: Challenges Non-strict evaluationFunctions as valuesPartial evaluation/“currying”Type switches
9 Challenge: Non-strict Evaluation Mondrian: “External” non-strictnessClient must knowManual evaluationInterpretive-likeJIT Objects: “Internal” non-strictnessNon-strictness hidden from clientAutomatic evaluationDoesn’t support disjoint union types wellDisjoint union types central to Haskell 98…JIT Objects was an earlier project that produced “non-strict C#” – actually a non-strict framework for any language to use but demonstrated using C#
10 Haskell.NET: Non-strict Evaluation Use “Internal” non-strictnessBest for interworkingPrimitive typesFollow JIT ObjectsOptimise to use single class, rather than type/subtype combinationAuto conversion to/from values & boxed valuesFunction typesUse hidden nested subtype
11 Non-strict Evaluation (cont) Disjoint union typesType: abstract classAlternatives: sub-classesDiscrimination:use tag fieldsResolution:“asX” methods rather than castingNon-strictnessHidden sub-classInternal: evaluation hidden by tag/asXIssues:Casting only works for evaluated valuesNot totally transparentBut disjoint unions not “standard” OO
12 Non-strict typesdata List a = Cons a (List a) : Nil
13 Challenge: Functions as values .NET provides delegates, which are “OO function pointers”Unfortunately:Relatively inefficient given the high usage in HaskellDifficult to combine with non-strictnessReplace using a parametric function typeProvide conversions to/from delegates for inter-language workingExtends to support partial applicationMight extend to support higher-rank types (Glasgow extension)
14 Challenge: Partial Evaluation Calling a function omitting arguments, to create a new function, e.g.Inc x = x+Calling (inc 3) returns a function that adds 3 to its argumentWe extend our previous function typeInstance fields used to store pre-supplied arguments
15 Challenge: Type Switches Very slow in .NETMust use a series of type checks/castsThese checks take account of subtypesAddressed by the addition of an explicit tag enumerand to each type. I.e:Effectively duplicate the hidden VM tagDo exact, as opposed to subtype, matching
16 Status Compiler functional Performance? But incomplete… Large %age of Haskell 98 languageSmaller %age of Haskell 98 librariesLargely engineering, not research, leftPerformance?Primes Sieve (first 1000 primes)GHC Native: 0.9sGHC .NET: 1.5s
17 Future Work: Glasgow Haskell Higher Rank TypesPassing generic functions as valuesPartly supported now:Wrap inside interfaceHigher Kind TypesE.g. allow M<X> where both M & X are variableHow to do reasonably efficiently in .NET?Fallback is reflection/runtime code generation…Currently by-passed (e.g. hardwire Monad to IO)
18 Future Work: IL Changes? Compared to “native” implementation:More classes – adds VM loadSome extra indirections – a runtime costVirtual dispatch for tag checkingEtc.Investigate if IL changes would:Provide Haskell a good benefit:costBenefit other languages