Posts: programming

After a ton of work, a lot of which was unexpected, I am ecstatic to announce that EndBASIC is now a reality on the web! The whole language interpreter can now run as a fully client-side web app on a computer, on a tablet… and even on a phone. Yes: the whole thing, which is written in Rust (94%), works in a modern browser with just a tiny bit of JavaScript glue (1%).

A couple of weeks ago, I announced EndBASIC: a simple BASIC language interpreter written in Rust with a goal to provide an environment for teaching my kids how to code. That first release provided what-I-think-is a robust interpreter, but that was about it: the language features were still minimal and the interactive features were non-existent.
Well, EndBASIC 0.2.0 is here and things are changing! It’s still far from the vision I want to reach, but it’s slowly moving towards that direction.

Rust provides a bunch of traits that you may use or implement in your code, but unless you have experienced them first-hand, it can be hard to imagine what their real utility is. For example, if you go read Into’s documentation, all you find is:
Trait std::convert::Into
A value-to-value conversion that consumes the input value. The opposite of From. […]
Yay, very useful. This text tells me what this trait does, which is fine for a reference manual, but not when I could find it useful.

Introducing EndBASIC, a new interpreter for a BASIC-like language that is inspired by Amstrad's Locomotive BASIC 1.1 and Microsoft's QuickBASIC 4.5. Like the former, EndBASIC intends to provide an interactive environment that seamlessly merges coding with immediate visual feedback. Like the latter, EndBASIC offers higher-level programming constructs and strong typing. The main idea behind EndBASIC is to provide a playground for learning the foundations of programming in a simplified environment.

Hello everyone and welcome to this new decade!
It’s already 2020 and I’m only 17 days late in writing a first post. I was planning to start with an opinion article, but as its draft is taking longer than I wanted… I’ll present you the story of a recent crazy bug that has kept me busy for the last couple of days.
Java crashes with Bazel and sandboxfs On a machine running macOS Catalina, install sandboxfs and build Bazel with sandboxfs enabled, like this:

Quite some time ago, I wrote a handful of guest posts for O’Reilly’s ONLamp.com online publication. Unfortunately, that site seems now gone from the interwebs and I only noticed by chance upon realizing that some of my links to those articles were now broken.
Fortunately, I was able to find copies of those articles via archive.org’s WayBack Machine. So I have now taken the chance to import those articles into this site.

