Showing posts with label Z2. Show all posts
Showing posts with label Z2. Show all posts

Thursday, July 21, 2011

Z2 – 02 – How to start? (part 2)

In order to break the trend of huge Z2 posts I’ll dive right into it, going for the benchmark explanation and skipping most theory and other things I wanted to mention in part two.

For this test, I’ll consider 26 master sets of classes, each contained in its own file. Each master set is named after a capital letter in the English language: so we’ll have master set “A” in the file “A.zsr”, master set “B” in the file “B.zsr” and so on until “Z” in “Z.zsr”. A master set file will be using the next file that comes in alphabetic order, so “D” will be using “E”, except for “Z” who won’t be using any other file. Taking the master set’s name, we add three other characters, again from “a” to “z” (lower case) in order to get every possible permutation. So we’ll get the names: “Aaaa”, “Aaab”, … “Aaaz”, “Aaba”, …, “Aabz”, …, “Zaaa”, …, “Zzzz”. All names that start with the capital letter corresponding to a master set will be in the same file. Each name is the name of a class. Each class contains 26 constants, named form “A” to “Z”. The constants form a master set are initialized with the same constants from the similarly named class from the very next master set, plus one, so Aaaa.A = Baaa.A + 1, Fghj.O = Gghj.O + 1 and so on, except for the constant from the “Z” master set, which will be initialized with values from 0 to 25.

So we have 26 files, with 17,576 classes each (26 * 26 * 26). Every class has 26 constants, so every file has 456,976 constants. In order to initialize this number of constants, we need the next 456,976 constants from the next master set/file. So the total number of constants is 11,881,376. Now clearly, this test is completely ludicrous and no compiler on Earth is expected to be able to compile this, and if it is somehow capable of actually compiling it, it will take a lot of time and use an astronomic amount of resources.

Each file corresponding to a master set has a size of 10.3 MiBs, except for the last one, which is 6.6 MiBs. The main program file, one that prints a subset of these constants is 7.4 MiBs and tries to print only the Z subset. The total amount of disk space used by the test suite is 272.6 MiBs. Ludicrous amount of constants. Let me add some screenshot, first from “A.zsr”:



Then “Z.zsr”:



And finally “main.zsr”:


But when firing up the Z2 compiler, with a “main.zsr” that only uses the “Z” master set, we get very interesting results: the first time it takes roughly two seconds and on successive tries it goes down to 1.5 seconds (caching must set in). The execution time is very good, but we are not asking the compiler to do complicated stuff, only a lot of simple tasks. Memory wise, during compilation it eats up between 150 and 180 MiBs. When I set out to experiment with this project, I knew that I wanted to achieve the paradoxical goal of getting better compilation times with Z2 than with C++, and while I am not there yet, at this early stage at least the Z2 compiler is not hindering me. And Z2 compiles the constants without any requirement on their order and while checking for circular dependencies.

But the interesting part is related to the resulting C++ file. And here is where I encounter my first huge roadblock: the resulting C++ file is 23.1 MiBs. Notepad needs a good deal of seconds to open it and my C++ IDE has some troubles with editing the file with syntax highlighting. And when I tried to compile it the compiler gave me this message:

fatal error C1128: number of sections exceeded object file format limit : compile with /bigobj
test2: 1 file(s) built in (7:31.77), 451779 msecs / file, duration = 454057 msecs, parallelization 0%

After working for over 7 minutes, it gave up and said that it goes over some internal limit it has related to object file size. This was in debug mode. Let me try in optimal mode:

fatal error C1128: number of sections exceeded object file format limit : compile with /bigobj
test2: 1 file(s) built in (5:22.68), 322688 msecs / file, duration = 322782 msecs, parallelization 0%

Now it takes less time, probably because it does not have to generate debug information, but still fails. I am going to have to think seriously about this problem. Is it worth it to fix? Can it be done? Does using the option “/bigobj” help? I can try and insert the constants inline into the statements where they are needed so the backend compiler does not need to parse the constant definitions. But the resulting C++ code will be less readable. Using header files goes against the principles of this project. I can also try and break up the resulting C++ file into a lot of small ones. I would probably need to use a combination of methods.

Anyway, I can’t continue the official testing phase until I can get the resulting C++ code to compile.

