Showing posts with label functional programming. Show all posts
Showing posts with label functional programming. Show all posts

Wednesday, April 20, 2022

Advances in programming come from restraints

Advances in programming come from, to a large extent, advances in programming languages. And those advances in programming languages, unlikely as it seems, are mostly not expanded features but restrictions.

That advances come from restrictions seems counter-intuitive. How does fewer choices make us better programmers?

Let's look at some selected changes in programming languages, and how they enabled better programming.

The first set of restrictions was structured programming. Structured programming introduced the concepts of the IF/THEN/ELSE statement and the WHILE loop. More importantly, structured programming banished the GOTO statement (and its cousin, the IF/GOTO statement). This restriction was an important advancement for programming.

A GOTO statement allows for arbitrary flows of control within programs. Structured programming's IF/THEN/ELSE and WHILE statements (and WHILE's cousin, the FOR statement) force structure onto programs. Arbitrary flows of control were not possible.

The result was programs that were harder to write but easier to understand, easier to debug, and easier to modify. Structured programming -- the loss of GOTO -- was an advancement in programming.

A similar advance occurred with object-oriented programming. Like structured programming, object-oriented programming was a set of restrictions coupled with a set of new features. In object oriented programming, those restrictions were encapsulation (hiding data within a class) and the limiting of functions (requiring an instance of the class to execute). Data encapsulation protected data from arbitrary changes; one had to go through functions (in well-designed systems) to change the data. Instance functions were limited to executing on instances of the class, which meant that one had to *have* an instance of the class to call the function. Functions could not be called at arbitrary points in the code.

Both structured programming and object-oriented programming advanced the state of the art for programming. They did it by restricting the choices that programmers could make.

I'm going to guess that future advancements in programming will also come from restrictions in new programming languages. What could those restrictions be?

I have a few ideas.

One idea is immutable objects. This idea has been tested in the functional programming languages. Those languages often have immutable objects, objects which, once instantiated, cannot change their state.

In today's object-oriented programming languages, objects are often mutable. They can change their state, either through functions or direct access of member data.

Functional programming languages take a different view. Objects are immutable: once formed they cannot be changed. Immutable objects enforce discipline in programming: you must provide all of the ingredients when instantiating an object; you cannot partially initialize an object and add things later.

I would like to see a programming language that implements immutable objects. But not perfectly -- I want to allow for some objects that are not immutable. Why? Because the shift to "all objects are immutable" is too much, too fast. My preference is for a programming language to encourage immutable designs and require extra effort to design mutable objects.

A second idea is a limit to the complexity of expressions.

Today's programming languages allow for any amount of complexity in an expression. Expressions can be simple (such as A + 1) or complex (such as A + B/C - sqr(B + 7) / 2), or worse.

I want expressions to be short and simple. This means breaking a complex expression into multiple statements. The only language that I know that placed restrictions on expressions was early FORTRAN, and then only for the index to an array variable. (The required form was I*J+K, where I, J, and K were optional.)

Perhaps we could design a language that limited the number of operations in an expression. Simpler expressions are, well, simpler, and easier to understand and modify. Any expression that contained more than a specific number of operations would be an error, forcing the programmer to refactor the expression.

A third idea is limits on the size of functions and classes. Large functions and large classes are harder to understand than small functions and small classes. Most programming languages have a style-checker, and most style-checkers issue warnings for long functions or classes with lots of functions.

I want to strengthen those warnings and change them to errors. A function that is too long (I'm not sure how long is too long, but that's another topic) is an error -- and the compiler or interpreter rejects it. The same applies to a class: too many data members, or too many functions, and you get an error.

But like immutable objects, I will allow for some functions to be larger than the limit, and some classes to be more complex than the limit. I recognize that some classes and functions must break the rules. (But the mechanism to allow a function or class to break the rules must be a nuisance, more than a simple '@allowcomplex' attribute.)

Those are the restrictions that I think will help us advance the art of programming. Immutable objects, simple expressions, and small functions and classes.

