Introduction
Ten years ago, when I started to develop the Programming Without Coding Technology (PWCT) software, I was interested in creating a visual programming language. Unlike many visual programming tools that target beginners or limited to a specific domain, this tool is created for expert programmers, But why should an expert programmer care about using a visual language to program instead of just typing the text based source code directly in his/her favourite programming language like C & C++ ?!
It's all about applying the principles of programming on the process of typing code itself. Yes, we are doing it the wrong way for many years, but how can we notice that and prove it at the theoretical and practical side.
This article will provide the concept behind visual programming to C programmers, why you shouldn't write C code directly again, why the code must be generated for you, why you should have visual representation for your programs, why you should interact with the visual representation and become able to use visual programming to create your new code without typing that code directly.
We are programmers, what are we doing everyday? We are writing code? Sure but, it's not our goal to write code, it's just the method that we use to achieve our goals. We are here in that world to solve problems, to make the world better by developing new software, the more innovative and useful the software we create, the better the world. We can't accept problems, when we simply know how to solve it using technology, what non-programmers may accept to do like unplaned work, redundancy and randomized tasks, etc. can't be accepted by programmers. because we are the masters of the machine and we know how to control it to avoid doing the same thing again and again and to get results very fast and at high level of accuracy. For this reason, I always encourage all of the computer users to know at least about the basics of programming, but this article is not about introducing programming to non-programmers, it's about introducing visual programming to expert C programmers, the real programmers behind many useful and powerful software like (Operating Systems, Compilers, Virtual Machines, Game Engines, DBMS, Network Protocols, Drivers, ...etc.)
So let us start from the beginning, do you remember your first day in the programming world? Yes, I mean that funny and famous program that prints the "hello world
" message on the screen.
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello world\n");
return 0;
}
Sure, we can write it smaller than that, we can change int
to void
and remove the return
statement, also we can remove the function parameters.
What is the problem with typing this simple code?
The problem is that when I wanted to print a message on the screen (The Goal), I used the next steps:
- Using a header file
- Writing the main function
- Using braces { } to determine the function start and end
- Using the
printf
function to print the message - Using semicolon ; to end the statements
Too much work that can be replaced by one line of code.
In batch files, it is:
echo Hello world
In Python:
print "Hello world"
In Ruby:
puts "Hello world"
In Clipper/Harbour/Visual FoxPro:
? "Hello world"
Now we have another problem, too many programming languages, by the way most of them are implemented in C, so why C programmers are creating new programming languages? They are experts in C, they know the language, they know how to create stable and efficient software using it. Of course, new languages are not coming to solve this little problem, each programming language has a story, the rise of a programming paradigm or a particular technology, C++ started by adding the Object-Oriented programming paradigm to C, then along the time many more features are added, Java is known for portability and using a Virtual Machine to execute the same program on different platforms without recompiling, it's VM provided portability and security and that is important for internet applications, now Java is playing a vital role in Android Applications development, languages like Cobol, Clipper, Visual Foxpro, Harbour, and many more are developed to make developing business applications a simple and quick task, a Language like Ruby is designed to merge between different programming paradigms in a smart way, having a dynamic langauge that provides Object-Oriented programming, Functional programming and Meta-programming helped a lot in developing a successful web framework like Ruby on Rails (ROR) that uses the MVC design pattern and apply nice principles like don't repeat youself and convention over configuration. Python is a very successful scripting language that fills the gap between simple scripting language and powerful languages like C, it's easy to extend Python using C and we can use Python in many ways like desktop and web development, also it can be embedded in C & C++ applications when we need more features that are provided by a fast and small language like Lua.
Why am I talking about all of these stories? Because it's one of the main problems that are related to programming languages and writing code. The extension and customization level provided by different programming languages is not enough for everyone and this pushes programmers to create new programming languages instead of using one language.
A new language doesn't solve the problem, it's just a workaround some problems for some time and once the technology goes in its way, many new problems will come that open the door towards creating another new languages!
Let us now wrap up some of the problems that we have:
- Redundancy (things like ; , {} , using break, many more!)
- Level of extension is not enough (not 100% natural and this lead to new languages)
- Level of customization is very low (changing the syntax of a language = creating new language!)
- To use a language you need to know the syntax (not difficult but sometimes you may have syntax errors)
- Writing more code to express about yourself = decrease productivity
- Conflict between readability and writability
- Changing a language = learning curve + more cost
What will happen when we solve all of these problems? And say no redundancy any more, we can get high level of extension and customization, now you can free yourself from the language syntax and get the ability to change it and work with your favorite words (in a way better than using preprocessor) without any effect on other programmers working on the same project on the same part of program where each programmer sees the same code in his own language. what about treating the current programming languages as platforms that you can change without changing your program. What about using a natural language when you read your programs, and using another non-verbose language when you write your programs, at the same time.
All of these things is what we can do using Programming Without Coding Technology, and since 2013 I supported the C programming language to be able to use PWCT to create more powerful software.
Background
I assume that you are a C programmer, and have spent some time watching the next movies to know how PWCT enviroment looks like here.
Using the Code
When I started to learn programming, I started by reading some books then most of the time I used to learn from practical examples and projects. After that, I started to read the same books again to discover that I missed a lot of useful information but I learned a lot more too! Along the time, I have learned a lot from books, open source projects and solving new problems myself!
One of the most important things that I learned was "When you read be patient, try to trust the author, forget that you know how to do things, maybe you will get some new ideas here or there, some ideas can change the world, treat ideas as a child who can grow and become strong along the time".
In this section, we will see some examples about using PWCT on the top of the C language for creating real world project.
Goal: I want to create a new dynamic programming language (Compiler, Virtual Machine, Standard Library, etc.) that provides better flexibility than the languages I know, I need to use declarative programming using nested structures on top of object oriented programming where I can create domain-specefic languages for the client code and still have my classes for the object-oriented design. Unlike Ruby that does something like that but by using functional programming, code blocks and Metaprogramming, my new language will present something different and new that looks like QML (Qt) and REBOL but in a different way that gives me more power to express quickly about the problem solution.
- Stage (1): Create some ADT for Strings and Lists
- Stage (2): Create the Scanner, Parser and Code Generation phases for the compiler
- Stage (3): Create the virtual machine to execute the code and optimize it
- Stage (4): Create standard library for common tasks
- Stage (5): Test the language in developing web applications
I will talk in more details about this new language later, once it's released for public users.
For now, I will show you some sections of the language during its design inside Programming Without Coding Technology where PWCT generates the C code for us!
Example: I want a fast function to get the list item from the linked list.
When I deal with linked lists in C, I can use the data structure directly or I can use functions that hide the implementation details. I decided to do Abstraction using functions (no direct interaction with the data structure from the client code, and reduce the usage of preprocessor that I use only when it's really necessary).
The next picture presents the List
structure.
We have pointers to the first and the last items (pFirst
& pLast
) and each item has pointers to the next and previous items.
We store the size of the list in the nSize
variable of type int (I target at least 32bit systems).
The list structure contains a pointer to the last item accessed by the user, and the number of the next item after that item (it's the cache used by the list to quickly get items).
The next picture presents a high level view of the get item function.
The function gets the list pointer and the item index to find and return the item pointer.
Note: the search uses the item index (not the item value).
Welcome to the Programming Without Coding Technology world! It looks like code, but it's a tree with useful colors and related data entry forms. Everything that you do in this world is isolated from your text based code. Here you are programming in a GUI world instead of just text based code editor enhanced by syntax coloring, code folding, intellisense.
Visual Studio, Code-Blocks, Qt Creator, Sublime, Notepad++, or any text editor may help you a lot but still the code is text based and you can easily make syntax errors, you don't have control on the language syntax, you can't change it without creating a new language or at least making problems to other programmers working in the same project.
Let us see the navigation power and start looking at what we are interested in.
For example, we can open the declared variables:
pItem
initial value is NULL
, the function returns pItem
in success or fail.
In the start, the function can quickly get the first or the last item, then update the cache.
The first item pointer is stored in pList
->pFirst
->pValue
while the last item pointer is stored in pList
->pLast
->pValue
.
pFirst
and pLast
are of type Items *
while pValue
is like pItem
from the type Item *
.
In the first case, when the index == 1
, we can set pList
->nNextItemAfterLastAccess = 2
directly instead of using the expression index + 1
.
The function returns the result directly instead of setting pItem
value and using one return statement in the end of the function.
The List
cache are updated inline without using a function that take the list pointer and and the item pointer to update the cache and increment the nNextItemAfterLastAccess
.
We can do many changes or improvements but for now concentrate on the navigation power.
We have a group of steps packaged together under one comment "Quickly Get The First or The Last Item".
Later this helps in understanding the sections of function or doing operations on a group of steps together like (Cut, Copy, Paste, Delete, etc.).
Now, we can see the function definition:
From the previous form, we can determine the function name and parameters.
We can type the returned value type or select it from a static list.
You will see a check box called "Prototype only". When it's selected, we will get the function prototype without the body to be used in the header files.
When we write things by hand, we have the intellisense/autocomplete feature the present variables, items in structures and nested structures, function names & more.
Now, we have seen a practical example about using the visual components to represent our programs instead of text based source code, you will notice that I have made some little changes to the language appearance but the generated code looks like any code written by hand.
You have full control on what will be generated.
Note: This function can be optimized and rewritten in a better style, for example the linear search doesn't need to start from the first element to the end because this case will not happen (finding the first item or the last item by the linear search) because in the previous steps we get first/last items directly.
The function get the item using the item index, when if find the item using if ( x == index ) , i don't use the break statement because the for loop already will not continue after we get the item.
The practical usage of the theis list and this function appears when you want to replace the usage of structures with static members with the usage of lists and nested lists with dynamic members.
Item * ring_list_getitem ( List *pList,int index )
{
int x ;
Items *pItems ;
Item *pItem ;
pItem = NULL ;
assert(pList != NULL);
if ( index > 0 && ( ring_list_getsize(pList) > 0 )
&& index <= ring_list_getsize(pList) ) {
if ( index == 1 ) {
pList->pLastItemLastAccess = pList->pFirst ;
pList->nNextItemAfterLastAccess = index + 1 ;
return pList->pFirst->pValue ;
}
else if ( index == ring_list_getsize(pList) ) {
pList->pLastItemLastAccess = pList->pLast ;
pList->nNextItemAfterLastAccess = index + 1 ;
return pList->pLast->pValue ;
}
else if ( ( index == pList->nNextItemAfterLastAccess )
&& ( pList->pLastItemLastAccess != NULL ) ) {
pList->pLastItemLastAccess = pList->pLastItemLastAccess->pNext ;
pList->nNextItemAfterLastAccess++ ;
return pList->pLastItemLastAccess->pValue ;
}
else if ( index == pList->nNextItemAfterLastAccess - 1 ) {
return pList->pLastItemLastAccess->pValue ;
}
else if ( ( index > pList->nNextItemAfterLastAccess )
&& ( pList->pLastItemLastAccess != NULL ) ) {
pItems = pList->pLastItemLastAccess ;
for ( x = pList->nNextItemAfterLastAccess - 1 ; x <= index ; x++ ) {
if ( x == index ) {
pList->nNextItemAfterLastAccess = index+1 ;
pList->pLastItemLastAccess = pItems ;
}
pItem = pItems->pValue ;
pItems = pItems->pNext ;
}
return pItem ;
}
else if ( ( ( pList->nNextItemAfterLastAccess - index ) < index )
&& ( pList->pLastItemLastAccess != NULL ) ) {
pItems = pList->pLastItemLastAccess ;
for ( x = pList->nNextItemAfterLastAccess - 1 ; x >= index ; x-- ) {
if ( x == index ) {
pList->nNextItemAfterLastAccess = index+1 ;
pList->pLastItemLastAccess = pItems ;
}
pItem = pItems->pValue ;
pItems = pItems->pPrev ;
}
return pItem ;
}
pItems = pList->pFirst ;
for ( x = 1 ; x <= index ; x++ ) {
if ( x == index ) {
pList->nNextItemAfterLastAccess = index + 1 ;
pList->pLastItemLastAccess = pItems ;
}
pItem = pItems->pValue
pItems = pItems->pNext ;
}
}
return pItem ;
}
Points of Interest
You can change any component (The generated steps and the generated source code), you can change components names, data-entry forms. PWCT is open to any change like that in very little time.
This link provides tutorials that explains everthing about that.
History
I started developing PWCT in Dec. 2005, the tool supports many languages like Harbour, Python and C.
Most of my applications are based on HarbourPWCT, in the last two years I started to spend most of my time using CPWCT.