Building a programming language from scratch is no easy feat. In addition to creating the compiler, defining the standard library, and supporting tools like editors and build systems, you need to design the language — will it be imperative or functional? What systems will the language be used for? Will it have metaprogramming capabilities?
Zig, a member of our Open Source and Nonprofit Program, is a general-purpose programming language and toolchain for maintaining optimal and reusable software. It’s simple yet robust, and has portable SIMD. For the team working on Zig, the decision to build a language that was intentionally designed for their needs wasn’t made lightly. To learn more about what inspired this journey, we sat down with Loris Cro, one of the team members working on the project.
C++ has had three kinds of template parameters since basically always: type template parameters (the vast majority), non-type template parameters (sometimes called value template parameters, which strikes me as a better term), and template template parameters (parameters that are themselves templates, the rarest of the three).
From C++98 up through and including C++17, these three kinds were very easily distinguishable by syntax:
template type parameters are always introduced by
template template parameters are always introduced by
template </* some parameters /> classor, since C++17,
template </ some parameters */> typename
anything else is a non-type template parameter (I’m excluding the case where you might have something like
#define Iterator class)
The kinds of values you could use as value template parameters has greatly been increased from C++98 to C++17 (it used to be quite limited), but the syntactic form of template parameters really hadn’t changed all that much. The introduction of
autonon-type template parameters in C++17 was a new form of parameter, but the
autokeyword still makes it quite obvious that this is a value parameter and not a type or a template parameter.
As a result, if looking through unfamiliar code, you came across
template <Kind Name>where you didn’t know what
Kindwas, you could rightly conclude that this is a non-type template parameter. Indeed, in C++17, I would guess that it’s most likely some kind of enumeration, following by an alias for an integer type, followed by an alias for a function pointer type. But, importantly, you know for sure that it’s a value - because types are always introduced by
typenameand templates are introduced by
template. You might not know yet what actual type
Kindis, but at least you do know that it is a type.
This all changes dramatically in C++20 due to a confluence of several features.
Ada proves itself in reliability with a track record of nearly four decades of usage in embedded, safety, and critical systems. Over this timeframe, Ada was updated three times, each time with a new Reference Manual, a more in-depth Annotated Reference Manual, and a Rationale document, describing the reasoning for each feature. Backing each of these changes is the Ada Conformity Assessment Test Suite (ACATS), a battery of freely available tests to help Ada compilers or interprets properly interpret the standard. Ada 2012 takes reliability further, by supporting inline usage of an Ada subset called SPARK, which provides functional specification and static verification.
The main reason for this writeup is meant as a response to the sentiment I keep reading about in IT forums, that it’s “very time demanding”, “impossible to maintain”, “a pain to make sure your mails are being delivered”. I understand the reasons, and tend to agree when it comes to large-ish selfhosted mail deployments with hundreds of users and tens of thousands of mails per day, which also happens to be part of my current day job. It’s true that many IT people understandably don’t want to invest private time into things which appears to be another kind of work assignment. But personally, it fills me with satisfaction to self-host my own infrastructure, my little internet island where I’m root, especially in times of mega corporations trying (and succeeding) in redefining “the internet” as a portfolio of services only they can offer, with little alternative.
Estonia’s successful e-residency programme is now more accessible to entrepreneurs across the world, thanks to the launch of new collection points in four cities across three continents.
The Estonian government’s hugely successful e-residency programme, the world’s first digital residency initiative, has announced the launch of four new international pick-up points across three continents to accommodate for the increase in entrepreneurs as a result of the Covid-19 pandemic.
The new locations – São Paulo, Bangkok, Singapore and Johannesburg – meet rising demand from local entrepreneurs seeking to scale their businesses internationally and expand into the European market.
At work we’ve been using feature flags to roll out various changes of the product. Most recently the rebrand from Icebreaker to Gatheround. This allowed us to continuously ship small pieces and review and improve these on their own pace without creating two vastly different branches of changes.
With the rebrand work in particular there were lots of places where we needed relatively small, local differentiations between the old and the new appearance. Oftentimes just applying a different set of classes to a DOM element. Less often, up to swapping entire components.
Overall this approach seemed to work really well and we shipped the rebrand without significant delays and at a level of quality that made everyone happy. What we’re left with now is some 250+ conditionals involving our
This tells the story of how we got rid of those.
Tom Witowsky (@devgummibeer) shared on Twitter a scaling issue with his service opendor.me, which helps any developer share and highlight their open source work. As the service grows, more and more data is stored in the database and needs to be browsed. One particularly slow query that he needed help optimizing is fetching random users, organizations, and repositories that are already part of the service.
The following query illustrates the problem reduced to its important component:
SELECT * FROM repositories ORDER BY RANDOM() LIMIT 3
Oscar Spencer recently presented Grain, a new strongly-typed, high-level language that compiles to WebAssembly. Grain includes functional programming features (e.g., type inference, pattern matching, closures) while allowing mutable variables. Grain also has a standard library with composite data structures (Option, Stack, Result) and system calls (e.g., I/O, process handling).
In a talk at the WebAssembly Summit 2021, Spencer went through the main characteristics of Grain, a programming language that he said is made exclusively for WebAssembly, its only compile target.
The Wenyan-lang Hello World program reads like this:
Even those of us who don’t understand the characters can likely recognize it as a form of Natural Language Programming—a programming language whose code mimics prose—in its wordiness and its structure as sentences. In fact, Wenyan is built on its namesake, Classical Chinese (or Wényán), the written form of Chinese used from the 5th century BCE to the early 20th century. Because Wenyan-lang’s inventive feature occurs in the nuance and humor of its multicoding between Classical Chinese and code, as a non-reader, I am exploring this language through the insights of others. Yidi Tsao, a Berlin-based artist, curator and writer, explains that the text the Hello World actually prints (you can see it between the quotes 「「 and 」」) translates not to “Hello, World!” but closer to “Greetings to Heaven and Earth.”
I am following the evolution of the embedded Rust community and in particular the work of James Munns from Ferrous-Systems. One of the projects that caught my attention is bbqueue, a single producer, single consumer, lockless, thread safe queue, based on BipBuffers.
The main usage for this library is asynchronous handling of data coming in or going out of a peripheral, in particular when using Direct Memory Access (DMA).
When receiving data from a peripheral, say an Ethernet controller, the user has to provide a chunk of memory where a packet can be stored when it is received. Once the packet is fully received, there will usually be an interrupt to signal the arrival of the packet and another chunk of memory has to be provided very quickly in case another packet arrives during the processing of the first one. Most of the time the reception and the processing of the data will be handled in different contexts, for example an interrupt handler and a thread. The packet has to be decoded through various stacks of protocol and in the end the data has to be presented to the user. Copying potentially large blocks of data as it moves through the protocol stacks to the user must be minimized for the sake of performance.
Sometimes data structures need to mutate one or more of their fields even when they are declared immutable. This may sound surprising at first, but you’ve probably relied on this behavior before, like when you clone a reference counted wrapper such as
Rc, or when you lock a
Mutex. However, in Rust, mutability is an all-or-nothing attribute: either a variable is declared as mutable and all of its fields are also mutable (if it is a
struct), or it’s declared immutable and so are all of its fields. How do we get selective field mutability? Something mysterious is afoot.