Of these ideas, I think the immutable objects will be the first to enter mainstream programming. The concept has been implemented, some people have experience with it, and the experience has been positive. New languages that combine object-oriented programming with functional programming (much like Microsoft's F#, which is not so new) will allow more programmers to see the benefits of immutable objects.

I think programming will be better for it.

Tuesday, September 21, 2021

Functional programming requires different discipline

I am worried about the programming industry. Specifically, I fear that we may have trapped ourselves in the object-oriented programming paradigm. I can explain, but it will take some time. Please bear with me.

Paul Graham has written several articles, most of them (if not all of them) thoughtful and thought-provoking. Some of them discuss programming languages. One of them (I cannot find it now) discussed the idea of programming languages and how different languages hold different constructs. If I remember correctly, Graham posited that older programming languages were simpler and modern languages had constructs that were not available in older languages.

If you "stacked" the languages from oldest (on the bottom) to newest (on the top) then programmers could pick their favorite language and look up (at newer languages) and down (at older languages). Graham commented that from such a view, the older languages made sense, because one's favorite language (from which one looked down) contained the things in the older languages. Older languages had constructs that were identical or similar to your language. They didn't have all of the constructs, but the ones that they did have were recognizable.

Conversely (Graham continued), looking up the stack at newer languages was less clear. Those newer languages had constructs and ideas that weren't in your favorite language, and weren't known to you. They looked weird.

I'm not sure I agree completely with this idea. If we start with a simple stack of assembly language, FORTRAN, COBOL, BASIC, Pascal, C, C++, and Java, we can see that yes, later languages have features that are not available in earlier languages. Pascal lets you define records and sets, which are not available in BASIC or FORTRAN. C++ and Java have classes and allow overloading of functions. But the view from new to old is not always clear. BASIC had GOTO, which has all but been removed from modern languages. COBOL had level-88 values, which do not exist in newer languages. FORTRAN-66 had the arithmetic IF statement with its three-way branching, which looks weird from any other language, old or new. The simple rule "old is familiar and newer is strange" doesn't hold.

Instead of programming languages, perhaps it is better to think about programming paradigms. These are broader and not tied to a single language. I can see four major programming paradigms: simple procedural programming, structured programming, object-oriented programming, and functional programming. We developed these paradigms in that sequence, with procedural programming in the 1960s (FORTRAN, COBOL, BASIC), structured programming in the 1970s (Pascal, C), object-oriented programming in the 1990s (C++, Java, C#), and functional programming in the 2000s (Haskell, Erlang). [The lists of languages are not complete, and the years reflect the popularity of the languages, not the initial design.]

My personal history with programming had all of these paradigms. Over time, I moved from one paradigm to another. I started with simple procedural programming (BASIC, FORTRAN) and later moved to structured programming (Pascal, C). That transition was fairly easy. I understood the concepts and had only to learn discipline to apply them.

Later, I moved to object-oriented programming (C++, Java, C#). Changing from structured programming to object-oriented programming was more difficult. That may have been due to age (I was fifteen years older) or perhaps the learning method (I learned structured programming in a classroom; object-oriented programming was on my own). It may be that object-oriented programming is that much harder that structured programming. But learn it I did.

Recently I have looked into functional programming, but only out of curiosity. I'm not using functional programming for any serious projects. (At least not yet.)

Notice that my progress was moving up the stack of programming paradigms. I started with the simplest paradigm (procedural) and moved to structured programming and then to object-oriented programming.

Functional programming is different from the other programming paradigms. Procedural programming is the base, upon which is built structured programming. Object-oriented programming is built on top of structured programming. The three of them make a nice little tower.

But functional programming is not an extension of object-oriented programming. It doesn't include the concepts of OOP (data-hiding and polymorphism). You don't build function-oriented programs out of classes. (I recognize that there are programming languages that combine functional programming and object-oriented programming, but they are hybrids. More on them later.)

Functional programming, in my view, is an alternative to structured programming. It sits by the side of our tower of paradigms, not on top. Just as structured programming imposed discipline on procedural programming, function programming imposes discipline on procedural programming -- but a different set of rules.

To transition from object-oriented programming to functional programming, one has to forget object-oriented programming, and then forget the discipline of structured programming, and then -- and only then -- can one learn the discipline of functional programming. (The hybrid of OOP and FP is another level on top of functional programming, much as OOP is another level on top of structured programming. We're building another tower of programming paradigms, with procedural at the bottom, then functional programming, and then object-oriented/functional programming on top.)

Let's get back to the transition from object-oriented programming to functional programming, by forgetting object-oriented programming and structured programming and building functional programming on top of procedural programming.

That transition is difficult, but not impossible. At least, not for me, because of the sequence in which I learned programming. I started with procedural programming, and then added structured programming and then object-oriented programming. In my brain, I can ignore the later additions and recall pure procedural programming. (I can still write programs in BASIC.)

But that is me. I suspect it holds for programmers who followed that same path.

What about other programmers?

For the past two decades, programmers have been taught object-oriented programming, and nothing else. They were not taught procedural programming, followed by structured programming, followed by object-oriented programming. No indeed. The primary programming languages for learning was C++, later replaced by Java, later replaced by C#, and today Python (and possibly JavaScript).

We have been teaching people how to write object-oriented programs, and nothing else. That's going to make the transition to functional programming extremely difficult. Modern-day programmers, who learned only object-oriented programming, cannot simply forget "the new bits" and revert to the old style or procedural programming.

One cannot simply jump from an object-oriented programming language into a functional programming language. For programmers who know object-oriented programming and nothing else, they cannot "forget the new stuff and learn the new bits" because everything, to them, is connected. Switching to functional programming is a complete reset. They have to forget everything (well, almost everything) and start over.

That's a big task.

I'm not saying that functional programming is wrong, or that we shouldn't use it. Nor am I saying that only the really smart programmers should attempt to move from object-oriented programming to functional programming.

My point is that the transition requires one to unlearn a lot of techniques, techniques that have become habits. The transition is a large change, and will require time, effort, and patience.

Thursday, August 13, 2020

Add Functional Programming to Object-oriented Programming, not the other way round

The programming world has multiple paradigms, or styles of programming. The reigning champion is Object-oriented Programming, embodied in C++, Java, and C# and oriented around, well, objects. The prior champion was Structured Programming (or Procedural Programming) represented by C and Pascal and oriented around control structures (and avoiding GOTOs). The challenger is Functional Programming oriented around functions, and in the languages Haskell and F#, among others. An older paradigm is Unstructured Programming (USP), which does use GOTOs and lacks the modern IF/THEN/ELSE and DO/WHILE constructs of Structured Programming.

SP and USP operate in the same space: small and medium-side programs. Since they operate in the same space, one often picks one of them, but does not use both. (One can use both, but it is not easy.)

Object-oriented programming (OOP) operates in "the large" and helps us organize large systems. Structured Programming (SP) and Functional Programming (FP) operate in "the small" and help us build short blocks of code that are reliable and readable. In this view, SP complements OOP and they work well together. SP and FP, on the other hand, compete in the same space. We can build large systems with OOP and SP, or with OOP and FP. (We can build small programs with SP alone, or with FP alone. OOP is not useful with small programs.)

Structured Programming is demonstrably better than Unstructured Programming. Functional programming is arguably better then the older Structured Programming. One would think that we would use the best paradigm, and that we would use Functional Programming. But we don't. It takes time to learn a programming paradigm, and most programmers know the Structured Programming paradigm. Structured Programming is what we have, buried inside many modern systems.

The mix of Object-oriented Programming and Structured Programming makes sense. To use a programming paradigm, or a mix of paradigms, one must have a language that supports the paradigms. C++, Java, and C# all support OOP and SP. Pascal supports only SP; Object Pascal and Delphi support both. Haskell supports FP.

The advocates of Functional Programming have noticed that their preferred languages have achieved modest acceptance, but none have become as popular as the most popular languages C++, Java, and C#, or even Python. That lack of acceptance makes some sense, as a Functional Programming language does not have the Object-oriented Programming concepts that help us organize large systems. (Conversations with practitioners have probably ended with project managers and OOP programmers saying something along the lines of "Functional Programming is nice, but we have a large code base in an Object-oriented Programming language, and we cannot give up that organization." 

I think these conversations have spurred the advocates of Functional Programming to merge OOP into FP languages, the hope that project managers and programmers will accept the new combination. The combination of object-oriented programming and functional programming is a nice trick, and it works.

But this approach is, in my view, the wrong approach.

When programmers and managers say that they want a programming language that supports OOP and FP, they don't really mean that they want an FP programming language that supports OOP.

What they want is a programming language that supports their current code base and allows them to add Functional Programming in small doses.

They want a compromise, much like C++ was a compromise for OOP. C++ offered classes to C programmers -- and was originally called "C with classes". It didn't mandate a pure OOP approach. Instead, it let programmers add OOP to an existing code base, and add OOP in a gradual manner.

The "FP plus OOP" approach fails because the existing code base is not OOP, but OOP with SP. A "FP plus OOP" language requires that all of the SP code blocks be re-written in FP. That can work for tiny programs and classroom exercises, but it doesn't work in the industry with large sets of code.

Yes, some companies have large, million-lines-of-code systems written in FP. But those systems were built in FP from the beginning.

Companies that have large, million-lines-of-code systems written in OOP (with procedural code too) don't want to stop everything and re-write that code. They want to add FP in small doses. They want the benefit of FP in a few key locations. Over time, they can expand FP to other parts of the system.

They don't want an FP language with OOP extensions. They want an "OOP and SP" language with FP extensions.

There is a language that may provide a path forward. Microsoft has its F# language, which is a Functional Programming language, but it also lives in .NET, which means one can combine F# modules with C# modules. If one has a system in C# and wants the advantages of Functional Programming, F# is worth investigating.

But beyond F#, I see no languages that offer a compromise between paradigms, and a way forward for managers and programmers. The current set of FP languages are too "pure" and don't allow the mixing of OOP, FP, and SP paradigms.

Perhaps we will see some new languages that bridge the worlds of Structured Programming, Object-oriented Programming, and Functional Programming.

Friday, May 17, 2019

Procedures and functions are two different things

The programming language Pascal had many good ideas. Many of those ideas have been adopted by modern programming languages. One idea that hasn't been adopted was the separation of functions and procedures.

Some definitions are in order. In Pascal, a function is a subroutine that accepts input parameters, can access variables in its scope (and containing scopes), performs some computations, and returns a value. A procedure is similar: it accepts input parameters, can access variables in its scope and containing scopes, performs calculations, and ... does not return a value.

Pascal has the notion of functions and a separate notion of procedures. A function is a function and a procedure is a procedure, and the two are different. A function can be used (in early Pascal, must be used) in an expression. It cannot stand alone.

A procedure, in contrast, is a computational step in a program. It cannot be part of an expression. It is a single statement, although it can be part of an 'if' or 'while' statement block.

Functions and procedures have different purposes, and I believe that the creators of Pascal envisioned functions to be unable to change variables outside of themselves. Procedures, I believe, were intended to change variables outside of their immediate scope. In C++, a Pascal-style function would be a function that is declared 'const', and a procedure would be a function that returns 'void'.

This arrangement is different from the C idea of functions. C combines the idea of function and procedure into a single 'function' construct. A function may be designed to return a value, or it may be designed to return nothing. A function may change variables outside of its scope, but it doesn't have to. (It may or may not have "side effects".)

In the competition among programming languages, C won big early on, and Pascal (or rather, the ideas in Pascal), have gained acceptance slowly. The C notion of function has been carried by other popular languages: C++, Java, C#, Python, Ruby, and even Go.

I remember quite clearly learning about Pascal (many years ago) and feeling that C was superior to Pascal due to its single approach. I sneered (mentally) at Pascal's split between functions and procedures.

I have come to regret those feelings, and now see the benefit of separating functions and procedures. When building (or maintaining) large-ish systems in modern languages (C++, C#, Java, Python), I have created functions that follow the function/procedure split. These languages force one to write functions -- there is no construct for a procedure -- yet I designed some functions to return values and others to not return values. The value-returning functions I made 'const' when possible, and avoided side effects. The functions with side effects I designed to not return values. In sum, I built functions and procedures, although the compiler uses only the 'function' construct.

The future may hold programming languages that provide functions and procedures as separate constructs. I'm confident that we will see languages that have these two ideas. Here's why:

First, there is a new class of programming languages called "functional languages". These include ML, Erlang, Haskell, and F#, to name a few. These functional languages use Pascal's original idea of functions as code blocks that perform a calculation with no side effects and return a value. Language designers have already re-discovered the idea of the "pure function".

Second, most ideas from Pascal have been implemented in modern languages. Bounds-checking for arrays. Structured programming. Limited conversion of values from one type to another. The separation of functions and procedures is one more of these ideas.

The distinction between functions and procedures is one more concept that Pascal got right. I expect to see it in newer languages, perhaps over the next decade. The enthusiasts of functional programming will realize that pure functions are not sufficient and that they need procedures. We'll then see variants of functional languages that include procedures, with purists holding on to procedure-less languages. I'm looking forward to the division of labor between functions and procedures; it has worked well for me in my efforts and a formal recognition will help me convey this division to other programmers.

Monday, January 16, 2017

Discipline in programming

Programming has changed over the years. We've created new languages and added features to existing languages. Old languages that many consider obsolete are still in use, and still changing. (COBOL and C++ are two examples.)

Looking at individual changes, it is difficult to see a general pattern. But stepping back and getting a broader view, we can see that the major changes have increased discipline and rigor.

The first major change was the use of high-level languages in place of assembly language. Using high-level languages provided some degree of portability across different hardware (one could, theoretically, run the same FORTRAN program on IBM, Honeywell, and Burroughs mainframes). It meant a distant relationship with the hardware and a reliance on the compiler writers.

The next change was structured programming. It changed our notions of flow control, using "while", "if/then/else", and "for" structures and discouraged the use of "goto".

Then we adopted relational databases, separate from the application program. It required using an API (later standardized as SQL) rather than accessing data directly, and it required thought and planning for the database.

Relational databases forced us to organize data stored on disk. Object-oriented programming forced us to organize data in memory. We needed object models and for very large projects, separate teams to manage the models.

Each of these changes added discipline to programming. The shift to compilers required reliable compilers and reliable vendors to support them. Structured programming applied rigor to the sequence of computation. Relational databases applied rigor to the organization of data stored outside of memory, that is, on disk. Object-oriented programming applied rigor to the organization of data stored in memory.

I should note that each of these changes was opposed. Each had naysayers, usually basing their arguments on performance. And to be fair, the initial implementation of each change did have lower performance than the old way. Yet each change has a group of advocates (I call them "the Pascal crowd" after the early devotees to that language) who pushed for the change. Eventually, the new methods were improved and accepted.

The overall trend is towards rigor and discipline. In other words, the Pascal crowd has consistently won the debates.

Which is why, when looking ahead, I think future changes will keep moving in the direction of rigor and discipline. There may be minor deviations from this path, with new languages introducing undisciplined concepts, but I suspect that they will languish. The successful languages will require more thought, more planning, and prevent more "dangerous" operations.

Functional programming is promising. It applies rigor to the state of our program. Functional programming languages use immutable objects, which once made cannot be changed. As the state of the program is the sum of the state of all variables, functional programming demands more thought given to the state of our system. That fits in with the overall trend.

So I expect that functional languages, like structured languages and object-oriented languages, will be gradually adopted and their style will be accepted as normal. And I expect more changes, all in the direction of improved rigor and discipline.

Sunday, November 20, 2016

Matters of state

One difference between functional programming and "regular" programming is the use of mutable state. In traditional programming, objects or programs hold state, and that state can change over time. In functional programming, objects are immutable and do not change their state over time.

One traditional beginner's exercise for object-oriented programming is to simulate an automated teller machine (ATM). It is often used because it maps an object of the physical world onto an object in the program world, and the operations are nontrivial yet well-understood.

It also defines an object (the ATM) which exists over time and has different states. As people deposit and withdraw money, the state of the ATM changes. (With enough withdrawals the state becomes "out of cash" and therefore "out of service".)

The ATM model is also a good example of how we in the programming industry have been focussed on changing state. For more than half a century, our computational models have used state -- mutable state -- often to the detriment of maintenance and clarity.

Our fixation on mutable state is clear to those who use functional programming languages. In those languages, state is not mutable. Programs may have objects, but objects are fixed and unchanging. Once created, an object may contain state but cannot change. (If you want an object to contain a different state, then you must create a new object with that different state.)

Programmers in the traditional languages of Java and C# got an exposure to this notion with the immutable strings in those languages. A string in Java is immutable; you cannot change its contents. If you want a string with a different content, such as all lower-case letters, you have to create a new object.

Programming languages such as Haskell and Erlang make that notion the norm. Every object is immutable, every object may contain state but cannot be changed.

Why has it taken us more than fifty years to arrive at this, um, well, state?

I have a few ideas. As usual with my explanations, we have to understand our history.

One reason has to do with efficiency. The other reason has to do with mindset.

Reason one: Objects with mutable state were more efficient.

Early computers were less powerful than those of today. With today's computers, we can devote some percentage of processing to memory management and garbage collection. We can afford the automatic memory management. Earlier computers were less powerful, and creating and destroying objects were operations that took significant amounts of time. It was more efficient to re-use the same object and simply change its state rather than create a new object with the new state, point to that new object, and destroy the old object and return its memory to the free pool.

Reason two: Objects with mutable state match the physical world

Objects in the real world hold physical state. Whether it is an ATM or an automobile or an employee's file, the physical version of the object is one that changes over time. Books at a library, in the past, contained a special pocket glued to the back cover used to hold a card which indicated the borrower and the date due back at the library. That card held different state over time; each lending would be recorded -- until the card was filled.

The physical world has few immutable objects. (Technically all objects are mutable, as they wear and fade over time. But I'm not talking about those kinds of changes.) Most objects, especially objects for computation, change and hold state. Cash registers, ATMs, dresser draws that hold t-shirts, cameras (with film that could be exposed or unexposed), ... just about everything holds state. (Some things do not change, such as bricks and stones used for houses and walkpaths, but those are not used for computation.)

We humans have been computing for thousands of years, and we've been doing it with mutable objects for all of that time. From tally sticks with marks cut by a knife to mechanical adding machines, we've used objects with changing states. It's only in the past half-century that it has been possible to compute with immutable objects.

That's about one percent of the time, which considering everything we're doing, isn't bad. We humans advance our calculation methods slowly. (Consider how long it took to change from Roman numerals to Arabic, and how long it took to accept zero as a number.)

I think the lesson of functional programming (with its immutable objects) is this: We are still in the early days of human computing. We are still figuring out how to calculate, and how to represent those calculations for others to understand. We should not assume that we are "finished" and that programming is "done". We have a long journey ahead of us, one that will bring more changes. We learn as we travel on this journey, and they end -- or even the intermediate points -- is not clear. It is an adventure.

Thursday, October 27, 2016

Actually, new platforms compel new languages

My previous post claimed that new platforms spur the adoption of new languages. The more I think about it, the more I believe I was wrong.

New platforms don't simply spur the adoption of new languages. They compel the adoption of new languages.

A platform offers a set of capabilities and a set of concepts. Languages are designed around those capabilities and concepts. Change the platform, and you change the capabilities and the concepts, and you need a different language.

For batch processing, COBOL and FORTRAN were acceptable. They didn't work for timeshare systems and they didn't work for microcomputers. Timeshare and micrcomputers were interactive, and they needed a language like BASIC.

Windows and OS/2's Presentation Manager required a language that could handle event-driven processing, and object oriented languages (first C++, later Visual Basic and Java) met that need.

Web applications needed a run-time system that was constantly present. We started web applications with Perl and C++ and quickly learned that the startup time for the programs was costing us performance. Java and C# load their run-time systems independently of the application program, and can keep the run-time in memory, which gives better performance.

Changing languages (and the mindset of the underlying platform) is a significant effort. One does not do it lightly, which is why large organizations tend to use older technology.

But where does this leave functional languages?

From my view, I see no platform that requires the use of functional languages. And without a compelling reason to use functional languages, I expect that we won't. Oh, functional languages won't go away; lots of developers use them. (I myself am a fan, although I tend to use Ruby or Python for my own projects.)

But functional languages won't become the popular languages of the day without a reason. Inertia will keep us with other languages.

At least, until a platform arrives that compels the capabilities of functional languages. That platform might be the "internet of things" although I expect the first versions will use the currently popular languages.

Functional languages offer increased reliability. It may be possible to prove certain programs correct, which will be of interest to government agencies, banks, and anyone in the security field. (Turing proved that we could not prove correct most programs, but I believe that we can prove correct programs that are subject to a set of constraints. Functional languages may offer those constrants.)

I'm not abandoning functional languages. I like what they offer. Yet I recognize that they require an additional level of discipline (much like structured programming and object-oriented programmed required additional discipline) and we will switch only when the benefits are higher than the cost.

Tuesday, January 19, 2016

Functional programming is waiting for microservices

Functional programming has been bubbling on the edge of mainstream development for years (perhaps decades). The advent of microservices may give functional programming its big break.

Why has it taken so long for the industry to adopt functional programming? I can think of a few reasons:
  • The effort to learn the techniques of functional programming
  • The effort to convert existing programs
  • The belief that current techniques are "good enough"
Individual developers (and teams of developers) have already learned the techniques of object-oriented programming. They are comfortable with them. They know the tools and understand the issues of object-oriented development. Changing to functional programming is a big change, with new techniques and new issues. That change can make people reluctant to switch to functional programming.

Existing systems are large and complex. Converting them to functional programming is a large effort, and one that must be done completely. The switch from procedural programming to object-oriented programming could be done gradually, especially if you were moving from C to C++. Functional programming has no gradual path.

Switching from object-oriented programming to functional programming incurs a cost, and the benefits are not so clear. The "return on investment" is not obvious.

These are all reasons to not switch from object-oriented programming to functional programming. (And they're pretty good reasons.)

Microservices change the equation.

Microservices are small, independent services. Changing an existing system (probably a large, monolithic system) to one that is composed of microservices is a large significant effort. It requires the decomposition of the monolith into smaller pieces.

If one is constructing small, independent services, either as part of a re-engineering effort or a new system, one can certainly consider functional programming -- if only for some of the microservices. Writing small functional programs is much easier than writing large systems in a functional language. (A statement that holds for object-oriented programming languages, and procedural languages, and assembly language.)

For microservices, a functional language may be better than an object-oriented one. Object-oriented languages are suited to large systems; classes and namespaces are designed for organizing the data and code of large systems. Microservices are, by design, small. It is possible that functional programming will be a better match for the small code of microservices.

If you are building microservices, or just contemplating microservices, think about functional programming.

Tuesday, July 7, 2015

I can write any language in FORTRAN

Experienced programmers, when learning a new programming language, often use the patterns and idioms of their old language in the new one. Thus, a programmer experienced in Java and learning Python will write code that, while legal Python, looks and smells like Java. The code is not "Pythonic".

I, when writing code in a new programming language, often write as if it were C. As I learn about the language, I change my pattern to match the language. The common saying is that a good programmer can write any language in FORTRAN. It's an old saying, probably from the age when most programmers learned COBOL and FORTRAN.

When the IT world shifted from structured programming languages (C, BASIC, FORTRAN) to object-oriented programming languages (C++, Java, C#) much of the code written in the new languages was in the style of the old languages. Eventually, we programmers learned to write object-oriented code.

Today, most programmers learn C# or Java as their first language.  Perhaps we should revise our pithy saying to: A good programmer can write any language in Java. (Or C#, if you prefer.)

Why is this important? Why think about the transition from structured programming ("procedural programming") to object-oriented programming?

Because we're going through another transition. Two, actually.

The first is the transition from object-oriented programming to functional programming. This is a slow change, one that will take several years and perhaps decades. Be prepared to see more about functional programming: articles, product releases, and services in programming platforms. And be prepared to see lots of functional programs written in a style that matches object-oriented code.

The second is the transition from web applications to mobile/cloud applications. This change is faster and is already well underway. Yet be prepared to see lots of mobile/cloud applications architected in the style of web applications.

Eventually, we will learn to write good functional programs. Eventually, we will learn to design good cloud systems. Some individuals (and organizations) will make the transition faster than others.

What does this mean for the average programmer? For starters, be aware of one's own skills. Second, have a plan to learn the new programming paradigms. Third, be aware of the skills of a hiring organization. When a company offers you a job, understand how that company's level matches your own.

What does this mean for companies? First, we have yet another transition in the IT world. (It may seem that the IT world has a lot of these inconvenient transitions.) Second, develop a plan to change your processes to use the new technology. (The changes are happening whether you like them or not.) Third, develop a plan to help your people learn the new technologies. Companies that value skilled employees will plan for training, pilot programs, and migration efforts. Companies that view employees as expensive resources that are little more than cost centers will choose to simply engage contractors with the skills and lay off those currently on their payrolls.

And in the short term, be prepared to see a lot of FORTRAN.

Tuesday, January 13, 2015

Functional programming exists in C++

Some programmers of C++ may look longingly at the new functional programming languages Haskell or Erlang. (Or perhaps the elder languages of Common Lisp or Scheme.) Functional programmi-ness is a Shiny New Thing, and C++ long ago lost its Shiny New Thing luster of object-oriented programming.

Yet C++ programmers, if they look closely enough, can find a little bit of functional programming in their language. Hidden in the C++ specification is a tiny aspect of functional programming. It occurs in C++ constructor initializers.

Initializers are specifications for the initialization of member variables in a constructor. The C++ language provides for default initialization of member variables; initializers override these defaults and let the programmer specific actions.

Given the class:

class MyInts {
private:
    int a1_;
    int a2_;
public:
    MyInts(void);
}

one can store two integers in an object of type MyInts. The old-style C++ method is to provide 'setter' and 'getter' functions to allow the setting and retrieval of values. Something like:

class MyInts {
private:
    int a1_;
    int a2_;
public:
    MyInts(void);
    void setA1(int a1) { a1_ = a1; };
    int getA1(void) const { return a1_; };
    void setA2(int a2) { a2_ = a2; };
    int getA2(void) const { return a2_; };
}

The new-style C++ (been around for years, though) dispenses with the 'setter' functions and uses initializers and parameters in the constructor:

class MyInts {
private:
    int a1_;
    int a2_;
public:
    MyInts(int a1, int a2) : a1_(a1), a2_(a2) {};
    int getA1(void) const { return a1_; };
    int getA2(void) const { return a2_; };
}

The result is an efficiently-constructed object. Another result is an immutable object, as one cannot change its state after construction. (The 'setter' functions are gone.) That may or may not be what you want, although in my experience ir probably is what you want.

Initializers are interesting. One cannot do just anything in an initializer. You can provide a constant value. You can provide a constructor for a class (if your member variable is an object). You can call a function that provides a value, but it should be either a static function (not a member function) or a function outside of the class. (Calling a member function on the same class is an undefined operation. It may work, or it may not.)

These restrictions on initializers enforce one of the attributes of functional programming: immutable objects. In my example, I eliminated the 'setter' functions to may objects of MyInts immutable, but that was an intentional effect. I could have left the 'setter' functions in place, and then objects of MyInts would be mutable.

Initializers brook no such nonsense. You have one opportunity to set the value for a member variable (you cannot initialize a member variable more than once). Once it is set, it cannot be changed, during the initialization. You cannot call a function that has a side effect of changing a member variable that has been previously set. (Such a call would be to a member function, and while permitted by the compiler, you should avoid them.)

Initializers provide a small bit of functional programming inside C++. Who would have thought?

Technically, the attributes I have described are not functional programming, but merely immutable objects. Functional programming allows one to treat functions as first class citizens of the language, creating them and passing them to other functions as needed. The initializers in C++ do not allow such constructs.

Monday, July 14, 2014

Spreadsheets can help us learn functional programming

Spreadsheets are quite possibly the worst way to learn programming skills. And they may also be the best way to learn the next "wave" of programming skills. A contradiction? Perhaps.

First, by "spreadsheets" I mean the cell grid and its formulas. I am omitting Visual Basic for Applications (VBA) code which can accompany Microsoft Excel sheets.

Spreadsheets as a programming environment are capable and flexible. They let one assemble a set of data and formulas into a meaningful arrangement. They let you format the data. They provide immediate feedback, with the results of changes displayed immediately.

Spreadsheets also violate a lot of the generally accepted principals of program design. They mix input, data, calculation, and output. They have no mechanisms for structuring calculations or encapsulating data. They have no way to isolate data; everything is "global" and any cell can be used by any other cell.

The lack of structural elements means that spreadsheets tend to "scale up" poorly. A small set of data is easily handled. A somewhat larger set of data (if it is the same type of data) is also manageable. A larger collection of different types of data becomes a challenge. Even with multi-page spreadsheets, one starts allocating regions of a sheet for certain data and certain calculations. These regions become problematic as they grow -- especially if they grow at different rates.

There is no way to condense similar calculations. If ten cells (or one hundred cells) all perform the same operation, they must all contain the same formula. Internally, the spreadsheet may optimize memory usage, but from the "programmer's" point of view, the formulas are repeated. If the general formula must change, it must change in all the cells. (While it is easy to change the formula in one cell and then replicate it to the other cells, it is not always easy to identify which other cells use that formula.)

Spreadsheets offer nothing in the way of a high-level view. Everything is viewed at the cell level: to examine a formula, you must look at the specific cell that contains the formula.

So spreadsheets offer power and immediate feedback, two important aspects of programming. Yet they lack the concepts of structured programming (subroutines, control blocks) and the concepts of object-oriented programming (custom types, encapsulation, inheritance).

With all of these omissions, how can spreadsheets be a good way to learn the next programming style?

The answer is functions.

The next wave of programming (as I see it) is functional programming. With functional programming, one defines and uses functions, and functions are first-class constructs of the language. Functions can be passed as arguments to other functions. They can be constructed by functions, and evaluated by functions. The change from object-oriented programming to functional programming is as large (and maybe larger) than the change from structured programming to object-oriented programming.

Spreadsheets can help us learn functional programming because spreadsheets (the core, non-VBA version of spreadsheets) are all about functions. Every cell contains the result of a function. Once a cell's value is defined, it does not change. (Changing cells in the spreadsheet and pressing the "recalc" button is, in essence, modifying the program an re-executing it.)

Now, the comparison is not complete. Functional programming lets you pass functions as arguments to other functions and lets you build functions "on the fly", and spreadsheets let you do neither. So designing a spreadsheet is not the same as programming in a functional language.

But programming spreadsheets is a start. It is a jumping-off point. It is an introduction to some of the concepts of functional programming.

If you want to learn functional programming, perhaps a good place to start is with your local spreadsheet. Turn off (or ignore) the VBA or macro programming. Stick with cells, values, and functions. Avoid the "optimize" or "search for result" capabilities. Design spreadsheets that compute things that are easy in "real" programming languages. You may be stuck at first, given the constraints of spreadsheet calculations. But keep at it. You will learn techniques that can help you with the next wave of programming.

Tuesday, December 17, 2013

The transition from object-oriented to functional programming

I am convinced that we will move from object-oriented programming to functional programming. I am also convinced that the transition will be a difficult one, more difficult that the transition from structured programming to object-oriented programming.

The transition from structured programming to object-oriented programming was difficult. Object-oriented programming required a new view of programming, a new way of organizing data and code. For programmers who had learned the ways of structured programming, the shift to object-oriented programming meant learning new techniques.

That in itself is not enough to cause the transition to functional programming to be more difficult. Functional programming is, like object-oriented programming, a new view of programming and a new way of organizing data and code. Why would the transition to functional programming be more difficult?

I think the answer lies within the organization of programs. Structured programming, object-oriented programming, and functional programming all specify a number of rules for programs. For structured programming, functions and subroutines should have a single entry point and exit point and IF/THEN/ELSE blocks and FOR/NEXT loops should be used instead of GOTO statements.

Object-oriented programming groups data into classes and uses polymorphism to replace some conditional statements. But object-oriented programming was not totally incompatible with structured programming (or 'procedural programming'). Object-oriented programming allowed for a top level of new design with lower layers of the old design. Many early object-oriented programs had large chunks of procedural code (and some still do to this day). The thin layer of objects simply acted as a container for structured code.

Functional programming doesn't have this same degree of compatibility with object-oriented programming (or structured programming). Functional programming uses immutable objects; object-oriented programming is usually about mutable objects. Functional programming works with sets of data and leverages tail recursion efficiently, object-oriented programming uses the explicit loops and conditional statements of procedural programming.

The constructs of functional programming work poorly at containing object-oriented constructs. The "trick" of wrapping old code in a containing layer of new code may not work with functional programming and object-oriented programming. It may be better to build functional programming constructs inside of object oriented programming constructs, working from the "inside out" rather than from the "outside in" of the object-oriented transition.

One concept that has helped me transition is that of immutable objects. This is a notion that I have "imported" from functional programming into object-oriented programming. (And I must admit that the idea is not mine or not even new; Java's String objects are immutable and have been since its inception.)

The use of immutable objects has improved my object-oriented programs. It has moved me in the direction of functional programming -- a step in the transition.

I believe that we will transition from object-oriented programming to functional programming. I foresee a large effort to do so, and I foresee that some programs will remain object-oriented programs, just as some legacy programs remain procedural programs. I am uncertain of the time frame; it may be in the next five years or the next twenty. (The advantages of functional programming are compelling, so I'm tending to think sooner rather than later.)

Wednesday, November 20, 2013

We need a new UML

The Object Management Group has released a new version of UML. The web site for Dr. Dobb's asks the question: Do You Even Care? It's a proper question.

It's proper because UML, despite a spike of interest in the late 1990s, has failed to move into the mainstream of software development. While the Dr. Dobb's article claims ubiquity ("dozens of UML books published, thousands of articles and blogs posted, and thousands of training classes delivered"), UML is anything but ubiquitous. If anything, UML has been ignored in the latest trends of software: agile development techniques and functional programming. It is designed for large projects and large teams designing the system up front and implementing it according to detailed documents. It is designed for systems built with mutable objects, and functional programming avoids both objects and mutable state.

UML was built to help us design and build large complex systems. It was meant to abstract away details and let us focus on the structure, using a standard notation that could be recognized and understood by all practitioners. We still need those things -- but UML doesn't work for a lot of projects. We need a new UML, one that can work with smaller projects, agile projects, and functional programming languages.

Thursday, August 22, 2013

Migrating from desktop to cloud is no small deal

The popularity of smart phones and tablets has made mobile (and its server-side colleague cloud) the new darling technology. They are the new buzzwords that garner attention -- and probably funding. They get attention for new apps, and some folks have been migrating existing desktop and web apps.

If you are embarking on such a project, I encourage you to look into three technologies: mobile devices, cloud computing, and functional programming.

Functional programming is a specific way of designing programs, much like structured programming and object-oriented programming. But in contrast to those techniques, functional programming guides one to smaller units of code. Structured programming and object-oriented programming allow one to build small units, but do not encourage it. As a result, most (non-homework) code built with structured and object-oriented techniques contains collections of large modules and objects.

Cloud computing is a specific way of designing systems out of smaller components, many of which are part of the cloud infrastructure. Cloud-based applications use data stores, message queues, and a measured amount of code. (Previous architectures such as desktop and web often saw applications made of whole cloth with little use of pre-made components.)

Mobile devices force a split of code between the server (typically a cloud-based server) and the user interface on the device. The device usually performs some processing with most occurring on the server. (A few apps perform all processing on the device, such as in the game "Angry Birds". But they are exceptions.) Splitting the code between the device and the server forces you to build not a single application but two programs that communicate.

The new technology set encourages us to build systems of smaller programs. Mobile/cloud is for collaborating programs, not monolithic ones. Functional programming techniques reward small programs and penalize large ones.

This "impedance mismatch" between mobile/cloud and desktop applications (and to a somewhat lesser extent, web applications) means that porting to mobile/cloud is difficult. The legacy systems on the earlier platforms were built to take advantage of the strengths of the platform, and small, collaborating programs were not efficient.

The mismatch between object-oriented systems and functional programming is even greater. Object-oriented programming is often about objects holding state -- mutable state, so that objects change over time -- and functional programming is about immutable objects.

A few well-designed (from the mobile/cloud perspective) applications for the desktop and web can be migrated to mobile/cloud. Most, I think, will be difficult. Some may be close to impossible.

My advice: Build some new apps for mobile/cloud, to gain experience with the new design paradigm. Try out the functional programming languages (or at least, your favorite object-oriented language is with immutable objects). Once you have that experience, evaluate your legacy apps and select a small number (perhaps two) of "easy" apps for migration. I'm sure that the exercise will give you greater insight into the effort for the other (more difficult) legacy apps.

Then, armed with experience of the new technologies and a good understanding of your code base, should you migrate from desktop to mobile/cloud.

Saturday, June 22, 2013

Functional programming has no loud-mouth advocate

I'm reading "The Best of Booch", a collection of essays written by Grady Booch in the 1990s.

In the 1990s, the dominant programming method was structured programming. Object-oriented programming was new and available in a few shops, but the primary programming style was structured. (Structured programming was the "better" form of programming introduced in the 1970s.)

We had learned how to use structured programming, how to write programs in it, and how to debug programs in it. We (as an industry) had programming languages: C, Visual Basic, and even structured methods for COBOL. Our compilers and IDEs supported those languages.

We had accepted structured programming, adopted it, and integrated it into our processes.

We had also learned that structured programming was not perfect. Our programs were hard to maintain. Our programs contained bugs. Our programs were difficult to analyze.

Object-oriented programming was a way forward, a way to organize our programs and reduce defects. Booch was an advocate, out in front of the crowd.

Now, these essays were also a way for Booch to hawk his business, which was consulting and training in UML and system design. Boosh was one of the early proponents of object-oriented programming, and one of the participants in the "notation wars" prior to UML. The agreement on UML was a recognition that there was more money to be made in supplying a uniform notation for system design than in fighting for one's own notation.

But despite the advertising motivation, the articles contain a strong set of content. One can feel the passion for object-oriented programming in Booch. These are legitimate articles on a new technology first, and convenient advertising for his business a distant second.

Fast-forward to the year 2013. We have accepted object-oriented programming as mainstream technology. People (and projects) have been using it for years -- no, decades. We have learned how to use object-oriented programming, how to write programs in it, and how to debug programs in it. We (as an industry) have programming languages: C++, Java, Python, and Ruby. Our compilers and IDEs support these languages.

We have accepted object-oriented programming, adopted it, and integrated it into our processes.

We have also learned that object-oriented programming is not perfect. Our programs are hard to maintain. Our programs contain bugs. Our programs are difficult to analyze.

In short, we have the same problems with object-oriented programs that we had with structured programs.

Now, functional programming is a way forward. It is a way to organize our programs and reduce defects. (I know; I have used it.)

But where are the proponents? Where is the Grady Booch of functional programming?

I have seen a few articles on functional programming. I have read a few books on the topic. Most articles and books have been very specific to a new language, usually Scala or Haskell. None have had the broader vision of Booch. None have described the basic benefits of functional programming, the changes to our teams and processes, or the implications for system architecture and design.

At least, none that I have read. Perhaps I have missed them, in my journeys in technical writings.

Perhaps there is no equivalent to Grady Booch for functional programming. Or perhaps one does not exist yet. Perhaps the time is too early, and the technology must develop a bit more. (I tend to think not, as functional programming languages are ready for use.)

Perhaps it is a matter of passion and business need. Booch wrote his articles because he felt strongly about the technology, and because he had a business case for them.

Perhaps it is a matter of distribution. The software business in 2013 is very different from the software business in 1997; the big change is the success of open source.

Open source projects emerge into the technology mainstream through channels other than books and magazine articles. They are transmitted from person to person via e-mail, USB drives, and Github. Eventually, magazine articles are written, and then books, but only after the technology is established and "running". The Linux, Apache, and Perl projects followed this path.

So maybe we don't need an obvious advocate for a new technology. Perhaps the next programming revolution will be quieter, with technology seeping slowly into organizations and not being forced. That might be a good thing, with smaller shocks to existing projects and longer times to learn and adopt a new programming language.

Sunday, April 28, 2013

C++ without source (cpp) files

A thought experiment: can we have C++ programs without source files (that it, without .cpp files)?

The typical C++ program consists of header files (.h) and source files (.cpp). The header files provide definitions for classes, and the source files provide the definition of the implementations.

Yet the C++ language allows one to define function implementation in the header files. We typically see this only for short functions. To wit:

random_file.h

class random_class
{
private:
    int foo_;
public:
    random_class( int foo ) : foo_(foo);
    int foo( void ) { return foo_ };
}

This code defines a small class that contains a single value and has no methods. The sole member variable is initialized in the constructor.

Here's my idea: Using the concepts of functional programming (namely immutable variables that are initialized in the constructor), one can define a class as a constructor and a bunch of read-only accessors.

If we keep class size to a minimum, we can define all classes in header files. The constructors are simple, and the accessor functions simply return calculated values. There is no need for long methods.

(Yes, we could define long functions in headers, but that seems to be cheating. We allow short functions in headers and exile long functions into .cpp files.)

Such a design is, I think, possible, although perhaps impractical. It may be similar to the chemists' "perfect gas", an abstraction that is nice to conceive but unseen in the real world.

Yet a "perfect gas" of a class (perhaps a "perfect class") may be possible for some classes in a program. Those perfect classes would be small, with few member variables and only accessor functions. Its values would be immutable. The member variables may be objects of smaller classes (perhaps perfect classes) with immutable values of their own.

This may be a way to improve code quality. My experience shows that immutable objects are much easier to code, to use, and to debug. If we build simple immutable classes, then we can code them in header files and we can discard the source files.

Coding without source files -- no there is an idea for the future.

Sunday, October 23, 2011

Functional programming pays off (part 2)

We continue to gain from our use of functional programming techniques.

Using just the "immutable object" technique, we've improved our code and made our programming lives easier. Immutable objects have given us two benefits this week.

The first benefit: less code. We revised our test framework to use immutable objects. Rather than instantiating a test object (which exercises the true object under test) and asking it to run the tests, we now instantiate the test object and it runs the tests immediately. We then simply ask it for the results. Our new code is simpler than before, and contains fewer lines of code.

The second benefit: we can extract classes from one program and add them to another -- and do it easily. This is a big win. Often (too often), extracting a class from one program is difficult, because of dependencies and side effects. The one class requires other classes, not just direct dependencies but classes "to the side" and "above" in order to function. In the end, one must import most of the original system!

With immutable objects, we have eliminated side effects. Our code has no "side" or "above" dependencies, and has fewer direct dependencies. Thus, it is much easier for us to move a class from one program into another.

We took advantage of both of these effects this week, re-organizing our code. We were productive because our code used immutable objects.

Monday, August 22, 2011

Immutable Object Programming

I've been working with "Immutable Object Programming" and becoming more impressed with it.

Immutable Object Programming is object-oriented programming with objects that, once created, do not change. It is a technique used in functional programming, and I borrowed it as a transition from traditional object-oriented programming to functional programming.

Immutable Object Programming (IOP) enforces a discipline on the programmer, much like structured programming enforced a discipline on programmers. With IOP, one must assemble all components of an object prior to its creation. The approach of traditional object-oriented programming allows for objects to change state, and this is not possible with IOP. With IOP, you do not want an object to change state. Instead, you want a new object, often an object of a different type. Thus, when you have new information, you construct a new object from the old, adding the information and creating a new object of a similar but different type. (For example, a Sale object and a payment are used to construct a CompletedSale object.)

IOP yields programs that have lots of classes and the logic is mostly linear. The majority of statements are assignment statements -- often creating an object, and the logic for iteration and decisions are contained within the constructor code.

As a programmer, I have a good feeling about the programs I write using IOP techniques. It is a feeling of certainty, a feeling that the code is correct. It is a good feeling.

I experienced this feeling once before, when I learned structured programming techniques. At the time, my programs were muddled and difficult to follow. With structured programming techniques, my programs became understandable.

I have not had that feeling since. I did not experience it with object-oriented programming; OOP was difficult to learn and not clarifying.

You can use immutable object programming immediately; it requires no new compiler or language. It requires a certain level of discipline, and a willingness to change. I use it with the C# language; it works with any modern language. (For this conversation, C++ is omitted from the set of modern languages.) I started with the bottom layer of our objects, the ones that are self-contained. Once the "elementary" objects were made immutable, I moved up a layer to the next set of objects. Within a few weeks I was at the highest level of objects in our code.

Saturday, June 11, 2011

Better programming with immutable objects

Recent buzz in the development community has discussed functional programming languages. These languages have a different approach to the organization of code. They are not object-oriented languages, nor are they procedural. Functional programming languages include Haskell, Erlang, and F#.

Working with old-fashioned object-oriented languages (C++ and C#), I suffer from language envy. I can see the shiny new languages but use the old, dented languages for my daily work. (Of course, I recognize that at one time C# and even C++ were the new, shiny languages. I also recognize that at some point in the future, Haskell and F# will be considered the old, dented languages. But for now, the grass is greener over the fence and in the yard of the new languages.)

I may be suffering from envy, but I don't sit and curse the darkness. Instead, I try to use the techniques of the new languages in my current toolset. I did this when programming in C and gazing longingly at C++; I wrote code in a style that I called "thing-oriented" programming. My thing-oriented programming let me identify key objects in the code (data structures, not objects in the OO sense) and collect and organize functions by the objects they manipulated. It was a step towards object-oriented programming. (Eventually I did learn C++ and work on C++ projects.)

With the introduction of C# and .NET, I used the same idea. For this transition, I wrote class libraries in C++ that mimicked the class libraries in .NET. (Not the entire .NET collection, just the basic classes to get the work done.) The work was a bit difficult, as we were not allowed to use STL. But like "thing-oriented programming", it was a step towards .NET and made the transition easier.

So here I am again, and this time the target is functional programming languages. I want to transition to functional programming from object-oriented programming, but don't have the tools. (The day job uses "classic" OO languages, and I struggle to find time outside of the office.)

My transition technique is to use "immutable object programming".

This has some interesting effects:

1) To construct an object, all data must be present. I cannot instantiate an object and later give it more information. Once an object is instantiated, it is complete and final. (I can construct other objects from built objects, so I can construct a "sales price" object and later use it to construct a "discounted sales price" object. But I cannot wedge in a discount to the "sales price".

2) I find myself thinking about the sequence of operations and the dependencies between objects.

3) My programs are designed in three phases: collect data (and construct objects), construct other objects from the collected data, and produce output. This is a pattern that goes back to the beginnings of the programming age. It may be a natural fit for the "immutable object programming" style, or it may be driven by the calculations of the systems.

4) My thinking is more rigorous. Not necessarily up front, but the end result (the final code) is more disciplined. I write some code, and sometimes take non-immutable shortcuts (or even OO shortcuts). These shortcuts are obviously wrong, but they yield the correct output. Once I have the correct output (and tests to check that output), I revise the code and remove the shortcuts.

5) My code is easy to debug. When the output is incorrect, I know that an object has incorrect data. (Or possibly the output routine is incorrect.) If the object has incorrect data, I know that it was constructed improperly. (There is no other method that modifies the object.) Finding the problem is a simple matter of identifying the incorrect object and then identifying the construction of that object.

6) My code is easy to change. I have made a number of changes to the code, and all have been simple and obvious. (And therefore, they worked.) These were not trivial changes, either; some were large and affected multiple modules.

I will admit that I do not understand functional programming languages. I have created some small programs in Haskell, but not enough that I "grok" the concept. My "immutable object programming" trick may be a step towards functional programming or it may be a step away from functional programming. It feels right, and I like the results.

Wednesday, March 9, 2011

Hybrid for functional languages

Are there hybrid functional languages? Languages that correspond to the hybrid object-oriented programming languages of C++, Object Pascal, and Visual Basic? A quick survey of the web (if there is such a thing as a quick survey) yields a page (from stackoverflow.com) that lists the following languages: Scala, Clojure, F#, Ruby, OCaml, Common LISP, Nemerle, Smalltalk, and O'Haskell. A few other web pages list these languages as hybrids.

So yes, there are hybrid functional languages. And this is important.

The jump from the "classic" languages of C++, C#, and Java to pure functional languages (Haskell, Erlang) is a large one. We were able to move from procedural languages (C, Pascal, and BASIC) to object-oriented languages (Java, C#) by using hybrid languages as an intermediate step. (A rather expensive intermediate step, as we look back at the mountains of hard-to-maintain C++ code we have created, but it was a step.)

We humans, for the most part and in most situations, tend to do better with small steps. Small changes in our programming languages are more acceptable to us that large changes. (Hence the migration from FORTRAN II to FORTRAN IV to FORTRAN 66 and then to Fortran 77, and not a migration from FORTRAN II to Pascal.)

The hybrid object-oriented languages became popular because they were useful.

I expect that hybrid functional languages will become popular for the same reason. We will want to move to the functional languages, to reduce programming time and improve reliability. The jump to a pure functional language is large, often requiring not only a complete re-write of the application but a re-thinking of our thinking for the application. Hybrid functional languages will allow a more gentle transition to functional programming.

Exactly *which* hybrid functional languages become popular is quite hard to predict. Microsoft will push F#, or possibly extend C# with functional qualities. The Java crowd will like Scala. The Ruby enthusiasts will like... Ruby. I'm not sure what the Apple camp will adopt.

Apple, with its devotion to C, C++, and Objective-C is in an interesting position. There is no clear path to functional programming on the Apple platform. This may present a problem for Apple. (Or maybe not, as they may choose to support a functional or hybrid functional language in the future.)