GHood Visualising Observations of Haskell Program Runs Claus Reinke Computing Lab, University of Kent at Canterbury.

Slides:



Advertisements
Similar presentations
Introduction to Java 2 Programming
Advertisements

Introduction to Java 2 Programming
Purdue University Center for Education and Research in Information Assurance and Security Building a distributed intrusion detection system with Perl Diego.
Lecture 22, Revision 1 Lecture notes Java code – CodeFromLectures folder* Example class sheets – 4 of these plus solutions Extra examples (quicksort) Lab.
Agenda Definitions Evolution of Programming Languages and Personal Computers The C Language.
Programming Logic and Design Fourth Edition, Introductory
Feature requests for Case Manager By Spar Nord Bank A/S IBM Insight 2014 Spar Nord Bank A/S1.
1 Frameworks. 2 Framework Set of cooperating classes/interfaces –Structure essential mechanisms of a problem domain –Programmer can extend framework classes,
DAST, Spring © L. Joskowicz 1 Data Structures – LECTURE 1 Introduction Motivation: algorithms and abstract data types Easy problems, hard problems.
Discrete-Event Simulation: A First Course Steve Park and Larry Leemis College of William and Mary.
© 2005 Prentice Hall12-1 Stumpf and Teague Object-Oriented Systems Analysis and Design with UML.
Computers: Tools for an Information Age
Semantics with Applications Mooly Sagiv Schrirber html:// Textbooks:Winskel The.
© Copyright Eliyahu Brutman Programming Techniques Course.
WebDynpro for ABAP Short introduction.
The Basic Tools Presented by: Robert E., & Jonathan Chase.
Chapter 2: Algorithm Discovery and Design
DAST, Spring © L. Joskowicz 1 Data Structures – LECTURE 1 Introduction Motivation: algorithms and abstract data types Easy problems, hard problems.
1 An Introduction to Visual Basic Objectives Explain the history of programming languages Define the terminology used in object-oriented programming.
1 An introduction to design patterns Based on material produced by John Vlissides and Douglas C. Schmidt.
Abstraction: Polymorphism, pt. 1 Abstracting Objects.
1 CS101 Introduction to Computing Lecture 19 Programming Languages.
Microsoft Visual Basic 2012 CHAPTER ONE Introduction to Visual Basic 2012 Programming.
Bret Juliano. Introduction What Documentation is Required? – To use a program – To believe a program – To modify a program The Flow-Chart Curse Self-Documenting.
JAVA: An Introduction to Problem Solving & Programming, 5 th Ed. By Walter Savitch and Frank Carrano. ISBN © 2008 Pearson Education, Inc., Upper.
Epydoc API Documentation Extraction in Python Edward Loper.
Microsoft Visual Basic 2005: Reloaded Second Edition
GENERAL CONCEPTS OF OOPS INTRODUCTION With rapidly changing world and highly competitive and versatile nature of industry, the operations are becoming.
CSC 142 O 1 CSC 142 Java More About Inheritance & Interfaces [Reading: chapter 13]
J-OCM is a system for monitoring distributed Java applications conforming to OMIS specification with J-OMIS extensions. It is used to: gather information.
Putting together a complete system Chapter 10. Overview  Design a modest but complete system  A collection of objects work together to solve a problem.
OOP with PHP Roman Bednarik
Introduction Algorithms and Conventions The design and analysis of algorithms is the core subject matter of Computer Science. Given a problem, we want.
Stephen P. Carl - CS 2421 Recursion Reading : Chapter 4.
Method Overriding Remember inheritance: when a child class inherits methods, variables, etc from a parent class. Example: public class Dictionary extends.
Ex3 Preview, Swing tutorial Ex1 review Amit Shabtay.
WEB BASED DATA TRANSFORMATION USING XML, JAVA Group members: Darius Balarashti & Matt Smith.
SE: CHAPTER 7 Writing The Program
MD – Object Model Domain eSales Checker Presentation Régis Elling 26 th October 2005.
Introduction to Software Development. Systems Life Cycle Analysis  Collect and examine data  Analyze current system and data flow Design  Plan your.
Chapter 8 Object Design Reuse and Patterns. Object Design Object design is the process of adding details to the requirements analysis and making implementation.
Design.ppt1 Top-down designs: 1. Define the Problem IPO 2. Identify tasks, Modularize 3. Use structure chart 4. Pseudocode for Mainline 5. Construct pseudocode.
Elucidative Programming Kurt Nørmark Aalborg University Denmark SIGDOC September 2000.
Data Tree a = E | N (Tree a) a (Tree a) deriving (Show) task :: Integer -> [Tree Integer] -> Tree b -> (Integer,[Tree Integer],[Tree b],Tree Integer) task.
Intro to Applets. Applet Applets run within the Web browser environment Applets bring dynamic interaction and live animation to an otherwise static HTML.
Preliminary Ocean Project Page 1 WGISS SG May 15, C. Caspar G. Tandurella P. Goncalves G. Fallourd I. Petiteville Preliminary Ocean Project Phase.
Computer Science Projects Internal Assessment. Mastery Item Claimed Justification Where Listed Random Access File – Searching Lines P. 53 Random.
Week 04 Object Oriented Analysis and Designing. What is a model? A model is quicker and easier to build A model can be used in simulations, to learn more.
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
1 An infrastructure for context-awareness based on first order logic 송지수 ISI LAB.
JAVA: An Introduction to Problem Solving & Programming, 6 th Ed. By Walter Savitch ISBN © 2012 Pearson Education, Inc., Upper Saddle River,
JavaScript Introduction and Background. 2 Web languages Three formal languages HTML JavaScript CSS Three different tasks Document description Client-side.
Ada, Scheme, R Emory Wingard. Ada History Department of Defense in search of high level language around Requirements drafted for the language.
Lecture #1: Introduction to Algorithms and Problem Solving Dr. Hmood Al-Dossari King Saud University Department of Computer Science 6 February 2012.
Visual Basic.NET Comprehensive Concepts and Techniques Chapter 1 An Introduction to Visual Basic.NET and Program Design.
CSE 143 Lecture 9: introduction to recursion reading: 12.1.
PROGRAMMING (1) LECTURE # 1 Programming and Languages: Telling the Computer What to Do.
Progranimate an Introduction. What is Progranimate Progranimate is a programming environment designed specifically for novices Progranimate allows the.
More About Objects and Methods
Agenda Preliminaries Motivation and Research questions Exploring GLL
CSCI-235 Micro-Computer Applications
Introduction to Visual Basic 2008 Programming
Unified Modeling Language
Behavioral Design Patterns
Debugging Haskell by Observing Intermediate Data Structures
Patterns.
Dynamic Data Structures and Generics
An Introduction to Software Architecture
Dynamic Data Structures and Generics
Presentation transcript:

