Showing posts with label book. Show all posts
Showing posts with label book. Show all posts

Monday, June 17, 2013

I've finished reading "Refactoring: Ruby Edition"

Since this post, it has taken 17 months because I read it slowly with doing another coding or reading another book.

Fortunately, I have already done most of refactoring examples. But these three examples are not, so that this book is useful for me.

  • Introduce Class Annotation
  • Replace Type Code with State/Strategy
  • Introduce Expression Builder

Tuesday, May 7, 2013

Difference between typeof and typedefof

(In learning from "Programming F# 3.0, 2nd Edition")

There are two functions to know type information - typeof and typedefof. typeof shows information both class-itself and its type parameter while typedefof shows only class-itself and shows generics as-is.
> let typeOfSeqInt = typeof<seq<int>>;;

val typeOfSeqInt : System.Type =
  System.Collections.Generic.IEnumerable`1[System.Int32]

> let typeOfSeqGeneric = typeof<seq<'a>>;;

  let typeOfSeqGeneric = typeof<seq<'a>>;;
  ----------------------------------^^

stdin(7,35): warning FS0064: This construct causes code to be less generic than
indicated by the type annotations. The type variable 'a has been constrained to
be type 'obj'.

val typeOfSeqGeneric : System.Type =
  System.Collections.Generic.IEnumerable`1[System.Object]

> let typeDefOfSeqInt = typedefof<seq<int>>;;

val typeDefOfSeqInt : System.Type =
  System.Collections.Generic.IEnumerable`1[T]

> let typeDefOfSeqGeneric = typedefof<seq<'a>>;;

  let typeDefOfSeqGeneric = typedefof<seq<'a>>;;
  ----------------------------------------^^

stdin(9,41): warning FS0064: This construct causes code to be less generic than
indicated by the type annotations. The type variable 'a has been constrained to
be type 'obj'.

val typeDefOfSeqGeneric : System.Type =
  System.Collections.Generic.IEnumerable`1[T]

Tuesday, April 23, 2013

Extend module

(In learning from "Programming F# 3.0, 2nd Edition")

Extending existing module is just same syntax to creating new module. For example, add slice function like phosphorescence: The way to add both indexer and slice to F# sequence with extending both Seq and List modules.

> module Seq =
-     let slice (lower : int option, upper : int option) aSeq =
-         match lower, upper with
-         | Some(lower), Some(upper) -> aSeq |> Seq.skip lower |> Seq.take (upper - lower + 1)
-         | Some(lower), None -> aSeq |> Seq.skip lower
-         | None, Some(upper) -> aSeq |> Seq.take (upper + 1)
-         | None, None -> aSeq;;

module Seq = begin
  val slice : lower:int option * upper:int option -> aSeq:seq<'a> -> seq<'a>
end

> let seq1To5 = seq {1..5};;

val seq1To5 : seq<int>

> Seq.slice (Some(1), Some(3)) seq1To5;;
val it : seq<int> = seq [2; 3; 4]
> module List =
-     let slice (lower : int option, upper : int option) aList =
-         match lower, upper with
-         | Some(lower), Some(upper) -> aList |> Seq.skip lower |> Seq.take (upper - lower + 1) |> Seq.toList
-         | Some(lower), None -> aList |> Seq.skip lower |> Seq.toList
-         | None, Some(upper) -> aList |> Seq.take (upper + 1) |> Seq.toList
-         | None, None -> aList;;

module List = begin
  val slice : lower:int option * upper:int option -> aList:'a list -> 'a list
end

> let list1To5 = [1..5];;

val list1To5 : int list = [1; 2; 3; 4; 5]

> List.slice (Some(1), Some(3)) list1To5;;
val it : int list = [2; 3; 4]

Saturday, April 20, 2013

ConcurrentDictionary on F#

(In learning from "Programming F# 3.0, 2nd Edition")

While Dictionary has syntax sugar for F# (check also phosphorescence: Studying F# : Dictionary (a.k.a. Hash or Map)), System.Collections.Concurrent.ConcurrentDictionary has not. So that we use it manually.
> open System.Collections.Concurrent;;
> let concurrentDict = new ConcurrentDictionary<int, string>();;

