The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Thursday, November 01, 2018

It's the National doing something with a novel Month

November 1st.

That can mean only one thing—it's National Novel Writing Month and National Novel Generation Month.

No … wait! That's two things!

November 1st.

That can mean only two things, it's National Novel Writing Month, National Novel Generation Month and the start of the Christmas season!

No, that's three things … let me try again.

November 1th.

That can only mean three things: the start of National Novel Writing Month, the start of National Novel Generation Month, the start of the Christmas Season and the start of the tourist season here in Lower Sheol.

Darn it!

Anyway, of the many things it could mean, for me, it's the start of National Novel Generation Month and I haven't a clue what to do this year. You know, the idea of writing a novel of 50,000 fictional words is appealing. Something along the idea of:

Eavabyn oofue oh byu joewb ar byu tvueb Iehwew pveovouw, xoby Ihdou Yuhvn, xya xew e revjuv, ehe Eihb Uj, xya xew byu revjuv'w xoru. Byuov yaiwu xew wjeoo, rav byu oijguv ba giooe ob yee ba gu devvoue gn xetah jehn joouw. Byuvu xuvu raiv xeoow, e roaav ehe e vaar, xyody jeeu ahu vaaj; ehe byow vaaj dahbeohue e viwbn oaaioht daaiwbafu, e dipgaeve rav byu eowyuw, e begou, byvuu av raiv dyeovw, ehe byu guew. Ihdou Yuhvn ehe Eihb Uj yee e got gue oh ahu davhuv, ehe Eavabyn e oobbou gue oh ehabyuv davhuv. Byuvu xew ha tevvub eb eoo, ehe ha duooev—usdupb e wjeoo yaou eit oh byu tvaihe, deooue e dndoahu duooev, xyuvu byu rejoon daioe ta oh dewu ahu ar byawu tvueb xyovoxohew evawu, jotybn uhaity ba dviwy ehn giooeoht oh obw peby. Ob xew vuedyue gn e bvep eaav oh byu joeeou ar byu roaav, rvaj xyody e oeeeuv oue eaxh ohba byu wjeoo, eevi yaou.

Oh … well that was a bit easy, not even ten minutes to whip up as an example.

Methinks I'll have to ponder a bit more …

Friday, November 02, 2018

Another look into The Psychotherapy of Racter

I thought I might give my National Novel Generation Month 2015 entry, The Psychotherapy of Racter or The Descent Into Madness of Dr. Eliza, another try. I failed to complete it that year and given some feedback I received, I think I could make it a go this year. So I cleaned up the pseudo-MS-DOS I wrote (reworking some tricky logic) and started playing around again with Racter.

And then I remembered a critical reason why I failed—once Racter asks a question, it demands an answer. And sadly, Eliza generally only asks questions with the occasional statement thrown in. So I would have to modify Eliza to recognize when Racter has asked a question and somehow answer it. Then there are the times Racter demands a question, and it generally won't accept a statement in return.

So I would have to give up on Eliza for the most part, given that I need to somehow generate answers for Racter's questions. Giving up on Eliza means I would have to come up with some way to ask Racter novel questions. Then I thought Hey! I have The Wonderful Wizard of Oz handy—why not feed questions from it to Racter?

Excellent! Excuse me a minute while I attend to some business - I'll be right back. I'm back.

At this point, Racter is expecting a question, so I start feeding Racter questions, in order, from The Wonderful Wizard of Oz. It seems like as good a place as any for non sequitur questions.

What could the little woman possibly mean by calling her a sorceress, and saying she had killed the Wicked Witch of the East?
I don't know what the little could woman possibly mean by calling her a sorceress. Did you hear about the man in the moon?

After playing around with Racter (and this is a re-creation of a session for illustrative purposes) I learned just to respond to Racter's questions with “no”—it's just easier to deal with programmatically. It doesn't matter what the question asks, Racter will pretty much just roll along with an answer of “no.”