Over the summer, I prototyped a bunch of web apps whose ideas had been floating in my mind for a long time. I spent some time reading through REST API documentation pages and, as part of these exercises, implemented sample RESTful web services in both Go and Rust. (Just for context, the last time I wrote a web app was in high school… and it involved PHP, MySQL, and I think IE6?

The current working directory, or CWD for short, is a process-wide property. It is good practice to treat the CWD as read-only because it is essentially global state: if you change the CWD of your process at any point, any relative paths you might have stored in memory1 will stop working. I learned this first many years ago when using the Boost.Filesystem library: I could not find a function to change the CWD and that was very much intentional for this reason.

There are two ways to handle abnormal conditions in a program: errors and assertions.
Errors are a controlled mechanism by which the program propagates details about a faulty condition up the call chain—be it with explicit error return statements or with exceptions. Errors must be used to validate all conditions that might be possible but aren’t valid given the context. Examples include: sanitizing any kind of input (as provided by the user or incoming from the network), and handling error codes from system calls or libraries.

There is no good answer to this question: people tend to put Go and Rust in the same bucket because they were released at around the same time, because Rust's release felt like a response to Go's, and because they are marketed to similar audiences. They are, however, vastly different. So let's give in and compare them anyway.

Thought that the Rust review was over? Think again; I was just on vacation! I’m back now to conclude the series with a bunch of random thoughts and a surprise follow-up post.
The series is coming to an end. It’s time to summarize everything we have discussed so far and to cover a few more items that didn’t really deserve full posts of their own. Most of these miscellaneous items were thoughts that I jotted down while reading TRPL book.

In this part of the review, I would like to focus on Rust’s ecosystem: in other words, how Rust plays with other parts of a functioning system and how Rust’s standard library vs. external libraries interact with each other. There are a lot of pieces to cover in these areas and they have left me with mixed feelings. Let’s look at some.
The standard library The std library feels generally well-thought out and full of features.

“The Rust Programming Language” is one of the free books that the community has put together to teach the language. The book does a good job in general, but there are some things that could be better. Let’s cover these, but first, some background.
A couple of years ago, right after getting started with Rust, I tried to go through the book’s first few chapters. It all sounded cool… but the first edition of the book moved at a glacially slow pace because it covered things in excruciating detail.

A commonly-acclaimed feature of Rust is its match keyword: a “conditional on steroids”. match lets you take the value of an expression and compare it against a bunch of values—or, more generally, patterns.
As you write and read Rust, you will notice that this keyword is used everywhere because it’s the way to access certain types, like Option values or error codes.
For example:
matchnode.get_parent(){// node is an Option<Something>. Some(parent)=>{// Do something with "parent", which we know points to a node.

Rust resembles a functional language in many ways although it does not claim to be one. In fact, I have been thinking of Rust as a “pragmatic Haskell” or as a “well-balanced mixture between C++ and Haskell“.
One of the ways the functional aspects show up is via expressions and how pretty much any construct in Rust can be treated as an expression. But before we begin, a little warning: the examples below are, by no means, idiomatic Rust—I just hope they are simple enough to illustrate what I want to show.

Writing Rust code is not restricted to programming gurus—but there is no denying that the learning curve is steeper than that of other languages. Or is it? In this post, I’ll try to convince you that the curve does feel steep, but it isn’t when taken into perspective.
Let’s first start by stating that learning a language is not the same as learning its syntax. Learning a language involves learning the syntax, of course, but it also involves familiarizing oneself with its common idioms and grabbing a good sense of what the standard libraries provide.

The one thing that blew my mind about Rust is its approach to data sharing in concurrent situations.
I had always thought of mutexes as something that is easy to get wrong and was convinced that the use of a RAII pattern to prevent lock leaks never happen (like with Abseil’s MutexLock) was the panacea. (I’m a fan of RAII in C++ by the way, in case you haven’t noticed.)

Aaaah, the borrow checker: the dreaded enemy lurking within the Rust compiler, ready to make its move to bring pain to your life by preventing your code from compiling. Or that’s what everyone seems to say, which is one of the reasons I put off learning Rust for so long. In reality… the borrow checker is a blessing, but it is true that getting past its gates is difficult at first.

Let’s start the deep dive by looking into a powerful feature of Rust: all variables and references are immutable by default unless qualified with mut.
To understand why this is important, let’s cover some context first. One of my pet peeves when reviewing C++ code is to ask authors to sprinkle the const qualifier everywhere: if something ain’t mutated, say so explicitly. This includes marking local variables, function arguments, function return values, class attributes, etc.

I had been meaning to learn Rust since I first toyed with Go a couple of years ago. During this period, I’ve written a non-trivial amount of Go code both inside and outside Google, but never found the chance to sit back and learn Rust.
This changed a month ago during my yearly family trip to Korea. This time around, I decided upfront that I would not work on any personal or work projects for the 2-week long vacation.

Many programming guides recommend to begin scripts with the #! /usr/bin/env shebang in order to to automatically locate the necessary interpreter. For example, for a Python script you would use #! /usr/bin/env python, and then the saying goes, the script would “just work” on any machine with Python installed.
The reason for this recommendation is that /usr/bin/env python will search the PATH for a program called python and execute the first one found… and that usually works fine on one’s own machine.

This article first appeared on this date in O’Reilly’s ONLamp.com online publication. The content was deleted sometime in 2019 but I was lucky enough to find a copy in the WayBack Machine. I reformatted the text to fit the style of this site and fixed broken links, but otherwise the content is a verbatim reproduction of what was originally published.
The i386 architecture is full of cruft required to maintain compatibility with old machines that go back as far as the 8086 series.

This article first appeared on this date in O’Reilly’s ONLamp.com online publication. The content was deleted sometime in 2019 but I was lucky enough to find a copy in the WayBack Machine. I reformatted the text to fit the style of this site and fixed broken links, but otherwise the content is a verbatim reproduction of what was originally published.
C++, with its complex and complete syntax, is a very versatile language.

This article first appeared on this date in O’Reilly’s ONLamp.com online publication. The content was deleted sometime in 2019 but I was lucky enough to find a copy in the WayBack Machine. I reformatted the text to fit the style of this site and fixed broken links, but otherwise the content is a verbatim reproduction of what was originally published.
My previous article, Making Packager-Friendly Software (part 1), explains why software packaging is sometimes problematic due to real problems in the mainstream sources.

This article first appeared on this date in O’Reilly’s ONLamp.com online publication. The content was deleted sometime in 2019 but I was lucky enough to find a copy in the WayBack Machine. I reformatted the text to fit the style of this site and fixed broken links, but otherwise the content is a verbatim reproduction of what was originally published.
A package maintainer, or packager, is a person who creates packages for software projects.