val concurrentDict : ConcurrentDictionary<int,string> = dict []

> concurrentDict.TryAdd(1, "one");;
val it : bool = true
> concurrentDict.TryAdd(2, "two");;
val it : bool = true
> concurrentDict.TryAdd(3, "three");;
val it : bool = true
> concurrentDict.TryAdd(4, "four");;
val it : bool = true

Saturday, March 30, 2013

F# Slice

(In learning from "Programming F# 3.0, 2nd Edition")

Ruby's indexer can take range as parameter. In F#, Item property cannot do that. But, in F", GetSlice property cannot do that and it is called "Slice".

defining
member this.GetSlice(lowerBound : int option, upperBound : int option) =
  ...
accessing
xxx.[1..42]
xxx.[1..]
xxx.[..42]

Both two arguments are option type.

Thursday, March 28, 2013

F# Indexer

(In learning from "Programming F# 3.0, 2nd Edition")

Like ruby, F# can define indexer as defining Item property.

defining
member this.Item (idx : int) =
  ...
accessing
xxx.[42]


And also like ruby, indexer can take one more arguments.

defining
member this.Item (prefix : string , idx : int) =
  ...
accessing
xxx.["Answer", 42]

Tuesday, March 19, 2013

Checked module

(In learning from "Programming F# 3.0, 2nd Edition")

