Reactive programming, WinForms,.NET. Björn Dagerman

Similar documents
Reactive Programming, and WinForms in F#

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

Collecting Hollywood s Garbage

Learning F# and the Functional Point of View. Robert Pickering, LexiFi

Investigating F# as a development tool for distributed multi-agent systems

Tomas Petricek. F# Language Overview

Asynchronous Computations

Programovací jazyky F# a OCaml. Chapter 5. Hiding recursion using function-as-values

With examples in F# and C# SAMPLE CHAPTER. Tomas Petricek. WITH Jon Skeet FOREWORD BY MADS TORGERSEN MANNING

Programovací jazyky F# a OCaml. Chapter 6. Sequence expressions and computation expressions (aka monads)

List Functions, and Higher-Order Functions

Programming Languages and Techniques (CIS120)

Demo: Controlling.NET Windows Forms from a Java Application. Version 8.2

Recap: Functions as first-class values

Collecting Hollywood s Garbage Avoiding Space-Leaks in Composite Events

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

F# - LISTS. In this method, you just specify a semicolon-delimited sequence of values in square brackets. For example

A retargetable control-flow construct for reactive, parallel and concurrent programming

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

Lecture Transcript While and Do While Statements in C++

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

Developing Microsoft.NET Applications for Windows (Visual Basic.NET)

FrTime: A Language for Reactive Programs

STARCOUNTER. Technical Overview

CSCI-GA Scripting Languages

MP 2 Continuation-Passing Style

Asynchronous Message Passing

Software Exception Flow Analysis for WPF C# Asynchronous Programs Using Microsoft Visual Studio

CITS 3242 Programming Paradigms Part II. Topic 10: Imperative Programming

FrTime: A Language for Reactive Programs

L3 Programming September 19, OCaml Cheatsheet

Variables and Bindings

Introduction to.net Framework Week 1. Tahir Nawaz

Lecture 3: Recursion; Structural Induction

Topic 5: Examples and higher-order functions

Signals, Synchronization. CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Implementing Recursion

The F# Team Microsoft

About Me Sushant Bhatia, From India/Malawi, Work at Citation Technologies Inc, an Environmental Health & Safety company with Compliance

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Customizing DAZ Studio

Functional Programming and Parallel Computing

Principles of Programming Languages

Programming Languages

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Expert C++/CLI:.NET for Visual C++ Programmers

Developing Microsoft.NET Applications for Windows (Visual Basic.NET)

CSC207 Week 4. Larry Zhang

Microsoft Visual Basic 2005: Developing Applications Additional Topics

CMSC 330: Organization of Programming Languages. Operational Semantics

CSE 341 Section 5. Winter 2018

Index. Cambridge University Press Functional Programming Using F# Michael R. Hansen and Hans Rischel. Index.

Begin at the beginning

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

(Refer Slide Time: 4:00)

CSci 4223 Principles of Programming Languages

COPYRIGHTED MATERIAL. Contents. Part I: C# Fundamentals 1. Chapter 1: The.NET Framework 3. Chapter 2: Getting Started with Visual Studio

Option Values, Arrays, Sequences, and Lazy Evaluation

Fall UI Design and Implementation 1

Imperative programming in F#

.Net Technologies. Components of.net Framework

10262A VB: Developing Windows Applications with Microsoft Visual Studio 2010

Part VI. Imperative Functional Programming

A Propagation Engine for GCC

Programming Language Concepts, cs2104 Lecture 09 ( )

Functions. Nate Foster Spring 2018

