What is Exodus
1 What is Exodus?
Exodus is a way to do traditional pick-basic programming in C++.
It was conceived and created by Steve Bush of NEOSYS Software as a way to move classic pick/multivalue basic into a classic industry standard environment with the minimum of upheaval.
Many people would like to migrate their classic pick/mv based applications into industry standard environments however they have so much code that relies on the nuances of pick/mv, or their programmers are so used to pick-basic, that it is virtually impossible to move.
Exodus is released under the modified BSD licence following the example of Postgres.
Not everything is working at the moment see Wishlist
2 Twin Issues
Exodus provides replacements for both language and storage but each part could be very valuable to add sql storage to an existing pick language or a language to an existing pick database.
2.1 Language Replacement
Use C++'s operator overloading feature to make C++ behave almost like, if not exactly look like, pick-basic programmers expect and be usable for classic pick-basic style application programming.
2.2 Database Replacement
Use standard SQL databases (currently Postgres) transparently as a pick style storage mechanism ensuring full SORT/SELECT functionality including dictionary items (columns) that invoke routines written in the pick-basic style CC++ environment.
3 Twin syntaxes
3.1 Classic Pick "Global function" style syntax
This is standard Exodus C++ syntax. Only the representation of print as function "print()" instead of a command "print x", - and the trailing ; gives it away as C++.
Pick programmers are used to this syntax and many will want to stay with this style for whatever reason.
It is a pity that C++ syntax doesnt allow the easy-to-write and easy-to-read pick-like array extract/replace like xxx<1,2,3> or x<3>="x". A great shame but not a killer.
3.2 Classic OO "Method Chaining" syntax
This is standard Exodus C++ code.
Variable xyz is one of Exodus' "Mv" objects ... with a method called "extract" ... which just produces another Mv object which is then processed by the oconv method and then printed.
What this actually does is: From variable xyz, extract field 1, multivalue 2, subvalue 3 then oconv it, then print it.
More C++ish style is also acceptable:
So a "pick variable" object (or class) Mv has all the various pick functions as methods. This means that you can use OO-like method chaining syntax. This is often the way people think in OO languages. In OO it is considered easier to understand code if you can simply read from left to right and it gives you the operations in the order that they are performed. As much as some people may not like OO method syntax, the many more people today are more comfortable with it than global function style.
4 Why not just Python or PHP?
Both of these are great languages to start new projects and many people using Pick language will have looked at the possibilities of porting to them.
However there are many subtle differences between the languages and, if you have thousands of lines of old code you dont have time to sort out all the subtle bugs without a complete rewrite with a programmer familiar with the intricacies of both languages.
Generally the objective is to convert often hundreds of thousands of lines of pick basic fairly accurately into another language. Changing syntax is laborious - but doesnt require highly skilled programmers. However any subtle changes in semantics (how operators and functions work exactly) means that ports are unreliable which is far more costly.
This means that the syntax can be changed when porting as long as not too bad then we will all get used to the new syntax. It also means that the sematics must remain almost identical otherwise people will be hunting down bugs forever. Anybody who has looked at replacing pick will have come to the same conclusion. porting needs meticulous rewriting into the new language mentality due to nuances in how the basic principles of how variables behave.
Python and PHP operators and variables just dont BEHAVE like pick operators and variables in too many cases.
4.1 Unpredictable overloading
Most modern dynamically typed languages suffer from the catastrophically inappropriate carry over of the concept of operator overload from statically typed languages. This means that you cannot trust what operators like + and * will actually do. Pick-basic, although dynamically typed, does not suffer from this. Pick's + will always do an arithmetic plus and fail if non-numeric strings are presented to it. Pick's * will always do an arithmetic multiply and fail if non-numeric strings are presented to it.
You just cannot trust dynamically typed languages that do operator overloading based on dynamic type. Accidents waiting to happen and frequently do.
4.2 Example PHP problems
This is a very tiny list of all the problems that exist. By problem we mean difference in way of processing, not that one way is wrong or right.
4.2.1 PHP * operator
If you give it a variable that happens to contain a string then, instead of converting it to a number to multiply numerically, it will repeat the string n times! This is fine for php people who are used to it ... but cause chaos when converting and maintaining pick code in php.
"100"*10 in php is "100100100100100100100100100100"
of course it isnt written as "100"*10 in code .. it is written as mynumber*10 ... BUT what happens depends on what data type happens to be in mynumber during execution
4.2.2 PHP . operator (concatenation)
It is very astute of PHP to have a special concat operator even if it does seem almost impossible to read to pickies used to a : for concat. Most other languages dont have proper concat operator at all. But then from the point of view of Pick-basic it has the wrong precedence.
php's concat operator (the dot) has the same precedence as + and - whereas in Pick, concat has a lower precendence than the arithmetic operators. This subtle difference introduces endless opportunity for hard to track down bugs if you try to simply translate large amounts of code from pick-basic to php.
5 Concat operator
The ability to concat variables in precisely the same way as pick is very important if you are going to move pick applications into any other language.
eg in pick if you concat two variables using the pick ":" operator that happen to be numbers you will still get a string out. ie concat in pick means concat. it DOESNT means add if the arguments happen to be numeric. the concat operator missing in c++ because it is strongly typed and it (and you) can tell from arguments whether it will add or concat
in exodus, "variables" are a c++ class that behaves like a pick variable very very closely so you can port pick basic without being nervous of subtle bugs due to differences in mentality of the original language designers.
6 Why Postgres?
Open source and technically very open and easy to extend with new datatypes etc.
Postgres is widely available and well supported on all major platform. There has been very strong interest in and development of Postgres since Oracle bought up the MySQL's underlying database .
Postgres licence in BSD so can be used in anyway you like whatsoever including using bits of the source code in your own code without GPL restrictions.
7 Why Boost?
Best of breed and is the prime place that C++ standards are worked out.
8 Why Visual Studio?
Only because the project is currently primarily developed in Windows. Previously it was primarily developed in Eclipse/Cygwin.
Visual Studio is prime development environment in Windows although there are perfectly good other ones eg Eclipse/Cygwin, Codeblocks (add more here).
there is a windows dependency in this project at the moment about pipes for ipc with postgres but I will be removing that and using the portable boost shared memory
there is also a C driver that you install in postgres ... this is assuming that you want database operations read/write/delete etc which is almost certain
the postgres C driver is in subverwsion under pgneosys
the project isnt setup very flexibly - ie hard coding lib folder locations whereas they should have a macro to ease modification if you have installed the various dependencies in non-standard locations.