Operators.Checked Module (F#) (in Japanese)

F#'s Microsoft.FSharp.Core.Operators.Checked is to check which signed numbers are overflowed or not.
> let maxInt = System.Int32.MaxValue;;

val maxInt : int = 2147483647

> maxInt + 1;;
val it : int = -2147483648
> maxInt - 1;;
val it : int = 2147483646
> open Checked;;
> maxInt + 1;;
System.OverflowException: 算術演算の結果オーバーフローが発生しました。
   場所 <StartupCode$FSI_0008>.$FSI_0008.main@()
Stopped due to error

Saturday, March 16, 2013

Active Pattern (3) : Parameterized Active Pattern

(In learning from "Programming F# 3.0, 2nd Edition")

Parameterized Active Pattern takes both condition to match and parameter of its condition, and also used with Partial Active Pattern as "Parameterized Partial Active Pattern".

let (|MultiplesOf|_|) (multiplier : int) (input : int) =
    if (input % multiplier = 0) then Some(input) else None

let fizzBuzz input =
    match input with
    | MultiplesOf 5 _ & MultiplesOf 3 _ -> "FizzBuzz"
    | MultiplesOf 5 _ -> "Buzz"
    | MultiplesOf 3 _ -> "Fizz"
    | _ -> input.ToString()

List.map fizzBuzz [1..40];;

Thursday, March 14, 2013

Active Pattern (2) : Partial Active Pattern

(In learning from "Programming F# 3.0, 2nd Edition")

If your "Single-case Active Pattern" should be considered for dealing option type (e.g. phosphorescence: Active Pattern (1) : Single-case Active Pattern: this sample is NOT considering invalid date), you should define as "Partial Active Pattern" like below:
> open System;;
> let (|WhatDayOfWeek|_|) (year, month, day) =
-     try
-         Some(System.DateTime(year,month,day).DayOfWeek)
-     with
-     | :? System.ArgumentOutOfRangeException -> None;;

val ( |WhatDayOfWeek|_| ) : year:int * month:int * day:int -> DayOfWeek option

> let weekEnd year month day =
-     match (year, month, day) with
-     | WhatDayOfWeek System.DayOfWeek.Sunday
-     | WhatDayOfWeek System.DayOfWeek.Saturday
-         -> "Week End !!"
-     | WhatDayOfWeek _
-         -> "Not Week End..."
-     | _ -> "invalid date";;

val weekEnd : year:int -> month:int -> day:int -> string

> weekEnd 2013 3 15;;
val it : string = "Not Week End..."
> weekEnd 2013 3 16;;
val it : string = "Week End !!"
> weekEnd 2013 2 29;;
val it : string = "invalid date"

Monday, March 11, 2013

Active Pattern (1) : Single-case Active Pattern

(In learning from "Programming F# 3.0, 2nd Edition")

Single-case Active Pattern is defined as a special function enclosed (| |).
> open System;;
> let (|WhatDayOfWeek|) (year, month, day) =
-     System.DateTime(year,month,day).DayOfWeek;;

val ( |WhatDayOfWeek| ) : year:int * month:int * day:int -> DayOfWeek

> let isWeekEnd year month day =
-     match (year, month, day) with
-     | WhatDayOfWeek System.DayOfWeek.Sunday
-     | WhatDayOfWeek System.DayOfWeek.Saturday
-         -> true
-     | WhatDayOfWeek _
-         -> false;;

val isWeekEnd : year:int -> month:int -> day:int -> bool

> isWeekEnd 2013 3 15;;
val it : bool = false
> isWeekEnd 2013 3 16;;
val it : bool = true

Saturday, March 2, 2013

Dispose pattern in F#

(In learning from "Programming F# 3.0, 2nd Edition")

If we want to access to unmanaged resources from C#,
  1. The class that indicates unmanaged resource should implement IDisposable interface and override Dispose method.
  2. When using this class, we should write the code with using () {} clause.

In F#, almost same.
  1. The class that indicates unmanaged resource should implement IDisposable interface and override Dispose method.
  2. When using this class, we should write the code with use binding.
> open System;;
> type SomeUnmanagedResource() =
-     interface IDisposable with
-         member this.Dispose() =
-             printfn "Some unmanaged resource is diposed.";;

type SomeUnmanagedResource =
  class
    interface IDisposable
    new : unit -> SomeUnmanagedResource
  end

> let greetings =
-     use res = new SomeUnmanagedResource()
-     printfn "Hello World";;
Hello World
Some unmanaged resource is diposed.

val greetings : unit = ()

Tuesday, February 19, 2013

Type dispatch with F# pattern match

(In learning from "Programming F# 3.0, 2nd Edition")

In F#, type dispatch is made with pattern match.
> let whatTypeNumberIs (n:obj) =
-   match n with
-   | :? int16 | :? int32 | :? int64 as i -> "This is int."
-   | :? uint16 | :? uint32 | :? uint64 as ui -> "This is uint."
-   | :? double as d -> "This is double."
-   | :? single as s -> "This is single."
-   | _ -> "This is not a number.";;

val whatTypeNumberIs : n:obj -> string

> whatTypeNumberIs 2;;
val it : string = "This is int."
> whatTypeNumberIs 2.0;;
val it : string = "This is double."

Saturday, February 16, 2013

Calling constructor of superclass in F#

(In learning from "Programming F# 3.0, 2nd Edition")

> open System.Globalization;;
> type AncientCalendar<'a> =
-   inherit JulianCalendar
-   val m_subfield : 'a
-   new(subfield) =
-     {
-       inherit JulianCalendar()
-       m_subfield = subfield
-     };;

type AncientCalendar<'a> =
  class
    inherit JulianCalendar
    new : subfield:'a -> AncientCalendar<'a>
    val m_subfield: 'a
  end

Monday, February 11, 2013

Reference cell

(In learning from "Programming F# 3.0, 2nd Edition")

Reference cell is another way to define mutable variable without mutable keyword. When using ref keyword, it creates reference cell that contains that you write after ref keyword.
> let x = ref 0;;

val x : int ref = {contents = 0;}

> x;;
val it : int ref = {contents = 0;}
> !x;;
val it : int = 0
> x := !x + 1;;
val it : unit = ()
> x;;
val it : int ref = {contents = 1;}
> !x;;
val it : int = 1
In sample above, x referres reference cell itself, if we want to refer the content of reference cell, we must use !x, and if we want to modify the content of reference cell, wemust use operator :=

Friday, February 8, 2013

Explain Seq.unfold verbosely

(In learning from "Programming F# 3.0, 2nd Edition")

Seq.unfold is a function hard-to-understand if I read any Microsoft's documents and any books. For example, the way in "Programming F# 3.0, 2nd Edition" is hard to understand.
> // Generate the next element of the Fibonacci sequence given the previous
// two elements. To be used with Seq.unfold.
let nextFibUnder100 (a, b) =
    if a + b > 100 then
        None
    else
        let nextValue = a + b
        Some(nextValue, (nextValue, a));;

val nextFibUnder100 : int * int -> (int * (int * int)) option

> let fibsUnder100 = Seq.unfold nextFibUnder100 (0, 1);;

val fibsUnder100 : seq<int>

> Seq.toList fibsUnder100;;
val it : int list = [1; 1; 2; 3; 5; 8; 13; 21; 34; 55; 89]

But, since I re-write this example verbosely like below, I can understand about it.
module UnfoldVerbosely =
    let fibSeed (current, next) =
        let yieldValue = current
        let next'current = next
        let next'next = current + next
        Some(yieldValue, (next'current, next'next))
    let fib = Seq.unfold fibSeed (1L, 1L)

printfn "%A" (Seq.take 2 UnfoldVerbosely.fib)
printfn "%A" (Seq.take 3 UnfoldVerbosely.fib)
printfn "%A" (Seq.take 4 UnfoldVerbosely.fib)
printfn "%A" (Seq.take 5 UnfoldVerbosely.fib)
module UnfoldVerbosely = begin
  val fibSeed : current:int * next:int -> (int * (int * int)) option
  val fib : seq<int>
end

seq [1; 1]
seq [1; 1; 2]
seq [1; 1; 2; 3]
seq [1; 1; 2; 3; ...]

Wednesday, February 6, 2013

Yield Bang is similar to Ruby's multiple assignment

(In learning from "Programming F# 3.0, 2nd Edition")

Yield Bang ( yield! ) is similar to Ruby's multiple assignment.

In Ruby (multiple assignment)

require 'pathname'

def all_file_under(pathname)
  pathname.each_child.find_all(&:directory?).reduce(pathname.each_child.find_all(&:file?)) do |accum, subpathname|
    accum = Array[*accum, *all_file_under(subpathname)]
  end
end

puts all_file_under(Pathname.new('C:\temp'))
C:\temp/AAAAA
C:\temp/BBBBBB
C:\temp/CCCCCCC
C:\temp/DDD/EEEE
...

In F# (Yield Bang)

> open System.IO;;
> let rec allFilesUnder basePath =
-     seq {
-         yield! Directory.GetFiles(basePath)
-         for subdir in Directory.GetDirectories(basePath) do
-             yield! allFilesUnder subdir
-     };;

val allFilesUnder : basePath:string -> seq<string>

> allFilesUnder @"C:\temp";;
val it : seq<string> =
  seq
    ["C:\temp\AAAAA"; "C:\temp\BBBBBB";
     "C:\temp\CCCCCCC"; "C:\temp\DDD\EEEE"; ...]

Monday, February 4, 2013

Lazy Evaluation in F#

(In learning from "Programming F# 3.0, 2nd Edition")

Define lazy instance

These two are completely same way.
> let current = lazy(System.DateTime.Now);;

val current : Lazy<System.DateTime> = Value is not created.
> let current = Lazy<System.DateTime>.Create(fun() -> System.DateTime.Now);;

val current : System.Lazy<System.DateTime> = Value is not created.

Evaluate lazy instance

These two are also completely same way.
> current.IsValueCreated;;
val it : bool = false
> current.Value;;
val it : System.DateTime = 2013/02/04 20:40:19 {Date = 2013/02/04 0:00:00;
                                                Day = 4;
                                                DayOfWeek = Monday;
                                                DayOfYear = 35;
                                                Hour = 20;
                                                Kind = Local;
                                                Millisecond = 676;
                                                Minute = 40;
                                                Month = 2;
                                                Second = 19;
                                                Ticks = 634956072196762680L;
                                                TimeOfDay = 20:40:19.6762680;
                                                Year = 2013;}
> current.IsValueCreated;;
val it : bool = true
> current.Value;;
val it : System.DateTime = 2013/02/04 20:40:19 {Date = 2013/02/04 0:00:00;
                                                Day = 4;
                                                DayOfWeek = Monday;
                                                DayOfYear = 35;
                                                Hour = 20;
                                                Kind = Local;
                                                Millisecond = 676;
                                                Minute = 40;
                                                Month = 2;
                                                Second = 19;
                                                Ticks = 634956072196762680L;
                                                TimeOfDay = 20:40:19.6762680;
                                                Year = 2013;}
> current.IsValueCreated;;
val it : bool = false
> current.Force();;
val it : System.DateTime = 2013/02/04 20:40:19 {Date = 2013/02/04 0:00:00;
                                                Day = 4;
                                                DayOfWeek = Monday;
                                                DayOfYear = 35;
                                                Hour = 20;
                                                Kind = Local;
                                                Millisecond = 676;
                                                Minute = 40;
                                                Month = 2;
                                                Second = 19;
                                                Ticks = 634956072196762680L;
                                                TimeOfDay = 20:40:19.6762680;
                                                Year = 2013;}
> current.IsValueCreated;;
val it : bool = true
> current.Force();;
val it : System.DateTime = 2013/02/04 20:40:19 {Date = 2013/02/04 0:00:00;
                                                Day = 4;
                                                DayOfWeek = Monday;
                                                DayOfYear = 35;
                                                Hour = 20;
                                                Kind = Local;
                                                Millisecond = 676;
                                                Minute = 40;
                                                Month = 2;
                                                Second = 19;
                                                Ticks = 634956072196762680L;
                                                TimeOfDay = 20:40:19.6762680;
                                                Year = 2013;}

Saturday, January 26, 2013

Tips for F# pattern match (3)

(In learning from "Programming F# 3.0, 2nd Edition")
(continued from phosphorescence: Tips for F# pattern match (2))
  • If a function takes one argument
  • And if that function uses pattern matching with same one argument

In this case, we can syntax sugar with function keyword. With using this keyword, we can omit both function argument and pattern matching keyword.

Before:
[<Literal>]
let Person_01_name = "Robert";;
let person_01_nickname = "Bob";;
[<Literal>]
let Person_02_name = "William";;
let person_02_nickname = "Bill";;
let greet name =
  match name with
    | Person_01_name -> printfn "Hello, %s" person_01_nickname
    | Person_02_name -> printfn "Hello, %s" person_02_nickname
    | x -> printfn "Hello, %s" x;;

After:
[<Literal>]
let Person_01_name = "Robert";;
let person_01_nickname = "Bob";;
[<Literal>]
let Person_02_name = "William";;
let person_02_nickname = "Bill";;
let greet =
  function
    | Person_01_name -> printfn "Hello, %s" person_01_nickname
    | Person_02_name -> printfn "Hello, %s" person_02_nickname
    | x -> printfn "Hello, %s" x;;

Thursday, January 24, 2013

Tips for F# pattern match (2)

(In learning from "Programming F# 3.0, 2nd Edition")
(continued from phosphorescence: Tips for F# pattern match (1))

If you want to declare some constants out of any pattern matches, simple let binding is not allowed. Because simple binding is not recognized, it is recognized as "value capture".
let person_01_name = "Robert";;
let person_01_nickname = "Bob";;
let person_02_name = "William";;
let person_02_nickname = "Bill";;
let greet name =
  match name with
    | person_01_name -> printfn "Hello, %s" person_01_nickname
    | person_02_name -> printfn "Hello, %s" person_02_nickname
    | x -> printfn "Hello, %s" x;;
      | person_02_name -> printfn "Hello, %s" person_02_nickname
  ------^^^^^^^^^^^^^^

stdin(8,7): warning FS0026: This rule will never be matched

      | x -> printfn "Hello, %s" x;;
  ------^

stdin(9,7): warning FS0026: This rule will never be matched

How do we do for? The answer is: using "literal binding".
  1. Add [<Literal>] atrribute
  2. Change an initial character of variable to upcase
[<Literal>]
let Person_01_name = "Robert";;
let person_01_nickname = "Bob";;
[<Literal>]
let Person_02_name = "William";;
let person_02_nickname = "Bill";;
let greet name =
  match name with
    | Person_01_name -> printfn "Hello, %s" person_01_nickname
    | Person_02_name -> printfn "Hello, %s" person_02_nickname
    | x -> printfn "Hello, %s" x;;

(continue to phosphorescence: Tips for F# pattern match (3))