Skip to main content

Progressive .NET Tutorials 2015: Phil Trelfords "Ready, steady, cross platform games on your phone"

It's been a while since I have been back from Progressive.Net but I thought I had better do a quick write up of the conference and my favourite talks.

This year I went down with a large contingent. A combination of the North 51  team and the Unidays team. There were 7 of us in total. We had a fantastic time. The program leaned quite heavily towards F# this year which was excellent for me. https://skillsmatter.com/conferences/6859-progressive-dotnet-2015#program.

There were quite a few talks I wanted to mention and my free time is exceptionally limited at the moment, so I thought I would break the talks up into separate blog posts.

Phil Trelfords "Ready, steady, cross platform games on your phone" 

This talk centered around game development. He gave some good advice on what was probably the area you were best to concentrate on, this meant that you should look to script on top of a framework / engine that already exists as opposed to trying to write everything from scratch. I tend to agree with this! I got some pleasing results from the examples and the talk given the time we had and also found a really neat piece of functionality in http://www.fssnip.net/ that I had neglected to notice before. You can include Nuget package sources in the snippets. This gets round a really annoying problem I normally face when sharing F# snippets that rely on packages. I have a tendency to just list the dependencies or make an example F# console app and attach the packages.config file (which is just a pain). Anyway, I have added link to the fssnip CSS and JS and my example below is an embedded example so I will see how it goes for now instead of using gist (I could just link to the snippet I guess but I like the code on the site). 

It's always difficult on these talks as there tends to be a reasonable amount in the room that have no experience in F# so part of the talk can be taken up with that. That said, Phil had foreseen this and had a preperation task. He had a version available for us to use that could work on just about every platform going.

