PurelyFunctional.tv Newsletter 440: Pub/sub done really well

Free Beginner Workshop

From OO to Clojure Workshop!

Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.

Issue 440 - August 23, 2021 · Archives · Subscribe

Future computing 🤖

Pub/sub done really well

We need to find new ways of wasting computer resources. —Alan Kay

The internet is inefficient. IP packets are a bit like sending a book through the mail one page at a time. Imagine putting each book page into a separate, addressed envelope and sending them through the mail. The receiver has to put them back together in order. And as pages show up, you send a letter back periodically saying which pages you got. The sender has to figure out which pages you didn't get and resend them. Compared with sending the book in a box, it seems pretty inefficient.

But it gets worse.

A street address pinpoints an exact location on the face of the earth. If I write your address on an envelope, we can easily translate it into driving directions so the postal carrier can deliver it to your house.

An IP packet isn't so lucky. There is no central place to look up the directions to an IP address. All a computer can say is, "it's not on this network; let me ask my router." And what does the router do if it's not on its network? The same: "Let me ask my router."

It's a bit like you go to mail a letter, and the post office says, "hmm, that's not in this city, let me send it to the state level." When it arrives at the state postal sorting center, someone reads the address and says, "well, that's not this state; let me see if the national center knows what to do with it." Etc. Until someone knows what to do with it.

And then, of course, the mail carrier's roads are half under construction. And you don't know which ones are under construction until you go down them. If you hit a dead-end, you try again.

The internet trades efficiency for robustness. We can add new nodes to the network without central control. We can install new network lines without consulting anyone. And outages don't cause major failure modes. Even if a shark chews through the sub-Atlantic lines, America can talk to Europe through Asia. And that happens automatically because of the same causes of inefficiency. The result is an organic, adaptive, global network.

Alan Kay, in a talk called "Is it really Complex? Or did we just make it complicated?", describes a publish/subscribe mechanism that is also inefficient but might give us more robustness. The gist of it is that nodes on the network describe what they need and what they produce. An agent connects products to needs. In this way, as Kay describes it, it's "receive only" because the problem with sending is knowing where to send it.

Imagine this: Just like we have an IP packet that describes the destination with only a vague hope of finding its way there, why can't we encode a request for a need, route it higher and higher, until something reads it and realizes it can fulfill it? If packet routing is a lousy way to send a book through the mail, this pub/sub model is a message in a bottle. You describe your desire to be rescued and hope the currents carry it to someone who can save you.

The question is: How do you describe needs?

eBook update! 📘

The Kindle and ePub versions of Grokking Simplicity have been updated! They are readable! You can get them on Amazon or at Manning.com (preferred; use coupon code TSSIMPLICITY for 50% off).

If you previously tried the ebook formats, please try them again. Manning has done a good job of reworking the layout for small screens.

I still recommend the paperback version. Each page was painstakingly laid out to address a topic. E-readers do their own layout and have small screens. They are acceptable, but not ideal for this kind of book. Get the paper copy!

Whatever version you decide to get, authors live or die based on Amazon reviews. Please leave a 5-star rating and review on Amazon because it helps others find the book and it helps me sell it.

Pandemic update 😷

I know a lot of people are going through tougher times than I am. If you, for any reason, can't afford my courses, and you think the courses will help you, please hit reply and I will set you up. It's a small gesture I can make, but it might help.

I don't want to shame you or anybody that we should be using this time to work on our skills. The number one priority is your health and safety. I know I haven't been able to work very much, let alone learn some new skill. But if learning Clojure is important to you, and you can't afford it, just hit reply and I'll set you up. Keeping busy can keep us sane.

Stay healthy. Wash your hands. Wear a mask. Get vaccinated if you can. Take care of loved ones.

Clojure Challenge 🤔

Last issue's challenge

Issue 439

This week's challenge

Dealing elements

There's a function in clojure.core called partition-all. It creates subsequences of a given maximum size.

(partition-all 3 [1 2 3 4 5 6 7 8]);=> [[1 2 3] [4 5 6] [7 8]]

Notice that the first sequence gets the first three elements, the second sequence gets the second three elements, etc. We could get the original sequence again by concatenating the sequences back together.

Your task is to write a function that deals out the cards more evenly. That is, the first element goes into the first sequence, the second element goes into the second sequence, etc. We're going to write two versions of this function.

Version one takes the maximum size of the subsequence. That means the number of subsequences will depend on the size of the given sequence.

;; at most 3 elements in each subsequence
(deal-max 3 [1 2 3 4 5 6 7 8]) ;=> [[1 4 7] [2 5 8] [3 6]]

Note that we can put these sequences back together with interleave (except for the behavior when you have a short sequence).

Version two takes the number of subsequences. It is variable in the size of the subsequence.

;; deal out 4 subsequences
(deal-out 4 [1 2 3 4 5 6 7 8]) ;=> [[1 5] [2 6] [3 7] [4 8]]

Note that this also can be put back together with interleave.

Write deal-max and deal-out. How do the implementations compare? Which is easier to write?

Thanks to this site for the problem idea, where it is rated Very Hard in JavaScript. The problem has been modified.

Please submit your solutions as comments on this gist.

Rock on!
Eric Normand