SLIDE 1
Programming Languages F28PL,Introductory Lecture 1 st Semester - - PowerPoint PPT Presentation
Programming Languages F28PL,Introductory Lecture 1 st Semester - - PowerPoint PPT Presentation
Programming Languages F28PL,Introductory Lecture 1 st Semester 2019/20 1 / 38 Programming Languages F28PL Languages OCaml (functional), weeks 1-4 Python (scripting), weeks 6-9 Prolog (logic), weeks 10-11 Lectures
SLIDE 2
SLIDE 3
F28PL Programming Languages course starts next lecture (Thursday morning). This introductory lecture: ◮ Property based tests ◮ Running OCaml code ◮ GitLab setup for this course ◮ Using git at command line
3 / 38
SLIDE 4
Unit Testing
◮ In SD3 we used unit tests to check implementations
assertEquals(12, add(10, 2), "10 + 2 is 12"); ◮ code under test: add method ◮ inputs: 10 and 2 ◮ expected result: 12
◮ validates if code results in the expected output ◮ checks piece of code is correct More tests:
assertEquals(0, add(0, 0), "0 + 0 is 0"); assertEquals(2, add(2, 0), "2 + 0 is 2"); ...
◮ Time consuming to write many tests ◮ How many unit tests until we have confidence in add(..)?
4 / 38
SLIDE 5
Declaring Properties of Code
◮ “Any number N added to 0 is N” ◮ “Any number N multiplied by 0 is 0” ◮ “Reversing a list then reversing it again returns the original list” ◮ “Multiplying an even number by 2 returns an even number” ◮ “After sorting an integer list the smallest value is the 1st element of the returned list” ◮ “After performing upheap on a binary tree the smallest value is the root of the tree” (priority queues from SD3) ◮ “After adding N unique words to a trie there are N words in the trie” (from SD3) QuickCheck is a framework that generates tests for these properties. Then runs the tests to find counterexamples.
5 / 38
SLIDE 6
Property Testing with OCaml
(* adding a list to an empty list returns empty list e.g. seqadd [1;2;3] [] = [] *) let seqadd_empty1 = QCheck.Test.make ~name:"seqadd_empty1" ~count:10000 QCheck.(make integer_sequence_gen) (fun list1 -> seqadd list1 [] = []);;
◮ Generator: integer_sequence_gen generates integer lists ◮ Generator bound to the list1 variable ◮ Property: seqadd list1 [] = [] QuickCheck will generate lots of tests:
seqadd [1;5;4;...] [] = [] seqadd [9;2;8;... [] = [] seqadd [8;8;3;... [] = []
6 / 38
SLIDE 7
Generators for test inputs
OCaml qcheck library has generators:
val small_nat : int arbitrary val int_range : int -> int -> int arbitrary val pos_float : float arbitrary val bool : bool arbitrary val char : char arbitrary val string_gen_of_size : int Gen.t -> char Gen.t -> string arbitrary val list : 'a arbitrary -> 'a list arbitrary val pair : 'a arbitrary -> 'b arbitrary -> ('a * 'b) arbitrary val oneof : 'a arbitrary list -> 'a arbitrary ...
OCaml’s QuickCheck API:
https://c-cube.github.io/qcheck/0.9/qcheck-core/QCheck/ https://c-cube.github.io/qcheck/0.9/qcheck-core/QCheck/Gen/
7 / 38
SLIDE 8
Generators for test inputs
User defined OCaml generators:
(* integer sequence generator of 100 elements *) let integer_sequence_gen = QCheck.Gen.(list_size (return 100) nat);; (* zeros sequence generator of 100 elements *) let zeros_gen = QCheck.Gen.(list_size (return 100) (return 0));; (* from the OCaml coursework *) type complex_number = CI of int*int;; (* complex number generator *) let complex_number_gen = (QCheck.Gen.map (fun (x,y) -> CI (x,y)) QCheck.Gen.(pair small_nat small_nat));;
8 / 38
SLIDE 9
Property Testing with OCaml
(* adding 0 to each element in a sequence result in the same sequence, and hence the input sequence should be the same as the output sequence e.g. seqadd [1;2;3] [0;0;0] => [1;2;3] *) let seqadd_zeros = QCheck.Test.make ~name:"seqadd_zeros" ~count:1000 QCheck.(make ~print:show_sequence (Gen.pair integer_sequence_gen zeros_gen)) (fun (seq,zeros) -> seqadd seq zeros = seq);;
9 / 38
SLIDE 10
Property Testing with OCaml
◮ seqmult multiplies every list element by a constant ◮ sum sums up all elements in a list Property: “for all integer lists, if we multiply every element by 0 then sum the resulting list is zero”.
let seqmult_zeros = let sum = List.fold_left (+) 0 in QCheck.Test.make ~name:"seqmult_zeros" ~count:1000 QCheck.(make ~print:show_sequence (Gen.pair integer_sequence_gen zeros_gen)) (fun (seq,zeros) -> sum (seqmult seq zeros) = 0);;
10 / 38
SLIDE 11
Property Testing with OCaml
Property: “For all lists of generated integer lists, bubble sort and quick sort functions output the same list”
let bubble_quick_equiv = QCheck.Test.make ~name:"bubble_quick_equiv" ~count:100 QCheck.(make (Gen.list Gen.small_nat)) (fun xs -> bubble_sort xs = quick_sort xs);;
◮ xs comes from (Gen.list Gen.small_nat) ◮ 100 tests generated ◮ Property: bubble_sort xs = quick_sort xs
11 / 38
SLIDE 12
Property Testing and Functional Programming
◮ Unit testing common for imperative and object oriented languages ◮ Property based testing almost exclusive to functional languages ◮ Why? In (pure) functional languages, the output of a function is exclusively determined by its input values. Quick Check property testing frameworks generate and run 100s/1000s/millions of tests. Imperative/OO languages have global/hidden state: calling the same function/method twice might return a different result. A unit test is ran only once.
12 / 38
SLIDE 13
Running OCaml
Interpreter (ocaml): Read–eval–print loop (REPL) ◮ run functions with different inputs ◮ ask what type values/functions have ◮ slower performance
> ocaml OCaml version 4.05.0 # #use "ocaml_part1.ml" ;;
13 / 38
SLIDE 14
Running OCaml
Compiler (ocamlc): compile to native code ◮ can’t test functions interactively ◮ code is optimised ◮ fast performance OCaml file has a main function:
let main = print_int (add 2 3) ;;
Compile it:
> ocamlc -o part1 ocaml_part1.m > ./part1 5
14 / 38
SLIDE 15
◮ Text editors
◮ Emacs
◮ Tuareg mode: https://github.com/ocaml/tuareg
◮ Vim
◮ Merlin: https://github.com/ocaml/merlin
◮ gedit ◮ VSCode
◮ vscode-reasonml: https:
//github.com/reasonml-editor/vscode-reasonml
◮ Compilers
◮ ocamlc
◮ Interpreters
◮ ocaml ◮ utop
◮ improved ocaml: line editing, history, real-time and context sensitive completion, colors. ◮ opam install dune ◮ https://github.com/ocaml-community/utop 15 / 38
SLIDE 16
Structure of Ocaml projects
◮ lib directory for implementation ◮ test directory for tests
- lib
|-> SequenceArithmetic.ml
- > dune
- test
|-> SequenceArithmeticTests.ml
- > dune
- dune-project
https://gitlab-student.macs.hw.ac.uk/f28pl-2019-20/ f28pl-2019-20-ocaml-coursework/tree/master/ sequence-arithmetic
16 / 38
SLIDE 17
Test files
◮ Ocaml coursework has unit tests and property based tests Unit tests:
(* test seqadd on two non-empty lists *) let seqadd_test2 _test_ctxt = assert_equal [7;5;6] (seqadd [2;3;5] [5;2;1]);;
Property tests:
(* adding an integer list to list of 0's should return the list e.g. seqadd [1;2;3] [0;0;0] => [1;2;3] *) let seqadd_zeros = QCheck.Test.make ~name:"seqadd_zeros" ~count:1000 QCheck.(make ~print:show_sequence (Gen.pair integer_sequence_gen zeros_gen)) (fun (seq,zeros) -> seqadd seq zeros = seq);;
17 / 38
SLIDE 18
Running OCaml Tests
> cd sequence-arithmetic/ > dune clean > dune runtest --profile release ... Ran: 12 tests in: 0.11 seconds. FAILED: Cases: 12 Tried: 12 Errors: 5 Failures: 7 Skip: 0 Todo: 0 Timeouts: 0.
Test driven development.. the goal:
Ran: 12 tests in: 2.28 seconds. OK
18 / 38
SLIDE 19
GitLab for F28PL
https://gitlab-student.macs.hw.ac.uk/f28pl-2019-20
19 / 38
SLIDE 20
Versioning metadata
◮ Who made changes?
◮ e.g. Rob Stewart R.Stewart@hw.ac.uk
◮ What files did they change?
◮ e.g. lib/arithmetic.ml
◮ Where in the file did they make the change?
◮ e.g. line 287 of lib/server.ml
◮ When did they make the change?
◮ e.g. 11:04, Friday 19th October 2018.
◮ Why did they make a change?
◮ e.g. to fix single-sign-on login
◮ Who is affected by the change?
◮ e.g. Paul to add login property based tests
20 / 38
SLIDE 21
Visualising git History
◮ GitLab website (click “N commmits” for history) ◮ git gui (gitk command)
21 / 38
SLIDE 22
Fork repository
22 / 38
SLIDE 23
Clone your fork
23 / 38
SLIDE 24
24 / 38
SLIDE 25
25 / 38
SLIDE 26
Check status
(Note: these slides are adapted from 3rd year course.)
$ git status On branch master nothing to commit, working directory clean
26 / 38
SLIDE 27
$ vim README $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)
27 / 38
SLIDE 28
Track new files
$ git add README $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README
28 / 38
SLIDE 29
Staging modified files
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: benchmarks.rb
29 / 38
SLIDE 30
Staging modified files
$ git add benchmarks.rb $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: benchmarks.rb
30 / 38
SLIDE 31
Committing files
$ git commit
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: # new file: README # modified: benchmarks.rb # ~ ".git/COMMIT_EDITMSG" 10L, 283C
31 / 38
SLIDE 32
Committing files
$ git commit
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: # new file: README # modified: benchmarks.rb # ~ ".git/COMMIT_EDITMSG" 10L, 283C
$ git commit -m "Story 182: Fix benchmarks for speed" [master 463dc4f] Story 182: Fix benchmarks for speed 2 files changed, 3 insertions(+) create mode 100644 README
31 / 38
SLIDE 33
History
$ git log --stat commit a11bef06a3f659402fe7563abf99ad00de2209e6 Author: Scott Chacon <schaconat at gmail.com> Date: Sat Mar 15 10:31:28 2008 -0700 first commit README | 6 ++++++ Rakefile | 23 +++++++++++++++++++++++ lib/simplegit.rb | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+)
32 / 38
SLIDE 34
History
$ git log commit ca82a6dff817ec66f44342007202690a93763949 Author: Scott Chacon <schaconat at gmail.com> Date: Mon Mar 17 21:52:11 2008 -0700 changed the version number commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Author: Scott Chacon <schaconat at gmail.com> Date: Sat Mar 15 16:40:33 2008 -0700 removed unnecessary test code commit a11bef06a3f659402fe7563abf99ad00de2209e6 Author: Scott Chacon <schaconat at gmail.com> Date: Sat Mar 15 10:31:28 2008 -0700 first commit
33 / 38
SLIDE 35
Pushing commits to GitLab
$ git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 4 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 391 bytes | 391.00 KiB/s, done. Total 4 (delta 2), reused 0 (delta 0) To gitlab-student.macs.hw.ac.uk:rs46/f28pl-2019-20-ocaml-demo.git 0453913..90a7d97 master -> master
This will trigger the GitLab server to test your code.
34 / 38
SLIDE 36
Automated testing with GitLab
Every time you push commits to GitLab, it runs all tests. Starts with: Aiming for:
35 / 38
SLIDE 37
Demonstration
Demo of Ocaml, automated testing and GitLab:
https://gitlab-student.macs.hw.ac.uk/f28pl-2019-20/ f28pl-2019-20-ocaml-demo
36 / 38
SLIDE 38
Learning Materials
◮ Vision
◮ coursework sheets ◮ lecture slides ◮ GitLab and git videos
◮ GitLab
◮ starter code for living coding in lectures ◮ coursework starter code
37 / 38
SLIDE 39
Actions for students
- 1. Register with the university’s GitLab server
- 2. Fork Ocaml repositories in the F28PL group:
◮ f28pl-2019-20-ocaml-coursework ◮ f28pl-2019-20-ocaml-lectures
- 3. Choose your preferred tooling
◮ git tooling: command line, or integrated into text editor ◮ text editors: Emacs, VSCode, gedit, Vim, ... ◮ interpreter/compiler: utop or ocaml
- 4. Read the git book: https://git-scm.com/book
- 5. Watch GitLab tutorial videos on Vision
- 6. Read the coursework crib sheet for running Ocaml tests (Vision)
- 7. Take a look at OCaml coursework sheet (on Vision soon)
- caml and ocamlc tools available in EM 2.50 lab.