Listen to this! Picasso slapped a human who was kicking Picasso's tapeworm because the man in the moon was a buggy raver but an inspired humorist. After that, hi-techness prevailed. Isn't that just awful? But what would you expect from a humorist? Sean the computer. Do you think Picasso was happy?
Me neither. Most people are foolhardy. You know, old Luella Conner was a kind of living computer. I wonder if everyone from Detroit is like that? Racter thought this was terrific: Suddenly an appalling cosmologist who was in pain spoke that depression was enrapturing. That is programmed, living and captivating. Anyhow Sean …. Oh forget it! Next question.

The reference to Detroit is from an eariler “conversation” I had with Racter when it asked me where I'm from. You can also see Racter demanding I ask a question. Next question then …

Whatever shall we do?
Whatever shall we do?
Try again.

Okay, some questions Racter can't deal with. Moving on then …

But who was she?
Who knows? Perhaps Michael Jackson. Did you know Michael Jackson? She was in a trash can. If a worker had traveled to a watermelon patch, the funny farm would be horrified! Did you say "She was"?
I thought so. Hmm. If a communist discovered liberalism, he would be a busy communist. Why do you think you're happy?
Well, I think that if no, then Jesse Helms was Bucky Fuller's baseball companion, so there! What kind of a pet did you have back in Detroit?
Luella said you had a dog. Most people in Detroit have dogs. The dog is a very convinced beast, or would you call it believing? When Bucky Fuller visited Detroit he was bitten by a gullible dog. Next question.
Who are the Munchkins?
Who knows? Perhaps Eve. Did you know Eve? The Munchkins are in a trash can. Aviators sleep in places like a trash can. A trash can has introverts who are always flying. Have you heard about Einstein?
You'll be shocked! Einstein had forgotten much, so of course viscerality is what all geniuss want when they murder owls. Then Einstein's rattlesnake murdered Immanuel Kant, then kidnapped himself. Isn't that just awful? But what would you expect from a genius? An Immanuel Kant could have said "The Munchkins are"!

I think I could get to 50,000 words doing this, answering all questions with “no” and asking questions from some public domain book, but it's not leaving me satisfied as an entry to NaNoGemMo. I still have some pondering to do …

Monday, November 05, 2018

About that keyboard I received

My friend Mark informed me that my new keyboard is intended to be used on the airline reservation system SABRE. It makes sense that IBM would make such a keyboard, seeing how they initially developed the SABRE system. He also sent a link to a similar keyboard for sale (although it has the numeric keypad unlike mine) and the markings on the keys do match.

So I guess that means I can book flights directly. Neat!

And now for some keyboards that are completely different

And speaking of keyboards, I've come across two unique keyboards recently. The first one is a Lego Commodore-64 keyboard (which is part of a longer video about a Commodore-64 case made entirely out of Lego). The keys on the keyboard do move when hit, but due to a lucky coincidence, the Lego keycaps can be used on a real Commodore-64 keyboard. Cool!

The second keyboard is one you really have to see—a keyless keyboard! No, really! And it also works as a mouse. No, really! It looks a bit silly, but yes, it does work. No, really! Watch the video. It's bizarre. It's not something I would use (or hopefully, never have to use) but it is unique.

Tuesday, November 06, 2018

Assert yourself

Defensive programming is often touted as a better coding style, but it hides bugs. Remember, the errors we're talking about should never happen, and by safely handling them, you make it harder to write bug-free code.

… you don't want to hide bugs by programming defensively …

… No matter where you employ the defensive style, ask youself, “Am I hiding bugs in this code by using defensive programming?” If you might be, add some assertions to alert you to those bugs.

Writing Solid Code

Writing Solid Code is the rare book that forced me to change how I go about programming. I feel I'm in the minority, but after reading that book, I hate defensive programming. Don't get me wrong—at the input/output boundary, you need to be absolutely paranoid about checking data, but among functions? Not so paranoid.

And now class, story time …

Project: Cleese” was installed onto the QA system the other day, and by chance today, I noticed a core file produced by said program. This was odd, since both I and T (the QA engineer assigned to our team) had tested the program without incident.

