Rostyslav Dzinko's DevNotes

Wednesday, December 23, 2015

With this short post I'd like to introduce you my small Nim language package called native_dialogs which is intended to implement framework-agnostic way to call underlying operating system file save/open/etc. dialogues.

From my experience it is always quite a pain for cross-platform GUI development to implement file dialogues, and both approaches: native and custom dialogues are used from framework to framework. Anyway, this small lib allows you to use file dialogues with a GUI framework of your choice as simple as withing small command-line applications or automation scripts.

Monday, October 19, 2015

Intro

My latest article was on the work I currently doing on Nim programming, namely, working on nimongo, and everyday this language takes more and more of my time at work, and outside of work, as it brings a lot of fun and addiction.

Now we heavily employ Nim on one of our company's projects, and more and more sub-projects appear as still non-mature ecosystem does not allow us to just take a stable instrument, and just do the job, and it really has some particular charm in contributing an extremely new technology, taking part in defining ways and niches it's going to take in the world of computer science.

Nim Workshop

And here we are, in barely a month (November, 14-15) we hold the very first workshop on Nim programming language here, in Kyiv, Ukraine. Our office is going to accept all those who's keen on something new in programming, and is always developing ahead of the technology mainstream.

The main goal of the workshop is to popularize Nim among the greater Ukrainian and world tech community, and this first step in building such a community with this offline event is going to be great, because Andreas Rumpf, the creator of Nim, will also be here opening the event, and leading the workshop itself.

It is also a great opportunity for all those who's going to take grips on this brand new technology to get all the info you want to know off the first hands.

This two-days event will also include some talks from the guys who already employ the language, and, of course from Andreas.

So, if you would like to register - follow the link on SplashThat, and register. It's free. And... we're waiting for you no matter what background you have: enthusiasm and interest are the only conditions :).

Monday, September 14, 2015

The situation

It happens that sometimes I have to write console application in C for Windows, and having only ASCII output is not always an option: basically, I need to have a possibility to perform text output in Ukrainian which is okay when you use UTF-8. Unlike others, Windows use legacy code pages system to make console work with natural languages text in different countries with different localisations, and that's a weird thing for Linux/Mac user.

I work in Qt Creator when coding in C, and it brings another tricky thing: qt_process_stub.exe - a nasty utility which is run from the IDE, which actually runs your app. My task was to find a non-tricky solution to have a possibility to work seamlessly when debugging my C programs from Qt Creator.

Step 1: Changing the font

Most of Windows developers possibly know that there's a default font in Windows cmd.exe (which is a terminal itself) that does not support UTF-8 encoding (yeah...), so the first thing you have to do is to run cmd.exe (via Ctrl+R), click Command Prompt icon and choose Properties context menu item (pic 1.1)

Step 1.1: Enter properties

There, you have to choose Lucida Console font as it supports UTF-8 symbols (at least Cyrillic ones ;), and press OK button at the bottom of the dialog.

Step 1.2: Choosing the need font.

Now, we are capable of using UTF-8 text in console and even see something meaningful there.

Step 2: Changing the code page

By default, the code page used by cmd.exe on my system is 437 which is a DOS Latin US character set. You can easily check it by running chcp command in the terminal:

chcp

The same command is used to change current code page. Everything you need is to pass codepage number as an argument:

chcp 65001

Cool! Now we use UTF-8 code page. But the problem is that when you close the terminal and start it again, the codepage will default to 437 again.

Here we actually don't need to play with codepages, but rather use the information that Qt runs console application from its IDE via qt_process_stub.exe. And it uses default system encoding information from MS Windows System registry. This setting can be easily tweaked from command-line:

REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 0xfde9

This command will fix the Qt Creator problem, but cmd.exe will still run 437 by default. If you want to change this setting globally, start regedir (if you have administrator rights, of course), and add a new setting to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor folder. Name it Autorun with value chcp 65001 >nul.

Step 3: Checking the Result

It is very easy now to check the result. Let's start minimal project in Qt Creator (Non-Qt Projects section -> Plain C Application), which main.c file will look like this:

Warning! Calling getch() serves here not for stopping console from disappearing as it usually happens (Qt Creator stops it by default), but it helps to avoid errors of qt_process_stub.exe. The absence of some sleeping/waiting mechanism will force errors because the utility has some bugs in reading from a pipe :). And the result of running this small code will look like this:

Tuesday, September 8, 2015

Foreword

Nim logo

Lately I've spent much time coding in Nim. If you're still not acquainted with this fascinating, one of the fastest growing programming languages, please visit its official site, and get your grips on it. To be short, it's a statically typed compiled programming language that translates its source code ANSI C, which is then compiled into native executables. Such flow makes it easy to employ Nimlang on a broad range of software and hardware platforms.

