Write Rust events with ease

Picturesque photo of a mountain range
Picturesque photo of a mountain range
Photo by J Scott Rakozy on Unsplash

I recently wrote an article about writing events in Rust. I must admit I wasn’t entirely satisfied with the solution I came to. My previous code used a clunky macro-capture pattern to define a signal and produced receivers that couldn’t easily transform the data like event receivers should be expected to do.

Thus, we’d have to write custom transformations for each of our receivers — not very ergonomic. I decided I could do better! What I came up with is ultimately declared like this:

Code that both declares and uses the variables for our emitter and receivers, emitter1, r1, and r2.
Code that both declares and uses the variables for our emitter and receivers, emitter1, r1, and r2.

In this way, we can both declare and use the variables for our emitter and receivers, emitter1, r1, and r2. We can use any names we want for our identifiers. By using repeating captures, we can have multiple receivers with variable functionality by pairing them with a unique closure. …


Building and Collapsing Expression Trees

Image for post
Image for post
Photo by Alex Perri on Unsplash

Since Rust has become so wildly popular and has amassed such a dedicated following, I decided to put down my beloved JS and learn Rust recently. And I must say, it’s not a journey for the faint of heart. Luckily (although misleading in some rare occasions) the compiler is your best friend — it will nearly always tell you what you did wrong, and will even offer helpful solutions. After you spend some time with it and get over the steep initial learning curve, you’ll begin to love Rust — I do!

Today I’d like to implement my favorite data structure, in Rust flavor: the Binary Tree. A Binary Tree is a typical tree — it consists of Nodes that hold it’s (potentially deeply) nested values. The special thing about a Binary Tree is that its nodes have only two child values: a Left and a Right. Typically, Binary Trees are used to represent things like mathematics expressions, but could be used to handle parsing lightweight grammars. For our implementation it will also be convenient for our nodes to know what type of operation they represent. We’ll try to make it generic so as to make the underlying structure type-agnostic. Here’s a simple representation of a Binary…


Image for post
Image for post
Photo by Weston MacKinnon on Unsplash

I’ve been playing around with Rust a lot lately. I was really inspired by a guy named Tom Leys, who used the Godot game engine’s NativeScript feature combined with the Godot C bindings for Rust to make a crazy space factory game. Seems to be in development still but looks pretty amazing. You can read about his adventure here. But Rust is gaining ground everywhere lately, it would seem. Rust is a very capable language and you have a lot of options (every option?) when it comes to build targets.

Anyway, I love the luxury of having access to functions like compose in JavaScript. I finally am feeling like I’m not fighting Rust’s compiler to write code, so I decided to dive into the Rust Macro system. And I must say, once you understand the rules it’s really nice to work with. …


Handling Impure Actions in a Pure Application

Image for post
Image for post
Photo by Héctor J. Rivas on Unsplash

If you’ve been studying up on Functional Programming in JS, you’ve probably heard about pure and impure functions, and side-effects. If not, I’ll quickly recap — a pure function is one that when given the same parameter any number of times, for each of those invocations it will produce the same result. Pure functions should also have a tangible result. Impure functions on the other hand may produce a different result when given the same parameters. Something non-static is happening behind the scenes in these impure functions. Those non-static factors are called side-effects. Functional programmers always say, ‘avoid impure functions, avoid side-effects’, etc. The only problem is, eventually you’ll need to incur side-effects. This is because the meat of an application is often the side-effecting portion. …


Monad Explained Simply

Image for post
Image for post
Photo by Michael Dziedzic on Unsplash

Monads are all-the-rage these days in the JS world. I’d be surprised if any serious JS developer hadn’t heard of Monads. But just in case you haven’t, I like to describe a monad as a fancy box. It’s a special box. You can’t (well, you shouldn’t be able to) see exactly what’s inside the box, but you can know that this box holds values of a certain type, and exposes three primary operators with which we can modify or take out the content of that box. Those operations are what I call the Monad Interface.

