RC W8 - Think before you build

Compilers

Lesson of the week - when screen sharing on Zoom, disconnect additional monitor(s).

I've been working on porting Crafting Interpreters from C to Python, and this naturally involves making some adjustments. First is avoiding circular dependencies in the Python version. I imagine this is less of an issue in C as the linking/compilation stage simply moves all the source code into a single blob. Second is separating out pointers to arrays into arrays and arrays indices.

I'm happy with the progress so far, but now I'm at implementing functions and the interactions are getting a lot more complex. In particular is how variable scopes interact with function call frames; I'm constantly puzzled on how to debug (and if my adjustments overlooked more fundamental underpinnings of how things work). I know, last week I was all about "let's set up guardrails" to make reasoning about the code easier - it's all there now and I'm still stuck.

I'm contemplating starting over with my own custom implementation, but with function support right out of the door (or at least, with the minimal infrastructure needed for to the implementation). I anticipate this involves a lot more sketching designs on paper even before the first line of code - how fun!

The other fun thing with creating your own toy implementation is selecting your own set of reserved words. I've switched from 'var' to 'let' (to suppress prior trauma of learning JavaScript pre-ES6) and from 'this' to 'self'.

WebAssembly

New technology can be rough around the edges. Earlier in my time at RC I wanted to set up Python-Rust interop via WebAssembly. This involves compiling Rust functions to WebAssembly and loading the .wasm binaries in Python, in order to benefit from performance improvements.

I finally got this to work, example here. Calculating the 10,000th prime in Python with Rust achieves a 10x speedup vs pure Python. What's interesting is this closed issue, which might have been what tripped me up previously. The issue close date? August 24, 2020.

Content: What you'll wish you'd known

Paul Graham was invited to speak at a high school in 2005, but somehow the school authorities vetoed the plan. I wonder if they're kicking themselves now. 

http://www.paulgraham.com/hs.html

The excerpt below is a highlight from a recent re-reading of the talk he prepared. On the back of this I'm going to indulge myself on something I've been curious about for a while - design.

If you're deciding between two projects, choose whichever seems most fun. If one blows up in your face, start another. Repeat till, like an internal combustion engine, the process becomes self-sustaining, and each project generates the next one. (This could take years.)

The excerpt that caught my eye on the first reading emphasizes the importance of experience, and draws parallels with Rilke's quote.

If it takes years to articulate great questions, what do you do now, at sixteen? Work toward finding one. Great questions don't appear suddenly. They gradually congeal in your head. And what makes them congeal is experience.

Content: Experiments at Airbnb

Data science at Airbnb had a mixed reputation a few years back, but something they did very well was marketing the practice through content and events. The well-curated blog attracted many to apply for a role. The post I enjoyed the most discussed best practices for A/B testing - on duration of experiments, understanding context and setting up guardrails.

https://medium.com/airbnb-engineering/experiments-at-airbnb-e2db3abf39e7

Speaking of experiments and causal inference, I'm adding causal forests to the list of things to review...

Content: Indie Game

I'm fascinated how distribution (or perhaps in a more direct way, monetization) plays a role in content creation. Jonathan Blow in his talk discusses parallels between TV shows and computer games when each medium moves from gatekeepers to direct-to-consumer distribution - highly recommended.

What's also super fascinating is seeing the travails of indie game developers. The attention to detail, the degree of craftsmanship and the pursuit of perfection - I can't help but think of Jiro.

Content: Empty Streets (Haji + Emanuel Remix)

This mix is legendary, and amusingly, apt for 2020.

Content: Think before you build

I remember reading this post, spending hours on Google looking for it again, and feeling very sad when I couldn't find it. When I was compiling the content I wanted to share on this blog, I looked through my notes and there it was. The lone URL, no annotations, no comments. It was like finding treasure. I was overjoyed.

Perhaps there's a dream job there somewhere. Content finder?

http://www.slate.com/id/2289527

The post is about how computers have done wonders for productivity, but in many cases speed compensates for the lack of rigorous thought. It's a reminder to pause and reflect before we write that first line of code, and as per a previous post, to cut through to what matters by thinking clearly from first principles.