But I can test Z2 a little bit more. I’ll change “main.zsr” to use “Y.zsr” and print the constants from that file. And the results are quite predictable: double the number of constants, double the time and memory use on the worst case scenario. After caching sets in, time goes down to even 2.3 seconds. Memory consumption does not go down. It is important to note that the “Y” set uses more RAM then the “Z” set, because “Y” constants are “Z” constants plus 1, while “Z” constants are just plain integers.

Repeating the experiment with using the “X” set is not possible on this computer. Either I do not have enough RAM or there is a problem with the memory allocator. Anyway, the compiler handled 913,952 constants and chocked before reaching the next milestone, 1,370,928 constants. Not that bad for some fresh code without any actual optimizations or a lot of development time sunk into it.

And such a short Z2 post! After more tests I’ll put up the test suite and the compiler somewhere on the Intewebz. See you next time!

Wednesday, July 13, 2011

Z2 – 01 – How to start? (part 1)

Very good question? How to start the series, especially since I want to avoid major rants like the introduction was. My first idea was to really dive into the belly of the beast, and tackle one of the major failings of C when viewed from a modern perspective. Strings are a perfect candidate, strings in C being one of the most horrible missfeatures of it. Strings are bad for a lot of reasons that I will get into at a later date, but one of the reasons is that they inherit everything that is bad about C arrays. So tackling arrays first would make more sense. But array are bad due to their design plus the bad API used to handle common task for them. So I would get a huge post again that tries to tackle too much at once. Plus doing all the coding would take too much time.

Diving into advanced topics without presenting syntax may seem strange, but it is a widely used approach. A lot of programming books have a first chapter that walks you through a large set of features as an introduction. But since I’ll skip arrays and memset for now, maybe I could do a post about syntax. But I found this boring to write and read, since in my introduction I made a huge case out of how syntax is very important, but getting hung up on small details is just silly and this potential post would be about the small details.

So I’ll talk about definitions and dependencies, touching just a little bit on syntax and going into circular dependencies. The way a language handles modules is a vital point, which C handles the same way it handles most of its “features”: it has zero support for it and misuses another feature to give a workable but often problematic solution. C has no module support (and passes on this lack to C++) and uses the precompiler to stitch together a forward declaration system and the linker to handle the final processing and merging of your object files. You compile every single source file separately and then the linker puts them together, often causing link errors when something is not found or repeated. This would never happen with a module system. A lot of programmers are not aware how rudimentary this system is, how little C does when compared to any modern (and a few old) alternative, because by having a good and consistent convention you can mask a lot of the problems. But still: how many times have you had problems including headers, especially from third party components? If your answer is “never”, then either you are part of a very lucky minority or never had to work with huge code bases.

So having a good module support is essential for a language and thus for Z2. Another facet of a module system is how you handle modified sources, updated incremental builds and search for other modules. For C and Linux, one usually uses “make” or a more advance IDE. Make is a simple but generally good tool for automating some tasks. But it is particularly poorly suited for the needs of C, so a more powerful tool is needed. This is where “autotools” and friends come in. A.K.A. the Antichrists! Yes, plural! I will not talk about autotools in fear of my head exploding due to sheer cranial pressure induced by massive rage. Maybe I’ll write a post in which I systematically analyze and give arguments why autotools and friends and any other tool that uses the same principles are not the right tools for the job.

But the conclusion is that the Z2 compiler will handle these tasks for you. Sure, you will still need to tell it where to search your file system for the modules, and you will be able to use shell scripts or autotools or whatever to do that, but the actual building is handled by Z2. You will be able to only tell it the location of your main source file and the compiler will handle everything, locating every module automatically that is in the “object search path” and only compiling what is needed based on timestamps. As an added bonus, it will only pull in definitions once per module and compiler sessions. Look at any compiler time break down and you will see that the preprocessor ends up taking a disproportionately large chunk out of the total compilation time. Headers get pulled in and preprocessed in every compilation unit. Add to that C++ template instantiation and you will see why compiling C++ is so slow. There is this myth that C++ compilers are extremely fast. And this is true, but they have to do so much more than compilers for other better designed languages that the end result is a lot worse.