Meet nimongo

We have been adopting Nim as an experiment for quite a time at one of our commercial projects here, at ZeoAlliance. Lack of powerful ecosystem and wide community made me to start working on some tools that are crucial for the project. One of such tools (located at Github), which is fully open source, is a nimongo - pure MongoDB driver for Nimlang. Although there's standard mongo client, it is still in an unusable state, and has one minus - it uses libbson.c, and libmongo.c, which makes setting it up a bit more painful, than if the package was native to Nim language.Note: Nimongo implements thread-safe synchronous client, AsyncMongo is still in an active development.

Installing nimongo

In order to install nimongo, you can either, clone it from Github, or use Nim native package manager called nimble:

$ nimble install https://github.com/SSPkrolik/nimongo

For now, you have to specify repository URL directly. Later, when some stable state of the project is achieved, I will add it to nimble repo, so you could just type nimble install nimongo.

Importing prerequisities

In order to start using nimongo, you have to import two of its modules - nimongo.mongo and nimongo.bson which contains BSON serialization/deserialization routines, helper templates, and converters that help integrate Bson objects into Nim source code as seamlessly as possible. Also you have to import oids which is a Nim standard library module for working with MongoDB Object IDs. Other modules like times will also be helpful if you plan to use date and time data in your application.

import oids
import times
import nimongo.bson
import nimongo.mongo

nimongo.mongo module contains objects needed to work with MongoDB: Mongo, Database, Collection, Find, and other supportive types and constants.

Establishing connection with MongoDB server

The main object to start with is a Mongo, which is a reference type that manages communication between your application and MongoDB server. You can use newMongo(...) constructor by passing host and port connection parameters, or leaving those empty in order to connect to localhost:27017, - default MongoDB server parameters:

var m: Mongo = newMongo()
let connected = m.connect()

Also you can see procedure connect() call here, which actually establishes connection to server, and returns bool result that equals to true if connection was established successfully.

Performing commands on Mongo server

If you're familiar with how MongoDB operates, you are aware that there are different groups of operations that can be also split into different levels: server-, database-, collection-level. In nimongo those are distributed into procedures bound to Mongo, Database, and Collection types respectively. For now, there is only one operation available for server level - isMaster():

let ismaster = m.isMaster()

This procedure returns true if connected MongoDB instance is master in a replica set, or false if not. Other commands will also be added, but the work is still in progress. Also, beware using such kind of commands, having in mind that such commands perform actual network communication with server over network.

Accessing Databases and Collections

As Nim has nice operator overloading implemented, accessing to databases, and collections are made via [] (indexing operator) the same way as you take values by keys from hash tables. Also the syntax becomes quite friendly to Python developers ;) It looks like that:

Dealing with BSON

MongoDB operates documents encoded in BSON format, and that's why nimongo.bson module exists. In order to perform data manipulations with nimongo you have to create such objects. They are able to be serialized into a byte stream that MongoDB server understands.

BSON document can be created using initBsonDocument() constructor:

let empty = initBsonDocument()

This constructor creates empty BSON document, and then have to be filled with fields. You can also use B template, which simplifies the way you create BSON document objects, by squashing empty document creation, and offering ability to add fields right in place. Documents are filled with fields using procedure call operator ():

As you can see from the example, two sample documents are created. Documents are created as "field-value" pairs, and value must be of Bson type. Fortunately, Nim offers such kind of procedures as converters, so all values like "Sam", "Uncle", and 1000 are implicitly converted to Bson type objects. Also mention the last field which is a sequence. This field is converted to BSON array. Also, () operator, as you could have mentioned, returns Bson type object, so you can append fields to objects any time in future.

Whether you are doing inserts, updates, or find queries, Bson objects is a strong foundation on which queries to MongoDB are made.

Inserting data into MonoDB using nimongo

When we have some documents created, we are ready to insert() those into database collection:

if collection.insert(doc):
echo("Document was successfully inserted.")

Here we insert previously created BSON document into collection. insert() procedure returns bool value indicating success of the operation. This example shows how to insert single document, though it is also possible to insert serveral documents at a time with a single insert query by using overloaded insert() procedure that accepts sequence of Bson objects:

collection.insert(@[doc, doc, doc])

Updating documents using nimongo

Almost the same way as you do insertion, it is possible to perform document updates. Here how you can easily update single document using update() procedure:

Removing document using nimongo

This procedure also return bool value, which indicates success of the operation.

Querying data from MongoDB

Querying data from MongoDB is a bit more complex than inserting, updating, or removal. Finding data in MongoDB usually requires some kind of configuration depending on the performed query. That's why find() procedure does not perfrom immediate querying, but creates Find object that is configurable, and the actual query is run with one(), all(), and items() procedures of the Find object. Let's fetch one document from database:

And the last way to use query results is to use iterator in order to work with fetched documents:

for item in collection.find(B("name", "John")).items():
echo item

Also you can tweak querying process by configuring Find object with such procedures as tailableCursor(), slaveOk(), noCursorTimeout(), and others, which you can find in MongoDB documentation.

Afterword

All this functionality, though does not fully implements MongoDB wire protocol, and does not expose whole power of MongoDB database, allows us to use it in small projects, or on early stages of large long-term projects.

I encourage all of those who plans writing Nim applications, and likes nimongo aproach, play with the driver, and support the project by contributing via pull requests, or filing issues, and wishlists.

In the near future, I plan to finish all BSON types support (now only widely used ones supported), add more service commands, and implement asynchronous driver based on asyncnet, and asyncdispatch Nim standard library modules.

Sunday, April 6, 2014

Where Is D now?

DMD logo

The history of D is quite rich by now. The language evolves for about 10 years, but the interesting thing is that the fully rethinked and redesigned D 2.0 is now in active development and still does not have its stable niches and mature practices / patterns / etc., like C++, Java, Python, and so on.

Also it worths mentioning that the development means the language itself, compilers (there are 3 for now:

dmd 2 - reference one from Digital Mars;

gdc - based on gcc;

ldc - llvm

), and standard library (called "phobos") often change. Also stable versions of ldc and gdc are a bit behind dmd, so it is better to use the latter in order to get access to the last features and changes of the language.

What I don't like in C++ (... after I've met D)

If you've ever tried to use C++, you can mention that the language is quite difficult itself (whatever it means). One of the evidences of that is that C++ applications can be written in dozens of coding styles, using dozens of practices and approaches. It can even seem, looking at two applications written in C++, that they are written in two different languages (consider two desktop applications, one written using bare Win32 API, and the other one using Qt).

Qt, for example, offers meta object compiler and objects tree system in order to simplify memory management and allow event-driven applications to be written in a convenient manner so that it seems you're using the very different language.

The existing of such monstrous tools for simple tasks (really, memory management mess in twenty first century?) is an indicator to me, that something is really wrong with the language.

The second thing is that no-one knows whole C++ :), (even Stroustrup o_O?). Really, you can spent years learning possibilities of the language, that was not been redesigned for decades, but dozens of new features are stably added every couple of years.

And the last thing is the absence of a comprehensive standard library (IMHO "over-templated" STL is not the best choice). Yeah, you can find hundreds of C++ json and xml parsing libraries, every framework also has those (remember Qt here :)). BUT you don't have the standard one! WTF? Everybody has!

D is Better! ... ?

Well, D does not have those disadvantages I've written about above, having the same and even more possibilities than C++. Also there's garbage collector sitting in your D application runtime. A lot of mature developers don't like GCs, but the nice thing is that you can disable or ignore it :)

Why D is better? Just try... Maybe it won't be better for you.

(c) me

SMTP Library for D

Check it out at my github page. It is very far from using all tasty features of the language, but still shows how much convenient a system programming language can be still having comparable performance to C++.

Saturday, March 1, 2014

My Story of Go

I've started working with Go language far before the first official release of Go 1.0, and this language seemed, I think, beautiful for me from the first steps.

While Go language in its current state (version 1.2) still remains quite raw from some points, it is still finished enough to be successfully used in production for different goals. I personally use it for building web services, and the most magnificent is that you basically need only standard library to start doing web application development in Go.

My Story with PACKT Publishing

About a half years ago I've been contacted by guys from PACKT Publishing, about making a video course about building applications with Google Go. It was a very exciting offer which I've accepted even not thinking much about it. Having some experience teaching other people programming, and writing some tutorials inside my personal blog in Russian, I though I could do the job, even if working language is English which is not my native one.

How Was It, Doing the Job?

Making some educational product is interesting personally to me, it can not be that interesting to others. And that was, possibly, the most motivational thing for me. The working process of making video is a hard and sometimes monotonic job as any other job, unless it may seem different before you start working on it.

The most complex thing is to make a content which perfectly fits target audience, particularly to decide what to explain and what to consider to be left out of scope, especially if your target audience is non-expert environment: novices or junior developers.

What about the results

The result I've got is a published video course called "Building Your First Application with Go" and a lot of excitement when you see the job done. About the quality: it's up to viewers to decide if I did my job well or not.

Nevertheless, it was fascinating experience, and now I'm sure I'm not to stop at this point, and will try to work further on creating new educational products and materials. Doing the job you like is the best think that can happen with you, that is what I think.

Acknowledgements

I would like to say many thanks to my wife, that patiently supported me all this time, and a highly professional team from PACKT Publishing house, that led me through all the process starting from writing first texts till the moment the course was published.