What kept me looking for this post were the immortal words of Renzo Piano.

But architecture is about thinking. It's about slowness in some way. You need time. The bad thing about computers is that they make everything run very fast, so fast that you can have a baby in nine weeks instead of nine months. But you still need nine months, not nine weeks, to make a baby.

RC W5D5 - Speed without wizardry

WebAssembly

Nick Fitzgerald has a post on using Rust compiled to WebAssembly to replace performance-sensitive parts of the JavaScript library source-map, achieving a 6x speedup. Vyacheslav Egorov responded with his own post on matching the speedups with JavaScript alone. The profiling and optimization process is detailed and very cool to see. In the third and final post, Fitzgerald discussed the end result of an 11x speedup of the Rust and WebAssembly implementation by incorporating ideas from both sources.

What I find illuminating is the process in which these optimizations are at obtained (as per the title). The JavaScript version resulted in hard-to-maintain code in the name of performance, whereas in Rust one was able to get the best of both worlds - clear expression of interest and optimal runtime performance.

Excessive allocation rates make any garbage collector (or malloc and free implementation) a bottleneck. Monomorphization and inlining are crucial to eking out performance in both Rust and JavaScript. Algorithms transcend programming languages. But a distinction between JavaScript and Rust+WebAssembly emerges when we consider the effort required to attain inlining and monomorphization, or to avoid allocations.

Rust lets us explicitly state our desires to the compiler, we can rely on the optimizations occurring. Rust's natural idioms guide us towards fast code, so we don’t have to be performance wizards to get fast code. In JavaScript, on the other hand, we must communicate with oblique incantations to match each JavaScript engine’s JIT’s heuristics.

Content: Custodians of the custard

Antiga Confeitaria de Belém is a cafe/bakery in the Lisbon suburb of Belém that's been making Portuguese egg tarts since 1837. The secret recipe of the filling is entrusted to three pastry chefs, the most recent one after 20 years in the kitchen! The quest for the perfect tart, and resisting the temptation to move to the mass market, makes for a charming story (enclosed below).

Content: Somewhere Inside

I love Tiësto, and I especially love how the track comes together with Julie Thompson's energetic vocals.

Content: POP/STARS

I've always been fascinated by new mediums that inspire new business models. Defense of the Ancients (more commonly-known by its acronym DotA) started as a fan-made modification of the computer game Warcraft 3. The game developer Valve then hired DotA's lead designer to develop a sequel to the highly popular 'mod'. DotA 2 was released for free, but monetized through sales of cosmetic enhancements for the game characters (referred to as 'skins').

To promote the shift to DotA 2, Valve organized a gaming competition for top teams from all over the world called The International. The International started in 2011 with a $1.6mm prize pool. In 2013, Valve started crowdfunding the prize pool through sales of an in-game battle pass. The prize pool grew to $3mm and was already the largest prize pool for any e-sports competition. By 2020 the prize pool ballooned to $34mm.

The featured video is actually from League of Legends, DotA's main competitor. League has Worlds, their own version of The International, as well as a talented team of composers, songwriters and producers to orchestrate cinematic music for the opening ceremony. The musical score for Worlds 2018 was performed by a virtual K-pop group called K/DA, created especially for the occasion. The song POP/STARS went viral, receiving 5 million views within 24 hours.

How did this start? To promote sales of skins.

Content: Startup

I read Jerry Kaplan's Startup from time to time, and always amazed how his struggles as a founder in the late 1980s are ever familiar today - raising money, hiring talent, finding product-market fit, dealing with partners and competitors (while constantly assessing which is which). I particularly enjoy the framing of the venture as a game.

It begins with an aspiring entrepreneur who is willing to step right up and be tested. As in many other games, the player starts with an artificial currency - in this case the stock of a new venture. The goal is simple: increase the value of the entrepreneurs' shares, because when the game is over, these can be cashed in for real money. The trick is to swap some of the stock for three resources - ideas, money and people - then use these resources to increase the value of the remaining stock.