GHood Visualising Observations of Haskell Program Runs Claus Reinke Computing Lab, University of Kent at Canterbury

data Tree a = E | N (Tree a) a (Tree a) deriving (Show) task n ~rs E = (n,rs,[],E) task n ~(r':l':rs) (N l x r) = (n+1,rs,[l,r],N l' n r') taskM n [] = [] taskM n (t:ts) = rs'++[t'] where (n',rs',tp',t') = task n ts' t ts' = taskM n' (ts++tp') bfnum t = head $ taskM 1 [t] The problem: program comprehension What does this program do? hey, this is functional, it should be obvious... The comments, read the comments!.. Use the source, Luke! data Tree a = E | N (Tree a) a (Tree a) deriving (Show) task :: Integer -> [Tree Integer] -> Tree b -> (Integer, [Tree Integer], [Tree b], Tree Integer) task n ~rs E = (n,rs,[],E) task n ~(r':l':rs) (N l x r) = (n+1,rs,[l,r],N l' n r') taskM :: Integer -> [Tree b] -> [Tree Integer] taskM n [] = [] taskM n (t:ts) = rs'++[t'] where (n',rs',tp',t') = task n ts' t ts' = taskM n' (ts++tp') bfnum :: Tree a -> Tree Integer bfnum t = head $ taskM 1 [t] Check the types someTree = N (N (N E 0 E) 1 (N E 0 E)) 2 (N (N E 0 E) 1 (N E 0 E)) main = print $ bfnum someTree Find type inhabitants, apply program, and print what is going on Tool support for..but what if we need to observe programs in existing contexts? context supplies type inhabitants,might not permit printing

