F# for heating

Sometimes, when you feel really alone and want a bit of heat then F# can help you here.

All you need is a laptop and F#. Just type the following snippet into FSI and wait for a minute. =)

[|1..999|] |> Array.Parallel.iter (fun _ ->
    while true do ignore())

Wish you warm Christmas!

P.S. The same solution works when you are freezing.

Accessing Local Variable Information in FSI

It’s time to make first steps to the new improved FSI. I feel that I should start looking for ways to implement something from My wish list for FSI. Let’s begin from #3 and try to find a list of declared variables and functions.

Before execution of any piece of code, FSI compiles it and creates a new type in current assembly. This type contain all named variables as properties and named function as function. The latest unnamed variable/function stores in property that called ‘it‘. So, it means that we can collect all required information using reflection.

Below you can find my implementation of the function objects() that prints lists of declared variables and functions.

let objects() =
  let methods =
    System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
      |> Seq.filter (fun t ->
        t.CustomAttributes |> Seq.exists (fun a ->
          a.AttributeType = typeof<Microsoft.FSharp.Core.CompilationMappingAttribute>))
      |> Seq.sortBy (fun t -> t.Name)
      |> Seq.map (fun t ->
        t.GetMethods() |> Seq.filter(fun m -> not(m.IsHideBySig)))
      |> Seq.concat
      |> List.ofSeq
  let var, func =
    Map.empty<string, System.Reflection.MethodInfo>
      |> List.foldBack (fun (m:System.Reflection.MethodInfo) map ->
              let name = if (not(m.IsSpecialName)) then m.Name
                         else m.Name.Substring(4)
              if ((m.IsSpecialName && (m.GetParameters().Length > 0)) ||
                  map.ContainsKey(name)) then map
              else map.Add(name, m))
         methods
      |> Map.toList
      |> List.partition (fun (_,m) -> m.IsSpecialName)

  let printList title ls =
    printfn "%s : %A" title ( ls |> List.map fst |> List.sort )
  var  |> printList "Variables"
  func |> printList "Functions"

Now let’s look at a real-life example on the screenshot below.

My wish list for FSI

I have thought about possible directions of FSI development. I have some ideas that I would like to share and discuss.

In general, it would be great to make FSI more than just an execution shell. It can become a really powerful development tool. What exactly we can do:

1) Session Save/Load functionality

It will be nice to have an ability to save current FSI state into the file and continue work in the next time.

2) Native C# interaction with FSI saved sessions

It could sound crazy, but  it would be cool to save FSI session to assembly and provide an easy C#-F# interaction with such assemblies.  For example, it might be useful for Machine Learning tasks. You will be able to create, train and tune your model directly from FSI then save it to assembly and use it from your C# application.

3) Current environment overview

Provide an ability to see the difference between current FSI state and default state. For example:

  1. Print all declared variables with their values
  2. Print all declared function with their signatures
  3. Print list of referenced assemblies with included directories
  4. Provide an ability to print function’s body

There is a tool that provides a part of this functionality. This is FsEye – a visual object tree inspector for the F# Interactive.

4) Intellisense for FSI
5) Detailed type provider description

One of the main cons in type providers is impossibility to explore the schema of the provided world. For example, I want to use Freebase type provider, but I do not know the nature of the provided types. I cannot use provided types fully, because I do not know what data they have.

I am pretty much sure that we need to supply a way to explore provided types. This feature for sure should be tightly integrated with F# IDEs (into Object browser for example).

6)Interactive help

All we use MSDN to understand how things work. We copy type name + function name and paste them to Google, find first MSDN link and go there. Why cannot we teach FSI to do it? We just need to build an easy syntax for that.

7) The ability to use the load directive inside of modules\functions (by @davidkl_)

P.S. I will be happy to hear your feedback or new ideas. Feel free to post comments here or to contact me in twitter (@sergey_tihon).

“F# Weekly” under the hood

Under the F# Weekly news preparation lies a simple F# script.

This script uses Twitterizer2  – one of the simplest Twitter client libraries for .NET. Source code ia available on GitHub, binaries are available through NuGet.

Script logic is relatively simple. First of all, collect a list of queries for Twitter.

    let tweets = ["#fsharp";"#fsharpx";"@dsyme";"#websharper";"#fsharpweekly"]