I know. It's become a cliché. I'm still a believer.

It is comforting to know that the human impulse to make the world a better place is not today confined to the young or the foolish. It is alive and well among the people that live and work in Silicon Valley.


RC W5D3 - Why doctors hate their computers

WebAssembly

The primary use case for WebAssembly in recent discussions is to enable languages other than JavaScript to run in the browser. The .wasm format, however, could itself become the standard in portable binaries.

Suppose we wanted to speed up Python code with Rust bindings. This requires the Rust code to be compiled to a dynamic library, i.e. .dylib file on Mac, .so on Linux, or .dll on Windows, which can then be imported in Python with a standard Python import (discussion here).

Now suppose the Rust code was compiled to a .wasm file instead. We can similarly import the .wasm file into Python with wasmtime (example here). Since the .wasm format is OS-independent, I believe we now have a portable version of the dynamic library.

Neural networks

At Square, I ran workshops on machine learning and (separately) on neural networks. I presented on the latter today at RC.

Starting with the most basic representation of a neural network as matrix operations, we build it up in stages - reducing loss systematically, capturing non-linear behavior, and introducing regularization with dropout layers. We would train a convolutional neural network by the end of the session, highlighting the improved performance when the model architecture incorporates the 2-dimensional structure of image data.

The Github repo has been updated to Python 3 and the latest Keras API. Then and now, I couldn't resist re-iterating Andrej Karpathy's advice to use model training best practices i.e. "don't be a hero".

Content: Why doctors hate their computers

At the start of my coffee chat with SengMing, I told him I was choosing between New Yorker articles to feature and had just opened a browser tab on Atul Gawande's article. SengMing then shared how much he loved the article; this made the decision easy.

It was published in 2018 but I enjoyed reading it so much more this time around. The references to pain points in the user experience were all too familiar - too many clicks, too difficult to find relevant information, too complicated to use. The issues pertaining to software development are universal except in this case, to use Sengming's words, the quality "literally affects life and death". 

https://www.newyorker.com/magazine/2018/11/12/why-doctors-hate-their-computers

Consider that, in recent years, one of the fastest-growing occupations in health care has been medical-scribe work, a field that hardly existed before electronic medical records. Medical scribes are trained assistants who work alongside physicians to take computer-related tasks off their hands. This fix is, admittedly, a little ridiculous. We replaced paper with computers because paper was inefficient. Now computers have become inefficient, so we’re hiring more humans. And it sort of works.

RC W5D2 - Relentlessly resourceful

WebAssembly

I ran a demo on WebAssembly at Presentations last Friday. I had to gloss over a number of details given the 5-minute format, so I did an extended version today.

As per Lin Clark's post, WebAssembly is "taking code written in programming languages other than JavaScript and running that code in the browser". Today I added how a major project underway is a standalone runtime so .wasm binaries can be run independent of the browser.

Re: portability, I previously used the following image with C, C++ and Rust as starting points. These so-called system languages are particularly suitable for compiling to WebAssembly given the absence of a garbage collector and minimal language runtime. I'm often confused by the term runtime, more detailed explanation here.

Re: performance, I had mentioned how WebAssembly gets to skip some execution steps compared to JavaScript. The wrinkle is the JIT currently doesn't know how to deal with WebAssembly directly, limiting speed gains (see 'trampolining' here). In fact, the main example I've come across in practice is a Figma post focusing on speed ups from smaller binaries.

Re: security, I had skipped this entirely. I provided a high-level overview of the ArrayBuffer today.

In the demo, I compiled and ran WebAssembly. I spoke a bit more on future improvements on the roadmap (see 'post MVP features' here), in particular access to the DOM and direct loading of WebAssembly modules (hence no need for a web server).

Microbenchmarks

Reviewing the feedback on the 5-minute presentation, comparing the performance of WebAssembly against JavaScript was at the top of the list. What's amusing is I wanted to learn WebAssembly but ended up having newfound respect for the V8 JavaScript engine.

