470 likes | 536 Views
F# Information Rich Programming. Donna Malayeri Program Manager, Visual Studio F#. What’s in this talk?. Intro to F# sytax Language features for solving real-world problems F# type provider demos Type providers: under the hood Future directions. F# Tagline.
E N D
F# Information Rich Programming Donna Malayeri Program Manager, Visual Studio F#
What’s in this talk? Intro to F# sytax Language features for solving real-world problems F# type provider demos Type providers: under the hood Future directions
F# Tagline F# is a practical, functional-first language that lets you write simplecode to solve complexproblems
Simplicity abstractclassCommand{ publicvirtualvoid Execute(); } abstractclassRoverCommand: Command { protected Rover Rover { get; privateset; } publicRoverCommand(MarsRover rover){ this.Rover = rover; } } classBrakeCommand: RoverCommand{ publicBrakeCommand(Rover rover): base(rover) { } publicoverridevoid Execute(){ Rover.Accelerate(-1.0); } } classTurnLeftCommand: RoverCommand{ publicTurnLeftCommand(Rover rover): base(rover) {} publicoverridevoid Execute(){ Rover.Rotate(-5.0); } } C# Functions as values F# type Command = Rover -> unit letBrakeCommand = fun rover ->rover.Accelerate(-1.0) letTurnLeftCommand = fun rover ->rover.Rotate(-5.0<degs>)
Challenges Impedance mismatch with statically-typed languages Need to manually integrate codegen tools with build process, source control, etc. No elegant way to handle schema change Loss of type information due to up-casts to Object, or even have to just parse strings
But… Data sources often have rich schemas and associated data definitions Static types should make your experience better, not worse!
Programming the web Why this matters
// Freebase.fsx // Example of reading from freebase.com in F# // by Jomo Fisher #r"System.Runtime.Serialization" #r"System.ServiceModel.Web" #r"System.Web" #r"System.Xml" open System open System.IO openSystem.Net openSystem.Text openSystem.Web openSystem.Security.Authentication openSystem.Runtime.Serialization [<DataContract>] type Result<'TResult> = { [<field: DataMember(Name="code") >] Code:string [<field: DataMember(Name="result") >] Result:'TResult [<field: DataMember(Name="message") >] Message:string } [<DataContract>] typeChemicalElement = { [<field: DataMember(Name="name") >] Name:string [<field: DataMember(Name="boiling_point") >] BoilingPoint:string [<field: DataMember(Name="atomic_mass") >] AtomicMass:string } letQuery<'T>(query:string) : 'T = let query = query.Replace("'","\"") letqueryUrl = sprintf "http://api.freebase.com/api/service/mqlread?query=%s" "{\"query\":"+query+"}" let request : HttpWebRequest = downcastWebRequest.Create(queryUrl) request.Method <- "GET" request.ContentType <- "application/x-www-form-urlencoded" let response = request.GetResponse() let result = try use reader = newStreamReader(response.GetResponseStream()) reader.ReadToEnd(); finally response.Close() let data = Encoding.Unicode.GetBytes(result); let stream = newMemoryStream() stream.Write(data, 0, data.Length); stream.Position <- 0L letser = Json.DataContractJsonSerializer(typeof<Result<'T>>) let result = ser.ReadObject(stream) :?> Result<'T> ifresult.Code<>"/api/status/ok"then raise (InvalidOperationException(result.Message)) else result.Result let elements = Query<ChemicalElement array>("[{'type':'/chemistry/chemical_element','name':null,'boiling_point':null,'atomic_mass':null}]") elements |> Array.iter(fun element->printfn"%A" element)
Demo 2 summary • Can program against web-scale schematized data • code gen would never work here! • Don’t have to wait for codegen or code to compile • With typechecking! • Can detect schemachange • With great tooling!
Codegen is not fun Bing SOAP Services
It gets worse… Note The name of this class and its constructor may be different depending on the tool you use to generate the client proxy classes.
F# Matches the Math List.map2 (-) x y |> List.map square |> List.map2 (*) weights |> List.sum |> sqrt
Demo 3 summary Can easily program against multiple data sources using type providers Access web services, databases, etc, using a uniform interface F# works well for the program logic
Under the hood • A type provider is a standard .NET assembly • Extends a particular interface and includes special metadata attributes • Plugs into the compiler and typechecker • (We’ll see the interface in a moment)
Web Service Database Local file Unknown.Identifier IDE Integration -r:Provider.dll Typechecker/Compiler System.Type (synthetic) + how to compile method calls to synthetic types
How it works • Typechecker encounters method application/type instantiation that is not in the environment • Typechecker queries all referenced type providers • Type provider returns a AST fragment and synthesized type definitions • Typechecker and compiler merge this into the rest of the AST
Type provider interface public interface ITypeProvider{ Type GetType(string name); Expression GetInvokerExpression( MethodBaseprovidedMethod, ParameterExpression[] params); event System.EventHandler Invalidate; Type[] GetTypes(); }
Implementing a type provider • Two alternatives • Erasure-based: inline the code, don’t create types • Generated: inject IL into the assembly • In principle, no unwanted references to external code/types
“Sort of” a plugin • Extends the typechecker and compiler • But is not a general compiler plugin • Can’t do arbitrary AST manipulation • Not inserting a phase in a pipeline • A component that changes typechecking and IDE integration • Needs to work well in both batch and interactive mode • Get auto-completion “for free” since it's built into the typecheck process
Advantages • Allows scaling to huge schemas • e.g., a web database with millions of types • Strong, static types • Compile-time checking • Integrate with the IDE • Makes it easy to add new data protocols
Examples of type providers • SQL • Web services • Structured files (CSV, XML,…) • Regular expressions • Facebook
Language design driven by IDE features • IDE is usually an afterthought • Features rarely designed explicitly for improving IDE (though possibly tweaked) • Examples • DrScheme, Racket, Alice • Java annotations: make J2EE tools work better • C# partial classes: allow UI design tools to generate code that the user does not edit
Example: Hands • Programming language designed for children • Language syntax designed to ensure good syntax errors if <expression> <relational operator> ... <expression> then <statements> <expression> then <statements> otherwise <statements> end if
What’s next for F#? • Cloud, cloud cloud! • Make F# programming on Azure even easier • Can use F# computation expressions to add new syntax in a library • for example, cloud { … } • F# asyncand queryexpressions are not built-in syntax—they use computation expressions
Cloud Numerics • Extensive library of numerical algorithms • Ranges from basic math to advanced statistics to linear algebra • Supports distributed arrays and computation • Can deploy to Azure when lots of compute resources are needed
Summary • Type providers provide an integrated solution for accessing data sources • Keeps the experience code-focused • Provides a consistent and uniform programming experience • Schema change integrates with IDE and build system