OK, so Monad isn’t exactly an interface. But in JS we can think of it as one. As a quick refresher, in a strongly typed language (such as the C family) an interface is the definition of what a class object has. If you’ve ever used TypeScript, you know that an interface describes the expected shape of something — like an object, or the parameters and return value of a function. What an interface boils down to is a contract to be upheld by anything that implements that interface, but it gives no specifics of the implementation. It’s useful to think of things as interfaces, because interfaces are abstract. Abstraction is one of the most useful concepts in computer science. To say something is abstract is to express how far away it is from machine code. The further away from machine code we can be the better because humans brains understand the abstraction of languages; only machines are made to read machine code. The best part about an interface is that it is a cost-free abstraction. If you write one in TypeScript, for example, it doesn’t even generate code in the end, it only compile-time checks that the interface’s contract is upheld. In bare JS, an interface is only in the mind of the author. So we can only uphold an interface’s contract by assuring on our own that all of the expected methods and fields are correctly implemented — there are no compile time checks to help you out. But that’s OK, because the dynamically-typed nature of JS comes with some other very nice benefits, which I won’t necessarily discuss just this moment. …


Implementing Monads in Rust

Image for post
Image for post
Photo by Zane Lee on Unsplash

I’ve done a lot of writing about functional programming. But mostly in JavaScript. I love the simplicity of declarations that are possible thanks to JavaScript’s dynamic typing system. It makes defining generic things very easy — a concept that is much more complicated in strongly typed languages. One generic concept that I love expressing in JS is the functional keystone known as the Monad. A Monad is an encapsulation of an associative binary operation. In other words, you can call map on it with an appropriate function parameter to change the inner value — even its type. It wraps some value and and allows us to adhere to a simple interface to act on that value. So how can I express this highly generic concept in Rust? …


Defining and implementing reusable event signals

Image for post
Image for post
Photo by Mickey O'neil on Unsplash

(I’ve recently released an upgraded version of this article that explains a better solution, but go ahead and read them in sequence if you like!)

Rust is a young and exciting systems language that has a lot of potential in a vast range of applications. Rust programs can be built to target just about any platform. I wouldn’t be surprised if people started using Rust to write things like operating systems (and people already are using Rust to build cool things). The most incredible part about Rust is that it’s memory safe — a whole category of industry crippling insidious bugs don’t even exist in Rust. Microsoft has even endorsed Rust for future projects. Maybe some day it will even mature to replace C family languages! …


Recreating one of GitHub’s most popular libraries in Rust

a rust-covered machinery part sitting on rocks
a rust-covered machinery part sitting on rocks
Photo by Felix Brendler on Unsplash

Rust is an amazing language, boasting speeds comparable to C, and abstraction comparable to high-level languages like C# or TypeScript. It piqued my interest a few years back — but that’s as far as I went with it (merely interested). I have a pretty solid (and fanatically functional) JavaScript background, but I have always felt like I was a front-end dev only by default. There is such high availability of classic web technology guidance at the tips of my googling fingers! I have done a bit of programmerly soul-searching of late in an attempt to find my niche and really build something. And since Rust can literally go anywhere (?) …


Memory, Iterators, Pointers, and Recursive Types

Image for post
Image for post
Photo by Patrick Robert Doyle on Unsplash

I’ve been pretty dedicated to learning and sharing about Rust lately. I also have an ongoing thing with data structures — they’re like little puzzle boxes; like a conglomerate of abstract simple-machines whose unique structures have inherent advantages and disadvantages. And even more so in Rust, since I get to think about how they actually are laid out in memory. So I decided I’d try to implement a Linked List in Rust flavor. …


Making Our Binary Tree Better

Image for post
Image for post
Photo by Matt Lamers on Unsplash

Rust is a beautiful and complex beast. Despite being a truly low-level language, it has amazing features and abstractions available for us as developers. I personally have a (functional) JavaScript and C# background, and am rather new to Rust by comparison. So it amazes me when I see elegantly written Rust, especially code that really takes advantage of the awesome language features. I recently released this article about Binary Trees in Rust. I received a bit of feedback on Reddit:

Image for post
Image for post

Coriolinus also sent me a helpful Rust playground link. I’m going to walk through the modifications they’ve made to my code and why I actually really like their implementation! In the end we’ll simplify the code significantly, drop unnecessary wrapper types, make our code more generic, and also reduce the footprint of tree construction. If you’re new to Rust you’ll also get an opportunity to learn about Rust closures and pointer types— all thanks to coriolinus’ refactor. …

About

Ross

Programming maniac, #JavaScript zealot. I'm crazy about #FunctionalProgramming and I love Rust.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store