So C has zero module support, it uses external clunky tools that have (and need to have) a huge pile of flaming ancient wisdom in order to be portable and it uses the preprocessor to handle definitions while not having any built in mechanism to do this or even prevent multiple definitions. And we did not even get to the capabilities of the compiler itself. Which are lacking again. There are multiple ways to handle the act of locating definitions of items in different locations of the code, and C does the most basic of them: take them in order. And when this is not possible, uses forward/extern declarations and header files. Based on moving around blocks of text. The compiler can only refer to entities that it has encountered before in the linear process of compiling a single file.

Finally, here we are at the topic of this post! After two pages of ranting! Z2 being a research compiler, I will be doing the very opposite of what C does: full circular reference resolution. There are other methods that use some slight compromises, getting better performance, but this is not essential for our needs. The compiler will be able to reference any object that is included in the module or other modules that are used by the current one, without the programmer having to think about how to assure visibility by manually placing items at key locations. This feature can be abused by programmers, making things unreadable, but I am going to assume that you are working with people with good intentions that will structure programs in a readable fashion. And since this post is already too long, I am only going to talk about the resolution of constants, leaving variable for another time. Even as such, the topic of constants is going to be a two part post.

Let’s get to the first snippet of code. Since doing text formatting on Blogger is not that easy, I’ll use pictures to allow for better syntax highlighting and indentation:


Do not worry about the syntax. Z2 supports multiple levels of detail when expressing what you want the compiler to do, and I will generally be using the most spartan one available. Still, it should be quite readable to anyone. On the first line we are pulling in a module. This is actually a normal C header, not a Z2 module, which is why it ends with “.h”. This is temporary and used only until we can get a minimal standard I/O module rolling. Then we declare a class called “Foo”, which has a single constant called “Bar”. I am intentionally using ambiguous naming conventions. More on this later. And finally, and empty main method. You will notice that there are no semicolons at the end of statements. This should be familiar to people who use modern scripting languages. A lot of people use them for rapid prototyping, automation and other small tools. I tend to use C++ for these tasks with the aid of powerful libraries but I do sometimes use Python or Ruby. Whatever the case, there is one thing I do not miss: semicolons. When designing something, generally speaking, it is good to cater for the most frequent use scenario. The overwhelming majority of statements in most programming languages are one liners. Sometimes you need to extend to more lines, but there are a lot of good alternatives to semicolons that do not cause ambiguity and even more that cause. There is a huge class of languages out there that get by perfectly without semicolons as statement terminators and including them in Z2 feels like an anachronism.

Now let’s see what the equivalent generated C++ code looks like:


Hmmm, a lot shorter. I put great value on compilation speed and I try to avoid making both compilers do the same job. Z2 has already handled the entire source code and determined that it should eliminate both the constant and the class. There is no need for the backend, in this case C++ (and all other cases for the foreseeable future) to parse the class only to decide that it is not needed. Now, let us actually use the constant. I will also use this opportunity to show you a more verbose syntax that is semantically identical to the first one, but more explicit, giving information that the compiler can figure out on its own:


The constant “Bar” now has an explicit type. In the first sample I left the compiler figure out the type of the expression, but this time I have chosen to give it explicitly. I also gave the return type for the “main” method. One thing you will notice both from the naming conventions and the syntax highlighting is that types, including “built in” types like integers start with a capital letter. Z2 is class, value, reference, copy and move centric (I’ll explain all these keywords in the future), thus everything is an object. Like in most dynamic languages. But the difference is that the objects actually map to true hardware types when possible so there is no performance penalty involved. Even though normal integers are called “Int” and the declaration of this class is available in text form to the compiler in the same manner as “custom” classes are, and Int has a bunch of constants and methods, after compilation Int is mapped to a 32 bit signed integer and is no different from “int” in C. “printf” is also not the normal printf, but it is enhanced so it understands the types of the parameters it is getting and you will be able to get the same behavior for any function without any hardcoding or the compiler understanding or treating I/O or varargs specially.

And C++:


This time the definition of “Foo” has been pulled in. We have a forward class declaration section after the include directive. I could avoid this, adding classes that are only needed but right now it does not seem worth the effort.

Now let’s do dome circular constant initialization:



Yikes! What is that? A = A (= is assignment)? This makes sense for variables, but not for constants. This is obviously a compilation error and should be signaled as such. I could signal it as an “undefined identifier error”, but instead you get this:


The two numbers after “error” give us the line and column of the error: 4 and 11. At these coordinates we have exactly the beginning of the constant “A”. Then the compiler informs us again that something is wrong with “Foo.A”: a circular constant initialization. It also informs us that I make spelling errors. I noticed too late that I spelled the error message wrong and I ma not redoing the screenshot. Then we get the breakup of the cycle: the constant “Foo.A” form the file “0103.zsr” at coordinates 4, 11. So the value of A from the first coordinates is dependent on the value of A from the same coordinates. This makes a lot more sense if we consider a more complex example:


The first constant, “A” is initialized properly. But when initializing the rest of the constant chain, the programmer made a mistake: instead of initializing E with “F % 4”, it was initialized with “C % 4”, thus creating a circular reference. And this is what the compiler tells us, but in its own words:



I couldn’t go on without correcting Foo:


 And let’s check out the resulting C++ code:


You will notice that the constants have been evaluated and we only get the final result in the C++ file. As said, I do not want both the Z2 compiler and the backend compiler to do the same computations. But the main reason for this is that there is no way C/C++ can handle such constant initializations because they expect a linear progression of value dependencies and Z2 does not have such a progressions. There are multiple cases where one cannot reorder the constants when dealing with multiple classes. One would need to break up the classes and/or insert dummy constants to make C happy. Using evaluated values hits two birds with the same rock. And the results are equivalent in both cases.

I hope that the advantages of this constant system are clearly visible. The word “class” may make you think about OOP, but here we are actually creating a named constant repository. An absolute repository that grants its values to everyone to use, including other constants. And it has no troubles initializing values based on values that were not encountered before as long as they are initialized somewhere else. This is similar to the way human minds work. Let’s say you are using C and the constant M_PI a lot. After using it for an extended time, you notice that you use the expression “2 * M_PI” a lot, so you decide to create a new constant “M_2PI”. If someone asks you what the value is, you answer “two times M_PI”, without actually stopping to think what value Pi has. And if you use M_2PI exclusively for extended periods of time, you (or a programmer new to the project) may actually write “M_2PI / 2” when Pi is needed, associating the desired value with one you are overly familiar with. The human mind is not as ordered as a compiler that can only see statements encountered until it has reached the current line. Here is the problem in other words: I care about giving constants a symbolic name. Only the name is important. The value can change. I am in charge of naming and giving straight forward values to them. The compiler is in charge of figuring out the values when computations are needed. Classes as abstract constant pools do not care about order since you cannot reinitialize a constant.

The only problem here is that I have intentionally left the scoping rules ambiguous and I did not impose a coding convention and thus it is easy to image a scenario that might cause problems, like when “B” is both a constant in the current class and the name of a different class. I will give clear scoping rules in due time. Right now I want to focus on the little things first.

I would also like to point out that Z2 outputs proper C++ code only for convenience reasons. It would be trivial to make it output other types of code, but some languages are more problematic. Without classes or namespaces, Foo::A would look something like Z2_C__Foo__A or some other mangled name in C. But with time I’ll add this option too. As stated in the first post, a LLVM backend would make the most sense and translating to C++ is just the fastest solution right now, not the ideal one.

This concludes the first part of this topic. In the second one we’ll have more fun, this time initializing constants across classes, checking out again circular references and doing an extensive benchmark. For the benchmark I am thinking about using several MiBs of constant definitions in multiple classes/files and seeing how fast we can compile, the size of the resulting translated file and memory consumption. In the next post I’ll try to be more structured and slowly migrate away from the “huge block of ranting” model, but the plan is for Z2 posts to be around 5 pages a piece, so do not expect short posts like for DwarvesH.

Wednesday, June 29, 2011

Z2: An introduction

This is going to be a fairly long off topic post about programming languages research and the introduction post for my new series. I understand that people come to this blog to read about DwarvesH, so I will be taking two measures to keep this new series from hogging the spotlight. First, I’ll prefix all posts from the series with “Z2” so people that are not interested can easily skip these posts. This series will be of very little interest to non programmers. Second, development for this research project will have several constrains, the most important one will be related to the length of the programming sessions. When I fell like it, I will enter a heightened mental mode and do a 60/120 minutes long frenzied programming session. On the clock. When the time runs out I’ll stop and I will only do this at most once a week. So plenty of time left for DwarvesH! Damn it, I really need a new name for the game ASAP!

