Category Archives: Other

F# on Mac and Linux

is not, in 2012, in a great state. There are 2 not-great options and I add here a third, also not-great option. It has the advantage of working, and not requiring you to learn emacs. (Jump straight to F# with Sublime)

F# on MonoDevelop

The F# language bindings for MonoDevelop broke after version 2.4. You can get MonoDevelop version 2.4 by consulting the wayback machine for the MonoDevelop Download page at July 2011. You can then use the fsharpbindings and instructions from http://functional-variations.net/monodevelop/.
Personally I fould MonoDeveloper before 2.6 more prone to crashing, and I couldn’t get 2.4 working with FSharp.

F# on Aquamacs

If you’re an emacs fan, then you won’t need my help to find and install the f# mode for it.
For emacs newbies on the Mac with a day to burn on the learning curve, a couple of the answers on stackover gives you some clue as to how to get fsharp working:
http://stackoverflow.com/questions/1210125/is-there-any-f-ide-that-works-over-mono
http://stackoverflow.com/questions/2120533/how-to-setup-aquamacs-for-clojure-development

F# with Sublime Text 2 (Quick and Dirty)


This was the best I could do in 2 hours:

  1. Get Sublime Text 2
  2. In the Sublime text menu : Tools – Build System – New Build System
    {
    	"cmd": ["/usr/bin/fsharpcandrun", "$file"]
    }

    and save as fsharp.sublime-build .

  3. At a terminal command line, use your favourite editor to save this file as /usr/bin/fsharpcandrun :
    #!/bin/bash
    fsharpc "$1" && nameafterquote=${1#\"} && exe=${nameafterquote%.*}.exe && mono "$exe" && echo done
  4. Make it executable, again from a terminal command line:
    sudo chmod a+x /usr/bin/fsharpcandrun

    The password that sudo asks your for is your login password.

  5. If your new favourite editor is in fact Sublime, you can save files in directories requiring sudo-ed permissions by putting a command line alias for sublime in your ~/.bash_profile script:
    alias edit='open -a /Applications/Sublime\ Text\ 2.app/Contents/MacOS/Sublime\ Text\ 2'

    and typing edit foo.txt to open Sublime

  6. Choose Tool — build system — fsharp in Sublime
  7. Now, <f7> your file. It should compile and run. At least, it did for me.
  8. Get some kind of syntax colouring by creating a .fs file, and then choosing View — Syntax — Open all with current extension as … OCaml. This is because F# is near enough to OCaml for the colouring to be pretty good.

I wouldn’t call this great, but it will do for the moment. It only “builds” a single file, which is hardly a build system. But it does give you syntax colouring and compile-and-run for learning F#.

The next step forwards might be to modify the bash script to fsharpc a list of files, or all files in the directory of the file to be run.

Code Kata One as Code – Supermarket Pricing

The code kata on supermarket pricing is one we wanted to do because we have some interest in pricing rules. However, it’s written as a design exercise (which is a good thing), whereas we still wanted to do some coding.
So :

The Checkout Pricing Kata

Some things in supermarkets have simple prices: this can of beans costs £0.20. Other things have more complex prices. For example:
• three for a £ (so what’s the price if I buy 4, or 5?)
• £1.99/pound (so what does 4 ounces cost?)
• buy two, get one free (so does the third item have a price?)
Here’s an example stock list with pricing and rules

Stock Pricing
Baked Beans: 20p per can, with a three-for-two offer.
Bananas: £1 per Kg
Bagged Bananas: £1.20 per bag
Beer: £1.50 per bottle, with a three-for-£4 offer
Bagels: £3 per dozen or £2.00 per half-dozen or 50p each
Kitchen Roll: 50p each
Beer ‘n’ Beans Cleanup Offer: Buy 3 cans of beans, 3 bottles of beer and get one free kitchen roll (not combinable with any other offer).
Beans ‘n’ Bagel Breakfast Offer: Get 6 cans of beans and a dozen bagels for £3.50 (not combinable with any other offer).

Checkout Pricing

Write something which, given a list of items purchased, will print out a priced and itemised receipt, with weights shown where relevant and all discount rules correctly applied. The customer should not be able to get a better price by re-organising or splitting up the shopping basket. The receipt should help the uncertain customer to see this.
In TDD style, do it by writing code to pass tests for a list of increasingly complex requirements.

Example shopping baskets

• 1 can of beans, and 1 bottle of beer
• 6 can of beans, and 3 bottles of beer
• 5 cans of beans and 1.4 kg of loose bananas
• 3kg of bananas and 7 bagels
• 4 cans of beans, 3 bottles of beer and a kitchen roll
• 10 cans of beans, 15 bagels, 4 bottles of beer, 2 kitchen rolls, 3.5 kg loose plus 1 bag of bananas.

I leave to the retail stategists amongst you the question, “Should it always be impossible for the customer to get a cheaper price by adding something to their basket?”

iPad printing problems

iPad printing is unreasonably difficult. It all works fine no doubt if you go out and buy a shiny new AirPrint enabled printer. Otherwise the simplest/cheapest thing I’ve found is:

I’ve had network problems too, similar to the problems with iTunes. Replacing my router was the best solution I had for that. If your router is old, or a very cheap broadband freebie, you may need to replace it.

Sending large byte[] of binary data through WCF – a simple approach

You can send large streams of data through WCF in two ways: by streaming or by buffer. How to enable streaming is discussed here but has the significant restriction that if you stream, you can only have one (yes, 1) parameter into and out of the service. If your goal is just to pass largish objects such as a spreadsheet or a PDF as part of a service operation this could be a significant hurdle to code around.

“By buffer” means that your large data can be handled with no special treatment at all: it is sent, read into memory (the buffer), and processed just like small messages are. You must understand that buffering means the whole message is buffered; As of early 21st century, that fine on most servers for muliti-megabyte data, but not fine for gigabytes of data.

The simple way to handles megabyte messages is to create a binding Configuration with 2 or 3 parameters increased:

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpFor2MBMessage" maxBufferSize="2097152" maxReceivedMessageSize="2097152">
          <readerQuotas maxArrayLength="2097000" />
        </binding>
      </basicHttpBinding>
    </bindings>

and have your service endpoint use it:

<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpFor2MBMessage" contract="yourContractName>

Voila. You can now send a 2MB large array through SOAP to WCF.

If your large array is binary data, you declare it in your service classes as byte[], which is why you need the maxArrayLength setting. If you are creating test messages by hand or in a testing tool, you also need to know how to represent binary data in a SOAP message.
The usual answer is, use base64 encoding and it should just work, thus:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://MyServiceName">
   <soapenv:Header/>
   <soapenv:Body>
      <dat:Save>
         <dat:Id>111</dat:applicantId>
         <dat:Pdf>JVBE ... <i>base64 encoded string</i> .... JUVPRgo=</dat:contractPdf>
      </dat:Save>
   </soapenv:Body>
</soapenv:Envelope>

Caveats

Security

The WCF default small buffer and message sizes are a guard against DoS attacks so if your service is publicly visible this would leave it less well guarded.

Performance

How fast does your service process large requests?

If (Expected Peak Requests Per Minute) * (Seconds to Process a Request) is bigger than 60 (Seconds in a Minute) then you need more horsepower.

How much memory do you have?

If (Size of Message * Requests per Hour) – (Speed at which WCF frees up an hour’s worth of used buffers) is bigger than your available memory then you’ll fall over. Alas there is no simple setting for ‘Speed at which WCF frees up an hour’s worth of used buffers’ so that calculation is a problem for another blog post. If you might have a problem, you can use PerfMon to watch memory behaviour during a stress test.