Then make a call to the Twitter Search API for each query, concatenate the results for last week and sort all tweets by creation date.

                |> List.map (getTweets (DateTime.Now - TimeSpan.FromDays(7.0)))
                |> List.concat
                |> List.sortBy (fun t -> t.CreatedDate)

Then leave only ‘en’ news and filter out tweets without links and RT leaving only first occurrence of each unique link.

                |> List.filter (fun t -> t.Language = "en")
                |> filterUniqLinks

Also in the source code below you can find console printing method for results verification and html printing method for further manual results review.

Feel free to use it in your social researches.

#r "Twitterizer2.dll"

open Twitterizer
open Twitterizer.Entities
open System
open System.Net
open System.Text.RegularExpressions;

let getTweets (sinceDate:DateTime) query =
    let rec collect pageNum =
        let options = SearchOptions(NumberPerPage = 100, SinceDate = sinceDate, PageNumber = pageNum);
        printfn "Loading %d-%d" (pageNum*options.NumberPerPage) ((pageNum+1)*options.NumberPerPage)
        let result = TwitterSearch.Search(query, options);
        if (result.Result <> RequestResult.Success || result.ResponseObject.Count = 0)
            then List.empty
            else result.ResponseObject |> List.ofSeq |> List.append (collect (pageNum+1))
        collect 1 |> List.rev

let urlRegexp = Regex("http://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?", RegexOptions.IgnoreCase);

let filterUniqLinks (tweets: TwitterSearchResult list) =
    let hash = new System.Collections.Generic.HashSet<string>();
    tweets |> List.fold
        (fun acc t ->
            let mathces = urlRegexp.Matches(t.Text)
            if (mathces.Count = 0) then acc
            else let urls =
                   [0 .. (mathces.Count-1)]
                       |> List.map (fun i -> mathces.[i].Value)
                       |> List.filter (fun url -> not(hash.Contains(url)))
                 if (List.isEmpty urls) then acc
                 else urls |> List.iter(fun url -> hash.Add(url) |> ignore)
                      t :: acc)
        [] |> List.rev

let printTweets (tweets: TwitterSearchResult list) =
    tweets |> List.iter (fun t ->
        printfn "%15s : %s : %s" t.FromUserScreenName (t.CreatedDate.ToShortDateString()) t.Text)

let tweets = ["#fsharp";"#fsharpx";"@dsyme";"#websharper";"#fsharpweekly"]
                |> List.map (getTweets (DateTime.Now - TimeSpan.FromDays(7.0)))
                |> List.concat
                |> List.sortBy (fun t -> t.CreatedDate)
                |> List.filter (fun t -> t.Language = "en")
                |> filterUniqLinks
printfn "Tweets count : %d" tweets.Length
printTweets tweets

let printTweetsInHtml filename (tweets: TwitterSearchResult list) =
    let formatTweet (text:string) =
        let matches = urlRegexp.Matches(text)
        seq {0 .. (matches.Count-1)}
            |> Seq.fold (
                fun (t:string) i ->
                    let url = matches.[i].Value
                    t.Replace(url, (sprintf "<a href=\"%s\" target=\"_blank\">%s</a>" url url)))
                text
    let rows =
      tweets
        |> List.mapi (fun i t ->
            let id = (tweets.Length - i)
            let text = formatTweet(t.Text)
            sprintf "<table id=\"%d\"><tr><td rowspan=\"2\" width=\"30\">%d</td><td rowspan=\"2\" width=\"80\"><a href=\"javascript:remove('%d')\">Remove</a><td rowspan=\"2\"><a href=\"https://twitter.com/%s\" target=\"_blank\"><img src=\"%s\"/></a></td><td><b>%s</b></td></tr><tr><td>Created : %s <br></td></tr></table>"
                     id id id t.FromUserScreenName t.ProfileImageLocation text (t.CreatedDate.ToString()))
        |> List.fold (fun s r -> s+"&nbsp;"+r) ""
    let html = sprintf "<html><head><script>function remove(id){return (elem=document.getElementById(id)).parentNode.removeChild(elem);}</script></head><body>%s</body></html>" rows
    System.IO.File.WriteAllText(filename, html)

printTweetsInHtml "d:\\tweets.html" tweets