ITT8060: Advanced Programming (in F#)

(Provisional) Lecture 08: List recursion and recursive diagrams 10:00 AM, Sep 22, 2017

Programming Languages

Implementation of F# language support in JetBrains Rider IDE

Forward recursion. CS 321 Programming Languages. Functions calls and the stack. Functions calls and the stack

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Unit 1: Visual Basic.NET and the.net Framework

Hands-On Lab. Introduction to F# Lab version: Last updated: 12/10/2010. Page 1

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

CSE 341: Programming Languages

NODE.JS MOCK TEST NODE.JS MOCK TEST I

Declarative Concurrency (CTM 4)

Programming Languages and Techniques (CIS120)

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #17. Loops: Break Statement

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

CS 4300 Computer Graphics

B.E /B.TECH DEGREE EXAMINATIONS,

User-defined Functions. Conditional Expressions in Scheme

Programming C# 5.0. Ian Griffiths O'REILLY' Beijing Cambridge * Farnham Kbln Sebastopol Tokyo

Written Presentation: JoCaml, a Language for Concurrent Distributed and Mobile Programming

CSE341 Section 3. Standard-Library Docs, First-Class Functions, & More

Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Programming Languages

FUNCTIONAL PROGRAMMING

Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

Programming Languages

Transcription:

Reactive programming, WinForms,.NET Björn Dagerman

Motivation - Troublesome for many students previous years - Most student solutions we see are imperative - Useful techniques when working with GUI s, web,... - Well suited to be used with functional concepts like higher-order functions - Give an introduction to WinForms and.net

Goals After the lecture you should know how to: - Handle event streams - Set up asynchronous workflows - Structure reactive programs - Use WinForms - How some feeling for what to look at next (continued learning)

.NET & CLR Microsoft F# F# is a functional programming language for the.net Framework. It combines the succinct, expressive, and compositional style of functional programming with the runtime, libraries, interoperability, and object model of.net. [F# home page]

.NET & CLR.NET provides a run-time environment called the Common Language Runtime (CLR) Compilers and tools expose the CLR s functionality Allows you do develop code that targets the runtime Such code is called managed code

.NET & CLR Benefits of managed code include: - Cross-language integration - Cross-language exception handling - Enhanced security - Versioning and deployment support - Simplified model for component interaction - Debugging and profiling services

Using.NET libraries from F# F# has been a first-class.net citizen since its early days It can access any of the standard.net components Any.NET language can access code developed in F# For example, F# doesn t have its own GUI library. However, by going through.net we can create GUI s in F#

Windows Forms A GUI class library part of.net We will use WinForms to create GUI applications in L4 and (some) projects Alternatives: using the graphical Windows Forms Designer, or programmatically writing the necessary code Windows Forms Designer is unfortunately not supported directly by F#

Windows Forms Windows Forms Designer Workaround: create a project in a language that supports the designer, i.e. C# and create the GUI, then either - Add this project to your F# solution, or - Export as library (F# to C# or vice-versa)

Windows Forms programmatically Straight-forward approach. Remember to add a reference to System.Windows.Forms Opening a window using F# interactive: > open System.Windows.Forms;; > let form = new Form(Text = Demo, Visible = true, TopMost = true);;

Reactive Programming Create programs that wait for some input or event Examples: GUI s, Server applications

Reactive programming Asynchronous programming describes programs and operations that once started are executed in the background and terminate at some later time Dataflow programming is a way of modeling programs as a series of connections between data. The main concern is how the data moves and propagates through these connections We combine these concepts with those of functional programming, such as higher-order functions (map, reduce, filter,...)

Reactive programming Events Events are a recurring idiom in.net programming An event is something you can listen to by registering a callback

Reactive programming Events Example using F# interactive: > open System.Windows.Forms;; > let form = new Form(Text = "Click Form", Visible = true, TopMost = true);; val form : Form = System.Windows.Forms.Form, Text: Click Form > form.click.add(fun evargs -> printfn "Clicked");; Opens a window When clicked, Clicked is printed to the console form.click is an event form.click.add registers an event handler (also known as a callback)

Reactive programming Events as First-Class Values Events in F# (such as form.click) are first-class values, meaning you can pass them around like any other value We can use the combinators in the Event module to map, filter, and otherwise transform the event stream in compositional ways Example: form.mousemove > Event.filter (fun args -> args.x > 100) > Event.listen (fun args -> printfn "Mouse, (X, Y) = (%A, %A)" args.x args.y)

Reactive programming Observables Events are a F# idiom to express configurable callback structures F# also supports a more advanced mechanism for configurable callbacks that is more compositional than events: Observables Example: > open System.Windows.Forms;; > let form = new Form(Text = "Click Form", Visible = true, TopMost = true);; val form : Form > form.click > Observable.add (fun evargs -> printfn "Clicked");;

Overview of the most important functions of the Observable module Function filter map add scan merge partition Type and description ('T -> bool) -> IObservable<'T> -> IObservable<'T> Returns an event that s triggered when the source event occurs, but only if the value carried by the event matches the specified predicate. This function corresponds to List.filter for lists. ('T -> 'U) -> IObservable<'T> -> IObservable<'U> Returns an event that s triggered every time the source event is triggered. The value carried by the returned event is calculated from the source value using the specific function. This corresponds to the List.map function. ('T -> unit) -> IObservable<'T> -> unit Registers a callback function for the specified event. The given function is called whenever the event occurs. This function is similar to List.iter. ('U -> 'T -> 'U) -> 'U -> IObservable<'T> -> IObservable<'U> This function creates an event with internal state. The initial state is given as the second argument and is updated every time the source event occurs using the specified function. The returned event reports the accumulated state every time the source event is triggered, after recomputing it using the source event s value. IObservable<'T> -> IObservable<'T> -> IObservable<'T> Creates an event that s triggered when either of the events passed as arguments occurs. Note that the type of the values carried by the events ('T) has to be the same for both events. ('T -> bool) -> IObservable<'T> -> IObservable<'T> * IObservable<'T> Splits an event into two distinct events based on the provided predicate. When the input event fires, the partition function runs the predicate and triggers one of the two created events depending on the result of the predicate. The behavior corresponds to List.partition function.

