Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell...
Transcript of Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell...
Agenda• JSON Class Generator
• Joining the worlds
• Architecture
• In practice
• Retrospective
2
JSON Class Generator
• Mac Application
• ~15.000 lines of Haskell
• ~ 3.000* lines of Objective-C
• Mac App Store
• Web ⬇
• Sandboxed
• lifted.software
3
Demo
4
5
Recap
• Define Classes/Enums/Methods
• Export Objective-C code
• Use code to serialize/deserialize JSON
• Drop in (HTTP-)Client to connect to Service
6
How Did I Write It?
• Hardcoded types in Haskell source (2014)
• Command Line Tool (2015)
• Mac/Cocoa NSDocument based GUI App (2016)
7
Evolution
• Hardcoded types in HS source (2014)
• Command Line Tool (2015)
• Mac/Cocoa NSDocument based GUI App (2016)
8
> api --lang objc --def api.json --out ./src/api
Cutting Edge
• Hardcoded types in HS source (2014)
• Command Line Tool (2015)
• Mac/Cocoa NSDocument based GUI App (2016)
9
Joining the Worlds
10
How to Build the UI• Non-native UI
• Web
• Cross platform UI Libraries (GTK, QT)
• Native UI
• Cocoa/ObjC UI + ObjC model -> call CLT
• Cocoa/ObjC UI + HS model (together in one app)
11
Adding Some Glue• Communicate to HS via FFI
• c2hs
• Bindings (HoC, ObjectiveHaskell)
• language-c-inline
• Others (Apache Thrift)
• Client-Server (no network)12
How Do We Connect ObjC to a Server that
Speaks JSON?
13
JSON Code Generator!
14
~3000 LoC + ~13000 LoC
~16000 LoC
15
ObjC Generated
⌨ ⚙
How to Compile• Compiled languages
• Xcode, not Terminal
• Build phases
• HS to static library "-staticlib" => liba.a (ext. build tool)
• Generate API from specification file
• Compile ObjC (+Storyboards), copy asses/frameworks
• Link with liba.a libiconv
16
Compile Attempts
17
Application Launch
• Two runtimes to start
• Bound threads
• FFI
• -threaded
18
Architecture
19
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
20
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
21
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
22
Client-Server (HS)• Stores model (synchronized access)
• Serves JSON API
• No HTTP needed (server hardwired)
• Blocking calls
• No latency
• One instance per Document23
Haskell Server
24
Model• Undo Manager
• Outline View
• Encoding Callbacks
• Continuation Passing Style
• Performance (outline view, json serialization)
25
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
26
(ObjC) Client-Server• Powers service
• Serializes requests (Object -> JSONValue -> char *)
• Memory management
• Deserializes responses (NSData * -> JSONValue -> Object)
• Logs errors and exceptions
• Updates ModelRevisionCounter
27
(ObjC) Client-Server• Powers service
• Serializes requests (Object -> JSONValue -> char *)
• Memory management
• Deserializes responses (NSData * -> JSONValue -> Object)
• Logs errors and exceptions
• Updates ModelRevisionCounter
28
Memory Management• ObjC ARC
• HS GC
• Avoidance
• Request: FFI bracket
• Response: NSData allocation, ARC
• Problem: wasting memory (make model strict)29
Exception Handling
• Error reporting
• What happens if ObjC crashes?
• What happens if HS crashes?
• Problem: Lost exceptions
30
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
31
Service
32
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
33
NSDocument RAC Write
34
NSDocument RAC Read
35
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
36
User Interface
37
Server (Haskell)
Client
Service
ApiDocument : NSDocument
WindowController
Document
RAC
38
Unidirectional Data Flow
In Practice
39
Development Tools• Xcode, -debugger, for ObjC
• Haskell for Mac (Haskell.app IDE) for HS
• Sublime: for shell scrips (Haskell Shelly)
• Instruments
• Threadscope (performance), RTS opts MEM
40
Debugging
41ObjC HS
Testing
• Unit tests for ObjC and HS
• UI tests
• Server interface tests
42
Retrospective
43
Challenges
• Getting started
• Building, Setup, Architecture
• Debugging
• Persistence. All problems solvable.
44
Reflecting• Haskell Language
• Two Languages in one app
• Domain specific
• Cross platform
• Swift
• Cross platform UI Libraries45
Where to get started• Tim Scheffler's blog (1) (2) (3)
• FFI section of HS2010 report
• Dropbox CppCon2014 Cross Platform (1) (2)
• Libs: language-c-inline (talk) (github) (hackage)
• Haskell for Mac IDE
46
Questions?
47