But why programming languages research? The design of programming languages has been my passion for ages, long before I picked up the mantle of the dwarf. I had a previous attempt of fixing programming languages, more precisely C/C++ that I have abandoned for good reasons a few years ago. That attempt was called Z, and I am reviving it as a research project and as a discussion and meditation on the art of programming language design.

Why now? Well it all started a few months ago, when I read that some company has revealed its “Java killer” after two years of development. I don’t remember the name of the company or language and I am not going to Google it since it is better if I don’t name them. Most of the ideas were good. God knows Java is far from perfect. Some ideas were really bad and in my opinion very narrow minded. “Let’s do some drastic change that will probably not affect our work flow but would force this upon other people who might be profoundly affected by this” sums this up very well. But the conclusion is that their language is a nice, but niche step forward. But not after two years of development. And there is no way you can label this attempt as a “Java killer” after two years of development. Under a different label and shorter development time I would welcome their language. But under these conditions, all I can say is: way to completely miss the point guys! Have you ever used Java? Do you understand the principles behind the problematic areas and why they should be fixed? Because it seems like you do not.

That is all I am going to say about that. I did not mean to insult their effort and apologize for any parts of the above that may seem insulting. I just disagree. Probably I could have been more polite in expressing this. And I would find it extremely amusing, yet sad at the same time, if during my efforts I would prove that I do not understand either what is wrong with my language of choice and lack any kind of greater insight. Anyway, after reading their presentations, I started thinking about this series. I did not start it before because I was afraid of taking time away from DwarvesH. But by keeping the discussion largely theoretical and strict development times this won’t happen.

But let us go back in time even more. DOODLY DOODLY DOODLY DOOP! My first programming language was Visual Basic. I started learning Visual Basic (VB from now on) one or two years before my formal training in CS started in high school. BASIC has a very poor reputation and it has been claimed that it “ruined generations”. I can’t say anything about that because I was not there during that period, but I can assure you: VB has nothing to do with that unstructured programming mess that the first versions of BASIC were. VB was a decent language and VB 4 was a great RAD environment, but in retrospect I do find it very verbose and the standard non GUI library lacking. This was way before VB .Net. Back in the day VB and Delphi were IMHO the only true RADs out there, with Microsoft Visual C++ claiming to be that but failing. Sure, it may have been RAD when compared to Windows API, but VB and Delphi were in a league of their own. And MFC has the honor of being the worst API I have ever worked with.

Then my formal training started with Turbo Pascal (TP from now on). A good didactic language, with Borland Pascal actually being a good choice for development with its advanced tools and build modes that were lacking from TP. While they were teaching us the basics of programming, I was experimenting with DOS graphical drivers, VESA modes and GUI. Especially Mode X. There was this great compilation of Pascal sources called SWAG. It contained very advanced stuff that I had troubles understanding at first but it was very fun. I was forced to start learning assembly to truly benefit from all the interesting parts from SWAG. Became obsessed with writing the fastest “putPixel” procedure out there. Everybody should read “The Art of Assembly Language” by Randall Hyde. Even if you are not interested in assembly, there are a few very important and very well handled chapters on data representation. Maybe even give HLA a try, but people experienced with assembly will hate the inverted operand order. I know that it is actually not inverted and what is considered normal can be seen inverted (see binary code representation on x86), but still. OK, side not finished. Now where was I? Ah yes! I even experimented a little with C before they started teaching it at school.

I kept playing around with Pascal and adopted a GUI convention from a Pascal library which I think was called R3. The names are starting to get fuzzy. This library colored all my future GUI API design and was quite compatible in principles with Delphi GUI. I ported R3 to C++ and was doing a lot of STD/STL C++ and a lot more Delphi. Lol, he said STD.