Reactive programming Observables Let s make a program where we change the value of a label by clicking on buttons: We start by defining the Event-processing pipeline for this program: Starting from the left, Increment and Decrement are the source events. The other boxes are events created using processing functions The idea is that we take the click events and transform them such that they propagate integer values

Reactive programming Observables In code: //helper function let always x = (fun _ -> x) //event processing code let incevent = btnup.click > Observable.map (always 1) let decevent = btndown.click > Observable.map (always -1) Observable.merge incevent decevent > Observable.scan (+) 0 > Observable.add (fun sum -> lbl.text <- sprintf Count: %d sum) incevent and decevent have type IObservable<int>. They represent events carrying integers We merge two events creating an event that will be triggered when either button is pressed Because the event carries integers, we can use scan to sum the values (starting with 0). We use (+) for aggregation, meaning every click will either add +1, or -1

Reactive programming Example Let s create a program that monitors the users download folder and unpacks any new.rar files: //Monitors files in the user s Downloads folder let filewatcher = new FileSystemWatcher( Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile ), "Downloads")) //Checks if a file is archived or not let isarchived(fse:filesystemeventargs) = let archive = FileAttributes.Archive (File.GetAttributes(fse.FullPath) &&& archive) = archive //Unpacks a file using the unrar command let unpack(fse:filesystemeventargs) = let command = /c unrar e + fse.fullpath.tostring() System.Diagnostics.Process.Start("CMD.exe", command) > ignore //The programs control flow filewatcher.changed //all new files > Observable.filter isarchived //ignore those that are not archived > Observable.add unpack //unpacks them

Asynchronous workflows Asynchronous: something that is not synchronous, i.e., non-blocking IO Used to perform requests that are not completed immediately Key observation: we don t want these requests to block our current thread Instead of waiting, multiple requests can be sent and results can be handled as soon as it becomes available. Example: web crawlers

Reactive programming Asynchronous workflows When designing applications that don t react to external events, we have many constructs that makes it easy to describe what the application does: if-then-else expressions, for loops and while loops in imperative languages higher-order functions and recursion in functional languages