This was my initial guess game (the pre flappy bird example). This really reminds me of little games I used to make when I was younger in Pascal. I also use this game as an example when teaching people how to code. I used it as an example (albeit in C#) with my wife but we expanded on it to have an online high scores table and various other bits of functionality.  


Another important point Phil had talked about when creating little games (and this really applies to traditional enterprise devs) is to just relax and have fun. Don't get caught up in writing perfect solid code. Just get back to the time when producing something was the thing you loved not creating perfect code. Some didn't listen and one persons example contained classes upon classes of bananas F# types with members and factories and all sorts of silly things, just to produce a little guessing game. I noticed a bit of this at the recent Hack24 event I attended too. People obsessing over service layers and repositories and factories and dependency injection. To me, that's against the spirit of a hack event and you also just waste endless amounts of time. The code you write is throw away stuff. Just get on with it.

Available on fssnip http://www.fssnip.net/rI

 1: open System
 2: open System.IO
 3: 
 4: // _____ _   _ _____ _____ _____  ______  _  _   _____  _____ _     
 5: //|  __ \ | | |  ___/  ___/  ___| |  ___|| || |_|  _  ||  _  | |    
 6: //| |  \/ | | | |__ \ `--.\ `--.  | |_ |_  __  _| | | || | | | |    
 7: //| | __| | | |  __| `--. \`--. \ |  _| _| || |_| | | || | | | |    
 8: //| |_\ \ |_| | |___/\__/ /\__/ / | |  |_  __  _\ \_/ /\ \_/ / |____
 9: // \____/\___/\____/\____/\____/  \_|    |_||_|  \___/  \___/\_____/
10: //                                                                  
11: //                                                                  
12: 
13: let game() = 
14:     let mutable notFound = true
15: 
16:     let fivetimestable = 
17:         seq { for i in 5 .. 5 .. 100 do yield i }
18: 
19:     let random = new Random(System.DateTime.Now.Millisecond)
20:     let next = random.Next(10)
21:     let ans = (Seq.nth next fivetimestable)
22: 
23:     Console.WriteLine("What's your name?")
24:     let name = Console.ReadLine()
25:     Console.WriteLine("Guess!")
26: 
27:     let mutable goes = 1
28: 
29:     let stopWatch = new System.Diagnostics.Stopwatch()
30:     stopWatch.Start() |> ignore
31: 
32:     while notFound do
33:         let guess = System.Int32.Parse(System.Console.ReadLine())
34:         if ans.Equals(guess) then
35:             notFound <- false
36:             stopWatch.Stop() |> ignore
37:         else 
38:             goes <- goes + 1
39: 
40:     Console.BackgroundColor <- ConsoleColor.Blue
41:     let time = (stopWatch.ElapsedMilliseconds / 1000L)
42:     Console.WriteLine("You did it {0} it took you {1} goes in {2} seconds", name, goes, time)
43: 
44:     name, goes, time
45: 
46: let highscore(result) =
47:     let name, goes, time = result
48:     let fileName = Environment.CurrentDirectory + "/highscores.txt"
49:     let scores = File.ReadAllLines(fileName)
50:     let newScore = [| String.Format("{0}, {1}, {2}", name.ToString(), goes.ToString(), time.ToString()) |]
51:     let newHighScores = Seq.append scores newScore
52:     File.WriteAllLines(fileName, newHighScores)  
53: 
54:     newHighScores |> Seq.iter (fun l -> Console.WriteLine(l))
55: 
56:     ()
57: 
58: [<EntryPoint>]
59: let main argv =  
60: // Should be broken down into loads of lovely little funcs but..... 
61: // _   _______ _     _____ 
62: //\ \ / /  _  | |   |  _  |
63: // \ V /| | | | |   | | | |
64: //  \ / | | | | |   | | | |
65: //  | | \ \_/ / |___\ \_/ /
66: //  \_/  \___/\_____/\___/ 
67: //                         
68:  
69:     let result = game()
70:     highscore(result) |> ignore
71:     Console.ReadKey() |> ignore
72:     0 // return an integer exit code
73: 
74: 
75: // this needs to be in a file called highscores.txt
76: 
77: //    .__                                                _____          .__        
78: //|  |   ____ _____     ____  __ __   ____     _____/ ____\ __  _  _|__| ____  
79: //|  | _/ __ \\__  \   / ___\|  |  \_/ __ \   /  _ \   __\  \ \/ \/ /  |/    \ 
80: //|  |_\  ___/ / __ \_/ /_/  >  |  /\  ___/  (  <_> )  |     \     /|  |   |  \
81: //|____/\___  >____  /\___  /|____/  \___  >  \____/|__|      \/\_/ |__|___|  /
82: //          \/     \//_____/             \/                                 \/ 
83: //
84: //Name, Goes, Time
namespace System
namespace System.IO
val game : unit -> string * int * int64

Full name: Snippet.game
val mutable notFound : bool

  type: bool
  implements: IComparable
  implements: IConvertible
  implements: IComparable<bool>
  implements: IEquatable<bool>
  inherits: ValueType
val fivetimestable : seq<int>

  type: seq<int>
  inherits: Collections.IEnumerable
Multiple items
val seq : seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>

  type: seq<'T>
  inherits: Collections.IEnumerable
val i : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
val random : Random
type Random =
  class
    new : unit -> System.Random
    new : int -> System.Random
    member Next : unit -> int
    member Next : int -> int
    member Next : int * int -> int
    member NextBytes : System.Byte [] -> unit
    member NextDouble : unit -> float
  end

Full name: System.Random
type DateTime =
  struct
    new : int64 -> System.DateTime
    new : int64 * System.DateTimeKind -> System.DateTime
    new : int * int * int -> System.DateTime
    new : int * int * int * System.Globalization.Calendar -> System.DateTime
    new : int * int * int * int * int * int -> System.DateTime
    new : int * int * int * int * int * int * System.DateTimeKind -> System.DateTime
    new : int * int * int * int * int * int * System.Globalization.Calendar -> System.DateTime
    new : int * int * int * int * int * int * int -> System.DateTime
    new : int * int * int * int * int * int * int * System.DateTimeKind -> System.DateTime
    new : int * int * int * int * int * int * int * System.Globalization.Calendar -> System.DateTime
    new : int * int * int * int * int * int * int * System.Globalization.Calendar * System.DateTimeKind -> System.DateTime
    member Add : System.TimeSpan -> System.DateTime
    member AddDays : float -> System.DateTime
    member AddHours : float -> System.DateTime
    member AddMilliseconds : float -> System.DateTime
    member AddMinutes : float -> System.DateTime
    member AddMonths : int -> System.DateTime
    member AddSeconds : float -> System.DateTime
    member AddTicks : int64 -> System.DateTime
    member AddYears : int -> System.DateTime
    member CompareTo : obj -> int
    member CompareTo : System.DateTime -> int
    member Date : System.DateTime
    member Day : int
    member DayOfWeek : System.DayOfWeek
    member DayOfYear : int
    member Equals : obj -> bool
    member Equals : System.DateTime -> bool
    member GetDateTimeFormats : unit -> string []
    member GetDateTimeFormats : System.IFormatProvider -> string []
    member GetDateTimeFormats : char -> string []
    member GetDateTimeFormats : char * System.IFormatProvider -> string []
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> System.TypeCode
    member Hour : int
    member IsDaylightSavingTime : unit -> bool
    member Kind : System.DateTimeKind
    member Millisecond : int
    member Minute : int
    member Month : int
    member Second : int
    member Subtract : System.DateTime -> System.TimeSpan
    member Subtract : System.TimeSpan -> System.DateTime
    member Ticks : int64
    member TimeOfDay : System.TimeSpan
    member ToBinary : unit -> int64
    member ToFileTime : unit -> int64
    member ToFileTimeUtc : unit -> int64
    member ToLocalTime : unit -> System.DateTime
    member ToLongDateString : unit -> string
    member ToLongTimeString : unit -> string
    member ToOADate : unit -> float
    member ToShortDateString : unit -> string
    member ToShortTimeString : unit -> string
    member ToString : unit -> string
    member ToString : string -> string
    member ToString : System.IFormatProvider -> string
    member ToString : string * System.IFormatProvider -> string
    member ToUniversalTime : unit -> System.DateTime
    member Year : int
    static val MinValue : System.DateTime
    static val MaxValue : System.DateTime
    static member Compare : System.DateTime * System.DateTime -> int
    static member DaysInMonth : int * int -> int
    static member Equals : System.DateTime * System.DateTime -> bool
    static member FromBinary : int64 -> System.DateTime
    static member FromFileTime : int64 -> System.DateTime
    static member FromFileTimeUtc : int64 -> System.DateTime
    static member FromOADate : float -> System.DateTime
    static member IsLeapYear : int -> bool
    static member Now : System.DateTime
    static member Parse : string -> System.DateTime
    static member Parse : string * System.IFormatProvider -> System.DateTime
    static member Parse : string * System.IFormatProvider * System.Globalization.DateTimeStyles -> System.DateTime
    static member ParseExact : string * string * System.IFormatProvider -> System.DateTime
    static member ParseExact : string * string * System.IFormatProvider * System.Globalization.DateTimeStyles -> System.DateTime
    static member ParseExact : string * string [] * System.IFormatProvider * System.Globalization.DateTimeStyles -> System.DateTime
    static member SpecifyKind : System.DateTime * System.DateTimeKind -> System.DateTime
    static member Today : System.DateTime
    static member TryParse : string * System.DateTime -> bool
    static member TryParse : string * System.IFormatProvider * System.Globalization.DateTimeStyles * System.DateTime -> bool
    static member TryParseExact : string * string * System.IFormatProvider * System.Globalization.DateTimeStyles * System.DateTime -> bool
    static member TryParseExact : string * string [] * System.IFormatProvider * System.Globalization.DateTimeStyles * System.DateTime -> bool
    static member UtcNow : System.DateTime
  end

Full name: System.DateTime

  type: DateTime
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: Runtime.Serialization.ISerializable
  implements: IComparable<DateTime>
  implements: IEquatable<DateTime>
  inherits: ValueType
property DateTime.Now: DateTime
property DateTime.Millisecond: int
val next : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
val ans : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
module Seq

from Microsoft.FSharp.Collections
val nth : int -> seq<'T> -> 'T

Full name: Microsoft.FSharp.Collections.Seq.nth
type Console =
  class
    static member BackgroundColor : System.ConsoleColor with get, set
    static member Beep : unit -> unit
    static member Beep : int * int -> unit
    static member BufferHeight : int with get, set
    static member BufferWidth : int with get, set
    static member CapsLock : bool
    static member Clear : unit -> unit
    static member CursorLeft : int with get, set
    static member CursorSize : int with get, set
    static member CursorTop : int with get, set
    static member CursorVisible : bool with get, set
    static member Error : System.IO.TextWriter
    static member ForegroundColor : System.ConsoleColor with get, set
    static member In : System.IO.TextReader
    static member InputEncoding : System.Text.Encoding with get, set
    static member IsErrorRedirected : bool
    static member IsInputRedirected : bool
    static member IsOutputRedirected : bool
    static member KeyAvailable : bool
    static member LargestWindowHeight : int
    static member LargestWindowWidth : int
    static member MoveBufferArea : int * int * int * int * int * int -> unit
    static member MoveBufferArea : int * int * int * int * int * int * char * System.ConsoleColor * System.ConsoleColor -> unit
    static member NumberLock : bool
    static member OpenStandardError : unit -> System.IO.Stream
    static member OpenStandardError : int -> System.IO.Stream
    static member OpenStandardInput : unit -> System.IO.Stream
    static member OpenStandardInput : int -> System.IO.Stream
    static member OpenStandardOutput : unit -> System.IO.Stream
    static member OpenStandardOutput : int -> System.IO.Stream
    static member Out : System.IO.TextWriter
    static member OutputEncoding : System.Text.Encoding with get, set
    static member Read : unit -> int
    static member ReadKey : unit -> System.ConsoleKeyInfo
    static member ReadKey : bool -> System.ConsoleKeyInfo
    static member ReadLine : unit -> string
    static member ResetColor : unit -> unit
    static member SetBufferSize : int * int -> unit
    static member SetCursorPosition : int * int -> unit
    static member SetError : System.IO.TextWriter -> unit
    static member SetIn : System.IO.TextReader -> unit
    static member SetOut : System.IO.TextWriter -> unit
    static member SetWindowPosition : int * int -> unit
    static member SetWindowSize : int * int -> unit
    static member Title : string with get, set
    static member TreatControlCAsInput : bool with get, set
    static member WindowHeight : int with get, set
    static member WindowLeft : int with get, set
    static member WindowTop : int with get, set
    static member WindowWidth : int with get, set
    static member Write : bool -> unit
    static member Write : char -> unit
    static member Write : char [] -> unit
    static member Write : float -> unit
    static member Write : decimal -> unit
    static member Write : float32 -> unit
    static member Write : int -> unit
    static member Write : uint32 -> unit
    static member Write : int64 -> unit
    static member Write : uint64 -> unit
    static member Write : obj -> unit
    static member Write : string -> unit
    static member Write : string * obj -> unit
    static member Write : string * obj [] -> unit
    static member Write : string * obj * obj -> unit
    static member Write : char [] * int * int -> unit
    static member Write : string * obj * obj * obj -> unit
    static member Write : string * obj * obj * obj * obj -> unit
    static member WriteLine : unit -> unit
    static member WriteLine : bool -> unit
    static member WriteLine : char -> unit
    static member WriteLine : char [] -> unit
    static member WriteLine : decimal -> unit
    static member WriteLine : float -> unit
    static member WriteLine : float32 -> unit
    static member WriteLine : int -> unit
    static member WriteLine : uint32 -> unit
    static member WriteLine : int64 -> unit
    static member WriteLine : uint64 -> unit
    static member WriteLine : obj -> unit
    static member WriteLine : string -> unit
    static member WriteLine : string * obj -> unit
    static member WriteLine : string * obj [] -> unit
    static member WriteLine : char [] * int * int -> unit
    static member WriteLine : string * obj * obj -> unit
    static member WriteLine : string * obj * obj * obj -> unit
    static member WriteLine : string * obj * obj * obj * obj -> unit
  end

Full name: System.Console
Console.WriteLine() : unit
   (+0 other overloads)
Console.WriteLine(value: string) : unit
   (+0 other overloads)
Console.WriteLine(value: obj) : unit
   (+0 other overloads)
Console.WriteLine(value: uint64) : unit
   (+0 other overloads)
Console.WriteLine(value: int64) : unit
   (+0 other overloads)
Console.WriteLine(value: uint32) : unit
   (+0 other overloads)
Console.WriteLine(value: int) : unit
   (+0 other overloads)
Console.WriteLine(value: float32) : unit
   (+0 other overloads)
Console.WriteLine(value: float) : unit
   (+0 other overloads)
Console.WriteLine(value: decimal) : unit
   (+0 other overloads)
val name : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
Console.ReadLine() : string
val mutable goes : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
val stopWatch : Diagnostics.Stopwatch
namespace System.Diagnostics
type Stopwatch =
  class
    new : unit -> System.Diagnostics.Stopwatch
    member Elapsed : System.TimeSpan
    member ElapsedMilliseconds : int64
    member ElapsedTicks : int64
    member IsRunning : bool
    member Reset : unit -> unit
    member Restart : unit -> unit
    member Start : unit -> unit
    member Stop : unit -> unit
    static val Frequency : int64
    static val IsHighResolution : bool
    static member GetTimestamp : unit -> int64
    static member StartNew : unit -> System.Diagnostics.Stopwatch
  end

Full name: System.Diagnostics.Stopwatch
Diagnostics.Stopwatch.Start() : unit
val ignore : 'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val guess : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
type Int32 =
  struct
    member CompareTo : obj -> int
    member CompareTo : int -> int
    member Equals : obj -> bool
    member Equals : int -> bool
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> System.TypeCode
    member ToString : unit -> string
    member ToString : string -> string
    member ToString : System.IFormatProvider -> string
    member ToString : string * System.IFormatProvider -> string
    static val MaxValue : int
    static val MinValue : int
    static member Parse : string -> int
    static member Parse : string * System.Globalization.NumberStyles -> int
    static member Parse : string * System.IFormatProvider -> int
    static member Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> int
    static member TryParse : string * int -> bool
    static member TryParse : string * System.Globalization.NumberStyles * System.IFormatProvider * int -> bool
  end

Full name: System.Int32

  type: Int32
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
Int32.Parse(s: string) : int
Int32.Parse(s: string, provider: IFormatProvider) : int
Int32.Parse(s: string, style: Globalization.NumberStyles) : int
Int32.Parse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider) : int
Object.Equals(obj: obj) : bool
Int32.Equals(obj: int) : bool
Diagnostics.Stopwatch.Stop() : unit
property Console.BackgroundColor: ConsoleColor
type ConsoleColor =
  | Black = 0
  | DarkBlue = 1
  | DarkGreen = 2
  | DarkCyan = 3
  | DarkRed = 4
  | DarkMagenta = 5
  | DarkYellow = 6
  | Gray = 7
  | DarkGray = 8
  | Blue = 9
  | Green = 10
  | Cyan = 11
  | Red = 12
  | Magenta = 13
  | Yellow = 14
  | White = 15