I started with prime number generation, and puzzled how WebAssembly ran slower against JavaScript. Then I realized how even the Rust implementation ran slower against JavaScript. Andrey found a post on this exact comparison. My sense was the execution involved one main loop, which provided a textbook example for JIT optimization.

Moving on, I found a post on Julia microbenchmarks and thought I can simply use the tests where JavaScript wasn't as fast. Running matrix multiply, I had LLVM issues and discovered I needed to install Fortran to use BLAS. Oh boy. Post-installation I might still have been missing some symlinks, so kept this on hold for the time being.

With quicksort, Rust completed in half the time of JavaScript but I didn't have time to set this up in the browser before the presentation. I did have the n-queens problem as an example where Rust (compiled to WebAssembly) ran in half the time of JavaScript, in the browser.

When running microbenchmarks in the past, it's always been about comparing two algorithms in the same language. Cross-language benchmarks are fascinating. Do you replicate step-by-step, or rewrite in the way the language performs best (hence needing to know best practices in both languages)? If the latter, would there be more subtlety when comparing imperative against functional languages?

The other issue I had was microbenchmarking in the browser. If you set up the start and end times in JavaScript, does this mean you can't time the parsing stage (since by that point the code is already parsed)?

Content: 15 startups in 21 months

In his essay, Paul Graham isolated the key quality needed in a founder - relentless resourceful(ness). The story that often gets told is of Airbnb, where the co-founders managed to extend their runway by selling cereal during the 2008 Presidential Elections. The story I quite like is actually this one.

https://medium.com/@mecolalu/how-we-did-15-startups-in-21-months-a7008c8f2c97

There's a happy ending; I won't spoil it more than that.

RC W5D1 - Connecting the dots

WebAssembly

Following up on the 'watch this space' declaration in last week's post, I created a Github repo on minimal examples to compile and run WebAssembly. It's designed to help consider different options - whether it be Rust or .wat as a starting point, whether to run in the browser or with an independent runtime, whether to extend with Rust-JavaScript interoperability or even go full stack Rust.

In summary, a starting point to those new to WebAssembly to construct a mental model and build on top of.

Learning WebAssembly, I've gone down the path of reading up more on how the browser works. I had actually mentioned wanting to review this in my first week of RC. This time, however, feels a lot more engaging. There's a lot more concepts to make connections with. Most importantly it feels more fun this way; it's not something looked into simply to solve a problem.

Python

Vinayak recommended a PyCon talk by Russell Keith-Magee at our coffee chat last week. I had the chance to watch this talk over the weekend. The talk was illuminating.

First, in thinking about the future of Python, one needs to think about black swan events. A black swan event is an event that is a surprise to the observer with a major effect on the world, but can be easily in explained in hindsight. This being the case, the best way to avoid being on the wrong side of a black swan event is to actively challenge one's own assumptions. The example he used was America's Cup; adhering to this principle has injected innovation into the sailing competition, breathing new life and excitement for many years to come.

Next was the framing of WebAssembly as Python's (or for that matter, all programming language's) black swan. WebAssembly started life as a research project to identify the set of primitive JavaScript operations that will execute in modern browser engines. The result of this work is the ability to run languages other than JavaScript in the browser, and do so in a fast and secure way. He's essentially throwing down the gauntlet, galvanizing the community to embrace this new paradigm instead of simply continuing to do what Python is good at. In this regard, perhaps be more like... the Rust community?

The final point that hit home was Keith-Magee's experience of burnout as a maintainer in the open source community. It's very disheartening to hear some members he had to deal with, who receive a product at no cost but somehow feel a strong sense of entitlement. I felt a renewed sense of appreciation for the open source community, and a continued desire to contribute.

It turned out the talk Vinayak recommended was the talk at PyCon AU 2019! This was also very good, and is more practical re: Python and WebAssembly. The talk covers a bit of history of WebAssembly, tools to help compile Python to WebAssembly, and the future for Python on the web. In a previous post I described how WebAssembly reminded me of Java, it's curious hearing Keith-Magee describe how "wasm has delivered on the promise Java made".

