// for Visual Studio only open System open Microsoft.FSharp.Reflection open FSharp.Data type student = JsonProvider<""" {"name":"John Grazer", "gpa":3.2, "id":702123456} """> [] let main argv = let x = student.Parse(""" {"name":"Nev Erstudy", "gpa":0.2, "id":702111111}""") printfn "%A" (typeof) Console.WriteLine(typeof) Console.WriteLine(x.GetType()) Console.WriteLine(x) Console.WriteLine(string(x.Name)) let y = student.Parse(""" {"name":"Haten Umbers", "gpa":"awesome", "id":"some long number"}""") // runtime type error Console.WriteLine(x.Gpa) Console.WriteLine(y.Gpa) 0 // return an integer exit code // A "type provider" is a meta-level device that dynamically creates new // types. Json itself is entirely untyped. Each json "object" may contain // different attributes with different types, so it is difficult to use // with a typed language. This is why C# added the keyword 'dynamic' - // to allow this kind of untyped processing. But here, once the type // type 'student' is created, type checking is enforced. You cannot // create a student object with a string for the gpa value: that is // enforced at compile time. Unfortunately, there is no way to detect // that there's anything wrong with a *string* at compile time. The // very definition of string is that it is unstructured: just a sequence // of bytes. Thus the "awesome" gpa for Haten Umbers is only detectable // at runtime, when 'Parse' tries to convert the string into a student object. // That is always going to be a problem when your program relies // too much on strings. Using too many strings to represent structured // information is a bad idea (yes, that's right, I'm critiquing the // overuse of JSON) or the following reasons: // 1. It is not efficient. 702123456 fits inside a 4-byte integer, but // requires 9 bytes to represent as a string. // 2. It is not type safe. You can use the most strongly typed language // in the world but a string is still just a string // 3. It is not secure, as strings are vulnerable to string injection attacks. // Formatted binary data are less vulnerable. // JSON is not suitable for intensive scientific applications. // For example, a DNA sequence consisting of 4 possible symbols A, C, G, // and T should be represented in base-4 binary: each symbol requires // 2 bits to represent. The human genome contains roughly 8-billion base pairs // so it should require 2 gigabytes, not 8 gigabytes to represent. // Yes, JSON is very easy to use with javascript, python, etc, which is why // it's popular. But using inferior programming technology will eventually // have consequences. The problem ultimately is SCALABILITY. About ten // years ago Twitter switched from Ruby to Scala after Twitter crashed. // The problem had to do with a flaw in Ruby's garbage collector, // which was in turn caused by the lack of static types (type information // tell us how memory is layed out). Ruby is otherwise a rather // well-designed language.