import Observe instance Observable a => Observable (Tree a) where observer E = send "E" (return E) observer E = send "E" (return E) observer (N l x r) = send "N" (return N << l << x << r) observer (N l x r) = send "N" (return N << l << x << r) data Tree a = E | N (Tree a) a (Tree a) deriving (Show) task :: Integer -> [Tree Integer] -> Tree b -> (Integer, [Tree Integer], [Tree b], Tree Integer) task n ~rs E = (n,rs,[],E) task n ~(r':l':rs) (N l x r) = (n+1,rs,[l,r],N l' n r') taskM :: Integer -> [Tree b] -> [Tree Integer] taskM n [] = [] taskM n (t:ts) = rs'++[t'] where (n',rs',tp',t') = task n ts' t ts' = taskM n' (ts++tp') bfnum :: Tree a -> Tree Integer bfnum t = head $ taskM 1 [t] someTree = N (N (N E 0 E) 1 (N E 0 E)) 2 (N (N E 0 E) 1 (N E 0 E)) runO $ main = runO $ print $ observe “after” $$ observe “before” $ observe “after” $ bfnum $ observe “before” $ someTree.. use Hood and observe

What does observe give you? with "plain" Hood: –static views of intermediate structures in your computation –works even where you could not easily print them –pre-defined instances of Observable for most standard types –combinators make it easy to define instances for your own types –information is not thrown out "at random" but is collected and pretty-printed at the end of the run –observation does not change strictness properties: you only see what is actually inspected by your program

Instrumented program output Main> main N (N (N E 0 E) 1 (N E 0 E)) 2 (N (N E 0 E) 1 (N E 0 E)) N (N (N E 4 E) 2 (N E 5 E)) 1 (N (N E 6 E) 3 (N E 7 E)) -- after N (N (N E 4 E) 2 (N E 5 E)) 1 (N (N E 6 E) 3 (N E 7 E)) -- before N (N (N E _ E) _ (N E _ E)) _ (N (N E _ E) _ (N E _ E))

What does observe give you? with GHood, you get all the goods of Hood, plus: –static and dynamic views of intermediate structures by animated graphical visualisation of observations –you can see the order in which observations are made (even differences between Haskell implementations), without losing the structured presentation –by animating two observations side-by-side, the relative order of observations can give you insights into data dependencies and strictness-properties –the animations can also be used separately from programs and Haskell implementations, to document and explain program behaviour on web pages (see GHood homepage; URL in paper) Hood/GHood demo (introduction)

How does it all work? just a quick tour, with two stops: from trace to observe, via unsafePerformIO –unsafePerformIO generalises trace –observe can be seen as a much improved trace –unsafePerformIO as an extension hook from Hood to GHood, via more hooks

Problems with trace trace:: String -> a -> a trace s a = unsafePerformIO $ hPutStr stderr s >> return a  no connection between s and a, no information apart from s (calling context has to supply information via s ), evaluation of s could force evaluation of a, or other traces.. traceShow:: Show a => String -> a -> a traceShow s a = -- trace (s++show a) a unsafePerformIO $ do hPutStr stderr (s++show a) return a  generic show solves first problems, but is strict in a !! order of output can still be hard to predict and messed up.. How does it work?

