Belbinson Toby 14 Jun 2010
Stockholm, Sweden
Less Code Is Better
The less code that you write, the less that you have to read, the less that you have to maintain, and usually the program will be simpler, and will often run faster.
Rewrite It.
It finally compiles! You just finished that big hairy part of the project, and it seems to work! Yeah, there are a few messy areas and some parts are a little hazy, but you got it done!
...you just found a bug. It won't be too bad to fix, just go in and add another if-statement to detect for the special case, and you're good to go!
If it's broken, don't fix it. Rewrite it.
95% of the time you are better off rewriting all of the code. That little if-statement that you are adding, to fix an innocuous bug, may seem harmless, but it should be signalling disaster to you. It most likely means that your abstraction wasn't quite correct. So now you are making it a little bit harder to read. You are adding a little bit more code. It only takes a few minutes, and rewriting it would take hours or even days.
In the long run, you would've been much better off not fixing it, but rewriting it. Now that you have found a few more bugs, and added a few more patches, and it's been a few months, the code is getting hairy. Now you are having a hard time being sure that the new code isn't making more bugs. And it's taking longer and longer to work with the program.
If you would've just rewritten it to be correct, all these times, then you would have great code, solid abstractions, you would know the code inside and out, it would be readable and maintainable. After rewriting it a few times, the code just flows as well. It no longer takes as long to write it as it first did.
Sure, sometimes you end up dumping the project or you didn't end up making things that much worse, by not rewriting it, but it's near impossible to guess when the 5% will be. Don't play that game. Just rewrite it.
UPDATE: I've posted more of my thoughts on this in it's own essay.
Code Is For People To Read
Only as a side-effect is it for computers to run. The easier your code is to read, the better understanding you will have of it. You will have less bugs. It will be more maintainable.
Sure, coding super fast, inline assembly makes you feel macho, but being macho doesn't help when CPU architecture changes, and you have to go back in, and decipher the mess you made.
Correctness Wins
Do it the right way. If you don't have enough time to do things right, then don't do them.
It almost always costs more in the long run, to do things less than correctly. Most often the reason for incorrect code, is trying to do too much in too little time. This is the beginning of feature creep. You are entering the world of hazy abstractions.
Do yourself a favor, stop coding.
Stop Designing, Start Coding
Instead of spending all of your time on the whiteboard, drawing up elaborate plans, start writing code. Yes, your code is going to suck. It is going to be a mess. But what's the rule when our code is a mess?
Rewrite it.
Your program will always be better off if you spend a day writing it 6 times, rather than designing it 6 times and writing it once. Writing code, and forcing yourself to rewrite it if it is incorrect, forces you to figure out the abstractions, and allows you to do deal with the real problems, instead of guessing what they will be.
You aren't building a car. You can forget to hook up the brakes and still live.
Fortran for .NET allows you to create applications for the Microsoft .NET Framework. Lahey and Fujitsu have combined advanced compiler technology with support for Forms designers and Web Services to enable Fortran organizations to develop .NET applications with Fortran as easily as with other Microsoft .NET languages. Fortran for .NET consists of a Fortran compiler and associated tools designed to help you create applications that run in the .NET Framework.
Fortran for .NET compiler
Fortran for .NET language
Visual Studio .NET integration
Windows Forms
ASP.NET Web Forms
ADO.NET
Fortran for .NET compiler options
Restrictions on Fortran for .NET Code
Hardware and software requirements for Enterprise and Academic Editions
What can you do with Fortran for .NET and why would you want to?
The Fortran for .NET language system is included in LF Fortran v7.1 Enterprise and Academic editions.
--------------------------------------------------------------------------------
Fortran for .NET compiler
Th Fortran for .NET compiler targets Microsoft's .NET Framework. The compiler does not directly generate processor dependent object code; rather, it generates Microsoft Intermediate Language (MSIL) code assemblies and code modules. The code in an assembly can be executed on any computer that supports an execution engine called the Common Language Runtime (CLR), such as the .NET Framework.
The CLR does much more than provide the ability to operate on different operating systems, it also provides the basis for interoperability between different .NET languages, interlanguage debugging, versioning, and application deployment, among other things.
Applications that are targeted for the CLR are called managed applications, or managed code. Managed applications are required to be type safe and to present standardized interfaces, so that interoperability and security requirements can be met. Because some older Fortran features (such as COMMON and EQUIVALENCE) can violate the CLRs rules for type safety and interfaces, certain restrictions had to be placed on .NET applications that do not allow 100% compatibility with Fortran standards. For details on restrictions, see Restrictions on Fortran for .NET Code.
Belbinson Toby
Logica Pvt Ltd
Stockholm, Sweden
May 2010
Summary: Discusses why COBOL and .NET are strong partners and explains how Fujitsu COBOL has been integrated into the .NET Framework. (12 printed pages)
Contents
Introduction
Why COBOL for .NET Makes Sense
What COBOL for .NET Looks Like
Migrating COBOL Code to the .NET Framework
How COBOL for .NET is Implemented
Getting Started with COBOL for .NET
Introduction
Microsoft’s .NET Framework not only enables the vision of companies sharing Web Services but also establishes a whole new development and execution environment for applications – whether on or off the Web. With components winning awards even before their full release, .NET is truly the latest and greatest happening in the application development world. COBOL, on the other hand, has been around almost from the beginning of business applications on computers and is unlikely to be mentioned by anyone talking about the “latest and greatest”. Why, then, have Microsoft and Fujitsu Software expended considerable effort in bringing these two technologies together? Has it been possible to integrate the “old” and “new” in a worthwhile manner? Does this combination of COBOL and .NET have anything to offer you, and how easy is it going to be for you to take advantage of those benefits?
This paper aims to answer these questions for you firstly by laying out why the .NET Framework is attractive to business applications and COBOL programmers, and what COBOL has to offer to .NET. It will then give you a feel for COBOL for .NET by showing you what it looks like in different .NET technologies such as ASP.NET, Web Services and class sharing, explaining how you might use COBOL in each of these areas. It will give you an insight into what was done to make COBOL work in the .NET environment and conclude by describing how you can experience COBOL for .NET yourself.
Why COBOL for .NET Makes Sense
To understand why COBOL and .NET come together well, it is best to start with what COBOL has to offer. The reasons that COBOL runs over 70% of the world’s production business applications are that it has always provided:
•Record-oriented data structures
•Built-in business-oriented data types: alphanumeric, alphanumeric-edited, decimal, numeric-edited, and packed-decimal.
•Simple control flow constructs
•Readable and maintainable code
Although often put down by speedy programmers, COBOL’s verbosity has been a big part of it providing readable and maintainable code. Maintainable code is a critical feature for business applications that can have life spans of many decades. Consider if you are in the position of committing your company’s core business processes to a programming language – do you want to select the “in” language of the moment which history has shown will be “out” in 10 years’ time, or do you want to select a language that has a 40 year track record, and which any programmer can understand?
Another factor in favor of using COBOL for business logic, is that COBOL programmers typically have a lot of experience in supporting business needs. Their focus tends to be more on implementing the business functions rather than getting into the latest technology (just because it’s the latest).
However, businesses still need to take advantage of the latest technology as this can often give them their competitive advantage or ensure that they aren’t disadvantaged relative to the competition. This, if anything, has been COBOL’ s weakness in the last decade – it has not always been able to take advantage of the latest technologies as the interfaces or architectures have not been accessible to COBOL.
The .NET Framework changes all this. Web applications need a secure, managed environment in which to operate. In providing this Microsoft decided not just to create an environment that supported a single programming language, but to create an environment that was capable of supporting all programming languages, and to extend it so that it could support console, Windows GUI, and Web HTML styles of applications as well as the typically interface-less Web services. Figure 1 gives an overview of what the .NET Framework provides.
This figure shows how Visual Studio .NET provides a common development environment for programming. Any language, such as COBOL, which is enabled for that development environment, can be developed with language-sensitive features including highlighting of text, project building and debugging. Then the code is compiled into a standard intermediate language called Microsoft Intermediate Language (MSIL) that is executed by the Common Language Run-time (CLR) in a secure, managed environment. MSIL is platform independent and is compiled to native code by the part of the run-time loading software.
One big benefit of the common execution environment is that its design is such that classes can be inherited from one language to another. .NET includes several frameworks, or libraries of classes, that any .NET language can use, including COBOL.
The net result is that .NET offers an environment in which you develop in the language that makes most sense for the task.
Now it should be obvious how COBOL can benefit from being a full player in the .NET framework. COBOL gets:
•An award winning development environment (Visual Studio .NET) that is designed for creating .NET applications.
•The ability to inherit the latest technologies from the framework classes.
•The option to invoke code written in other languages in a seamless manner, whenever that code provides useful functionality.
•The ability to support application needs wherever MSIL is supported - such as in ASP.NET pages and Web services.
.NET benefits too by gaining:
•The language that is best for many business logic implementations
•The ability to execute the valuable business logic contained in around 200 billion lines of COBOL code worldwide (Gartner Group estimate)
•The business expertise of hundreds of thousands of COBOL programmers
Thus COBOL and .NET make a strong partnership; one that is worth exploring to see how you can exploit it to your company's advantage.
What COBOL for .NET Looks Like
To show you what COBOL looks like in the .NET Framework this paper presents three examples of COBOL code in different .NET areas:
•Within an ASP.NET page, illustrating the provision of dynamic Web content using COBOL
•As a Web Service, demonstrating how simple it can be to package existing modules as Web services.
•Within the GUI Framework, showing how COBOL can inherit from other languages and how OO COBOL has been adapted to fit the object oriented .NET architecture.
ASP.NET (language="COBOL")
ASP.NET is the Microsoft successor to Active Server Pages (ASP), which were designed to deliver dynamic Web content. ASP faced a number of weaknesses in the areas of performance and programmability, and ASP.NET makes substantial improvements in those areas. Instead of being interpreted like ASP, ASP.NET compiles pages to native code. This change results in enormous performance benefits, with only a one-time cost to compile the page when it is first deployed. The other important side effect of the design choice (to compile instead of interpret) is that it opens the door for compiled languages to provide code in ASP.NET pages.
ASP.NET Example 1
The following is a sample ASP.NET page written using COBOL that displays "Welcome to ASP.NET (now in COBOL!)" in increasing font sizes:
<%@ page language="COBOL" %>
<script runat="server">
OBJECT.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 Font-Size PIC S9(9) COMP-5.
END OBJECT.
</script>
<% PERFORM VARYING Font-Size FROM 1 BY 1 UNTIL Font-Size > 7 %>
<font size="<%=Font-Size%>"> Welcome to ASP.NET (now in COBOL!) </font>
<br>
<% END-PERFORM. %>
The "<%@" characters introduce the directive that allow us to set the programming language for the page to COBOL. The <script> block allows us to introduce COBOL code that declares the FONT-SIZE variable and the characters "<%" allow us to introduce inline COBOL code to loop over the HTML that displays "Welcome to ASP.NET (now in COBOL!)"
Fujitsu COBOL takes advantage of this important benefit by allowing COBOL programmers to embed COBOL code in ASP.NET pages.
Writing a class which implements ITemplate
Here is the skeleton of class DynamicallyTemplatedGridViewHandler implementing ITemplate with a list of data members and methods.
Listing 2
public class DynamicallyTemplatedGridViewHandler : ITemplate
{
ListItemType ItemType;
string FieldName;
string InfoType;
public DynamicallyTemplatedGridViewHandler(ListItemType Item_type,
string field_name, string control_type);
public void InstantiateIn(System.Web.UI.Control Container);
private void OnDataBinding(object sender, EventArgs e);
}This class has three data members:
ListItemType ItemType;
string FieldName;
string InfoType;ItemType keeps the type of a list item type: Item, EditItem, Header, Footer, AlternatingItem, Pager, SelecetdItem or Separator. In this demo version we need only three of these; we need Header (For heading of each column), Item (for showing fields when GridView will be in normal mode) and EditItem (for showing fields when GridView will be in Edit mode).
FieldName keeps the name of each template field that will be displayed in the header.
InfoType keeps an indicator in string form for a type of information within a template field i.e. whether a template field has information of "Command" or "String" so that later data retrieval and data binding of that particular child control will be made accordingly. A "Command" (Edit, Delete, and Insert) requires instantiation in the Button control while he "String" requires a Label or TextBox.
Now, coming to the member methods listed above, there is a constructer which simply sets the aforementioned data members with those passed as parameters.
Listing 3
public DynamicallyTemplatedGridViewHandler(ListItemType item_type, string field_name,
string control_type)
{
ItemType = item_type;
FieldName = field_name;
InfoType = info_type;
}Here is the explanation of InstantiateIn the only method of ITemplate being implemented by our class DynamicallyTemplatedGridViewHandler.
InstantiateIn
InstantiateIn ensures that the list item type of each template is created in its appropriate control. For better understanding of functionality of this method see its name "InstantiateIn." It means "Instantiate Item In Literal/Label/TextBox/Button/." The choice will be according to the requirement. Like in the case of a Header, it is instantiated in Literal control as shown in this part of the implementation of InstantiateIn.
InstantiateIn takes a "Container," a Control type object as a parameter. Container's control collection is filled with all controls in which items of each type are instantiated. Its implementation in the current scenario is a little lengthy, yet it is quite easy as we have to do a similar type of job with each control; instantiate it, set its text property with FieldName and add it into Container's control collection.
For example, below the code of InstantiateIn shows that if the ItemType is a Header, then it creates a literal object called header_literal. After making it bold, set the text property of header_literal with FieldName. Finally, add this control to the control collection of the Container control passed as parameter to InstantiateIn method.
Similarly, we have to write instantiation code for ItemType if it is "Item" and "EditItem." In case the ItemType is "Item" (fields look when GridView is in normal mode), we need one more check inside it to see that InfoType tells whether the Item will be instantiated with a Button (Edit, Insert, and Delete) or Label. If InfoType is a Button then it creates three buttons for the aforementioned tasks. It is simple to do; create a button object, set its all properties accordingly, also add the button's click event handler and finally, add it into the control collection of the control (Container) passed as an argument.
Listing 4
public void InstantiateIn(System.Web.UI.Control Container)
{
switch (ItemType)
{
case ListItemType.Header:
Literal header_ltrl = new Literal();
header_ltrl.Text = "" + FieldName + "";
Container.Controls.Add(header_ltrl);
break;
case ListItemType.Item:
switch (InfoType)
{
case "Button":
ImageButton edit_button = new ImageButton();
edit_button.ID = "edit_button";
edit_button.ImageUrl = "~/images/edit.gif";
edit_button.CommandName = "Edit";
edit_button.Click += new ImageClickEventHandler(edit_button_Click);
edit_button.ToolTip = "Edit";
Container.Controls.Add(edit_button);
/*Similarly, add button for delete just set its
command to equal to "Delete." It is important to know when
"insert" button is added, its CommandName is set to "Edit" like
that of the "edi" button because we want the GridView to enter into
Edit mode and this time we also want the text boxes for corresponding fields
empty*/ ImageButton insert_button = new ImageButton();
insert_button.ID = "insert_button";
insert_button.ImageUrl = "~/images/insert.bmp";
insert_button.CommandName = "Edit";
insert_button.ToolTip = "Insert";
insert_button.Click += new ImageClickEventHandler(insert_button_Click);
Container.Controls.Add(insert_button);
default:
Label field_lbl = new Label();
field_lbl.ID = FieldName;
field_lbl.Text = String.Empty;
field_lbl.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_lbl);
break;
}
break;
case ListItemType.EditItem:
if (InfoType == "Button")
{
ImageButton update_button = new ImageButton();
update_button.ID = "update_button";
update_button.CommandName = "Update";
update_button.ImageUrl = "~/images/update.gif";
update_button.ToolTip = "Update";
update_button.OnClientClick =
"return confirm('Are you sure to update the record?')";
Container.Controls.Add(update_button);
// Similarly, add a button for Cancel
}
else
// if other key and non key fields then bind textboxes with texts
{
TextBox field_txtbox = new TextBox();
field_txtbox.ID = FieldName;
field_txtbox.Text = String.Empty;
// if to update then bind the textboxes with coressponding field texts
//otherwise for insert no need to bind it with text
if ((int)new Page().Session["InsertFlag"] == 0)
field_txtbox.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_txtbox);
}
break;
}
}When InfoType is not a Command it means we have to instantiate it with a label as in GridView's normal mode when each cell text of GridView's rows is displayed in label. Therefore, by default, control is instantiated with Label and is added into the Container. Since we have no more info types (other than command and string) then no further checks are required. We come to the outer check when ItemType is EditItem. Now, we need an inner check for info type (command or string). The template field will be instantiated in Button if the info type is Command; otherwise it requires TextBox for the cell text of edit item.
It is important to know that the CommandName of insert_button is set to "Edit" just to take advantage of the Edit mode that provides text boxes for all editable items. If the these text boxes are emptied, they can be used for insertion instead of editing without dedicating an extra row for it. This is easy and handy as it becomes a better approach when it is not known in advance how many columns there are in GridView's data source. I have taken a session variable InsertFlag that is set to 0 and 1 for Edit and Inert operations respectively.
Since we have to bind the labels in Item template and text boxes in EditItem template with corresponding cell values, the data binding event handler OnDataBinding of both label and text box populates the fields with cell values accordingly.
And you might also want to know how text boxes for each field get emptied when Insert button is clicked. The solution is simple; do not bind them with a database and apply a check while adding the data binding event handler of text box. Do not call OnDataBinding if the insert button is clicked.
Listing 5
if ((int)new Page().Session["InsertFlag"] == 0)
field_txtbox.DataBinding += new EventHandler(OnDataBinding);DataBinding Event Handler
The implementation of the data binding event handler "OnDataBindin"' is simple. First, we get the "bound_value_object" that is returned by the static method Eval of DataBinder class which takes two parameters. One is of type object called "data_item_container" (containing the DataItem that is assigned with sender control's NamingConatiner) and other is the string expression, FieldName. Once we get this bound_value_object, we assign its value (string) to the Text property of Label (if ItemType is Item; for normal mode) and TextBox (if ItemType is EditItem; for Edit mode).
Listing 6
private void OnDataBinding(object sender, EventArgs e)
{
object bound_value_obj = null;
Control ctrl = (Control)sender;
IDataItemContainer data_item_container =
(IDataItemContainer)ctrl.NamingContainer;
bound_value_obj = DataBinder.Eval(data_item_container.DataItem, FieldName);
switch (ItemType)
{
case ListItemType.Item:
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
break;
case ListItemType.EditItem:
TextBox field_txtbox = (TextBox)sender;
field_txtbox.Text = bound_value_obj.ToString();
break;
}
}The implementation of ITemplate is complete, although I want to mention that there are some event handlers, "insert_button_Click" and "edit_button_Click" for Insert and Edit buttons respectively. They do nothing except the former sets the Session[InsertFlag] to 1 and the later sets it to 0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// Developer : Belbinson Toby
/// </summary>
namespace Class
{
public interface IEmployee
{
void Result();
}
public interface IDeveloper
{
void Result();
}
public class Employee
{
public void Result()
{
Console.WriteLine("Employee");
}
}
public class Developer : Employee, IEmployee, IDeveloper
{
void IEmployee.Result()
{
Console.WriteLine("IEmployee");
}
void IDeveloper.Result()
{
Console.WriteLine("IDeveloper");
}
public new void Result()
{
Console.WriteLine("Developer");
}
}
public class Program
{
static void Main(string[] args)
{
Developer objDeveloper = new Developer();
objDeveloper.Result();// This will call Result Method in Developer Class
Employee objEmployee = new Developer();
objEmployee.Result();// This will call Result Method in Employee Class
IEmployee objIe = new Developer();
objIe.Result();// This will call Result Method in IEmployee Class
IDeveloper objId = new Developer();
objId.Result();// // This will call Result Method in IDeveloper Class
Console.ReadLine();
}
}
}