Reactive programming Asynchronous workflows A typical GUI program that reacts to multiple events usually involves some mutable state. Depending on the event, this state changes somehow and more code may be run as a response Difficult to understand all possible states and the transitions between them Using asynchronous workflows we can write our code in such a way that the control flow becomes visible even for reactive programs

Reactive programming Asynchronous workflows In F# we design asynchronous workflows using the async block async { some expression } and the let (bang) primitive

Common constructs used in async {... } workflow expressions Construct let pat = expr let pat = expr do expr do expr return expr Description Execute the asynchronous computation expr and bind its result to pat when it completes. If expr has type Async<'a>, then pat has type 'a. Equivalent to async.bind(expr,(fun pat ->...)). Execute an expression synchronously and bind its result to pat immediately. If expr has type 'a, then pat has type 'a. Equivalent to async.let(expr,(fun pat ->...)). Equivalent to let () = expr. Equivalent to let () = expr. Evaluate the expression, and return its value as the result of the containing asynchronous workflow. Equivalent to async.return(expr). return expr use pat = expr Execute the expression as an asynchronous computation, and return its result as the overall result of the containing asynchronous workflow. Equivalent to expr. Execute the expression immediately, and bind its result immediately. Call the Dispose method on each variable bound in the pattern when the subsequent asynchronous workflow terminates, regardless of whether it terminates normally or by an exception. Equivalent to async. Using (expr,(fun pat ->...)).

Reactive programming Asynchronous workflows Example: let form, label = new Form(...), new Label(...) let rec loop(count) = async{ let args = Async.AwaitObservable(label.MouseDown) label.text <- sprintf Clicks: %d count return loop(count + 1) } do Async.StartImmediately(loop(1)) Application.Run(form) Counting is done in a single recursive function that implements an asynchronous workflow AwaitObservable wait until the first occurrence of the given event (label.mousedown) Appears to create an infinite loop. Yet, the construction is valid as it stats by waiting for the MouseDown event

Reactive programming Asynchronous workflows Example: let form, label = new Form(...), new Label(...) let rec loop(count) = async{ let args = Async.AwaitObservable(label.MouseDown) label.text <- sprintf Clicks: %d count return loop(count + 1) } do Async.StartImmediately(loop(1)) Application.Run(form) The Async.StartImmediately primate runs the workflow on the current thread Application.Run starts the application. The current thread will be the GUI thread WARNING: Accessing Windows.Form controls from outside the GUI thread causes undefined behavior

Reactive programming Asynchronous workflows Let s see what happens when we use the StartImmediate primitive to run a workflow containing a call to some async operation GUI thread StartImmediate AsyncGetResponse (start operation) (other work) (resume workflow) background thread AsyncGetResponse (runs in background) When we run an asynchronous operation (using the let primitive), the GUI thread is free to perform other work When the workflow running on a GUI thread spends most of the time waiting for completion of an asynchronous operation, the application won t become unresponsive

Summary AwaitObservable waits for the first occurrence of an event Async workflows can yield only a single value If we want to handle multiple occurrences we can use recursion Using recursion allows us to store the current state in the function parameters

Reading guide Real World Functional Programming: With Examples in F# and C#. Petricek, T., & Skeet, J. (2009). Manning Publications Co. Chapter 16 Developing reactive functional programs Chapter 12 Sequence expressions and alternative workflows Chapter 6 Processing values using higher-order functions Chapter 7 Designing data-centric programs Chapter 4 Exploring F# and.net libraries by example Expert F 3.0 Syme, D., Granicz, A., & Cisternino, A. (2012). Berkeley: Apress. Chapter 11 Reactive, Asynchronous, and Parallel Programming Chapter 2.2 Using Object-Oriented Libraries in F# Beginning F Pickering, R., & De la Maza, M. (2009). Apress. Chapter 8 User interfaces F# for Quantitative Finance Astborg, J. (2013). Packt Publishing Ltd. Chapter 2.1 Structuring your F# program Chapter 2.5 Asynchronous and parallel programming