Full name: System.ConsoleColor

  type: ConsoleColor
  inherits: Enum
  inherits: ValueType
field ConsoleColor.Blue = 9
val time : int64

  type: int64
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int64>
  implements: IEquatable<int64>
  inherits: ValueType
property Diagnostics.Stopwatch.ElapsedMilliseconds: int64
val highscore : 'a * 'b * 'c -> unit

Full name: Snippet.highscore
val result : 'a * 'b * 'c
val name : 'a
val goes : 'b
val time : 'c
val fileName : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
type Environment =
  class
    static member CommandLine : string
    static member CurrentDirectory : string with get, set
    static member CurrentManagedThreadId : int
    static member Exit : int -> unit
    static member ExitCode : int with get, set
    static member ExpandEnvironmentVariables : string -> string
    static member FailFast : string -> unit
    static member FailFast : string * System.Exception -> unit
    static member GetCommandLineArgs : unit -> string []
    static member GetEnvironmentVariable : string -> string
    static member GetEnvironmentVariable : string * System.EnvironmentVariableTarget -> string
    static member GetEnvironmentVariables : unit -> System.Collections.IDictionary
    static member GetEnvironmentVariables : System.EnvironmentVariableTarget -> System.Collections.IDictionary
    static member GetFolderPath : SpecialFolder -> string
    static member GetFolderPath : SpecialFolder * SpecialFolderOption -> string
    static member GetLogicalDrives : unit -> string []
    static member HasShutdownStarted : bool
    static member Is64BitOperatingSystem : bool
    static member Is64BitProcess : bool
    static member MachineName : string
    static member NewLine : string
    static member OSVersion : System.OperatingSystem
    static member ProcessorCount : int
    static member SetEnvironmentVariable : string * string -> unit
    static member SetEnvironmentVariable : string * string * System.EnvironmentVariableTarget -> unit
    static member StackTrace : string
    static member SystemDirectory : string
    static member SystemPageSize : int
    static member TickCount : int
    static member UserDomainName : string
    static member UserInteractive : bool
    static member UserName : string
    static member Version : System.Version
    static member WorkingSet : int64
    type SpecialFolderOption =
      | None = 0
      | Create = 32768
      | DoNotVerify = 16384
    type SpecialFolder =
      | ApplicationData = 26
      | CommonApplicationData = 35
      | LocalApplicationData = 28
      | Cookies = 33
      | Desktop = 0
      | Favorites = 6
      | History = 34
      | InternetCache = 32
      | Programs = 2
      | MyComputer = 17
      | MyMusic = 13
      | MyPictures = 39
      | MyVideos = 14
      | Recent = 8
      | SendTo = 9
      | StartMenu = 11
      | Startup = 7
      | System = 37
      | Templates = 21
      | DesktopDirectory = 16
      | Personal = 5
      | MyDocuments = 5
      | ProgramFiles = 38
      | CommonProgramFiles = 43
      | AdminTools = 48
      | CDBurning = 59
      | CommonAdminTools = 47
      | CommonDocuments = 46
      | CommonMusic = 53
      | CommonOemLinks = 58
      | CommonPictures = 54
      | CommonStartMenu = 22
      | CommonPrograms = 23
      | CommonStartup = 24
      | CommonDesktopDirectory = 25
      | CommonTemplates = 45
      | CommonVideos = 55
      | Fonts = 20
      | NetworkShortcuts = 19
      | PrinterShortcuts = 27
      | UserProfile = 40
      | CommonProgramFilesX86 = 44
      | ProgramFilesX86 = 42
      | Resources = 56
      | LocalizedResources = 57
      | SystemX86 = 41
      | Windows = 36
  end

