C++ => C# => F#, more functional, more parallel (2)

In this article, I will introduce two sample scenes to demonstrate how we can use functional programming to make the code more intuitive, more elegant and more parallel.

Text editing

Consider we want to implement some text editing interface on mobile platform. First, some rich text, i.e. the mixture of texts and images are shown on the screen. Then when users tap on some text, an editing panel will pop up, where users can do some editing work. When the editing finishes, users can tap on some button to return to the original interface, where the texts are modified according to the editing. As following flow chart shows.

BlogGeneratorFlowChart The algorithm seems simple. First bind an event handler to the click event of each label control. So that when user taps the label, the handler, which will be called A in following statements, will be invoked. Then the event handler A should pop up a floating editing panel, which contains a button expected to be clicked when user’s finishing editing. As the blue button with caption “Edit text, click me when finish” in the flow chart shows. In addition, another event handler, which will be called B, should be bound to the “finishing button”, to do some data update work, such as updating the text of the original label. Of course, hiding the editing panel is also its responsibility.

The obstacle is how event handler B knows which label’s text should he updated. Obviously no one knows this until user taps a label, when the information which label is tapped is delivered to event handler A by OS. Then how to communicate between A and B seems trivial. A member variable will do a good job in C++. Considering in C++ we cannot create functions at runtime, the final architecture will be like this:

First, event handlers A and B appear as existed functions in a class, with a member variable L. When A is invoked, he first assigns L as the tapped label, then shows the editing panel. And when B is invoked, i.e. the finish editing button is clicked, he reads text from editing panel, and assign L’s text.

Not too complex huh? Let’s see another way in C#, a language with many functional elements. As B needs information undecided until A is invoked, then why not create an event handler in A to do B’s work, dynamically? From this motivation, we have codes below, with no member variables to communicate between A and B:

1 //this is event handler A, where the parameter sender indicates which label is tapped.
2 void Label_Click(object sender, EventArgs e)
3 {
4 //add an editing panel.
5 //... ...
6 //create event handler B
7 finishingButton.Click += (object textBoxSender, EventArgs ea) =>
8 {
9 (sender as Control).Text = (textBox as TextBox).Text;
10 //assign text after editing to the sender
11 //please note that sender is not a local variable in event handler B,
12 //but a parameter from event handler A.
13 this.Controls.Remove(outerPanel);
14 outerPanel.Dispose(); //delete editing panel and release resources.
15 };
16 //some other codes ... ...
17 }

Please note that sender in B is from A, i.e. for every label clicked, A will create a different event handler and bind it to click event of finishing button. Isn’t it amazing? Although I cannot see any direct advantages from this change, but it appears more fun, more flexible and more readable. :-)

WebPages downloading

It seems very fundamental to download a web page from the internet. But it is a time consuming task so that often involves multi-threading to improve efficiency. Let’s see the typical solutions to download 10 WebPages in C++ and C#.

In C++, to download a webpage, we should first create a new thread explicitly, assign it a webpage, and then start the thread. Fortunately, there are no interactions among the threads, so this simple scheme works.

Let’s see how we can deal with this task in C# with asynchronous functions:

1 HttpWebRequest req = HttpWebRequest.Create(http://g.cn);
2 req.BeginGetResponse((IAsyncResult ar) =>
3 {
4 HttpWebResponse rsp = req.EndGetResponse(ar);
5 Stream stream = rsp.GetResponseStream();
6 //Redirect the stream to a file … …
7 });

We can see that HttpWebRequest class has a method named BeginGetResponse, which takes a function as parameter. This method will create a thread to do the work, and when the work finishes, the function as parameter will be invoked, in which we can deal with the result. This code in C# does the same thing as previous C++ one, in spite of the built-in load balance feature of C# threads. But it shows a new way to write codes if functions can be created, destroyed, passed as parameter dynamically at runtime, just as other kinds of variables do.

Of course these two samples do not demonstrate most fundamental differences between imperative programming and functional programming. But they do demonstrate some differences in how we treat functions; at least provide some fun solutions. It makes no sense to judge which one is better, but having more candidate solutions is not a bad thing, right?

(To be continued… We haven’t seen how to write parallel code with functional languages yet. And I personally insist that functional programming style in these two samples shows much more flexibility and potential than traditional imperative ways. When finding more persuasive examples, I will show you! ;-)

posted on 2010-01-25 22:45  grapeot  阅读(369)  评论(0编辑  收藏  举报

导航