A couple of days ago, while recovering from some flu, I managed to catch up a bit of me reading. If you know anything about the life of an independent contractor, you’d know that there’s never time for your personal projects or hobbies, so this was a most welcome break.
One of my favorite blogs is this one and I saw a great article on Sorting vectors in C++ by Nic Raboy. As it happens, C++ is one of my first commercial languages and I still make some moderate use of it for various mobile projects.
One thing that struck me, as I read the code, was how close this was to the Dart programming language. I’ve been doing a lot of Flutter development of late, and have been making more use of the Dart programming language. Mobile applications often contain complex logic, and this is where Dart has really proven it’s worth to me, in both being a concise and expressive language, but also being familiar enough that I didn’t have to learn everything from scratch to be productive.
In this short tutorial, we’ll take the quicksort algorithm Nic has built in C++ and convert it to Dart. Along the way, we’ll see how close Dart is to C++ and how much of your existing C++ knowledge easily transfers to the Dart environment.
Dart comes with an easy to follow installation guide, for each supported platform, that you can find at the official Dart Language website. There are detailed instructions for Windows, Linux and Mac. For this tutorial, you should install the Dart SDK.
The Dart SDK contains a number of useful command-line tools:
Once you have Dart installed, as per your platform instructions, open a command prompt and execute the following command:
dart --version
You should see something similar to this:
Dart VM version: 2.3.2 (Tue Jun 11 15:29:47 2019 +0200) on "macos_x64"
Let’s go ahead and create our first Dart program, just to see that everything is working as expected.
Create a file called hello_dart.dart in a folder of your choice, with the following content:
void main() {
print("Hello, Dart!");
}
Save the file, then run the program with this command: dart hello_dart.dart
. The output should be Hello, Dart!
.
If all went well, you should now be ready to start converting C++ to Dart code.
Let’s take a look at the source code for the Sorting Vectors in C++ article Nic Raboy wrote. It does a couple of interesting things that we will also need to do in our Dart program.
To do all of this, we’ll create a main
function as the driver for our program and it will call various functions to accomplish these goals.
Let’s start with the basic skeleton of our program. I’m going to call it qsort.dart and give it the following content:
void main() {
createList();
displayList();
sortList();
displayList();
}
This will of course not run yet, but it gives us an idea of what functions we’ll need to write to recreate the functionality of the C++ code.
Let’s make the createList
function work. It is tasked with creating a list (in C++ a vector) of random numbers that we can sort.
For this, we’ll need to import the Dart Math library functions, as we want to get access to the Random
function. We do this by adding import 'dart:math';
at the top of our qsort.dart source file.
Next, we’d like the createList
function to create a new list of random numbers which we’ll store in a local variable so our other functions can get access to it. Our source file now looks like this:
import 'dart:math';
void main() {
List numbers = createList(20);
displayList();
sortList();
displayList();
}
List createList(int howMany) {
var rnd = Random();
List numbers = List(howMany);
for (var i = 0; i < howMany; i++) {
numbers[i] = rnd.nextInt(250);
}
return numbers;
}
Our createList
function now takes a parameter, telling it how many random numbers to generate. It will create a new List of random numbers and will return that List which we’ll store in the numbers
variable in our main
function. Notice how close the for
loop is to it’s C++ counterpart.
Next, we’ll need a way to display our list of numbers, so that we can visually verify it has been sorted. We’ll start of by displaying the unsorted list, but the same code can be used to display the sorted list. To make this easier and avoid code duplication, we’ll make our function accept some parameters.
Instead of using print
, we’ll use the stdout
feature that allows us to output a character at a time, without advancing to the next line. This makes it easier to get all the numbers displayed on a single line. You’ll notice that we can still make use of String Interpolation though, which is a really handy Dart feature.
We’ll need a new import to use the stdout
feature. Add the following to the top of the source file, just beneath the math
import statement:
import 'dart:io';
Our new displayList
function:
void displayList(String description, List numbers) {
stdout.write("$description : ");
for (var i in numbers) {
stdout.write("$i ");
}
}
We’ll change how the main
function calls it as well. We pass in the description of the list we wish to display, as well as the actual list. Notice how in the second displayList
call, we pass a newline character (\n
) to start the second display string on a new line.
void main() {
List numbers = createList(20);
displayList("Unsorted list", numbers);
sortList();
displayList("\nSorted list ", numbers);
}
Finally, we get to the meat of the program : Sorting the list of numbers.
void sortList(List values, int left, int right) {
if(left < right) {
int pivotIndex = _partition(values, left, right);
sortList(values, left, pivotIndex - 1);
sortList(values, pivotIndex, right);
}
}
We’ll also need a partition
function, and, in this case, because we want to indicate it’s an private function, we’ll make use of the Dart naming convention where a function name that starts with an underscore, is private:
int _partition(List numbers, int left, int right) {
int pivotIndex = left + (right - left) ~/ 2; // notice the ~/ operator that casts the result to int
int pivotValue = numbers[pivotIndex];
int i = left, j = right;
int temp;
while(i <= j) {
while(numbers[i] < pivotValue) {
i++;
}
while(numbers[j] > pivotValue) {
j--;
}
if(i <= j) {
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
i++;
j--;
}
}
return i;
}
Here is the final result of our conversion efforts. When you compare it to the original C++ version, you’ll notice that it’s almost identical, line for line. While there are ways to make it more Dart-like, it’s a great starting point and shows that a lot of your existing skills transfer really well to the Dart ecosystem.
import 'dart:math';
import 'dart:io';
void main() {
List numbers = createList(20);
displayList("Unsorted list", numbers);
sortList(numbers, 0, numbers.length - 1);
displayList("\nSorted list ", numbers);
}
List createList(int howMany) {
var rnd = Random();
List numbers = List(howMany);
for (var i = 0; i < howMany; i++) {
numbers[i] = rnd.nextInt(250);
}
return numbers;
}
void displayList(String description, List numbers) {
stdout.write("$description : ");
for (var i in numbers) {
stdout.write("$i ");
}
}
void sortList(List values, int left, int right) {
if(left < right) {
int pivotIndex = _partition(values, left, right);
sortList(values, left, pivotIndex - 1);
sortList(values, pivotIndex, right);
}
}
int _partition(List numbers, int left, int right) {
int pivotIndex = left + (right - left) ~/ 2; // notice the ~/ operator that casts the result to int
int pivotValue = numbers[pivotIndex];
int i = left, j = right;
int temp;
while(i <= j) {
while(numbers[i] < pivotValue) {
i++;
}
while(numbers[j] > pivotValue) {
j--;
}
if(i <= j) {
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
i++;
j--;
}
}
return i;
}
An example of one of the runs on my machine:
Unsorted list : 177 173 130 217 117 154 198 189 219 212 80 112 6 22 231 215 225 72 216 36
Sorted list : 6 22 36 72 80 112 117 130 154 173 177 189 198 212 215 216 217 219 225 231
As you can see, Dart is closely related to programming languages like C++, so it’s easy to get going in Dart and you can make use of a lot of your existing knowledge. In my experience, it’s been really quick and easy to become productive using Dart, for both mobile and API development. With a little bit of experimentation, you’ll discover many similarities and overlaps with programming languages and paradigms you already know. Give Dart a try, it’s refreshing take on existing programming paradigms and familiar enough that it doesn’t feel like a big exercise to become productive in it.
You can reach out to me, Ewald Horn, if you get stuck running the sample code. This has been a very quick and dirty conversion from C++ to Dart, with little to no regard for performance or code correctness issues. I do hope you’ve learned a little something and that you’ll take a look at Dart as a potential language to learn for your development requirements.