Full name: System.Environment
property Environment.CurrentDirectory: string
val scores : string []

  type: string []
  implements: ICloneable
  implements: Collections.IList
  implements: Collections.ICollection
  implements: Collections.IStructuralComparable
  implements: Collections.IStructuralEquatable
  implements: Collections.Generic.IList<string>
  implements: Collections.Generic.ICollection<string>
  implements: seq<string>
  implements: Collections.IEnumerable
  inherits: Array
type File =
  class
    static member AppendAllLines : string * System.Collections.Generic.IEnumerable<string> -> unit
    static member AppendAllLines : string * System.Collections.Generic.IEnumerable<string> * System.Text.Encoding -> unit
    static member AppendAllText : string * string -> unit
    static member AppendAllText : string * string * System.Text.Encoding -> unit
    static member AppendText : string -> System.IO.StreamWriter
    static member Copy : string * string -> unit
    static member Copy : string * string * bool -> unit
    static member Create : string -> System.IO.FileStream
    static member Create : string * int -> System.IO.FileStream
    static member Create : string * int * System.IO.FileOptions -> System.IO.FileStream
    static member Create : string * int * System.IO.FileOptions * System.Security.AccessControl.FileSecurity -> System.IO.FileStream
    static member CreateText : string -> System.IO.StreamWriter
    static member Decrypt : string -> unit
    static member Delete : string -> unit
    static member Encrypt : string -> unit
    static member Exists : string -> bool
    static member GetAccessControl : string -> System.Security.AccessControl.FileSecurity
    static member GetAccessControl : string * System.Security.AccessControl.AccessControlSections -> System.Security.AccessControl.FileSecurity
    static member GetAttributes : string -> System.IO.FileAttributes
    static member GetCreationTime : string -> System.DateTime
    static member GetCreationTimeUtc : string -> System.DateTime
    static member GetLastAccessTime : string -> System.DateTime
    static member GetLastAccessTimeUtc : string -> System.DateTime
    static member GetLastWriteTime : string -> System.DateTime
    static member GetLastWriteTimeUtc : string -> System.DateTime
    static member Move : string * string -> unit
    static member Open : string * System.IO.FileMode -> System.IO.FileStream
    static member Open : string * System.IO.FileMode * System.IO.FileAccess -> System.IO.FileStream
    static member Open : string * System.IO.FileMode * System.IO.FileAccess * System.IO.FileShare -> System.IO.FileStream
    static member OpenRead : string -> System.IO.FileStream
    static member OpenText : string -> System.IO.StreamReader
    static member OpenWrite : string -> System.IO.FileStream
    static member ReadAllBytes : string -> System.Byte []
    static member ReadAllLines : string -> string []
    static member ReadAllLines : string * System.Text.Encoding -> string []
    static member ReadAllText : string -> string
    static member ReadAllText : string * System.Text.Encoding -> string
    static member ReadLines : string -> System.Collections.Generic.IEnumerable<string>
    static member ReadLines : string * System.Text.Encoding -> System.Collections.Generic.IEnumerable<string>
    static member Replace : string * string * string -> unit
    static member Replace : string * string * string * bool -> unit
    static member SetAccessControl : string * System.Security.AccessControl.FileSecurity -> unit
    static member SetAttributes : string * System.IO.FileAttributes -> unit
    static member SetCreationTime : string * System.DateTime -> unit
    static member SetCreationTimeUtc : string * System.DateTime -> unit
    static member SetLastAccessTime : string * System.DateTime -> unit
    static member SetLastAccessTimeUtc : string * System.DateTime -> unit
    static member SetLastWriteTime : string * System.DateTime -> unit
    static member SetLastWriteTimeUtc : string * System.DateTime -> unit
    static member WriteAllBytes : string * System.Byte [] -> unit
    static member WriteAllLines : string * string [] -> unit
    static member WriteAllLines : string * System.Collections.Generic.IEnumerable<string> -> unit
    static member WriteAllLines : string * string [] * System.Text.Encoding -> unit
    static member WriteAllLines : string * System.Collections.Generic.IEnumerable<string> * System.Text.Encoding -> unit
    static member WriteAllText : string * string -> unit
    static member WriteAllText : string * string * System.Text.Encoding -> unit
  end

