This is a quick follow up post to further tease some of the exciting developments in the world of RemObjects Elements. Yesterday I posted about implementing a Windows version of my trivially simple RandomNumber application. Today, I present another Windows version.
But this one doesn’t use .NET.
First of all, the end result:
True, it’s not as pretty as the OS X, Android or .NET versions of the application because as of right now the CPU-native codegen for x86/x64 only supports console applications (the same holds true on the Linux side of things. Currently).
So let’s take a look at the code involved:
namespace RandomNumber.Win32; uses RandomNumber; type Program = class public class method Main(args: array of String): Int32; begin writeLn('The magic happens here.'); writeLn((new RandomNumber).next(100).ToString); end; end; end.
Unified Class Declaration
The first thing to notice is that this looks a little strange for a Pascal implementation.
The template for an Island Windows Console Application produces a source file using the new Inline Implementation Syntax (a.k.a Unified Class Declaration) support in the latest Oxygene compiler (beta).
That is: There are no separate interface and implementation sections. The implementation of methods can be provided inline as part of a class declaration itself.
Scratch one more reason for the curly bracket brigade to dismiss Pascal. π
For larger, more complex classes I personally think that the separation of declaration and implementation makes for more maintainable code, and you still have the option of using that syntax in those cases (or as you see fit). But for small, lightweight classes such as this entry point class or extension methods etc, this inline syntax has a lot going for it in eliminating/reducing duplication of method declarations.
This syntax flexibility is available across all Oxygene platforms, obviously, and is not limited to only Island projects.
Cross Platform Concerns
The next thing to notice is that this implementation again makes use of my RandomNumber class. I have extended the implementation of that class to cater for the native codegen platform. With no .NET Framework available to a CPU-native application this means having to take a similar approach as adopted with the COCOA implementation for RandomNumber. I could have implemented my own PRNG from first principles (and the lack of Posix style PRNG state buffers in Windows means that if I were intent on a comprehensive, cross-platform PRNG implementation then I might have to consider that). But for the purposes of a quick proof of concept, I instead tried to use the C RTL functions provided by Elements’ own rtl namespace.
I say “tried” because I ran into a bit of a problem here however in that trying to use the rand and srand functions of the rtl resulted in a linker failure. The timeGetTime function presented no such problem however.
It’s perhaps to be expected that there will be some teething troubles like this in what is after all the very first beta drop of this technology.
Something else to mention here is that importing functions from DLL’s is supported in Island projects, so I could have imported these functions from the Windows C RTL DLL myself. But for now, a Not-at-all-PRNG was good enough for this exercise. I could have simply rolled a dice; any solution here would be a temporary kludge but I settled on returning the current timer value mod‘ed to the specified limiting range:
method RandomNumber.Next(limit: Integer): Integer; begin // Temporary bodge: result := (rtl.timeGetTime mod limit) + 1; end;
Other aspects of the RTL are clearly working perfectly, such as the availability of a ToString() method on the Integer type return value of my next() method.
The final thing to note w.r.t cross platform questions and this code is that there is nothing in this program source file that is platform dependent. You could place this program.pas file in a shared code project and then re-use this program source directly in Java, .NET and OS X console applications, as well as this Win32 application.
Garbage Collection
You might be thinking that without .NET to hold my hand I appear to have recklessly leaked a RandomNumber instance. But if we take a look at the default references setup for my project in the solution we can see a clue as to why this is not a problem:
Yes. Island projects are CPU-native codegen but they also benefit from having a Garbage Collector. For those interested in such details, I understand it is an implementation of Boehm GC
Linux
I mentioned yesterday that Island also supports Linux CPU-native codegen. I personally don’t play in the Linux space and do not have a Linux VM to hand with which to repeat the exercise for Linux, but I have no difficulty believing that it would be just as straightforward.
Beta Access and Availability
If you are interested in these developments, you might be wondering how you can get involved in these beta’s ?
It’s easy.
RemObjects makes beta versions available to all current subscribers to their compilers, so if you are interested in exploring the capabilities of these new platforms (and of course the existing .NET, Java/Android, iOS and OS X platform support) you only need to be a customer.
Thank you, Jolyon, for this quick first look into the new native capabilities of RemObjects Elements. I’m especially impressed by the fact that the resulting code is linked to a C runtime. I wonder if the Island platform at some point will allow it to program from Oxygene against C/C++ source code and C++ DLLs in a similiar way how this is already possible today with existing JAVA or C# modules. What an awesome thing it would be to be able to access large and/or well tested code bases like OGRE or OpenCascade from within your code and to use their classes as if they were defined in Pascal.
Calling code in C/C++ DLL’s certainly should be possible since the DllImport() attribute is supported for precisely that purpose and is already well proven for linking to DLL’s from .NET code, for example.
>That is: There are no separate interface and implementation sections. The
>implementation of methods can be provided inline as part of a class
>declaration itself.
Oh thank goodness; this may be one of the greatest, longest-overdue readability improvements in the history of Pascal! π
Otherwise, things tend to go like this:
“Ooh, method ‘XGA_Format’! I wonder what that does.”
method XDB_Format… method XER Format… method XFG Format….
“Wait, what was I looking for again? XG… something?”
“XGA… XGA… XGA…”
“XGA… XGA… XGA…”
“Ah! There it is!”
(Real story of browsing long Delphi code on the web)
You shouldn’t need to hunt all over a file to find a method’s source code. Browsing a method interface may not give you a clue as to what it actually does. It also violates “don’t repeat yourself”, you run the risk of the two being out of sync, it’s only convention that mandates methods be defined in the order they originally appear, etc.
One definition/implementation, used with adequate code folding, makes for the best readability and clarity and less chance of mistakes.
Hard to say for sure without the actual code in front of me, but this doesn’t sound like a problem that could/should be solved by the use of inline implementation. Even with inline implementation you would still have to wade through all those XDB XER XFG etc methods, except now you also have to contend with all the code intermixed with the declarations (parsing the method blocks themselves to even find the individual methods), unless you fold them all which even then leaves you no better off than the implementation-uncluttered interface declaration. No ? π
Rather the problem here sounds more like just a poorly designed/formatted/written class in the first place.
I’m guessing that XDB_Format XER_Format and XFG_Format had partner methods for doing other operations related to XDB, XER and XFG things (as well as the XGA things you were interested in). Which sounds like what was missing were XDB XER XFG and XGA classes.
But in any event, how I would have gone about it in that situation….
In the IDE (or a text editor with equiv. capabilities):
Even if browsing code on a web page (git hub source view etc):
Should find what you are looking for very quickly I would have thought. Certainly more quickly than eyeballing it.
Also worth bearing in mind is that for those situations where you don’t have the assistance of things like code folding to reduce the entirety of a class implementation down to a more digestible “summary” then having a class formatted with a “table of contents” (interface declaration) separate to it’s implementation in the raw source file can be a huge benefit.
e.g. in a commit diff you can more easily see what (for example) a method was added/removed/had it’s signature/directives changed etc without the additional noise of the changes to (or addition/removal of) the implementation of that method. Sometimes you are looking only for these high level changes in a class (e.g if trying to determine when a method was added/removed). Sometimes you are interested in changes to a specific method (or methods).
As well as DRY there is another principle: Separation of Concerns, and that I think that can apply just as much to the structure of a source file as it does to the behaviour of the code in that source file. π
If you can link to C++ code, there’s your answer right there for GUI. If Oxygene can have bindings for Qt, you’ve got a single framework capable of targeting Windows, OS X, Linux and mobile with CPU-native code!
Yep, Qt is just one numerous options in this area including, potentially, a port of VCL/LCL but taking advantage of all the great features of the Oxygene language and RTL. That would be a significant undertaking but would smooth the way for porting legacy Delphi applications more easily, for example. π
I think in spite of all these developer friendly features of Island it would require significant rewrite of existing Delphi code to port it.
The only (Delphi) code that may be portable is the business logic that does not have any interaction directly with the GUI or users or hardware in any. The rest will have to be recoded completely.
I feel the approach adopted by TMS to build a common framework that works Xplatform is a better then adopting, learning and then using a new tool altogether.
But anyways it is very good way to promote a new upcoming product indirectly!
But this doesn’t avoid having to learns something new – you then have to learn the TMS component library. Which in terms of adoption represents a subset of the development community supported on a development tool which itself is a small player and increasingly so.
On the other hand, developing in Elements, yes you are then required to learn the frameworks of the platforms you are developing for, but those platforms aren’t going away. Everything you learn about building Android apps, iOS apps etc all still applies, even if you then switch – either by choice or not – to another programming language.
But if you still want to learn a new, cross-paltform framework, why wouldn’t you choose C# and Xamarin ? It has the backing and commitment of a much bigger company than FireMonkey let alone TMS, is infinitely cheaper and many times more reliable.
Just saying. π
I think you are right about TMS being very tiny compared others but in case of TMS at least I am with Delphi which I already know, and what little I have to learn is the TMS framework and FMX. The rest I will not have to learn for each platform as these two frameworks will do the required grunt work for me.
Personally I don’t shy away from learning new things.
I feel Island is very late entry in the scenario. I have been developing x-platform applications using RB now Xojo since 2012. Most Delphi developers will scream that it is not a true compiler and that stuff but believe me in spite of it many limitations what it has achieved is way a head of what Delphi and for that matter Island are still striving to achieve and that also in an elegant way.
Just recently I developed a complete patient management solution for Windows and OS X in just 10 working days. And while developing it I did not have to even think or change my coding to accommodate for different platforms, while I was developing it on Windows 7.
As for choosing C# and Xamarin is concern, I already use Xojo which is more powerful, mature and easy to learn and program in! and I have to select any other that is more powerful than Xojo then I would either go for LiveApps or Live Code.
Probably you may not know much about LiveApps as it is just born recently but its main programming language is Pascal and it is x-platform.
As for Live Code most developers know about it after it went open source.
My broader point was that when you “learn” the Elements way of building applications, you are also learning the platform-native way of building applications for those platforms. You may find it easier to learn TMS and FMX, but if TMS decide that FMX is not actually worth supporting in the future, then your code – and your knowledge – will not transfer to any alternative.
Anything that relies on a platform on top of the platform is at risk from the same problem. YOu could invest a lot of time and effort learning their meta-platform only to find yourself starting from scratch.
The smaller players are especially at risk. They may simply fail to keep going or, if they do gain traction there is always the chance that the big fish will acquire them for the purposes of snuffing them out. As happened with RoboVM for (just one) example.
Having said that, Xojo does look interesting. π