First impressions about Rust

I finished my first patch with Rust! \0/ I don’t feel specially proud of it but I’m happy because it is my first contribution to a real project. It has a lot of flaws and technical debt but this is only a prototype and a sandbox for Rust exploration.

In short, the experience is exciting followed by a deep sense of uncertainty, then frustration with a small pinch of enlightenment just to be followed by a rewarding sensation at the end.

You can see 4 cycles here, each with stages of excitement, uncertainty, frustration, enlightenment and finally, the step upwards depicts the reward.

It is exciting because it introduces a lot of new syntax (for me, a new, cool and different syntax compared with JavaScript or Python) with lots of annotations and symbols everywhere. I feel like engineering something precious, delicate but at the same time I feel confident on its robustness cause I’m adding tons of metadata for the compiler. Furthermore, I’ve followed some tutorials and the compiler errors seems very clear, they are even helping and advising me. I’ve read about borrowing, lifetimes and mutability but in the tutorials those never seemed to be a problem.

Then it comes uncertainty. I know what to do but I don’t know how to write it. When learning a new language I lack from two things: a deep knowledge of the API and idioms. And idioms are the most important feature of a language because in the long term you prefer to read idioms. These are patterns that immediate associate with well know and repetitive behaviors. For instance. These three snippets do the same:

// Option 1
if let Some(value) = maybe {
} else {
  Err("Some error")

// Option 2
if maybe.is_none() {
  return Err("Some error");

// Option 3
maybe.ok_or_err("Some error")

My first approach was option 2. It is very similar to C or JavaScript. But then I remember the people that writes Python as it was C. I hate them. Probably I hate you. Naaaah… just joking. But as a Python and JavaScript teacher I try to explain why idioms matter. Then I turned to option 1 and only for this post and after investigating the Option API, I realize about option 3. Currently, I don’t know what is more idiomatic but I would bet for the last option.

Once you are happy with your third refactor, you finally launch the tests and they fail… No, wait! That happens, but much later. First it comes the compiler, the type reasoner and the borrow checker. Let me illustrate the problem with an example. Suppose you want to test the former option 2: in play Rust… (no! no the f*ck*ng game, I did not play it yet but I already hate it), this play Rust(-lang). You want to enclose it in a function, then call it. No run, just see if it compiles.

My first try failed with:

<anon>:1:16: 1:22 error: wrong number of type arguments: expected 1, found 0 [E0243]
<anon>:1 fn test(maybe: Option) -> Result {
<anon>:1:16: 1:22 help: see the detailed explanation for E0243
<anon>:1:27: 1:33 error: wrong number of type arguments: expected 2, found 0 [E0243]
<anon>:1 fn test(maybe: Option) -> Result {
<anon>:1:27: 1:33 help: see the detailed explanation for E0243
error: aborting due to 2 previous errors
playpen: application terminated with error code 101

Read the errors. Try again… Seriously, read the errors. You’ll discover that they make a lot of sense, Option must be an Option of some type so be it Result (but Result needs two types, one for valid values and other for errors).

The second try failed with:

<anon>:3:20: 3:32 error: mismatched types:
 expected `collections::string::String`,
    found `&'static str`
(expected struct `collections::string::String`,
    found &-ptr) [E0308]
<anon>:3         return Err("Some error");
<anon>:3:20: 3:32 help: see the detailed explanation for E0308
error: aborting due to previous error
playpen: application terminated with error code 101

Well, now it turns out string literals in Rust are not String but &’static str. What does it mean? That means reading the docs again. Fortunately the compiler gives you enough info to solve the errors. Uncertainty again, I could convert this &str to a real String (expected in the errors) but I’m happy with a Result of type &str (found in the errors). So, I modify the signature of the function and…

Bam! My third try failed again with:

<anon>:1:43: 1:50 error: missing lifetime specifier [E0106]
<anon>:1 fn test<T>(maybe: Option<T>) -> Result<T, &String> {
<anon>:1:43: 1:50 help: see the detailed explanation for E0106
<anon>:1:43: 1:50 help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
<anon>:1:43: 1:50 help: consider giving it an explicit bounded or 'static lifetime
error: aborting due to previous error
playpen: application terminated with error code 101

What the hell!? Ok, now I need a lifetime specifier. Lifetime specifier…, lifetime specifier… where are those bl**d* specifiers!? Oh, here! Well, you get the idea. This time the problem was I missed a lifetime specifier. As Rust needs to know how much this reference is going to live to check if the returning value lives long enough to not leave you with dangling pointers. Do you understand? Well, probably not, but I do (or at least, I did) which leads me to the next point: enlightenment!

The fourth try worked seamless.

Trying to figure out which kind of lifetime I want to assign for the returning structure, I though: I want these errors to be immortal strings (which translates into ‘static lifetimes) in order to not produce new strings and reuse them. Suddenly, for a fraction of time, I understand everything: lifetimes, specifiers, elision and immortality (well… staticness) and then… it’s gone. This is what I call enlightenment. No more than a fraction of second you understand what are you doing in this new context which is Rust.

Earth seen from the International Space Station
Similar to what astronauts call overview effect, this is what you experiment with Rust from time to time. When you are not fearing about the huge fall you have below.

Paradoxically, If I would read the errors from the second try more carefully, I should have read that the expected type was &’static str preventing me from the third try but at the same time impeding this moment of truth to happen.

The remaining sensation is rewarding. Bit after bit, I’ll adapt my mind to these new memory and execution models. Reading articles, answers and books I will learn more knowledge about the internals of the data and execution models for Rust at the same time I will borrow some idioms.

Of course, once the code compiles, test are failing and the cycle repeats again. Most hard part is frustration and uncertainty (what else?) but it is completely normal. You can think of yourself as some kind of ninja or choosen-one inside your comfort zone. Modesty aside, I think this of myself when working on JavaScript or Python but when you are in the wild, failure is something normal. During these days, I even realized that my way of debugging / developing with dynamic languages is not suitable for this strongly typed language! But if it was easy, where would be the fun?

Look at those bullet holes on Neo shirt: failure is natural before enlightenment. Mr Anderson learned it the hard way.

Static vs. Dynamic Typing

The other day I was invited to participate in the podcast of Nación Lumpen about the flaming topic Dynamic Typing vs. Static Typing. Luis Osa and I were there to argue in favor of dynamic typing, from Python and JavaScript perspectives respectively.

My first impression after the podcast was that we were not at the level to defend dynamic languages properly and I ended very surprised about the modern features of static typed languages.

Lots of things were told during the conversation and, in my opinion, lots of reasons arose to make static typed languages shine over dynamic ones. After 700 km of highway, I’ve got to sort my ideas and conclusions about the podcast. This is a long post, so be prepared!

Types are meaning

From the bare metal perspective, types are nothing. The pure hardware executing the programs in our devices understand only about memory addresses and data sizes. It does not perform any type-checking before running the assembly code, once the code it’s loaded, it’s on its own.

You start introducing types to mean something. Consider simple types in C: they are all about data sizes (int, word, byte), formats (float, double, pointer) and access (const) but you’re helping the compiler to create better target code: memory efficient, faster and safer. In addition, C gives us ways to combine simpler types into complex ones as well by using DEFINE macros and structured types. C is able to calculate each size, format and access type of the new abstraction preventing us from accessing invalid fields of a record or using them in incorrect places but, in addition, C makes new names to be charged with unique meaning (i.e two structures differing only in the name of the structure are actually different types) so we can abuse this feature to create abstract relationships.

This is what I think when talking about types. Types are (or at least, add) meaning. You use types as a way to perform a classification of data, to label some properties that some set of values should have and to establish relationships with other types.

Seguir leyendo «Static vs. Dynamic Typing»

Firefox OS: applications 101

Hi again!

The other day in TID I was told there is not much information about how to start a HTML5 application for Firefox OS and deploy it into the device. There is. Seriously. But I have to admit there is not a straight way to the topic and you could get lost in the middle of all the available information. So this is a try to provide a quick and basic Firefox OS application tutorial.

Step 0: set-up the environment

Firefox Nightly

Nightly is the latest version of Firefox. Always. Built every night from the source-code. You can download it from the Nightly’s official site.

Before open it, it is very important you close all sessions of Firefox.

Firefox OS Simulator

This is an extension to Firefox; grab it by clicking on «+ Add to Firefox» from the Firefox OS Simulator add-on page.

The device and drivers

If you are fortunate enough then you have a Firefox OS device. If not, you can purchase one from Geekphone’s store. You need its drivers as well and they depend on the device you have and the operating system of your PC.

Finally, in the device go to Settings > Information > More information > Developer and enable «Remote debugging».

Now you are ready to start  developing Firefox OS applications!

Step 1: the first app

Before starting, create a new folder. Name it as you want (i.e. myapp) and enter the folder. All your application files will go here.

Open your favorite text editor and create a new document named «index.html». Now enter the following HTML5 code and save it inside the folder you created before.

<!DOCTYPE html>
    <meta charset="utf-8" />
    <meta http-equiv="pragma" content="no-cache" />
    <p>This is my first Firefox OS application.</p>

If you are not used with HTML5, let’s take a quick review to the code:

  • Line 1 indicates the navigator we are using HTML5.
  • Line 2 is the beginning of the HTML5 document.
  • Line 3 indicates the beginning of the head section where metadata goes.
  • Line 4 is metadata saying the document is encoded in «UTF-8».
  • Line 5 is more metadata saying you don’t want Firefox OS to cache the content. This is very convenient while developing.
  • Line 6 indicates the end of the head section.
  • Line 7 indicates the beginning of the body section where content goes.
  • Line 8 is a paragraph with some text.
  • Line 9 indicates the end of the body section.
  • And line 10 indicates the end of the HTML5 document.

Step 2: the manifest

The index.html is one of the two things you need to make a Firefox OS application. Again, use your favorite text editor an create another file named «manifest.webapp», Put this text inside:

"name": "MyApp",
"description": "My first Firefox OS application",
"launch_path": "index.html"

This is a JSON file. Again, if you never read about this format before let’s review what is it saying:

  • Line 1 indicates the beginning of a JSON object. A JSON object is a list of pairs «key»: «value».
  • Line 2 is the key «name» which indicates the name of the application.
  • Line 3 contains the key «description» with the description of the application.
  • Line 4 has the key «launch_path» which says Firefox OS what file must be opened when launching the application.
  • Line 5 ends the JSON object.

Step 3: test your application!

Yes, you’ve read well, it’s time to test your application. Nothing more is needed. Now open Nightly and click on Tools menu, then go to Web Developer > Firefox OS Simulator.

Firefox OS Simulator dashboard
Firefox OS Simulator dashboard.

This will open the dashboard. Click on «Add directory» button and navigate to the folder you created in step 1. Select the manifest file and accept. This will launch the Firefox OS simulator allowing you to see your application as if it were running in a real device.

MyApp application in the dashboard.
MyApp application in the dashboard.

If you modify the application while the application is still running, go to «App» menu, then «Refresh» to reload the app.

Application running in the Simulator.
Application running in the Simulator.

Step 4: testing on the device!

If you have a device, connect it to your PC. If the drivers are installed properly you should see the phrase «Device connected» below the «Simulator» switch. Furthermore, your application entry will display a «Push» button.

Device has been recognized by the Firefox OS Simulator.
Device has been recognized by the Firefox OS Simulator.

Press the «Push» button and your application will be uploaded to your phone. The first time you upload an application, a prompt will be displayed on it. If you accept, the application will be installed and a status message will appear when finished.

Then you can go to your home screen and search for your application. Open it and see the results.

Note there is no such thing as Refresh in your real device. If you change the source files in your PC, you need to push your application again. Furthermore, you must close the application and reopen to see the changes.

Congratulations. You have written and run your first Firefox OS application.

Seguir leyendo «Firefox OS: applications 101»