OK one last note about previous posts - I mentioned how some open source projects may need a bit of hand holding. Keith-Magee's current project is called BeeWare and has a spectacular first-time contributors page.

Content: Climbing to the top

OK. Today I'm not just overloading with previous posts but also with content. Things are slowly coming together. I'm reminded of Rainer Maria Rilke in Letters to a Young Poet.

I would like to beg you dear Sir, as well as I can, to have patience with everything unresolved in your heart and try to love the questions themselves as if they were locked rooms or books written in a very foreign language. Don’t search for the answers, which could not be given to you now, because you would not be able to live them. And the point is to live everything. Live the questions now. Perhaps then, someday far in the future, you will gradually, without even noticing it, live your way into the answer.

I'm reminded of Steve Job's Stanford commencement speech on how you can't connect the dots moving forward, you can only connect them looking backwards, so you have to trust that the dots will somehow connect in the future.

That being said, I've only just gotten started. I'm reminded of Terence Tao who, despite all his achievements, speaks modestly of the journey still to come.

https://www.latimes.com/local/lanow/la-me-ln-ucla-math-prize-20140626-story.html

You want to get to the top of the cliff. But that’s not what you focus on immediately. You focus on the next ledge just beyond your reach, because you need to do one clever thing to get up there. And then once you get there, you do it again. A lot of this is rather boring and not very glamorous. But you can’t jump cliffs in a single bound.

RC W4D4 - The only intro you'll need

WebAssembly

I was preparing slides on WebAssembly today when I came across Lin Clark's cartoon intros. It's spectacular. I wished it was the first thing I read on the topic; it appears l'esprit de l'escalier is a thing for content too.

The background articles also provide helpful context and an easy read.

It's amazing how Google, Mozilla, Apple and Microsoft actually got together and agreed on the specs. The project has now expanded beyond the browser, with wasmtime as an independent runtime and WASI as the unified interface. In addition to its own foundation, called the Bytecode Alliance.

I do wonder, more broadly, if the technology will further consolidate the dominance that large tech companies have, or will a thousand startups bloom? Will there be a lot of end users who like it but only few love? What will the killer app be (or will there actually be one)? I was late to notice iPhones and bitcoin as platforms. I'm ecstatic at being able to follow the WebAssembly life cycle from an early stage, and see where it goes from here.

Julia

I woke up in the middle of the night, had trouble going back to sleep and actually looked up why Julia is 1-indexed (or rather, why most languages are 0-indexed). I came across this post which had the following quote.

So: the technical reason we started counting arrays at zero is that in the mid-1960’s, you could shave a few cycles off of a program’s compilation time on an IBM 7094. The social reason is that we had to save every cycle we could, because if the job didn’t finish fast it might not finish at all and you never know when you’re getting bumped off the hardware...

Intuitively it sort of make sense - if you start from zero it's a no-op vs having to do an `add immediate`. Fascinating.

Content: Dev Ops

This week's feature is Increment's post on cloud migration; it fits in nicely with a friend joining Stripe this week. I enjoyed reading how Netflix introduced planned instance failures so the on-call team can to deal with it during business hours. What's particularly impressive is the decision to implement this workflow at a time of rapid growth, forcing adoption of industry best practice at the same time as battling other fires.

https://increment.com/cloud/case-studies-in-cloud-migration

A hat tip to the marketing team who coined the term 'chaos engineering' from 'chaos monkeys'.

RC W4D2 - Let's try something different

On writing

It's September 1, let's try something different. Problem - I'm usually wiped out at the end of the day to be articulate (or at least, articulate as I'd like to be). Solution - write notes throughout the day on what I plan to write about.

As an aside, my blog posts are paying off already - I referred to a previous post on the simplest way to compile Rust to WebAssembly, instead of my notes.

WebAssembly

I know. I've been going on about WebAssembly for a while now. Part of it is accountability. It's an incentive for me to learn something I keep going on about to avoid embarrassment. I do believe the responsiveness that WebAssembly provides would accelerate the shift of native apps to be run in the browser. Yesterday I realized it could be even more groundbreaking.