Pseudo-code for observe class Observable a where observer:: a -> Parent -> a merge generic inspection into observation, so that inspection can be limited to preserve strictness, then replace show functionality with less intrusive code observe::Observable a => String-> a-> a observe s a = unsafePerformIO $ do parent <- init s a return $ observer a parent store partial observations out of the way, and preserve links between fragments; observe initialises, details are handled in an observation monad, and observer [] = send "[]" (return []) observer definitions guide the process How does it work?

Hood How does it work? Instrumented Haskell program Instrumented Haskell implementation Observe.lhs: Generic inspection Handling stream of partial observations Interpretation of observation event stream & pretty-printing observe, runOObservable eval unsafePerformIO

Observe.lhs: Generic inspection Handling stream of partial observations Observation event stream output Interpretation of observation event stream & pretty-printing Instrumented Haskell program Instrumented Haskell implementation observe, runOObservable eval unsafePerformIO GHood How does it work? ObserveEvents.log GHood Viewer (Java) Interpretation of event log Animation of tree layout GUI handling

A closer look at the example or: finding problems with solutions to Okasaki's breadth-first tree numbering exercise GHood demo: task-based solution, second version (reversed solution list for nicer code) GHood demo: task-based solution, original version GHood demo: task-based solution, third version (gets structure and label via separate paths) The problem (informally): label the nodes in a binary tree with natural numbers, in breadth-first order

Task1 task n ~[] E = (n,[],E) task n ~[l',r'] (N l x r) = (n+1,[l,r],N l' n r') taskM n [] = [] taskM n (t:ts) = t':rs' where (n',tp',t') = task n r t ts' = taskM n' (ts++tp') (rs',r) = splitAt (length ts) ts' bfnum t = head $ taskM 1 [t]

task n ~rs E = (n,rs,[],E) task n ~(r':l':rs) (N l x r) = (n+1,rs,[l,r],N l' n r') taskM n [] = [] taskM n (t:ts) = rs'++[t'] where (n',rs',tp',t') = task n ts' t ts' = taskM n' (ts++tp') bfnum t = head $ taskM 1 [t] Task2

Task1new task n ~[] E = (n,[],E) task n ~[l',r'] (N l x r) = (n+1,[l,r],N l' n r') taskM n [] = [] taskM n (t:ts) = t':rs' where (n',tp',t') = task n r t ts' = taskM n' (ts++tp') (rs',r) = splitAt (length ts) ts' bfnum t = fillIn t $ head $ taskM 1 [t] fillIn E ~E = E fillIn (N l _ r) ~(N l' x' r') = N (fillIn l l') x' (fillIn r r')

Evaluation seeing intermediate structures is useful, as expected surprisingly, seeing what is not used is just as useful new with Ghood: seeing when which parts are observed –the good old uses, but with more precise information –dynamic data dependencies become visible –graphical animation is a win for medium to large sizes animating observations is no substitute for animating reductions (in both senses) –only indirect insights into program behaviour, but less cluttered visualisation to begin with –more control over visualisation, including observation at different levels of abstraction

Conclusions Understanding operational program aspects is important program = declarative + operational aspects Animated visualisation of observations is a useful tool Visualising observations  visualising reductions; ideally, both should be part of the programmer's toolbox Other lessons learned: The advantages of compositionality extend beyond Haskell programs, to Haskell implementations and tools. Extending implementations with portable tool components depends on standard implementation extension interfaces (aka extension hooks).

Olde rule of thumb: "get it right before making it faster" Declarative/Functional programming: –Focus on description of data and algorithms relevant to problem and solution domains –Decompose complex problems into simpler ones, and compose complex solutions from simpler ones Not optimal in terms of resource usage, but automatically complementing concise declarative specifications with default operational aspects has proven successful But what happens after "we got it right"? –Resource usage may become important –Imperative programmers had to focus on that anyway  Modular/aspect-oriented programming:  specify both declarative and operational aspects,  combine separate aspects to get complete program