F# Weekly #44, 2012

Friends don’t let friends use null.
Don Syme

Welcome to F# Weekly,

A roundup of F# content from this past week:

Blogs & Tutorials

Resources & Books

F# Snippets

News from the past

 That’s all for now.  Have a great week and remember you can message me on twitter (@sergey_tihon) with any F# news or use hashtag #fsharpweekly.

P.S. Please share with me hashtags that you use for F# projects and F# related technologies.

Previous edition of the F# Weekly – #43

OData Type Provider with SharePoint 2010

‘Type Providers’ is an extremely cool F# feature that was introduced with F 3.0 and shipped with VS 2012 and .NET 4.5. You can find Type providers’ explanation  here and details about OData type provider here.

It maybe not a news, but OData Type Provider works pretty well with SharePoint 2010.

SharePoint 2010 has a OData Service. You can find mode details about this service at the MSDN article Query SharePoint Foundation with ADO.NET Data Services

One special thing that distinguishes SharePoint service from the others is that you should be authenticated. Just set your credentials into created data content before using it. You can find full code sample below.


#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.Services.Client.dll"

open Microsoft.FSharp.Data.TypeProviders
open System.Net

type sharepoint = ODataService<"http://server_name/_vti_bin/listdata.svc">
let web = sharepoint.GetDataContext() in
    web.Credentials <-
        (NetworkCredential("user_name", "password", "domain") :> ICredentials)

(web.Documents)
    |> Seq.iter (fun item -> printfn "%A : %s" item.Modified item.Name)

64bit fsi (FSharp Interactive) already available !!!

The good news for all F#/SharePoint lovers! As I learned today, 64 bit version of fsi already available as a part of F# 3.0. It is FsiAnyCPU.exe (at C:\Program Files (x86)\Microsoft SDKs\F#\3.0\Framework\v4.0).

These mean that now we should be able to connect to the SharePoint directly from fsi. It’s really cool !!!

As I see, into vs2012 we can choose version of fsi from Tools->Options.

P.S. Great thanks to the Mauricio Scheffer for great news.

How to delete broken EventReceiverDefinitions

When you use SharePoint 2010 event receivers for sites, webs or list you may get a broken event receiver definitions. It could be due to incorrect event receivers managment, you used packages that left broken event receiver definitions or something like that.

It is too hard to manually remove all broken definitions from whole site collection. I do not know useful tool for this purpose.

The following script do it for you. It is iterates through all webs and lists into site collection and remove all event receiver definitions that point to not exist assemblies.

open Microsoft.SharePoint

module EventReceiversCleaner =
    let private isAssemblyExist (assemblyName:string) =
        try
            match System.Reflection.Assembly.Load(assemblyName) with
             | null -> false
             | assembly -> assemblyName = assembly.FullName
        with
         | e -> false

    let private removeCandidates = ref List.Empty

    let CollectBroken (collection:SPEventReceiverDefinitionCollection) =
        for er in collection do
            if not (isAssemblyExist er.Assembly) then
                removeCandidates := er :: !removeCandidates

    let RemoveAll() =
        !removeCandidates |> List.iter
            (fun (er:SPEventReceiverDefinition) ->
                let name = sprintf "Assembly:'%s'" er.Assembly
                try
                    er.Delete()
                    printfn "Deleted : %s" name
                with
                 | e -> printf "Failed to delete: %s" e.Message)

try
    let url = "http://localhost/"
    printfn "Connecting to '%s'..."  url
    use site = new SPSite(url)
    site.EventReceivers |> EventReceiversCleaner.CollectBroken

    let rec collectFromLists (web:SPWeb) =
        printfn "Processing web '%s'..." web.ServerRelativeUrl
        web.EventReceivers |> EventReceiversCleaner.CollectBroken
        web.Webs |> Seq.iter collectFromLists

        for list in web.Lists do
            printfn "Processing list '%s'..." list.Title
            list.EventReceivers |> EventReceiversCleaner.CollectBroken

    use web = site.OpenWeb()
    collectFromLists web

    EventReceiversCleaner.RemoveAll()
    printfn "Finished."
with
    | e -> printfn "Exception : %s" e.Message

System.Console.ReadLine() |> ignore

P.S. You should compile it using .NET 3.5 and 64 bit project.