Sara shared what's she's reading on her blog, it's a fantastic list. The post by Andreas Rossberg on Motoko had a link to a comprehensive discussion of WebAssembly in the Communications to the ACM (direct link here), as well as the following quote.

Wasm’s main difference compared to other virtual machines is that it is not optimized for any specific programming language but merely abstracts the underlying hardware, with a byte code directly corresponding to the instructions and memory model of modern CPUs. On top of that, Wasm supports sandboxing through strong modularity and a rigid mathematical specification that ensures that execution is safe, free of undefined behaviour, and (almost) entirely deterministic. Moreover, these properties actually have a machine-verified mathematical proof!

This is in addition to Solomon Hykes, the CTO of Docker, tweeting how had WebAssembly existed in 2008, there would have been no need for Docker. Now I'm puzzled. Why isn't there more hype?

What I can say is the learning resources seem sparse. Perhaps due to things changing quickly. I had been trying to tweak a number of Hello World examples without much success, along the way discovering the myriad of tools available. I gave up and decided to work on the Programming WebAssembly with Rust book instead. The book uses wasm-bindgen for Rust-JavaScript interoperability, but it's not immediately clear how using wasm-pack in addition would help.

I've decided I'm going to come up with my own resources. Watch this space.

The advantage of going through a book is comprehensiveness. In the book I found the answer to a previous question posed - why do you need a web server to run WebAssembly? It turns out cross-scripting rules in the browser blocks reads to the file system.

Re: portability, when I compile Rust on my laptop, the base target is stable-x86_64-apple-darwin, i.e. version-processor-OS. For WebAssembly, it's wasm32-unknown-unknown, i.e. it's designed to be compile once, run everywhere!

Java

Last week I briefly mentioned portability of C, let's complete that thread. C binaries would only work for a specific OS, so C when compiled for Linux would not work on Windows. Java, however, is compiled to Java bytecode that would run on any Java VM by design. Thus Java achieves portability across operating systems, which extends to all JVM-based languages - Clojure, Groovy, Kotlin, Scala. It's the original compile once, run everywhere.

Content: Python interpreters

Coming across RustPython made me look up Allison Kaptur's post on 500 lines or less: A Python interpreter written in Python.

http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html

I then discovered this is something she worked on while at RC!

RC W3D4 - Enabling business models with technology

WebAssembly

Every Thursday there's a Front End Hack and Tell - we commit to working on something front end-related at the start of the session, and circle back at the end to share what we came up with. I've been learning Rust to get into WebAssembly, but so far still ramping up on the Rust part. I learned MIPS Assembly a while ago, and thought a refresher might help me approach WebAssembly from a different angle.

This didn't quite work out as planned. The notes I have from that time assumed I'd be revising the material, as opposed to picking it up practically from scratch. Plus WebAssembly is a stack machine, not a register-based one like MIPS.

C

I spent the rest of the hacking time on Rust, but my refresher reminded me of the story of how C came about. Assembly can be thought of a set of instructions that the processor understands. For example, `add $t1, $t2, $t3` means add the values in $t2 and $t3 then place it in $t1. The tricky bit is each processor has its own instruction set, so you'll need to compose one set of instructions for a MIPS processor and a different set for an Intel x86.

The idea behind C is a language that's one layer up from the processor (so it works across both), but also sufficiently low level so things run fast. What did the creators of C do once they're done? They created Unix.

Content: Design

Having featured data science and product management, let's talk about design. First, a preamble.

Square allowed every person who had a smartphone the ability to accept credit cards. The problem was, now every fraudster could use Square to cash out stolen credit cards. Square solved this problem with machine learning. By leveraging the improved ability of ML models to flag suspicious payments, ability to accept credit cards is made accessible.

If Square is an example of a business model that becomes viable (amongst other things) on the back of machine learning, can we think about the analogue for, say, WebAssembly? Here Figma comes to mind - WebAssembly allows the functionality of the Adobe design suite to be run in the browser, but with the performance of a native app.

https://kwokchain.com/2020/06/19/why-figma-wins