Full name: System.IO.File
File.ReadAllLines(path: string) : string []
File.ReadAllLines(path: string, encoding: Text.Encoding) : string []
val newScore : string []

  type: string []
  implements: ICloneable
  implements: Collections.IList
  implements: Collections.ICollection
  implements: Collections.IStructuralComparable
  implements: Collections.IStructuralEquatable
  implements: Collections.Generic.IList<string>
  implements: Collections.Generic.ICollection<string>
  implements: seq<string>
  implements: Collections.IEnumerable
  inherits: Array
type String =
  class
    new : char -> string
    new : char * int * int -> string
    new : System.SByte -> string
    new : System.SByte * int * int -> string
    new : System.SByte * int * int * System.Text.Encoding -> string
    new : char [] * int * int -> string
    new : char [] -> string
    new : char * int -> string
    member Chars : int -> char
    member Clone : unit -> obj
    member CompareTo : obj -> int
    member CompareTo : string -> int
    member Contains : string -> bool
    member CopyTo : int * char [] * int * int -> unit
    member EndsWith : string -> bool
    member EndsWith : string * System.StringComparison -> bool
    member EndsWith : string * bool * System.Globalization.CultureInfo -> bool
    member Equals : obj -> bool
    member Equals : string -> bool
    member Equals : string * System.StringComparison -> bool
    member GetEnumerator : unit -> System.CharEnumerator
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> System.TypeCode
    member IndexOf : char -> int
    member IndexOf : string -> int
    member IndexOf : char * int -> int
    member IndexOf : string * int -> int
    member IndexOf : string * System.StringComparison -> int
    member IndexOf : char * int * int -> int
    member IndexOf : string * int * int -> int
    member IndexOf : string * int * System.StringComparison -> int
    member IndexOf : string * int * int * System.StringComparison -> int
    member IndexOfAny : char [] -> int
    member IndexOfAny : char [] * int -> int
    member IndexOfAny : char [] * int * int -> int
    member Insert : int * string -> string
    member IsNormalized : unit -> bool
    member IsNormalized : System.Text.NormalizationForm -> bool
    member LastIndexOf : char -> int
    member LastIndexOf : string -> int
    member LastIndexOf : char * int -> int
    member LastIndexOf : string * int -> int
    member LastIndexOf : string * System.StringComparison -> int
    member LastIndexOf : char * int * int -> int
    member LastIndexOf : string * int * int -> int
    member LastIndexOf : string * int * System.StringComparison -> int
    member LastIndexOf : string * int * int * System.StringComparison -> int
    member LastIndexOfAny : char [] -> int
    member LastIndexOfAny : char [] * int -> int
    member LastIndexOfAny : char [] * int * int -> int
    member Length : int
    member Normalize : unit -> string
    member Normalize : System.Text.NormalizationForm -> string
    member PadLeft : int -> string
    member PadLeft : int * char -> string
    member PadRight : int -> string
    member PadRight : int * char -> string
    member Remove : int -> string
    member Remove : int * int -> string
    member Replace : char * char -> string
    member Replace : string * string -> string
    member Split : char [] -> string []
    member Split : char [] * int -> string []
    member Split : char [] * System.StringSplitOptions -> string []
    member Split : string [] * System.StringSplitOptions -> string []
    member Split : char [] * int * System.StringSplitOptions -> string []
    member Split : string [] * int * System.StringSplitOptions -> string []
    member StartsWith : string -> bool
    member StartsWith : string * System.StringComparison -> bool
    member StartsWith : string * bool * System.Globalization.CultureInfo -> bool
    member Substring : int -> string
    member Substring : int * int -> string
    member ToCharArray : unit -> char []
    member ToCharArray : int * int -> char []
    member ToLower : unit -> string
    member ToLower : System.Globalization.CultureInfo -> string
    member ToLowerInvariant : unit -> string
    member ToString : unit -> string
    member ToString : System.IFormatProvider -> string
    member ToUpper : unit -> string
    member ToUpper : System.Globalization.CultureInfo -> string
    member ToUpperInvariant : unit -> string
    member Trim : unit -> string
    member Trim : char [] -> string
    member TrimEnd : char [] -> string
    member TrimStart : char [] -> string
    static val Empty : string
    static member Compare : string * string -> int
    static member Compare : string * string * bool -> int
    static member Compare : string * string * System.StringComparison -> int
    static member Compare : string * string * System.Globalization.CultureInfo * System.Globalization.CompareOptions -> int
    static member Compare : string * string * bool * System.Globalization.CultureInfo -> int
    static member Compare : string * int * string * int * int -> int
    static member Compare : string * int * string * int * int * bool -> int
    static member Compare : string * int * string * int * int * System.StringComparison -> int
    static member Compare : string * int * string * int * int * bool * System.Globalization.CultureInfo -> int
    static member Compare : string * int * string * int * int * System.Globalization.CultureInfo * System.Globalization.CompareOptions -> int
    static member CompareOrdinal : string * string -> int
    static member CompareOrdinal : string * int * string * int * int -> int
    static member Concat : obj -> string
    static member Concat : obj [] -> string
    static member Concat<'T> : System.Collections.Generic.IEnumerable<'T> -> string
    static member Concat : System.Collections.Generic.IEnumerable<string> -> string
    static member Concat : string [] -> string
    static member Concat : obj * obj -> string
    static member Concat : string * string -> string
    static member Concat : obj * obj * obj -> string
    static member Concat : string * string * string -> string
    static member Concat : obj * obj * obj * obj -> string
    static member Concat : string * string * string * string -> string
    static member Copy : string -> string
    static member Equals : string * string -> bool
    static member Equals : string * string * System.StringComparison -> bool
    static member Format : string * obj -> string
    static member Format : string * obj [] -> string
    static member Format : string * obj * obj -> string
    static member Format : System.IFormatProvider * string * obj [] -> string
    static member Format : string * obj * obj * obj -> string
    static member Intern : string -> string
    static member IsInterned : string -> string
    static member IsNullOrEmpty : string -> bool
    static member IsNullOrWhiteSpace : string -> bool
    static member Join : string * string [] -> string
    static member Join : string * obj [] -> string
    static member Join<'T> : string * System.Collections.Generic.IEnumerable<'T> -> string
    static member Join : string * System.Collections.Generic.IEnumerable<string> -> string
    static member Join : string * string [] * int * int -> string
  end