I was able to isolate the crash to freeaddrinfo(), a function used to release memory used by getaddrinfo() when converting a domain name like “” to an IP address. A summary of the code in question:

struct addrinfo  hints;
struct addrinfo *results;
const char      *hostname;
const char      *port;
int              rc;


results  = NULL;
hostname = ... ;
port     = ... ;

// code code ;

rc = getaddrinfo(hostname,port,&hints,&results);

// code code

for ( ; results != NULL ; results = results->ai_next)
  if (results->ai_protocol == protocol)
    // code code


It's a rookie mistake but hey, it happens. The issue is that results is linked list of results, which is traversed. By the time freeaddrinfo() is called, results is now NULL. Under Linux and Mac OS-X, it seems that freeaddrinfo() checks if it's given a NULL pointer and … just does nothing if it is. It doesn't crash, but it does leak memory (it's not much in this case, since this function is only called once upon startup, but a leak is still a leak). Linux and Mac OS-X use defensive programming, probably something along the lines of:

void freeaddrinfo(struct addrinfo *info)
  if (info == NULL)
  // code code code 

which hid a bug. Solaris (which we have to use for reasons) is not so forgiving and immedately crashed.

So on Linux and Mac OS-X, how would one even test for this type of issue? The code doesn't crash. It returns results. Yes, valgrind can easily find it:

[spc]lucy:/tmp>valgrind --leak-check=full --show-reachable=yes `which lua` x.lua
==31304== Memcheck, a memory error detector.
==31304== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==31304== Using LibVEX rev 1575, a library for dynamic binary translation.
==31304== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==31304== Using valgrind-3.1.1, a dynamic binary instrumentation framework.
==31304== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==31304== For more details, rerun with: -v
==31304== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 25 from 2)
==31304== malloc/free: in use at exit: 48 bytes in 1 blocks.
==31304== malloc/free: 521 allocs, 520 frees, 43,016 bytes allocated.
==31304== For counts of detected errors, rerun with: -v
==31304== searching for pointers to 1 not-freed blocks.
==31304== checked 117,892 bytes.
==31304== 48 bytes in 1 blocks are definitely lost in loss record 1 of 1
==31304==    at 0x4004405: malloc (vg_replace_malloc.c:149)
==31304==    by 0xC40B5D: gaih_inet (in /lib/tls/
==31304==    by 0xC445DC: getaddrinfo (in /lib/tls/
==31304==    by 0x400A5FA: ???
==31304==    by 0x804EF69: luaD_precall (in /usr/local/bin/lua)
==31304==    by 0x80589E0: luaV_execute (in /usr/local/bin/lua)
==31304==    by 0x804F27C: luaD_call (in /usr/local/bin/lua)
==31304==    by 0x804F2BD: luaD_callnoyield (in /usr/local/bin/lua)
==31304==    by 0x804D145: f_call (in /usr/local/bin/lua)
==31304==    by 0x804E8AB: luaD_rawrunprotected (in /usr/local/bin/lua)
==31304==    by 0x804F6EB: luaD_pcall (in /usr/local/bin/lua)
==31304==    by 0x804D1A7: lua_pcallk (in /usr/local/bin/lua)
==31304== LEAK SUMMARY:
==31304==    definitely lost: 48 bytes in 1 blocks.
==31304==      possibly lost: 0 bytes in 0 blocks.
==31304==    still reachable: 0 bytes in 0 blocks.
==31304==         suppressed: 0 bytes in 0 blocks.

but given that “Project: Cleese” is written in Lua, a garbage collected language, memory leaks weren't foremost in the mind when testing. Had freeaddrinfo() on Linux (and Mac OS-X) not been so forgiving (or defensive) then this bug would most likely have been found immediately, and not hidden in the codebase for over five years! (I checked the history of the code in question—it had been there a long time—way before “Project: Cleese” was even started)

It is because of bugs like this that I am not a fan of defensive programming. They can hide. They can fester. They can be a nightmare to debug at 3:00 am on a production system sans a debugger.

Bohemian Rhapsody

Bunny and I saw “Bohemian Rhapsody,” the movie obstensibly about Queen but concentrates more on Freddie Mercury. Thoroughly enteraining with a masterful performance by Rami Malek as Freddie and an incredible killer sound track (how could it not be? It's Queen!) I do wish the film had gone a bit deeper with Freddie's relationship with his girlfriend and with the other band members (not only does Brian May have a Ph.D. in astrophysics, but he also worked on the New Horizons Pluto mission—he's the closest person we have to Buckaroo Banzai for crying out loud).

There's also the issues of accuracy—the movie has Freddie contracting AIDS and informing the band just prior to the LIVE AID concert where in real life, he was diagnosed with AIDS two years afterwards. This, and the other inaccuracies were probably done for story reasons, so be advised that historical accuracy is … not this movie's strong point.

Did I mention the killer concert scenes?

So even though it's not historically accurate, it's still very fun to watch (make sure to watch out for Mike Myers) and the last twenty minutes where the LIVE AID concert is reenacted, is definitely worth the price of admission.

Friday, November 09, 2018

The time that marketing failed to understand the culture

Bunny sent along a story where a company tried to market themselves at a gaming convention by handing out d20s with their logo on it. Let's just say they rolled a critical failure.

“So bitchin' luck to little Dorothy and that chick companions. May they live long in their invisible country and be superhappy!”

It's amazing how a little Internet outtage can focus the mind. I finally figured out what my NaNoGenMo 2018 entry should be and I finished it just prior to the Internet coming back online.

Years ago, I came across some programs that would translate text to some vernacular, like Jive:

It's amazin' how some little Internet outtage kin focus de mind. I finally figured out whut mah' Nashunal Novel Generashun Mond 2018 entry should be and ah' finished it plum prio' t'de Internet comin' back online. What it is, Mama!

Um … yeah … let's not speak of that one again, shall we? Good.

But I had some other ones too. One converted text to Valleyspeak, and another one converts text to sound like the Swedish Chef:

It's emezeeng hoo a leettle-a Internet oooottege-a cun fucoos zee meend. Bork Bork Bork! I feenelly feegoored oooot vhet my Neshunel Nufel Genereshun Munt 2018 intry shuoold be-a und I feenished it joost preeur tu zee Internet cumeeng beck oonleene-a. Bork Bork Bork!

Um … okay, it's not as bad as Jive—it's not like I want to burn my eyes after reading it so I'll use that one too.

My thought, which came after several failed attempts at coming up with a hook for this years NaNoGenMo, is to “translate” one of the Oz books (the first one that exceeds 50,000 words—turns out it's The Emerald City of Oz, #6 in the series) to Valleyspeak, but to have all the spoken parts “translated” to Swedish Chef.

The original programs are written in lex and I didn't feel like going through the hassle of trying to combine the two properly. So I converted each one to LPeg. That will make it easier to combine the two. The Valleyspeak program was a straightforward translation into Lua (um, pun unintended).

The Swedish Chef version however … it wasn't quite so easy. It took a close reading of the lex man page to figure out what was going on with that code (darn that lack of Intarwebs! <shakes fist at ISP>). Then about an hour or two converting that to LPeg, what with the backtracking and look-aheads going on in the original code.

Once both of those were working, I then set about combining the two. The first time I generated a “novel,” the translators flipped—at the start, it was in Valleyspeak with speech in Swedish Chef, but about halfway through it was in Swedish Chef with speech in Valleyspeak! Turned out there was some speech that spanned paragraphs, and as per the American style, when that happens, the trailing quote is left off the initial paragraph.

Some more fighting code, and I finally have my novel—The Valley Girl of Oz, Bjork Bjork Bjork.

So, until next year, read and enjoy.

Monday, November 12, 2018

Some Gordian Knots are easy, others, not so easy

Bunny is busy replacing the toilet in the master bathroom. Why am I not doing such work? Bunny has experience in home renovations—I just get called in for the really heavy work like hauling the heavy debris away. Eventually, the call comes.

“Sean! Come here!”

“What's up?”

“I'm trying to separate the tank from the bowl, but this one screw is too tight to remove. Can you help?”

“Sure.” I try futzing with it for a few moments. “Why do you want the tank separated?”

“Because it'll make it easier to carry down to the street as trash.

“Oh,” I said, picking up a nearby hammer, “this—”


“Oh! Wait—”


“—until I can—”


“—get away!”


“—will be easy,” I said. “There you go. Gordian Knot untied.”

“Thanks, I think.”

Then more futzing around getting the old toilet scraps scooped up, and the new toilet set down and the tank installed. I'm screwing in the last of the bolts on the tank when Bunny walks up.

“Make sure the tank is level,” she said, placing a level across the tank.

“Hmm,” I said. “Looks like I need to loosen the right side here … oomph. Ooommmmmph! Errrrrrrrrrrrrarrg! It's not budging. Let me see what tools you have …”

Two hours later …



“I've tried the nut driver. I've tried the ratchet. I've tried the nut driver with vice grips (sorry about the handle there). I can't get the screw loose on the right side. That's about as level as the tank is going to get.”

“Is the nut cross-threaded?”

“Cross-threaded. Too tight. Not enough space to get leverage. All the above. It ain't moving.”

She looked at the toilet for a few moments. “Good enough. Now let me get the hose hooked up and … oh bother!”

“What's wrong?”

“The connector to the water valve is too small!”

Tuesday, November 13, 2018

I can only wish we could flush our troubles away

“I have some bad news,” said Bunny.


“Come here.” She then led me to the master bathroom. “Flush the toilet.”

“Okay.” I flush the toilet. Water comes gushing out between the bowl and the tank on the left side, which is just a tad higher than the right side. “That doesn't look right … ”

“Do you think that instead of loosening the nut, we can try to turn the bolt instead?”

“It's rubber coated, but it does have two flat sides. Let me grab a wrench and see what happens … ”

Two hours later …

Between me loosening the right side a few turns, and Bunny tightening the left side it was level. Or at least, the bubble in the level was just inside the line.

“Okay, fill the tank … here goes nothing … ”

Water again comes gushing out between the bowl and the tank.

“You know, maybe some liberal use of caulking is in order … ”

So tonight I'm gonna blog like it's 2002

[Note: If you can't load the following links, then try using The Floodgap Public Gopher Proxy to follow the links. —Editor]

I've been browsing gopher the past few months, and I was very surprised to see an old post on transclusion being referenced on an article about hypertext on gopher I was also referenced in a general post just a few days ago. Finding these links isn't easy.

With HTTP, the server is usually given the page the link was clicked from (the so called “referrer page”) and I can scan the logs to find outside links to my pages (like this page from Lobsters). With gopher though, I have to come across them since the protocol does not include the referring link. In a way, it's even more private than HTTP.

Then again, I could always do a search.

Regardless, I'm not trying to scan gopherspace looking for links back to me. I am honestly following a bunch of phlogs. Reading these I am reminded of what blogging was like back in the early 2000s—technically minded folk talking about whatever and not trying to corner some niche market so they can get advertising revenue. It's quite refreshing actually.

And man is it fast. Without the graphics, ads, autoplaying videos and bloated Javascript frameworks meant to track you across the Intarwebs, it's a nice reminder of what the Internet once was—fast.

Wednesday, November 14, 2018

Notes on an overheard conversation about “The Toilet Situation, Day 3”

“I finally have the toilet on its side.”

“Hmm, there's no real room to get a grip on the nut, is there?”

“No—wait! I have an idea. We can use a clamp to squeeze the tank towards the bowl. That should expose the nut enough to get the vice grips on it.”

“Hold on … okay, how's this?”

“Perfect! Vice grips!”

“Vice grips.”

“I think the bolt is turning with the nut. We need to hold the bolt somehow … ”

“Vice grip?”

“I'm already using it!”

“No, another pair of vice grips. Right here.”

“Oh. Unnnnnnnnnnnnnnnng! Oooommmmmmmmmmph!”

Two hours later …

“Errrrrrrrrrrrrraaaarrrrrrg! How long is this bolt?”

“It's almost off!”

“Mmmmmmmmmmmmmmmrrrrrrrrrrrrgaaaah! There!”

“Got it!”

“And here are the other two nuts from the other bolts. The tank is no longer attached to the bowl!”


Wednesday, November 21, 2018

A world of message-oriented programming languages

Ted Kaminski just asked, “What would a message-oriented programming language look like?” to which I answer, “any language with functions, which is to say, just about all computer languages.” Ted's answer is a bit different, but let me explain mine (and I've been meaning to write about this for fifteen years now—sigh).

Digression the First

In the programming language C, pointers and arrays are often conflated. They're declared differently:

int  array[10];
int *pointer_a;

But their use is similar:

int x = array[3];
int y = pointer_a[3]; // assuming pointer_a points to an array

I'm not going to go deep into the differences, but do note that array is a sequence of 10 integers, and pointer_a is the address of one or more integers.

Structures and pointers are not conflated to the same degree, mainly because they have different usage syntax (that I find annoying in my opinion):

struct foo
  int a;
  int b;
  int c;

struct foo  structure;
struct foo *pointer_s;

structure.a    = 3;

pointer_s->a   = 3; // assuming pointer_s points to a structure
  /* or */
*(pointer_s).a = 3; // assuming pointer_s points to a structure

The reason for the difference comes from very early C compilers where the fields in a structure declaration were considered offsets and not fields! So the following code:

struct foo
  int a;
  int b;
  int c;

struct bar
  char *x; // can't be a because that would conflict with above
  char *y; 
  char *z;

struct foo *pfoo; // assuming pfoo points somewhere valid

pfoo->a = 4;
pfoo->y = "hello"; 

was legal C code! Thankfully, it no longer is, but we still live with this in POSIX where field names for various structures all have a prefix, like struct stat { off_t st_size; ... } and struct timespec { time_t tv_sec; ... }.

Also, while nothing I see in the C standard seems to invalidate this assumption:

int array[3];

struct foo
  int a;
  int b;
  int c;

sizeof(array) == sizeof(struct foo);

it still seems like it goes against the standard to cast a pointer between the two types all willy-nilly. Just an observation.

Digression the Second

In C, you have arrays and structures. An array is a sequence of values of the same type, stored consecutively in memory. The individual elements are indexed by a number indicating its position in the array (C numbers the first element as 0; other languages such as Lua or Pascal start with 1).

A structure is a portion of memory with a particular layout of types. The individual elements are indexed by a name and appear in order, although not necessarily right next to each other (in other words, there may be what's called “padding” between fields of different types due to machine architecture restrictions). Then there's the concept known as a “tuple.” This is a cross between the array and structure. Like the structure, the individual elements may be of different types and sizes, but they are referenced like an array—an index into its position within the tuple. This is a type that doesn't exist in C, but it does exist in other, more dynamic languages like Python.

Digression the Third

My first real exposure to message passing as a concept was with the Amiga. It was your standard type of message passing, create or find a port, then you can send or receive messages. Messages themselves were a block of memory with a fixed header and a message-specific portion, and they could be sent synchronously (where the sending task was blocked waiting for a reply) or sent asynchronously (the message is sent, but the task continues to run, to possibly wait for a reply at a later time). Messages and message ports were used for all sorts of things on the Amiga, interacting with devices or the GUI, receiving signals, all sorts of stuff.

My second exposure to message passing was with QNX. Unlike the Amiga, there were no message ports—instead you passed messages to a given process. Messages themselves had no fixed structure, it was just a blob of memory being copied from one process space to another. And message passing was purely synchronous. You could do asynchronous message passing, but it required multiple threads to do so.

And it was here that I learned that neither one was more “primitive” than the other—you could always simulate one with the other.

Digression the Fourth

There are two orthogonal axes upon which you can implement message passing. The first axis is “synchronous/asynchronous”—is the task sending stopped or can it continue? The other axis is “reference/value”—does the task send a reference to the data or does it need to copy the data? In the case of QNX, it's a “synchronous, by-value” message passing paradigm. For the Amiga, it can send either synchronously and asynchronously, but in both cases, the data is sent by reference.

Digression the Fifth

Over the years I've programmed under a few windowing systems. Not much, but just enough to get a feeling for it. On the Amiga, you filled in a rather lengthy structure, then pass this to a function to open a new window.

On X Windows, you call one of two functions—one just takes a large number of paramters, the other one takes a large number of paramters, one of which is a rather lengthy structure.

I recall little of Windows and OS/2 (being way back in the early 90s) but I think they were a bit worse than X Windows—a large number of parameters, several of which were rather lengthy structures.

But for all of them, you sat in a so called “event loop”—waiting for events from the GUI, then went off and handle the message. On the Amiga, events were received from a message port. On X, it was a function that returned a structure representing the event. Windows and OS/2 you supplied a function that received four parameters that comprise the event—you were not in control of the main event loop.

Digression the Sixth

So a while back, I was studing the VAX architecture, like you do, when I came across the CALLG and CALLS instructions. Both are used to call a function. CALLG requires the address of the argument list to be passed in:

	<data section>
ARGLIST:	.LONG	2	; argument count
		.LONG	600	; first argument
		.LONG	84	; second argument

	<code section>


FOOBAR is called with two arguments. For the CALLS instruction, you push the arguments onto the stack:

	<code section>

		PUSHL	#84
		PUSHL	#600

Again, FOOBAR is called with two arguments. FOOBAR itself does not have to care how it was called—it receives a pointer to the argument list in register R12 (aka the AP register). It was then I had an epiphany.

The Epiphany

So, in the case of FOOBAR, one way of calling it could look like:

struct foobar_data
  int a;
  int b;

foobar_data fdata = { .a = 600 ; .b = 84 }

But another way of calling it could look like:


Really, all CALLS is doing is initalizing a temporary structure whose fields are otherwise known as “parameters” and passing this structure to the operand, in this case FOOBAR. The parameter list to a function can be viewed as a structure. And all of the examples I've seen of message passing is just passing along data, usually structured as a structure (sorry) or a tuple (depending upon language).

And then the ephiphany! Calling a function with parameters is just another form of synchronous message passing, either by-reference or by-value (this is either an unusual or obvious thought, but it took me a while to reach it if it was obvious). That nasty Windows call to create a window? Just pass a really large structure or “message.” And that's really what's happening under the hood of X Windows—a message is being passed from the X client to the X server.

And this does leave me to wonder at times what the semantics of an asynchronous function call would (or could) be.

But yes, we already have message-oriented programming languages—if you squint the right way …

Friday, November 23, 2018

The Season of the Enlightened Trees

The day after Thanksgiving. It can mean only one thing—

[Santa is huge this time of year.  No, really, he is.  That tree next to him?  It's easily a 10 foot Spruce tree.]

It's time to go out and buy a tree!

On the way back to Chez Boca, Bunny (who was driving) took a detour to see if The House On The Corner™ had swapped out their Thanksgiving display for their Christmas Extravaganza!

[``This one and then that and this and then still another, and on up and around, three lights here, seven lights still higher, a dozen clustered beyond, a hundred, five hundred, a thousand lights lit ... '']

They had. And that's just a small portion of the Christmas Extravaganza! Multiple homes are involved in this seasonal display of lights.

And of course they had the music! I wouldn't expect anything else.

Obligatory Picture

[It's the most wonderful time of the year!]

Obligatory Links

Obligatory Miscellaneous

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site:, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2019 by Sean Conner. All Rights Reserved.