• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

Date: Saturday, 29 Jun 2013 20:17

Originally posted on: http://geekswithblogs.net/Erik/archive/2013/06/29/153290.aspx

I've been staring at the computer for a few minutes now and I honestly don't know what to write.  First I thought of writing about myself, where I was born, where I studied, where I am now... but that seems shallow.  Now that I thought about it.  I'd rather not talk about who I am because it seems irrelevant right now.  What I really want to say is..

I'm sad.  Been like this for quite some time now.

I tried telling my wife but I guess she didn't think it was serious.  We were having a fight when I told her so she probably thought I was just making up an excuse for my behavior.

I'm not sad every single day.  Some days I'm perfectly fine.  I actually have no idea when I'd feel sad.  It just happens. I'd wake up cheerful and then before I go to bed I already feel depressed.  I have no idea what triggers it.  On the bed, I'd turn my back to my wife, curl up into a fetal position and start sobbing silently. Awful.

Maybe you're wondering now what's the cause of all this.

My grandma passed away and I haven't completely  come to terms with that fact.  I long to see her, talk to her and hold her... but I can't do that anymore because she's gone.  I will never be able to hear her voice and feel her touch again.  To make matters worse, the only person whom I wish would stay beside me whenever I'm feeling miserable and dejected is never around.  She's either working late or out with her friends.  Such is my life at the moment.  I doubt it will improve anytime soon.

Author: "Erik Araojo"

Date: Friday, 14 Dec 2012 08:55

Originally posted on: http://geekswithblogs.net/Erik/archive/2012/12/13/151544.aspx

## Introduction

REST services has been steadily gaining popularity over the past years.  While SOAP web services are still being used, (and will not go away), it is no longer the preferred method of providing an online API (application programming interface) to web sites and/or services.  Google for example have stopped supporting their SOAP-based API and is almost exclusively using REST based services. Several companies like , especially startups (or previous startups) such as Reddit, Imgur only provide REST APIs

With this tutorial I'd like to show you how easy it is to test REST services using a tool called WCFStorm.REST. With just 2 clicks you can already start interacting with your service

## Before we begin

WCFStorm.REST can be downloaded here at http://www.wcfstorm.com, or directly from here.  If you go into the web site, you probably noticed that WCFStorm.REST is a commercial tool.  But don't worry a LITE version of it is available for free and has enough features especially for developers who just needs to simply call REST services.  The FULL version is aimed mainly at Software Testers who needs to prepare test cases, compare actual and expected responses, etc.

So now go download WCFStorm.Rest.  The first time you run it, it will open in 15-day trial mode.  That is OK.  After the trial period is over it will convert to LITE mode and you'll still be able to use the tool.

Note:  You can use discount code RESTPROMO to get a 30% off on WcfStorm.Rest

In order to get the content of the programming subreddit, we need to use this url, http://www.reddit.com/r/programming.json.  Notice that it ends with ".json"?  That's because that URL returns JSON.  If you want to get back an XML instead, just change the ".json" to ".xml"

Reddit's full API is described here http://www.reddit.com/dev/api

## Let's get started

Assuming, you've already downloaded the tool,  go double click on WcfStorm.Rest.exe to open it up.   You'll get the screen below.  It's a welcome screen.  It shows you the operations/functionalities of the tool.

## Click #1 : Click on the QuickTest Tab

Or you can also click on the "Test" tile.  It doesn't matter you will still get the window below.  Enter the text "http://www.reddit.com/r/programming.json" on the url textbox.  Reddit expects an HTTP GET request on that URL, so leave the "Verb" dropdown list unchanged. By default, the it should have the "GET" option selected.

## Click #2: Click the Send button. Done.

Click the send button (the one with the Green Play icon) to send the HTTP GET request to reddit's service.  Wait a second or two and if all goes well you'll get back the response below.  The HTTP headers are displayed on the upper right while the response body is shown below it.  Notice that the JSON response has syntax highlighting ( a nice little touch, if I may say so)

So there you go.  All it took was 2 clicks.  And finally, as the JSON response says, the top submission is about a security vulnerability in internet explorer, titled "Any page loaded in IE can track your mouse movements, anywhere, any time",".  Not a very comforting thought.

## Points to consider

WcfStorm.Rest runs on .NET 4.0 so you need to install the 4.0 framework if you want to use this tool.  If you only have .NET 4.5, you have to delete WcfStorm.Rest.exe.config so that it will run, otherwise it will crash.  For some reason the config points to the 4.0 Fsharp assemblies.  Deleting the config file, forces it to use the 4.5 assemblies.

Author: "Erik Araojo"

Date: Monday, 20 Sep 2010 05:29

you must be a C++ programmer.

Author: "Erik Araojo"

Date: Wednesday, 04 Aug 2010 19:36

Originally posted on: http://geekswithblogs.net/Erik/archive/2010/08/04/141185.aspx

One of the benefits of using WCF is that you're not  required to host it in IIS.  Most people create console hosts during development and then just use windows service in production.  This is a quick and very easy way of hosting WCF services especially if you just have 2 or 3 services.  However, when the number of wcf services gets too high, controlling them using the mmc snap-in (services.msc) can get a bit tedious (maybe not if your powershell or WMI kung fu skills are quite good).

