F# Simple Twitter Update

A short while ago I posted some code for a C# twitter update.  I decided to move the same functionality / logic to F#.  Here is what I came up with.

   1:  namespace Server.Actions
   2:   
   3:  open System
   4:  open System.IO
   5:  open System.Net
   6:  open System.Text
   7:   
   8:  type public TwitterUpdate() = 
   9:   
  10:   //member variables
  11:   [<DefaultValue>] val mutable _body : string
  12:   [<DefaultValue>] val mutable _userName : string
  13:   [<DefaultValue>] val mutable _password : string
  14:   
  15:   //Properties
  16:   member this.Body with get() = this._body and set(value) = this._body <- value
  17:   member this.UserName with get() = this._userName and set(value) = this._userName <- value
  18:   member this.Password with get() = this._password and set(value) = this._password <- value
  19:   
  20:   //Methods
  21:   member this.Execute() = 
  22:      let login = String.Format("{0}:{1}", this._userName, this._password)
  23:      let creds = Convert.ToBase64String(Encoding.ASCII.GetBytes(login))
  24:      let tweet = Encoding.ASCII.GetBytes(String.Format("status={0}", this._body))
  25:      let request = WebRequest.Create("http://twitter.com/statuses/update.xml") :?> HttpWebRequest
  26:      
  27:      request.Method <- "POST"
  28:      request.ServicePoint.Expect100Continue <- false
  29:      request.Headers.Add("Authorization", String.Format("Basic {0}", creds))
  30:      request.ContentType <- "application/x-www-form-urlencoded"
  31:      request.ContentLength <- int64 tweet.Length
  32:      
  33:      let reqStream = request.GetRequestStream()
  34:      reqStream.Write(tweet, 0, tweet.Length)
  35:      reqStream.Close()
  36:   
  37:      let response = request.GetResponse() :?> HttpWebResponse
  38:   
  39:      match response.StatusCode with
  40:      | HttpStatusCode.OK -> true
  41:      | _ -> false

 

While the above seems to work, it feels to me like it is not taking advantage of some functional concepts.  Love to get some feedback as to how to make the above more “functional” in nature.  For example, I don’t like the mutable properties. 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted @ Wednesday, April 07, 2010 9:15 AM
Print

Comments on this entry:

# re: F# Simple Twitter Update

Left by Mark at 4/7/2010 10:26 AM
Gravatar
Mike - great post!

I am just learning the basics of F# so I could be wrong, but surely you would need something to be mutable to be able to send varying data?

I know everyone wants to go "pure functional", but from what I understood if it was purely functional you wouldn't have any mutable properties which would be useless?

Great post - look forward to more!

# re: F# Simple Twitter Update

Left by Steve Gilham at 4/7/2010 1:58 PM
Gravatar
A more functional style would separate the data (username, password, text body) into a record type, and the Execute member function would become a free-standing function in a module, taking that record type as an argument. Each message would take a new record instance, generated from the new user input.

Moving back towards an object-based approach (making the interfacing with C# that less noisy), it's possible make this type immutable instead, taking the three strings as construction parameters, and creating a new instance for each message, where otherwise you would (re-)set the mutable properties.

# re: F# Simple Twitter Update

Left by Robert at 4/8/2010 3:43 AM
Gravatar
This class is just bad design, even in C#. There is no reason to keep body around as a mutable property in an instance class. Makes for buggy code.

In F#, if the code is not going to be used from other langs, I'd probably make a simple function that takes the three parameters and posts directly.
If I wanted to reuse user/pass for several tweets, I'd use currying to provide a function that takes only the body:
let postTweet user pass body = ... impl ...
let newTweet = postTweet "user" "pass"
newTweet "My message"

# re: F# Simple Twitter Update

Left by mroberts at 4/15/2010 2:07 PM
Gravatar
@Robert. Thanks for the comment. Not sure if there is a large enough picture of this class use to determine if there is bad design. The original C# code is used in an environment such that "Actions" (this is an action) are reflected upon and invoked in the Parallel ForEach. Also, part of the design required (a self imposed requirement, but it made sense) for a parameter-less constructor. Anyway, for what we were doing it makes sense.

Your thoughts about a F# design, more functional in nature, make a lot of sense.
Comments have been closed on this topic.
«February»
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910