concepts of higher programming languages chapter 11
play

Concepts of Higher Programming Languages Chapter 11: Random Numbers - PowerPoint PPT Presentation

Concepts of Higher Programming Languages Chapter 11: Random Numbers Jonathan Thaler Department of Computer Science 1 / 22 Introduction What is the first random number? 2 / 22 Introduction 3 / 22 Introduction 4 / 22 Introduction 5 / 22


  1. Concepts of Higher Programming Languages Chapter 11: Random Numbers Jonathan Thaler Department of Computer Science 1 / 22

  2. Introduction What is the first random number? 2 / 22

  3. Introduction 3 / 22

  4. Introduction 4 / 22

  5. Introduction 5 / 22

  6. Introduction 6 / 22

  7. Random Numbers in Java Random Numbers according to Java public class RandomProgram { public static void main(String[] args) { System.out.println(Math.random()); System.out.println(Math.random()); } } > java RandomProgram 0.3233645386970013 0.9529055748819252 > java RandomProgram 0.4004700712486171 0.3830534574335537 7 / 22

  8. Random Numbers in Java Random Numbers according to Java public class RandomProgram { public static void main(String[] args) { Random rng = new Random(); System.out.println(rng.nextInt()); System.out.println(rng.nextInt()); } } > java RandomProgram -1386140383 911372902 > java RandomProgram 1010768865 1040616881 8 / 22

  9. Random Numbers in Java Random Numbers according to Java public class RandomProgram { public static void main(String[] args) { Random rng = new Random(42); System.out.println(rng.nextInt()); System.out.println(rng.nextInt()); } } > java RandomProgram -1170105035 234785527 > java RandomProgram -1170105035 234785527 9 / 22

  10. Random Numbers in Java We can make the following observations: 1. Repeatedly calling Math.random() results in different values (also across repeated runs of the program). 2. Repeatedly calling Random.nextInt() , initialised with the standard constructor results in different values (also across repeated runs of the program). 3. Repeatedly calling Random.nextInt() , which was initialised with a fixed seed results in different values however not across repeated runs of the program. The behaviour of drawing random numbers seems to be sensitive to the history of the system - there seems to be some side effects involved! 10 / 22

  11. Side Effects Side Effects A side effect is an observable effect which happens in a computation besides computing the result. When a computation exhibits observable effects besides computing a result, then we talk about side effects of a computation. Drawing random numbers obviously has observable side effects: we will not get the same value twice even if we call the function twice with the same argument (no argument that is). When we fix the initial seed , we still get a different value each time we call the ”next” random number but we will observe the same random number sequence across repeated runs of the program. This is by design as it reflects the very nature of random numbers! 11 / 22

  12. Side Effects There seems to exist a context in the program in which the ”drawing random number” side effect is happening but this context seems to be hidden from the programmer. This ”context” is the seed of the random number generator which completely determines the random number sequence. If no seed is specified generally the current system time is used as seed. In general, a random number generator uses the seed in a complicated computation to generate the ”next” value. During this computation, also the seed is updated (an observable effect), therefore when repeatedly calling the generator the result is a different random number. This is obviously trivial in Java OOP where we use a private member for the seed and simply mutate it by destructive variable assignment. 12 / 22

  13. Random Numbers in Haskell What about Haskell? 13 / 22

  14. Random Numbers in Haskell Side Effects in Haskell Haskell is a pure functional programming language. Pure means that functions are generally referential transparent , that is they do not depend on the history of the program. A pure function will always return the same result given the same input. We can replace the computation of a pure function directly with their result, making the actual evaluation obsolete. This means there is no way you can mutate global state, or a variable in Haskell, access files, access references,... in a pure function in Haskell. There are also impure functions in Haskell, which will be covered in the Chapters on Monads. 14 / 22

  15. Random Numbers in Haskell 15 / 22

  16. Random Numbers in Haskell Random Numbers in Haskell Random Numbers in Haskell are implemented by explicitly threading the seed through all functions call. The seed acts as a kind of an explicit state , tied to a specific random-number generator implementation. By making the seed (the state) explicit and require to pass it in and out of a function call, it is possible to update the seed (the state) after having generated the next random number. 16 / 22

  17. Random Numbers in Haskell Random Numbers in Haskell class RandomGen g where genRange :: g -> (Int, Int) next :: g -> (Int, g) split :: g -> (g, g) data StdGen = ... -- Abstract instance RandomGen StdGen where ... mkStdGen :: Int -> StdGen 17 / 22

  18. Random Numbers in Haskell Random Numbers in Haskell > import System.Random > let g = mkStdGen 42 > g 43 1 > next g (1679910,1720602 40692) > next g (1679910,1720602 40692) > let (r, g') = next g > r 1679910 > g' 1720602 40692 > next g' (620339110,128694412 1655838864) > next g' (620339110,128694412 1655838864) 18 / 22

  19. Random Numbers in Haskell Random Numbers in Haskell class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) random :: RandomGen g => g -> (a, g) randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... 19 / 22

  20. Random Numbers in Haskell Random Numbers in Haskell > import System.Random > let g = mkStdGen 42 > randomR (1,100) g (10,1720602 40692) > randomR (1,100) g (10,1720602 40692) > fst (random g) -3900021226967401631 > randomRs (1,100) g [10,10,56,53,55,30,57,10,97,14,... > randoms g [-3900021226967401631,6115732954341747105,-7802898033696815382,... 20 / 22

  21. Random Numbers in Haskell Random Numbers in Haskell import System.Random sumOfThreeRolls :: RandomGen g => (Int, Int) -> g -> (Int, g) sumOfThreeRolls r g = (r1+r2+r3, g2) where (r1, g0) = randomR r g (r2, g1) = randomR r g0 (r3, g2) = randomR r g1 > fst (sumOfThreeRolls (1,10) (mkStdGen 42)) 26 > fst (sumOfThreeRolls (1,10) (mkStdGen 42)) 26 > fst (sumOfThreeRolls (1,10) (mkStdGen 0)) 12 21 / 22

  22. Exercises (1) Reproduce slides 18, 20, 21. (2) Write a function sumRand that runs functions like sumOfThreeRolls for n times and sums up the result. Think carefully about the type (HINT: use foldr). The following should hold: > sumOfThreeRolls (1,6) (mkStdGen 42) (12,2060101257 2103410263) > sumRand 1 (1,6) (mkStdGen 42) sumOfThreeRolls (12,2060101257 2103410263) > sumRand 3 (1,6) (mkStdGen 42) randomR (12,2060101257 2103410263) 22 / 22

Recommend


More recommend