However, if you're tired of writing these repetetive console/windows service hosts and is looking for another way of managing WCF services, then try out WcfStormHost.  It will let you dynamically host WCF Services without ever writing a single code.  Each WCF service is hosted in its own AppDomain so you wont have to worry about wcf services interfering with each other.

Here's a quick rundown of its features

1. Auto-discover and host WCF services
- WcfStormHost can read a folder containing assemblies (*.dll and *.exe) and *.config and automatically determine the service type to host.

2. It monitors changes in the *.dll and *.config files.  If it detects changes, it automatically re-hosts the service!  You won't have to manually restart the service, unlike a windows service host. It doesnt lock the assembly file which means deployment is much simplified.  You just simple need to copy over the dll or config file.

During development this is also very useful  because you can setup WcfStormHost to host a service located in your $Project/bin/Debug folder. This means that everytime you make a code change and recompile, the service automatically gets re-hosted. 3. It has a simple, intuitive UI for managing services. WcfStormHost (specifically the system tray host) can be started as an application that sits on your system stray (as in the screenshot above) which means it is easy to find. If you need to do something on a wcf service, just click on the system tray icon and the main UI will popup over it. 4. It can auto-load wcf services. WcfStormHost has an optional config file called Host.config. This file can be created by clicking the "Save" icon in the menu. The host.config file can contain a list of WCF services which are automatically loaded at startup. Shown below is a sample service configured to be auto-started. The assembly files + the config file (<ConfigFile>WcfService.dll.config</ConfigFile>) are located in the value specified by the <Path> node.  <WcfService id="MySvc" type="WcfService.MyTestSvc, WcfService"> <Status>Start</Status> <BinFolder> <ConfigFile>WcfService.dll.config</ConfigFile> <Path>D:\Work\Source-Mine\WcfStormHost\WcfService\bin\Debug</Path> </BinFolder> <Activity> <ShutDownifIdle>false</ShutDownifIdle> <MaxIdleTime>10000</MaxIdleTime> </Activity> </WcfService> 5. For quick debugging, it allows you to trace WCF messages being sent and received by the hosted wcf service. Just select a service and then click on the "Trace" button on the right-hand side. Shown below is the trace window. 6. It creates log files for each of the hosted services. The log files are created daily and can be configured not to exceed a certain size. By default a log file can not exceed 0.5 MB. Old log files and log files that exceed the size limit are moved into the "archive" folder. Try it out and see for yourself. Get Started Download WcfStormHost (blue download icon on the right hand-side) These are the current features of WcfStormHost and of course suggestions for more features are most welcome! Please post it in the comments or send a mail to erik-dot-araojo@wcfstorm.com Author: "Erik Araojo" Date: Friday, 04 Dec 2009 16:27 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/12/04/136688.aspx One of the more common design patterns used in object oriented languages like C# is the Composite Pattern. The main benefit of using this pattern is that it allows us to treat individual objects and composite of objects in the same way. In the UML below, the type Component is abstract and defines the operations (method1 and method2) which are implemented by the concrete types Leaf and Composite. The type Composite contains a collection of Component objects. Due to the fact that it inherits from Component we can write code that invokes method1 and method2 without knowing the specific type. For example, suppose we work at a fast food chain and we'd like to write code for computing the price of fries, burger, coke or a combo meal. Following the composite pattern, we could create an abstract class called Product which has the GetPrice() method and then one class each for Burger, Fries, Coke and ComboMeal. Component --- maps to --> Product Leaf --- maps to --> Burger, Fries, Coke Composite --- maps to ---> ComboMeal Our C# code would look like public abstract class Product { public abstract double GetPrice(); } public class Fries : Product { public override double GetPrice() { return 1.0; } } public class Burger : Product { public override double GetPrice() { return 5.0; } } public class Coke : Product { public override double GetPrice() { return 2.0; } } public class ComboMeal : Product { List<Product> _products = new List<Product>(); public void Add(Product p) { this._products.Add(p); } public override double GetPrice() { var sum = 0.0; foreach (var p in _products) sum += p.GetPrice(); return sum; } } we can then write a helper method that Computes a price. This method does not need to know whether its computing the price of a single item (Fries, Burger ) or that of a combo meal. public static double ComputePrice(Product p) { return p.GetPrice(); } Suppose, someone ordered 1 fries and 1 Burger separately, our code will be, var totalFriesAndBurger = ComputePrice(new Fries()) + ComputePrice(new Burger()); Now if another one ordered a Combo meal (Fries + Coke + Burger), our code will be var combo = new ComboMeal(); combo.Add( new Fries()); combo.Add( new Burger()); combo.Add( new Coke()); var totalCombo = ComputePrice(combo); That's it. For our C# implementation (not counting the helper method ComputePrice() ), we have 5 classes and approximately 40 lines of code. #### Now lets see how we can implement the same pattern in F#. Knowing that the types Fries, Burger, Coke and ComboMeal are just different representations of the Product type, we can model this relationship cleanly in F# using discriminated unions. To represent the the combo meal, we make it into a tupleof 2 products. An item of this tuple can be a single product (Coke, Fries or Burger) or any combination (i.e a combo) type Product = | Fries of double | Coke of double | Burger of double | Combo of Product * Product And how about the GetPrice method, you'd ask? That's easy enough; F# allows us to add methods to union types. Implementing that, our code now looks like this. Notice the "with member w.GetPrice()" part? type Product = | Fries of double | Coke of double | Burger of double | Combo of Product * Product with member w.GetPrice() = match w with | Fries(p) | Coke(p) | Burger(p) -> p | Combo(p1,p2) -> p1.GetPrice() + p2.GetPrice() Again, if someone ordered a combo meal our code will look like let combomeal = Combo(fries, Combo(burger, coke)) Console.WriteLine( "Combo meal Total = " + combomeal.GetPrice().ToString()) That's just cool isn't it? With F# we ony 1 Union type and about 10 lines of code Author: "Erik Araojo" Date: Thursday, 03 Dec 2009 12:33 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/12/03/136670.aspx I bought myself an early christmas gift and purchased the book "Functional Programming in the Real World" by Tomas Petricek. The book is available through Manning's early access program. I've been drooling over this book for a long time and finally I have it now! (cue music: Jingle bells, jingle bells jingle all the way..) Sadly though I have an exam coming (I'm taking my masters in Software Engineering) in 2 weeks time and now I need to force myself to study the lecture notes and not read Tomas's book. Arrgh. P.S I was able to buy the book using donations from Storm. Thanks guys! Author: "Erik Araojo" Date: Friday, 31 Jul 2009 10:44 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/07/30/133826.aspx A few months ago I've promised that version 1.1 will be released in July. Today I make good on that promise and am happy to announce that version 1.1 is ready for download! A very big thanks goes out to those who not only have purchased WCFStorm but also provided valuable feedback in terms of feature requests and bug reports. Thank you very much guys. Below are the main features of version 1.1 1. Loading of existing client App.config files into WCFStorm 2. One-click execution of all functional test cases under a method or of the whole WCF service. 3. A plugin interface for custom validations of functional test cases. 4. A plugin interface for randomizing requests or re-using the previous response as input to the next request. 5. A plugin interface for programmatically modifying the ServiceEndpoint instance 6. A plugin interface to support Duplex services Here's the full list of what's new in 1.1 Author: "Erik Araojo" Date: Wednesday, 08 Apr 2009 09:48 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/04/07/130799.aspx If you're not yet familiar on how to add a service and invoke a method, please see Getting Started The short video below shows how to create and execute a functional test case in WCFStorm. Towards the end of the video, it shows one of the main features of functional testing with WCFStorm - which is the ability to visually view the difference between the expected and actual responses in a test. Author: "Erik Araojo" Date: Wednesday, 08 Apr 2009 04:52 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/04/07/130793.aspx If you're not yet familiar on how to add a service and invoke a method, please see Getting Started The video below shows the steps on how to create and run performance test cases. When a performance test case is executed, WCFStorm captures the responses and displays a graph in real-time the actual and average response times as well the rate at which the service is responding the method invocations. ### The following are the performance test parameters • Number of agents • This is the number of background workers that will repeatedly invoke the service method until the test is stopped or the test duration has completed. • Rampup • This is the interval in seconds at which the agents are created. For example, if the rampup value is "1", every second, WCFStorm will create an agent until it has reached the specified number of agents • Test duration • This is the test duration in seconds • Invoke interval • This is the interval in milliseconds at which an agent repeatedly invokes a service method Sample Perf Test setup 1. Constant Load • This can be achieved by setting the "Rampup" value to zero 2. Incrementing number of users • Set "Rampup" and "Number of Agents" to a non-zero value. ### Some screenshots Author: "Erik Araojo" Date: Sunday, 05 Apr 2009 02:57 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/04/04/130732.aspx In order for WCFStorm to invoke a service having a netTcp endpoint, the service must be configured to expose the WSDL via http. A sample config for the WCF service will be, In above configuration, the service is using 3 bindings. mexHttpBindings is used to expose the WSDL, while netTcpBinding and wsHttpBinding are for the actual methods calls. To test the serivice using WCFStorm, use the mexHttpBinding url to add the service. As can be seen from the log, the tool detected both the netTcpBinding and WsHttpBindings. If we select a method and invoke it ( (please see getting started on the steps to invoke a method) , the tool will select the endpoint that was declared first (which is NetTcpBinding). If you'd like to use the other endoint, wsHttpBinding, right-click the service and select "ModifyEndpoint" This will bring up a form which lets you choose the binding that you'd like to use. Click on the dropdown to select a new binding. You can also specify a new endpoint address in this form. Click OK to use the selected binding. This will trigger WCFStorm to regenerate a proxy class that uses the new binding. All subsequent method invocations will now use the new proxy (and hence the new binding). Author: "Erik Araojo" Date: Sunday, 05 Apr 2009 02:19 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/04/04/130731.aspx EDIT : Please visit www.wcfstorm.com for th updated tutorials. This is a first in a series for post describing the tasks and the features available inWCF Storm. 1. Getting Started 4. How to create and execute a functional test Ok, so lets get started.... ## Getting Started : (Invoking a method of a WCF/Web service) 1. ### Add a service. This can be done by either clicking "File --> Service --> Add" or by clicking the Add button in the menu bar. This will bring up a form where you can type in the metadata exchange endpoint (i.e. WSDL endpoint). WcfStorm will then read the wsdl, generate the client code and compile it. If all goes well, the service and its method will be displayed on the left hand side. Now go ahead and select on method ### 2. Select a method If a method is selected, its parameters will be read and displayed in the "RequestPane'. In the screenshot below I've selected the method "GetDataUsingContract" which takes parameter of type "CompositeType" The structure of CompositeType is shown below. As you can see, what's displayed in the request pane matches exactly the defined type. Now, select a field of the composite type parameter. ### 3. Edit a field in the parameter This will bring up the Object Editor which will let you edit the field. If the type is not primitive, the "Set to null' checkbox will be enabled. If the tye of the selected field is polymorphic, the object editor will display the subtypes that can be assigned to the field. Here I've selected the string field. Clicking OK will assign the value "my string" to the StringValue field of the CompositeType parameter. Now Click Send (Green arrow) ### 4. Invoking the service method Click on send to invoke the web method. The test service we are invoking merely echoes back the input parameters it has received ( a convenient way of checking that the object editor in the previous step worked). This is shown in the screenshot below Looking at the log, we can see that WCFStorm used the NetTcpBinding endpoint. Recall that when we added the service, we used http://localhost:8080/httpEndpoint?wsdl - obvoiusly an endpoint that uses http. So how come the tool is now using NetTcpBinding? In this case, the service that we are using declared 3 endpoints in its config. An http endpoint for the metadata exchange (to expose the wsdl) a NetTcpBinding and a WsHttpBinding endpoint for the actual method calls. By default WCFStorm uses 1st endpoint that was declared by the service (which was the NetTcpBinding.) That's it! we have now successfully invoked the WCF service. Author: "Erik Araojo" Date: Friday, 03 Apr 2009 01:16 Originally posted on: http://geekswithblogs.net/Erik/archive/2009/04/02/130664.aspx During the last few months I've been working on a commercial tool for testing WCF services. The knowledge I learned building STORM really helped alot in building this tool. So here it is my fellow coders, WCF Storm. It has more features than its open source cousin, STORM and the best part is it works on both WCF and Web services! EDIT : www.wcfstorm.com is up! Please visit the site for updates and to purchase WCFStorm online ### System Requirement: • .NET Framework 3.0 or higher. ### Features at a glance: General: • Dynamically invoke and test WCF Services • Dynamically invoke and test Web services written in any language • Save your opened service and its test cases into a "project" which can be reloaded anytime • Dynamically invoke service methods even those containing complex data types • UI-based, dynamic editing of complex data types • Test multiple WCF and Web services within a single UI. • Multiple-tabbed interface • Basic and windows authentication • Test services sitting behind a proxy • Dynamically modify the URL endpoint of a WCF or Web service. • Dynamically edit the service binding. Functional Testing: • Create functional test cases and save it as part of a project • Create and save functional test cases containing Expected results. • Graphically compare (side-by-side) the expected results with the actual response of a service. Performance Testing: • Create performance test cases and save it as part of a project • Graphically display charts in real-time as the performance test progresses. • Configurable test parameters (# of Agents, Test duration, interval etc.). You can stress out your service as much as you want. What all these features mean is that testing WCF/Web services becomes a breeze and you'll have plenty of time to spend on writing the logic of your service (which is what you should be really doing). Performance testing screenshot: Functional testing screenshot: Check out the gallery for more screenshots. Try it out! Download the trial version below. ### or Buy Now orLearn more ### So how much does it cost? Short answer is ... Not so much! I've priced the tool for the budget conscious. Consider this, I used to work for a company that bought a license for a soap testing tool that costs almost 700 USD (that's right7 hundred!) annually per seat. It was a great tool. It had tons of features but the problem was, we rarely used them. We mainly used it to invoke web service methods and verify that the results are correct. All the other features that the company paid (dearly) for, were rarely or sometimes never used. Why pay so much for unused features? So how much does WCF Storm cost? • Personal Edition : 14.99 USD only (annually/seat ) • Enterprise Edition : 49.99 USD only (annually for 10 seats!) • (EDIT : I've finalized the pricing structure for WCFStorm. Please visit http://www.wcfstorm.com/wcf/buynow.aspx to view the offers) Not bad, huh? :) For such a low price not only can you test WCF services, it even works on Web services. if you buy now and be part of the first 100 to purchase WCF Storm, I'd extend your license for 2 years! However, if you think that the price is expensive, drop me an email and we can discuss the price we're both comfortable with. ### I love the price, but why didn't you just open source it like STORM? I think these words are sufficient to answer that question: • #### Recession This recession that we all are experiencing right now has also affected myself and my family. I still have my job but I can't tell whether next month I'd still have it. Some people had already been let go and management has been awfully quiet on when the next round of layoffs will be. I have a wife and a lovely 5 year-old daughter to care for. I also have a mortgage and credit card bills to pay. My job, which is our main source of income is in an unstable state right now. • #### 9 millimeter My wife is 2 months pregnant. During our last visit to the doctor, we found out our baby is about 9 mm in length already. In programmer-speak, our baby is in the Alpha or Beta state right now. But he/she has already achieved a major project milestone- he/she has a heartbeat! Oh I am the happiest person in the world right now! We can't wait for him/her to come join us in November later this year. I had a DONATE button on the codeplex site of STORM and even added it to the Storm application itself. Its been there for more than 6 months and inspite of the 6000+ downloads, I have yet to receive a single donation. I know, you'd say, open source doesn't work like that. One cannot expect donations on open source projects. It's the spirit of giving and sharing code that matters. Yes, that is true, I believe that as well. But as you can see, I simply can't afford to give out WCF Storm for free right now. If my family is to weather this difficult time we need to have another source of income. I hope people understand. ### or Buy Now or Learn more Author: "Erik Araojo" Date: Friday, 10 Oct 2008 04:29 Originally posted on: http://geekswithblogs.net/Erik/archive/2008/10/09/125732.aspx The Goal Simulate a class using the Record type How we'll do this Create a tool that can translate a number into another format. In particular, we'll convert a number into 1. Roman Numerals or 2. multiply it by 10 Why are you doing this? No particular reason. I was just curious. I was just thinking that if F# did not support OOP, how can I still achieve the same things I was used to doing in C#? Ok so here we go.. F# record types are simple named types. We can pattern match over it and it is also constructed quite easily. For example The record Person contains 2 named fields, which are both strings. Most of the time records are used to hold data but since F# is an FP language, we can also have the fields of the record carry a function. For example, we can modify the Person record type to instead of having the "LastName" as a string, we'll turn it into a function that computes the last name. Something like, As you can see we have changed the signature of LastName from "string" to "unit->string". The function "fun -> Guid.NewGuid().ToString() " matches this new signature. (Side note: as a C# coder, this was a big mind shift for me) Going back to our example, lets define a Converter record type as this type holds a string field "x" and "ToNewFormat" field with the signature unit->string. The function does not take any parameter because we'll have it use the value assigned to "x" i.e. it will convert the value in "x" into a different format. If we were using a class, our code (C#) will be something like and to use it we'd write So how do we contsruct our F# Converter record so that it would behave essentially like the C# Converter class? like this. We create a converter function that takes 2 parameters, "numStr" and "myConverterFunction". NumStr gets assigned to the field "x" while the myconverterFunction is wrapped inside the "intToNewFormat" function which has the signature unit->string. MyConverterFunction was wrapped inside intToNewFormat function because we want this function to work on the value of field "x". Well actually myConverter function uses the value of "positiveNum" (an int) which was derived from the string value of temp.x. The "temp" value is of course of type Converter. The important part here is that in order for us to acces the instance value of "x" we need add the "rec" keyword in the definition of the value temp. If we didn't do that we won't be able to access temp.x! To call this createConverter function, all we need to do is pass a string and a function that has the signature int->string In the code above, we create a romanConverter function that takes a string and creates the instance of the Converter record by passing the string and "RomanConverterFunction.romanConverter" function. The "RomanConverterFunction.romanConverter" function takes an integer and converts it to Roman numerals. For example, if you pass it "1980" it will output "MCMLXXX" That's it! whenever we call, romanNumeralConverter.ToNewFormat(), it is converting its instance value of "x" into roman numerals exactly the same way the C# Converter class is working. Note that because we are passing around functions we can easily create different kinds converters. In the above code we created another converter, "multiplier10converter" which merely multiplies a number by 10 (yes, this example is not very good. :-p ). If we needed a different converter all we need to do is write the code for that converter and pass the new conversion function to "createConverter". Simple. If we had to do this in OO, we have to through the inheritance-override route. Here's the tool in action Author: "Erik Araojo" Date: Thursday, 18 Sep 2008 02:05 Originally posted on: http://geekswithblogs.net/Erik/archive/2008/09/17/125226.aspx F# is an awesome language. I'd choose to write F# code any day over any language if my work allows it. The way you are able to concisely and cleanly write code with it is what brought me over. Sure there is an initial overhead (if you we are an OO programmer) in learning all the functional constructs but in the end its all worth it. Even though you might not be able to use it at work (read : management only wants C#/VB.NET), the way you are writing OO code will definitely be improved. I for example have come to appreciate Generics and delegates more because of F#. Microsoft Research has done such a great job with it and I'm quite sure they will continue to do so. There is no question that "F# as a language" is great. People do however have a gripe about "F# as a Microsoft product". It is not open source nor is it standard like C#. There is a technology-lockin which I presume some fear will later on will translate into a vendor-lockin. F# targets mainly the research and financial institutions. I can not say much about financial companies but research instituions and technology companies are big Linux users. There is very high likelihood that these people are also open-source advocates. It will be in their best interest to ensure that the language works perfectly on both Windows and non-windows systems. This is both a win for the users and for Microsoft. It would also propel the language forward at a much quicker pace. It might be too early to ask this given that the F# CTP was only recently released, but should Microsoft open source F# and get the community involved? Author: "Erik Araojo" Date: Friday, 23 May 2008 03:36 Originally posted on: http://geekswithblogs.net/Erik/archive/2008/05/22/122302.aspx One of the commonly used design pattern is the Observer Pattern because its just so easy to use and implement. The classic OO way of implementing it is to have a Subject class having the methods "Attach", "Detach" and "Notify". The Subject class usually stores the observers in an ArrayList and then when it needs to update the observers then iterates on the list and invokes the "Update" method of each observer. See diagram below. In C#, a more elegant way of implementing this is with Events and Delegates. Here's a nice sample implementation. By using using events and delegates, the code became a lot shorter and straight-forward In F#, implementation of the observer pattern became even more concise and elegant. How come? Take a look at the code below. line 11 : A clean and simple (one-liner!) way of creating events and triggers. A call to IEvent.create is all it takes lines 16 & 17 : calling "trigger" and passing the correct parameters notifies all listeners of the changeEvent. We don't even need to check if there are listeners attached. If this is in C# we need to make changeEvent != null otherwise a NullReferenceException will be raised. lines 28 & 30. In F# Events are first-class values , that means we can pass it around and more importantly we can do all sorts of wonderful things with it using the IEvent module. For example, in line 28, we filtered the event, basically saying that we are only interested in events of the Remove operation. Now imagine if the Operation type (an enum actually, lines 5-7 ) contains more items such as Update, Delete, AddedThenRemoved, AddedThenUpdated, RemovedAddedAgainThenFinallyUpdated ... (you get what I mean). If we want to a handle only the Remove operation then we'd have no choice but to break it down using an if-elseif-else or switch-case construct. It would work but its not going to be pretty. And this is where IEvent.filter shines. With just a single line of code (line 28, please ignore the comment above it.), we were able to filter out the event that we are only interested in. Apart from filtering, IEvent also allows us to map, partition, fold, split etc. events. lines 25 & 30 : 2 ways of attaching to an Event. I'm not very sure what's the difference between these 2. (TODO : Investigate) Here's the output! Notice that the "observerForRemove" printed out only the message related to the Remove operation even though the Subject class raised 2 events (one for Add, another one for Remove) in the Notify() method at line 15. Sweet. Author: "Erik Araojo" Date: Sunday, 11 May 2008 11:12 Originally posted on: http://geekswithblogs.net/Erik/archive/2008/05/10/122038.aspx To everyone who've either sent me an email or posted a comment asking whether SoapBits can be made into an open source project, well here I am pleased to let you all know that finally it has happened! SoapBits is now open source and is available at codeplex! In line with this change, it have given it a new name,STORM. (I meant "STORM" to be an acronym but I can only come up with Soap Testing for "ST" . The "ORM" part I have yet to figure out, so please do suggest if you think of a clever meaning. ;) ) Another major change is that the tool is now written mostly in F#, a language which I believe is a lot more expressive and powerful than C# because of the ease with which it has combined Object Oriented and Functional programming. The user interface part though is still written in C# mainly because F# is not yet fully integrated into Visual Studio. STORM site : http://codeplex.com/storm As you all can see below, the UI has also changed a bit but the old functionalities are still there Enjoy the tool everyone! And don't forget to give back and contribute to the project. Author: "Erik Araojo" Date: Wednesday, 02 Apr 2008 08:36 Here's a sample template that lets you have the String.Replace() functionality in XSLT 1.0. The template "string-replace-all" takes 3 parameters and recursively processes the input text string. • text : main string • replace : the string fragment to be replaced • by : the replacement string <xsl:template name="string-replace-all"> < xsl:param name="text" /> < xsl:param name="replace" /> < xsl:param name="by" /> < xsl:choose> < xsl:when test="contains($text, $replace)"> < xsl:value-of select="substring-before($text,$replace)" /> < xsl:value-of select="$by" />
<
xsl:call-template name="string-replace-all">
<
xsl:with-param name="text"
select="substring-after($text,$replace)" />
<
xsl:with-param name="replace" select="$replace" /> < xsl:with-param name="by" select="$by" />
</
xsl:call-template>
</
xsl:when>
<
xsl:otherwise>
<
xsl:value-of select="$text" /> </ xsl:otherwise> </ xsl:choose> </ xsl:template> Here's how it is called: < xsl:variable name="myVar"> < xsl:call-template name="string-replace-all"> < xsl:with-param name="text" select="'This is a sample text : {ReplaceMe} and {ReplaceMe}'" /> < xsl:with-param name="replace" select="'{ReplaceMe}'" /> < xsl:with-param name="by" select="'String.Replace() in XSLT'" /> </ xsl:call-template> </ xsl:variable> (Edit : Thanks to Marky and granadaCoder for typing out the xslt code in the comments.) The resulting value of$myVar after {ReplaceMe} is replaced is "This is a sample text : String.Replace() in XSLT and String.Replace() in XSLT"