Full name: System.String

  type: String
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
String.Format(format: string, args: obj []) : string
String.Format(format: string, arg0: obj) : string
String.Format(provider: IFormatProvider, format: string, args: obj []) : string
String.Format(format: string, arg0: obj, arg1: obj) : string
String.Format(format: string, arg0: obj, arg1: obj, arg2: obj) : string
Object.ToString() : string
val newHighScores : seq<string>

  type: seq<string>
  inherits: Collections.IEnumerable
val append : seq<'T> -> seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.append
File.WriteAllLines(path: string, contents: seq<string>) : unit
File.WriteAllLines(path: string, contents: string []) : unit
File.WriteAllLines(path: string, contents: seq<string>, encoding: Text.Encoding) : unit
File.WriteAllLines(path: string, contents: string [], encoding: Text.Encoding) : unit
val iter : ('T -> unit) -> seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val l : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
type EntryPointAttribute =
  class
    inherit Attribute
    new : unit -> EntryPointAttribute
  end

Full name: Microsoft.FSharp.Core.EntryPointAttribute

  type: EntryPointAttribute
  implements: Runtime.InteropServices._Attribute
  inherits: Attribute
val main : string [] -> int

Full name: Snippet.main
val argv : string []

  type: string []
  implements: ICloneable
  implements: Collections.IList
  implements: Collections.ICollection
  implements: Collections.IStructuralComparable
  implements: Collections.IStructuralEquatable
  implements: Collections.Generic.IList<string>
  implements: Collections.Generic.ICollection<string>
  implements: seq<string>
  implements: Collections.IEnumerable
  inherits: Array
val result : string * int * int64
Console.ReadKey() : ConsoleKeyInfo
Console.ReadKey(intercept: bool) : ConsoleKeyInfo

Comments

Popular posts from this blog

Creating star ratings in HTML and Javascript

I'd searched around a little for some shortcuts to help in doing this but I couldn't find anything satisfactory that included the ability to pull the rating off again for saving. I'd ended up coming up with this rather cheeky solution. Hopefully it helps you too! This is my first post in a while (I stopped blogging properly about 8 years ago!) It's strange coming back to it. Blogger feels very crusty and old by todays standards too.

Make your objects immutable by default

More about the Good Dojo In my post last week , I discussed creating objects that are instantiated safely. Please go back and read if you are interested. At the end of the post, I mentioned that I'd also written the class so it was immutable when instantiated. This is important!!! I feel like a broken record in repeating this but I am sure at the time of writing your code, you aren't modifying your object all over the place and so are safe in the belief that protecting against mutability is overkill. Please remember though, your code could be around for a hell of a long time. You aren't writing your code for now... you are writing for the next fool that comes along (including you) . Nothing is more upsetting that coming back to fix a bug on some wonderfully crafted code to say "Who has butchered my code?!", but often you were involved at the start of the process. You made the code easy to modify, allowing objects to be used / reused / modified without thi

An instantiated object should be "ok"

I've been QA'ing quite a bit of work recently and one common theme I've noticed across both Java and C# projects I have been looking at is that we occasionally open ourselves up unessacarily to Exceptions by the way objects are being created. My general rule of thumb (which I have seen mentioned in a Pluralsight video recently but also always re-iterate in various Robust Software talks I have done) is that you shouldn't be able to create an object and then call a method or access a property that then throws an exception. At worst, it should return null (I'm not going to moan about that now). I've created an example below. We have two Dojos, one is good and one is bad. The bad dojo looks very familiar though. It's a little class written in the style that seems often encouraged. In fact, many classes start life as something like this. Then as years go on, you and other colleagues add more features to the class and it's instantiation becomes a second