Delphi became my primary development language, especially since it had those very powerful “enterprise” components and also several third party online component repositories. The language is not extremely expressive, but unlike C/C++, it had very few bad design decisions and very little to object about. A lot of nitpicking for sure. And please, do not even try and link me “Why Pascal is Not My Favorite Programming Language” by Brian W. Kernighan. That text is from 1981 and is so outdated that basically every single point he made can be rebutted by Delphi, which is actually not Pascal, but a dialect of Object Pascal, Object Pascal being an OOP dialect of Pascal. So a dialect of a dialect. It may have been true when it was written, but after so many years, that paper is more outdated and irrelevant to the state of Delphi than a paper entitled “Why America will never have a black president” written by the fourth future black president of America. Sure, Delphi is not perfect and it has been having a hard time in past few years, switching owners and all, but still I never understood why it did not become very popular.

On the other hand, I stopped using Delphi! I have gotten bitten by a very nasty bug that caused a very serious sickness: Linux! Delphi was not cross platform! Kylix was a mess with its Wine dependency, difficulty to install and the fact that it was abandoned by Borland, making increasingly harder to install and run as the Linux platform was moving ahead at a brisk pace. C++ was portable, but lacked a viable GUI library and the STL was as pleasant to use as a bear for dental flossing purposes. I could write a book on the “failure” of STL and I will probably write a post sometime. But it is not awful and not really a failure. Just very unpleasant. Please use it and do not roll your own general use container library. I’ll go mental if I see another custom list implementation that is inferior to STL. Every open source library seems to roll its own. And ranges fix most of the problems with iterators (except one that I do care about), so check out Andrei Alexandrescu’s papers on ranges. I did not follow the recent development of ranges, so please please please do not let it be a dead idea. With the underwhelming new C++0x standard, all that is missing is that ranges get abandoned for some nonobjective reason.

So without a main programming language, I was penduling between C++, Delphi, Java and other on a case by case basis.

So in my free time I started to work on Z, symbolically named as the language that would end all other languages. Naïve, I know, but still a great programming and design exercise. But not long before it would reach a critical feature set to take off, I discovered something on the Internet: the D language. I was awestruck and spent that day and late into the night to around 5 o’clock reading the design documents and the forums. Most of the time was spent nodding my head in approval, as around 80% of D’s design was identical to Z. Sometimes even the syntax and semantics were 100% the same. Now Walter Bright is a person who truly understand the problems with C++, an understanding derived (I wager) from experiencing its faults first hand and reacting to them, the same way I reacted. This is why our designs were so similar. But D was light years ahead of Z and had a lot more ideas. It did use garbage collection, a feature Z did not have and one that I was not particularly fond off, but still totally worth it. I have this old saying: “The world does not need yet another programming language”. So a few days after the discovery I killed Z and started using D. I did not regret my time spent on Z or its untimely death. This was way before D 1.0. Meanwhile I stopped using D. The long awaited version 1.0 seemed lackluster, version 2.0 took the language on the path of concurrency, a path I am not that interested about personally (and I use concurrency basically every day professionally) and most importantly, getting D to use other C and especially C++ libraries was extremely difficult. The main reason for this is that the object files were not compatible, so you needed to recompile those libraries with Digital Mars C++, probably a good compiler, but one that constantly chocked on sources that GCC and MSC had no problems with. And Digital Mars C++ was not actively developed.

So I was out of a main language again, even before I have gotten to use D enough to call it “main”. So I did the only reasonable thing that would allow me to find a cross platform language with great expressive power, great compatibility with other libraries and a fully featured GUI library: I tried them all. The big ones anyway. I think I went through 20-30 GUI libraries/language combos, researching their pros and cons. Another requirement was the language/library combo needed to have support and a fair user base, so I unfortunately had to discard a few very promising candidates that were apparently used only by a handful of people. I am not going to list all candidates and my conclusions now, maybe someday. In the end I settled for C# and .Net for when a virtual machine is desired and Ruby just to play around and do some light webdev for my secondary languages. C++ with Qt was the strongest candidate (even with the unfortunate use of MOC) for GUI work, but in the end I settled on U++. It is more modular and easier to tweak, while still having immense power. So in the end I still stuck by C++. But C++ in conjunction with U++ is a very clean C++, one that could be considered almost as clean syntax wise as a Java with operator overloading (and slight operator overloading abuse).

