PureBasic Review


by Andreas Schipplock

Introduction

Today I'm writing about PureBasic, a portable programming language, that works on Microsoft Windows, Linux and os x. As you might have guessed PureBasic is a basic dialect but don't let that fact fool yourself because PureBasic is very powerful and when you start to become serious with PureBasic it's not so easy as it sounds anymore.

PureBasic is not a toy. It has a very well compiler that directly emits assembler code. Your binaries will be extremely small and they will depend on nothing. My irc client "asirc", which has a gui, only is about 32kb in file size and it's written in purebasic.

This simple console application e.g.:

OpenConsole()
PrintN("How old are you? ")
YourAge$ = Input()
PrintN("Oh, you are " + YourAge$ + " years old?!")
Input()
CloseConsole()

will produce an *.exe that's only 6kb. If you "upx --best" it, it will shrink to just 4kb and still work.

An empty window in purebasic:

OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "My Window")
Repeat
    Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

will produce a 21kb exe which you can shrink to 13kb.

With PureBasic you save yourself a lot of writing and still get an unbelievable small binary. Compared to Lazarus which uses freepascal this is small. In Lazarus an empty window weighs about 1.8MB (I set all optimisations and smart linking, disabled debugging info etc...). You can shrink that down to 687kb (upx --best) and it still starts quickly. So it's not really a problem today as we all got some sort of internet connection that's faster than 56K and even with 56K this wouldn't be a problem.

But I don't want to dig too deep into the "filesize" topic. This is just something purebasic is very good at. The compiler is also very fast.

PureBasic has a lot of builtin functionality which you can just use out of the box, e.g. Threading, DLL creation (or sharedobjects), XML, JSON, Sqlite, inline assembler, 2d and 3d libraries, access to the OS api etc...it also has its own "Gadget" library which is basically a wrapper for the gui framework used by the operating system. Your gui will be 100% native looking because it _is_ native.

Purebasic, though, has also some weaknesses. I didn't start programming with basic but with assembler and turbo pascal so I never felt at home with all the basic dialects out there. PureBasic doesn't feel better to me. I always have the feeling that I want to organize my code better. You start messing around pretty quickly. You don't really have a path you should follow in purebasic.

But PureBasic has a language feature which is called "Module" and it's _quite_ useful; at least you can structure your code somehow. Modules aren't anything more than static classes so you are limited.


Modules

Here is a basic module:

DeclareModule MyModule
    Declare.s getVersion()
EndDeclareModule

Module MyModule
    Global version.s = "0.0.0.1"

    Procedure.s getVersion()
        ProcedureReturn version
    EndProcedure
EndModule

OpenConsole()

PrintN(MyModule::getVersion())
Input()
CloseConsole()

First you declare a module so you can use it anywhere in your application (yes, everywhere) and then you implement what you declared in your "DeclareModule". That's it. No more "OOP" in purebasic. Of course you put all of your "modules" in a separate file (one file for each single module) and then include that module with "XIncludeFile". One problem I noticed with modules is that the order of "include" matters. If you define a module "A" in file "A.pb" and another module "B" in file "B.pb" then you can't call "procedures" from module "B" in module "A" :/. There's probably a workaround but I don't feel all too well with this approach.

If you wonder why "version" is "Global". It's not the same "Global" you think it is. "Global version" is only global _inside_ the module so that all the procedures can have access to that. This is strange, I know.

My next concern is gui programming. PureBasic makes you believe it's cross plattform but gui programming in PureBasic really isn't good. If you have a simple gui in mind, then go ahead and implement it in purebasic; it will work just fine but if you need a "datagrid" e.g. you will find out that there isn't one. You can find some downloads of custom made grids by some user in the purebasic forum but that's probably not what you really want, do you?

I also find it hard to structure my gui code. The purebasic IDE has form designer which works fine and should be used but it only generates the plain gui code for you. But though all the windows and gadgets (widgets) are made global by the form designer you can't use them inside a module. If you want a module to use any widget, you will have to pass it from the main code.

There are some quirks like scrolling to the last line in an editor gadget. There isn't anything like that. In practice you'll have to call the winapi (on windows), some cocoa magic on os x and some gtk-stuff on linux. So in the end you will have a method that can scroll to the end of the last line but is implemented 3-times :). This isn't a deal breaker but I'd consider this to be a weakness.


Conclusion

I bought myself a license several years ago and I have version 5.31 installed just right now. You get all upgrades for free once you bought a license. For 79 EUR you get a lot; especially if you like Basic dialects. I think PureBasic is quite nice but I don't like to use closed source software. I'm more and more using OpenBSD and out of luck if I wanted to use purebasic on it. There's no build available. If I really wanted to develop in basic, I would choose FreeBasic. It's opensource, gpl licensed and well maintained.

In the end it's up to you to choose the right tool for the job.

I hope this text was useful.