What I especially loved with the post is the framing of tighter iteration cycles. Before Figma, the design process involved back-and-forth between teams via e-mail. With Figma, all design and feedback are stored centrally in the cloud, allowing more context to be retained at handoffs (analogous to the same language across teams in a previous post). I must have overlooked the reference to other cool technologies deployed on the prior reading - WebGL and CRDTs.

In summary, I learned a lot working as a data scientist in a company where machine learning makes or breaks the business. I'm curious to see how new business models becomes viable with something like WebAssembly. Though first, one needs to understand WebAssembly...

RC W2D4 - The product-minded engineer

Open source

Today's open source event was on contributing to Kubernetes (hereafter, k8s). First, I should mention how open source contributors own the copyright over their contributions. If the maintainers want to change the type of licence, say, all contributors need to agree. Thus having a agreement to assign the copyright beforehand as a requirement is actually quite sensible (so not like signing an NDA).

Julian shared his experience on making open source contributions, and he's clearly into k8s. Given the number of different areas, he suggested choosing between them by first information-gathering - attending the meetings and following conversations on Slack to get a sense what the issues are. Plus k8s has lots of clients in different languages, so you can contribute even if you're less familiar with Go. Listening to his suggestions definitely makes contributing more approachable.

WebAssembly

I had planned to spend more time with urllib3, then realized I was hosting the Front End Hack and Tell. Conveniently getting WebAssembly to run in the browser had been elusive, thus something to hack on. It turns out the instructions missed out including the edition to the Cargo.toml file (source here). The package will compile with the change, and running it in the browser simply requires a web server be set up.

It's not clear to me why a web server is needed (since it's just importing a set of instructions), but repeating this for my rocket game from last week got it to run on repl.it - it's playable here (repl here)! Navigate the rocket with arrow keys and shoot with the space bar. The rocket game was featured in David Beazly's mind-blowing talk, where he livecodes a WebAssembly interpreter in Python from scratch.

Content: Product management

The extra content last week was on data science, this week we feature product management.

https://blog.pragmaticengineer.com/the-product-minded-engineer

At the end of the day, we use software to solve business problems. The better we understand the context of the problem, the more impact our solution will have.

RC W2D1 - Work hard

Twitter API

It’s Open Source Week at RC! Today I attended a few events to kick off the week, and spent time closing the circle on things I started looking at last week.

First, the Twitter API. The API doesn’t have a /bookmarks endpoint, so instead I looked at the /friends endpoint which returns the list of users you follow. The idea is to find new users to follow i.e. a ‘user recommender’. The algorithm I used was:

1. Find all users I follow (let’s call this group A)
2. Find all users these users follow (group B)
3. For every user in group B, count the number of users in group A who follow that user

I follow 291 users, so the maximum number of ‘votes’ each user in group B can get is 291. While this seems simple, there’s a rate limit of 15 API calls every 15 minutes for that endpoint i.e. 291 calls takes about 5 hours. In descending order of votes, the top 3 are:

1. Elon Musk (116 votes)
2. Barack Obama (110)
3. Bill Gates (105)

WebAssembly

The second item I looked at last week was WebAssembly. I can’t help but find it amusing how this optimization looks to shave off milliseconds off a job that takes 5 hours...

The simplest way to run WebAssembly I found was actually out of the browser with Wasmtime (Rust example here, Python here). It probably makes sense to revisit running in the browser once there's more sensible use case, or at least after the events this week.

Content: Wisdom beyond your years

Re: extra content, I absolutely adore this post Sam Altman created when he turned 30. The wisdom here is way beyond his years.

https://blog.samaltman.com/the-days-are-long-but-the-decades-are-short

On work: it’s difficult to do a great job on work you don’t care about.  And it’s hard to be totally happy/fulfilled in life if you don’t like what you do for your work.  Work very hard—a surprising number of people will be offended that you choose to work hard—but not so hard that the rest of your life passes you by.  Aim to be the best in the world at whatever you do professionally.  Even if you miss, you’ll probably end up in a pretty good place.