When I am saying main programming language (and library), I mean it as the language that I use for all my personal projects and the one I find that has the best principles put into practice. It is all about design, expressive power and most importantly elegance. If the language is not elegant or is not capable of providing an elegant subset it is wasted potential. This is why C++ can cover these requirements. It may be a horrible and ugly language in general, but one can use a subset from it, have a strong and consistent programming style and if you squint your eyes a little, it may even seem the perfect programming language (alcohol helps during the squinting process to facilitate the creation of this illusion).

How egotistical of me, filling three pages about what an experienced and great programmer I am. And I assure I censored myself and only included the most important key events. This is not an autobiography after all. I just felt like giving some background. Sharing is caring. Or scaring.

 

“The world does not need yet another programming language” 

So why am I doing a programming language? Is this not hypocritical? Well, no! I am not doing a programming language as much as researching and having theoretical discussions not as much about the failings of some specific construct in some languages, but more about the process of finding such failings, determining why they are failings and solving them while keeping the solution general. Any coding and actual language implementation is a simple exercise in grounding the theory a little in reality. And while the principles of this theoretical language, Z reborn, called Z2 (I know, I am not very good at picking names) may not always express this, the central idea is that C is a horrible language not fit off any practical purpose and its seed has corrupted C++. There are two good reasons to use C: you need very high performance low impact real time code very close to the machine or you are maintaining a C code base.

So the first principle I have already named above.

The second is also the second constrain on development. The code base will have limits put upon its maximum size. For starters it is going to be maximum 3000 lines of code. I will not allow it to go over only when some huge new feature comes. Then I’ll increase it to 5000. Some future increases after these are possible, but not too many. The source will always be short, very lightweight, easy to understand, didactic and very hackable. The Squirrel scripting language was at one point a fully featured language with only about 9000 lines of code. I don’t know how many lines a more recent version has, but I doubt it has blown up exponentially. Needless to say, any standard library code for the language will not be counted for this purpose.

All code will also be open sourced eventually. Every few months when I have time I’ll drop the code somewhere. And maybe I can do some binary releases more regularly, but DwarvesH has the top priority.

The language will be influenced by scripting languages. These languages have made a deep impact in the programming languages ecosystem and ignoring their influence would be silly. So even thought at its heart Z2 will be a very C++ styled language, its syntax will be more Ruby/Python/others inspired. But this does not matter. A lot of near religious buzz is generated by programmers around some conventions that are not important. One of the goals of Z2 will be to point a specific finger from its hand in the general direction of this nonsense. So no “indentation wars” or other minor yet blown up controversies will be given any attention. Indentation wars are particularly silly and a pet peeve of mine. Are we programmers or mice? No self respecting and professional programmers should ever have troubles following any kind of indentation from his favorite style to a style where everything is on the same line and never should he or she become profoundly disturbed by such styles or any kind of conventions. Especially not at the levels some people stick to their styles, turning them into crusades against everybody else. I can read any kind of indentation. I am not equally comfortable with all styles, but after a day or two I get over it and reach full performance. And I think no programmer with enough experience in the field has any excuse not to be fluent with all styles, or at least not become angry about them. My personal pet peeve it prefixing member variable with “m_”. I hate this convention and I think that proponents of it are completely missing the point of OOP. They are in one universe and the point is in a parallel universe, with the only thing making these two universes parallel is the fact they exist at the same time, not that they have even the slightest thing in common. Yet I do not get angry when seeing this convention. I avoid it though like the plague J.

So when there are two takes on the same idea, and one cannot objectively be declared a winner, Z2 will intentionally do both or neither, depending on case, in order to make o a point.

I will talk about one last topic and end this extremely long post right here, even though I did not systematically list all the principles of Z2. The compiler will take Z2 code and output C/C++ code. This will make it very portable and keep the source code small. This solution is not optimal, but perfect for a toy language. And yes, Z2 is a toy language. I will not be using it for real development and will not port DwarvesH to Z2. It is just the practical result of the theoretic talks related to programming languages and my two cents related to fixing C. An ideal solution would be to use LLVM. I have very high hopes for LLVM and I hope that one day it will be the messiah that will unite all languages the way JVM or CLI could never do. Muad'dib! Muad'dib! Muad'dib! But we are not there yet.