Software transformation is one of the key mechanics in any software. It proves relatively consistent and predictable, as it is relatively easy to establish how things work.
Turing Test has always been an interesting topic in the field of artificial intelligence. The idea is that one day we will be able to fool a machine into thinking that it is chatting with another human being. The basic idea behind this experiment is that if we were able to do this, it would mean that machines have progressed to the point where they can mimic human behaviors with enough accuracy and consistency to pass for human beings.
The point behind the Turing test was that it could be used as an indicator on how close we are to developing artificial intelligence, or at least fooling a machine into thinking that it was talking with a human being.
The test needs to be refined, though, as it doesn’t really work all that well. For example, there have been cases where judges thought they were talking with a 13-year-old boy, only to find out later on that they were talking with a 30-year-old man from Georgia. In other words, there are still many ways in which we can improve the test and make it more accurate in measuring how close we really are to developing AI.
I am fascinated by software transformations. I have been working with them since the late 80s when they were first devised as a way to make code more maintainable. Over the years I have seen many different approaches to them and many ways in which they have been used. In my experience, there are some key things about transformations that are important for any software developer to understand.
Towards that end, today I thought it would be useful to share some ideas about what transformations are, how they can be used, and how they fit into a larger software development picture.
Transformation is one of the key mechanics in any software application. It is a way of making a non-functional aspect of an application (e.g., code structure) conform to a given pattern (e.g., SOLID). It is also relatively inconsistent: you could write an analysis tool that would find examples of every transformation in use today!
I mean the actual transformation. The transformation is a function that takes an input, and produces an output. It is not the user interface. It is not the buttons or menus, but the code that makes them work. I mean the thing that really changes it from a program into an engine or tool.
I have been writing software for 30 years, and transformation has always been one of the key mechanics in any software I’ve written. At this point I can almost recite it by heart:
Input: source code files
Output: executable files
There are basically only two ways to change this process. One is to make the input more flexible: to accept different file types, or allow users to do things like override methods or change how variables are handled. That’s what we did with Rascal: made it more flexible so that transformations could be more complicated and more powerful at the same time.
The other way is to make the output less flexible: to take away features, and assume that all users want is a single destination, usually just a compiled program file. That’s what we did with Smalltalk: we wanted to focus attention on living code instead of dead results, so we limited what you could do with output by making everything compile into a single .
So, at the risk of going off on a tangent, I’d like to talk about transformation for a little bit.
No one really thinks about transformation anymore. It’s just not as sexy as testing or modeling or even refactoring. But it was one of the key mechanics in any software back in the day, and if you look at where we are now, you can see all kinds of ways that we’re still living in that world.
I’m not talking about the kind of transformation where you put a file through some kind of format converter. I’m talking about what happens when you take one representation of your data structure and make it into another representation.
I think most people who program have done something like this at some point: they’ve taken an array of stuff and turned it into a string that they can send to someone else. Or they’ve turned a bunch of strings into an array (or hash). Or they’ve pulled data out of a database and put it into an XML document (or vice-versa).
The thing is, these days, those operations tend to be under the control of APIs that abstract away their implementation details: you don’t care whether it’s an array or whether it’s XML; all you want is to
Software transformation is a key mechanism in all software systems. It is also an important, if often overlooked and undervalued, part of the development process.
Trying to grasp it as a whole is difficult to render in one image, but this should give you a general idea of what transformation covers, and how it is applied.
As you can see, transformation has a broad scope – from the sort of simple refactoring that everyone does (if only for clarity) to the complex changes that are necessary for upgrading or replacing components. This list includes language translation, data migration, system integration and even business process workflows.
As we have seen in previous blogs, software systems are often affected by evolution over time – improvised modifications and additions that require transformations for them to be integrated with the rest of the system. While this does bring about greater flexibility and usability, it is also one of the reasons why software maintenance takes so long and costs so much.
In fact, just as every individual change needs to be tested thoroughly before being released into production, so must every transformation be tested too. It’s not just a case of making sure it works with the rest of the system; there are various other criteria that need to be met:
– It has no negative side
When we hear the word “transformation” what usually comes to mind is a database or application server processing some data and producing a new state of data. This is not transformation art. Transformation Art is a term I’m coining for any software component that takes an input in one form and produces totally different output.
Turing’s original idea for computation was to use transformation on symbols to achieve his goals. His ideas have evolved into the notion of transforming data which has become a cornerstone of Computer Science. With the rise of object oriented programming, objects have become another important unit of computation and transformation.
This blog will explore all aspects of software transformation from the perspective of using them to achieve some purpose.
This blog is intended primarily for practicing software developers, architects, designers and students studying computer science, software engineering, or related topics. It’s also for people who are interested in software design and architecture as well as anyone who has ever struggled with the concept of software transformations because they don’t seem consistent with what they already know about them.
This blog will cover a wide variety of topics based on my own personal experience as well as that of others whom I interview or correspond with on various topics related to transformations. These people are often experts in their own fields, so this
I recently attended the International Conference on Software Engineering (ICSE), which was held this year in Gothenburg, Sweden. I presented a paper at the conference, and I also got to spend some time talking with people about various software issues. One topic that came up several times was the difference between testing and verification.
Test is supposed to be done by developers; it’s a form of validation. It’s supposed to help ensure that what you produce actually works as intended. You might test a web application by clicking on every button or entering every possible input; you might test a mobile app by making sure it still works when your phone is low on battery; you might test the memory allocation routines by trying to allocate huge amounts of memory and see what happens.
Testing is good, but it has its limits: things that are difficult to test sometimes make it past the tests, bugs can be hard to reproduce, tests can take too long, etcetera. That’s where verification comes in: verification is supposed to find bugs that testing didn’t catch. Testing exercises code paths through the program; verification checks whether those code paths make sense according to some specification (that is, whether they are “correct”). The idea is that if you have verified correct code then any bugs