misc tips_and_tricks, jekyll

I’m glad I moved my blog to GitHub pages (especially after I saw this news) and I’m very happy using Jekyll locally while working on my posts. But as a recent Surface Pro 3 owner (review pending) I thought I could work outside home more often which broached the subject how do I synchronize the posts that are not ready to be published.

So far, I was storing them locally on my machine until they are finished which always posed the risk of losing them as they are the sole copy of the post.

Today I discovered a neat feature of Jekyll to end my local copy problem and making all my posts easily synced to everywhere: _drafts folder

Normally the posts go to _posts folder. Now I keep all incomplete posts under _drafts folder. I can checkin anytime as they don’t go live. And I can still use local Jekyll server by using the –drafts flag such as

bundle exec jekyll serve --drafts

With this flag they are compiled like normal posts which allows me to preview them easily.

Best of both worlds!

dev fsharp

Yesterday I started devoting 2 pomodoros a day on learning F#. I will post my findings as I go along. Currently I’m on my second day and still working TryFSharp.org tutorial website. I think these notes will come in handy in the future so I decided to post them regularly.

What I’ve learned today

  • Record types can be defined by type keyword such as
type Book = 
  { Name: string;
    AuthorName: string;
    Rating: int;
    ISBN: string }

New objects of type Book can be created by let bindings

let expertFSharp = 
  { Name = "Expert F#";
    AuthorName = "Don Syme, Adam Granicz, Antonio Cisternino";
    Rating = 5;
    ISBN = "1590598504" }  

These values are immutable but new objects can be created based on the current values:

let partDeux = { expertFSharp with Name = "Expert F# 2.0" }

If there are similar types F# will infer the last one defined. So when there are duplicate types it may be needed to use explicit definitions. For example

let expertFSharp = 
  { Name = "Expert F#";
    AuthorName = "Don Syme, Adam Granicz, Antonio Cisternino";
    Book.Rating = 5;
    ISBN = "1590598504" }  

In the above example Rating is referred explicitly by using the dot notation so that the correct type can be resolved.

  • Option types represent data that may or may not exist. There are two types: Some and None. Some is used when the data does exist and None is used when it doesn’t.
type Book =
  { Name: string;
    AuthorName: string;
    Rating: int option;
    ISBN: string }

Now Rating value is optional can be assigned None

Rating = None;
  • Discriminated Unions are equivalent of enums in C# and they can be defined by listing pipe-separated values:
type MushroomColor =
| Red
| Green
| Purple

Basics are covered in 4 sections in TryFSharp.org and this concludes the notes for the basics section. Next section is called Advanced F# Programming is composed of 5 sections. Tomorrow in my alloted time I’ll be looking into these sections.

Resources

dev fsharp

I’m not a big fan of New Year’s resolutions. I was meaning to start learning F# and since it’s the new year’s 2nd day it might a good time to finally give it a shot!

Where to start

It’s always hard to find the best resource when you are starting. Some time ago I heard about a Microsoft Research project called TryFSharp.org. It’s a tutorial website geared towards the absolute beginners. It comes with a REPL editor so no extra tools are needed to start.

From now on I’m planning to spend 2 pomodoros (around 1 hour) every day to learn F#. After my first 2 pomodoros I completed the first 3 sections and below are my notes for today’s training.

Lecture Notes

  • let keyword to bind names to values. These bindings are immutable. If you try to assign a value to a same name twice you get the following error:
let duplicated = "original value"
let duplicated = "new value"

causes the following error:

stdin(8,5): error FS0037: Duplicate definition of value 'duplicated'
  • Mutable variables can be created by explicitly specifiying mutable keyword but it should be used cautiously.
  • F# is a statically typed language like C#
  • printfn can be used to display messages. Strings can be formatted by using special characters such %d for int, %s for string such as
printfn "The answer is %d" 42
  • let can also be used bind a name to a function. The following code
let square x =
    x * x

square 4

produces this result in the output window:

> let square x =
      x * x
  
  square 4

val square : x:int -> int
val it : int = 16

> 
  • F# is whitespace-sensitive. In the function above the body of the function was denoted by indenting it 4 spaces and return values is the last line of the function.
  • In times when F# cannot determine the type on itw own, it can specified explicitly bu using type annotations. For example:
let toLeetSpeak (phrase:string) =
    phrase.Replace('t', '7').Replace('o', '0')

toLeetSpeak "root"

In the example above it needs to be specified that phrase if of type string before String.Replace method can be called.

  • Functions can be defined inside other functions:
let quadruple x =    
    let double x =
        x * 2

    double(double(x))
  • A function can be used as an argument to another function to create what’s called a higher order function.
  • Inline functions can be created such as
let square = (fun x -> x * x)

Theres are called lambda functions or lambdas.

  • Lists can be created by semi-colon separated single values or a range values with .. in between such as
let evens = [2; 4; 6; 8]
let firstHundred = [0..100]
  • Higher-order functions can be combined with other functions such as
let firstHundred = [0..100]
List.map (fun x -> x * 2) 
    (List.filter (fun x -> x % 2 = 0) firstHundred)

which produces the following output

val it : int list =
  [0; 4; 8; 12; 16; 20; 24; 28; 32; 36; 40; 44; 48; 52; 56; 60; 64; 68; 72; 76;
   80; 84; 88; 92; 96; 100; 104; 108; 112; 116; 120; 124; 128; 132; 136; 140;
   144; 148; 152; 156; 160; 164; 168; 172; 176; 180; 184; 188; 192; 196; 200]

It first filters the odd numbers out of firstHundred list and send the result to map function to double all the values.

  • Forward-pipe operator can be used to make the code easier to read when functions are chained:
[0..100]
|> List.filter (fun x -> x % 2 = 0)
|> List.map (fun x -> x * 2)
|> List.sum
  • Array indexing is zero-based.

Resources