For those who are not familiar with XSLT syntax and here's the C# equivalent.  An excellent material for the thedailywtf! :)

(Note: I'm not so sure, but I think in XSL 2.0 there is already a built-in replace function on strings)

Author: "Erik Araojo"

Date: Monday, 18 Feb 2008 17:15

Problem:

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?

Solution:

Finding the LCM can be done via factorization.  Below is an excerpt from the wikipedia article.

The unique factorization theorem says that every positive integer number greater than 1 can be written in only one way as a product of prime numbers. The prime numbers can be considered as the atomic elements which, when combined together, make up a composite number.

For example:

$90 = 2^1 \cdot 3^2 \cdot 5^1 = 2 \cdot 9 \cdot 5. \,\!$

Here we have the composite number 90 made up of one atom of the prime number 2, two atoms of the prime number 3 and one atom of the prime number 5.

This knowledge can be used to find the lcm of a set of numbers.

Example: Find the value of lcm(8,9,21).

First, factor out each number and express it as a product of prime number powers.

$8\; \, \; \,= 2^3 \cdot 3^0 \cdot 5^0 \cdot 7^0 \,\!$
$9\; \, \; \,= 2^0 \cdot 3^2 \cdot 5^0 \cdot 7^0 \,\!$
$21\; \,= 2^0 \cdot 3^1 \cdot 5^0 \cdot 7^1. \,\!$

The lcm will be the product of multiplying the highest power in each prime factor category together. Out of the 4 prime factor categories 2, 3, 5, and 7, the highest powers from each are 23, 32, 50, and 71. Thus,

$\operatorname{lcm}(8,9,21) = 2^3 \cdot 3^2 \cdot 5^0 \cdot 7^1 = 8 \cdot 9 \cdot 1 \cdot 7 = 504. \,\!$

Code:

module Prob5 = begin
open System
open Microsoft.FSharp.Math

let primeFactors (num:float) =
//let num = 50.0
let divSeq = num |> Seq.unfold (fun x ->
let rec get num2  =
let sq = Math.Sqrt (num2)
let div = ref 2.0
while( (not(num2 % !div = 0.0)) && (!div < sq) ) do
if (!div = 2.0) then
div  := !div + 1.0
else
div  := !div + 2.0
div
let sq = Math.Sqrt (x)
let divisor = get x
if (x = 1.0) then
None
else if (sq < !divisor) then
Some (x, 1.0)  // x is prime!
else
Some(!divisor, x/(!divisor))
)
divSeq
let pFactors = (2,20) |> Seq.unfold (fun (x,limit) ->
let y = float_of_int x
let s =  (primeFactors y) |> Seq.map (fun x -> Convert.ToInt32(x))
if x <=limit then
Some ( (x,s), (x+1, limit))
else
None
)

let factorSort x y =
let (num1, _) = x
let (num2,_) = y

if (num1 < num2)  then
-1
else if num1 > num2 then
1
else
0
let powSort x y =
let (_,num1) = x
let (_,num2) = y

if num1 < num2 then
1
else if num1 > num2 then       -1
else
0

let all =   pFactors |> Seq.map (fun (num,s) -> s |>  Seq.countBy (fun x -> x ) )  |> Seq.concat
let allList =  (Seq.to_list all) |> List.sort factorSort |> List.sort powSort

let a = ref 0
let b = ref 0
let filtered = allList |> List.filter (fun (x,y) ->
let (factor,pow) = allList |>  List.find (fun (r,s) -> r=x )

if (factor = x ) && (pow = y) && ( (!a <> x) || (!b <> y) ) then
a := factor
b := pow
true
else
false

)

let main() =
let lcm = filtered |> List.fold_left (fun a (x,y) -> a * Math.Pow(float_of_int x, float_of_int y ) ) 1.0
printfn "\n\nLCM = %f" lcm

end

My solution for this one follows the steps outlined in the wikipedia excerpt above. It is a bit long but essentially it can be broken down into the following stages...

1 - Factor out the number 1 to 20.

This is done on function pFactors.  pFactors outputs a sequenct of tuples wherein the first value is the number being factored while the second value is a sequence of its prime factors. For example, the output of this function when applied to the numbers 2 to 20

{ (2, {2}); (3, {3}; (4, {2;2}) ; (5, {5}) ...,<snip> .. (12, {2;2;3}) ...<snip> .. (20, {2;2;5})       }

type : seq< int * seq<int>>

2 - Count the number of occurrences of each prime factor and consolidate into just one sequence

This is done on line  let all = pFactors |> Seq.map (fun (num,s) -> s |> Seq.countBy (fun x -> x ) ) |> Seq.concat

Seq.countBy counts the number of occurences of an item in a sequence.  For example, if we apply to the sequence of prime factors of the number 20, the output will be

(20, {2;2;5} ) -> (2,2),(5,1) : where the 2nd value of the tuple is the number of occurences

So for the number 2 to 20 the output is

(2, 1)(3, 1)(2, 2)(5, 1)(2, 1)(3, 1)(7, 1)(2, 3)(3, 2)(2, 1)(5, 1)(11, 1)(2, 2)(3, 1)(13, 1)(2, 1)(7, 1)(3, 1)(5, 1)(2, 4)(17, 1)

(2, 1)(3, 2)(19, 1)(2, 2)(5, 1)

type : seq<int * int >

3 - Sort the output of stage 2.

The output of stage 2 obviously contains duplicates.  Referring back to the wikipedia excerpt above, what we need only are those factors with the highest power (or most number of occurences).  So in order for us to identify those factors, first we sort the sequence.  This is done on line

let allList = (Seq.to_list all) |> List.sort factorSort |> List.sort powSort

The output (though a bit confusing) guarantees that the for any number, the one with the highest number of occurences comes out on top.  For example (2,4) is on top of all the other tuple entries with first value of 2. And so is (3,2) for tuple values with first value of 3.

(2, 4)
(2, 3)
(2, 2)
(2, 2)
(2, 2)
(3, 2)
(3, 2)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(3, 1)
(3, 1)
(3, 1)
(3, 1)
(5, 1)
(5, 1)
(5, 1)
(5, 1)
(7, 1)
(7, 1)
(11, 1)
(13, 1)
(17, 1)
(19, 1)

type : seq<int * int>

4.  Filter the resulting sequence of stage 3 and take only those with the highest 2nd element.  This is done on line

let filtered = allList |> List.filter (fun (x,y) -> ...  <snip>...

output is :  seq<int*int>

(2, 4)
(3, 2)
(5, 1)
(7, 1)
(11, 1)
(13, 1)
(17, 1)
(19, 1)

5. And finally we can compute the LCM.  This is done on the line

let lcm = filtered |> List.fold_left (fun a (x,y) -> a * Math.Pow(float_of_int x, float_of_int y ) ) 1.0

Total execution time on my machine is 0.17 seconds  which a great improvement from the 25 seconds using the brute force approach described here

Author: "Erik Araojo"

Date: Monday, 18 Feb 2008 15:36

These 2 problems have very short solutions so I'll put them together

Problem 3:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.

Solution:

let prodOf3digit =
(100,100) |> Seq.unfold (fun (x,y) ->
match y with
| y when y < 0 -> None
| y when x <= 999->
if (y <= 999) then
Some(x*y, (x,y+1))
else if (x+1) <= 999 then
Some ( (x+1)*(x+1), (x+1, x+2) )
else
None
| y -> None )

let palindromes =
prodOf3digit
|> Seq.filter (fun x ->
let intStr = Int32.to_string x
let rev (s:string) =
let chunks =s.ToCharArray()
let reversed = Array.rev chunks
let r = new string(reversed)
r
let newNum = System.Convert.ToInt32 ( rev intStr )

newNum = x
)
let largest =
palindromes |> Seq.fold (fun a x -> if x > a then x else a) 0

The problem asked for the largest palindrome of 3-digit numbers, hence the magic number 100 and 999.  The rest of the code is pretty much self-explanatory.

Problem 6:

The sum of the squares of the first ten natural numbers is,12 + 2 + ... + 102 = 385

The square of the sum of the first ten natural numbers is, (1 + 2 + ... + 10) = 552 = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Solution:

let sumOfSq (n:bigint) =
let rec getSum (x:bigint) =
match x with
| x when x = 1I -> 1I
| x -> x*x + getSum (x - 1I)
getSum n

let sqOfSum n =
let s = [ 1I .. n ] |> Seq.fold (fun a x -> a+x) 0I
s*s

let main2() =
let diff = (sqOfSum 100I) - (sumOfSq 100I)
print_any diff

To compute the sum of squares, I've decided to use recursion,  which apart from lists and sequences, is another workhorse of functional programming.   One thing to remeber when using recursion is to always make sure you cover the base case in order to avoid looping indefinitely.  In this case it is the line x when x = 1I -> 1I

Because of the large resulting values, the type used was BigInt.

Author: "Erik Araojo"

Date: Monday, 11 Feb 2008 15:58

Problem 1 :

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.

Solution :

let mySeqP1 = [ 1 .. 999 ] |> Seq.filter (fun x -> ( (x % 5 = 0) || (x % 3 = 0)) ) |> Seq.fold(+) 0
printfn "sum = %i" mySeqP1

Problem 2:

Find the sum of all the even-valued terms in the Fibonacci sequence which do not exceed one million.

Solution :

let sumofEven =   (1,1) |> Seq.unfold (fun (x,y) ->
match y with
| y when y < 0 -> None
| _ -> Some(y, (y, x+y)))
|> Seq.filter ( fun x ->      x > 0 && x < 1000000 && (x % 2 = 0))
|> Seq.fold (+) 0

printfn "Sum of even = %i" sumofEven

For this solution I had to put the guard statement "when y <  0" so that negative numbers won't be included in the generated sequence.  If that guard istatement s not there, negative numbers will be included when it goes over the maximum value of Int32.

Problem 3:

Find the largest prime factor of 317584931803.

Solution:

let primefactorsOf (num:float)=
let divSeq = num |> Seq.unfold (fun x ->
let rec get num2  =
let sq = Math.Sqrt (num2)
let div = ref 2.0
while( (not(num2 % !div = 0.0)) && (!div < sq) ) do
if (!div = 2.0) then
div  := !div + 1.0
else
div  := !div + 2.0
div

let sq = Math.Sqrt (x)
let divisor = get x

if (Int32.of_float(x) = 1) then
None
else if (Int32.of_float( sq ) < Int32.of_float( !divisor )) then
Some ( Int32.of_float( x ) , 1.0)  // x is prime!
else
Some(Int32.of_float !divisor, x/(!divisor))
)

divSeq

let primefactors =  (primefactorsOf 317584931803.0)

let mainp3() =
primefactors |> Seq.iter (fun x -> printfn "%i " x)

The function "primefactorsOf" takes a number and returns a sequence containing the prime factors of that number.  The prime factors are determined using Trial Division.  This of course is not very fast for ver large numbers but is sufficient enough for 317584931803.0 If it's not clear why the square root of the number being factored out was used instead of directly using the number itself, the wikipedia article explaining Trial Division is here

If you want to output only the largest primefactor you can just pass the value primefactors to Seq.fold like so

let largestFactor = primefactors |> Seq.fold (fun a x -> if x > a then x else a ) 0

Next time I'll post my solution to problems 4-6.

Author: "Erik Araojo"

Next page
» You can also retrieve older items : Read