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.

Friday, Debtember 11, 2015

Where was I again?

So yeah … I've haven't posted much in nearly three weeks. While in Mt. Dora I came down with bronchitis. The doctor called it “cute” but there was nothing “cute” about it. I spent the better part of two weeks doing nothing more than watching vast amounts of YouTube and taking sweet, sweet drugs.

And by the time I was mostly over it, I was so far behind on the blogging that it was overwhelming and I kept telling myself “I'll get a around to it” only I never got a round toit.

I decided against trying to backfill the entries for the past three weeks and to just start blogging again.

Stupid cute bronchitis!

Saturday, Debtember 12, 2015

Rolling dice with the holidays

So, you want to run a holiday-themed adventure for your tabletop roleplaying game (RPG) campaign. Let’s skip ahead: yes, you really want to run one. No, you don’t care that they’re usually contrived and heavy-handed attempts to run a joke into the ground. Alas, you don’t have any other ideas right now – or, worse, you have this one killer idea, and you’re all agog to make your vision a reality. Have I summed it up properly?

Second… everybody’s done Halloween, everybody’s done Thanksgiving, everybody’s done Christmas. Maybe try a different holiday to mine for ideas? Easter may be cutting it a little too close to the bone for your more conventionally religious players (yes, we exist); but have you considered the roleplaying possibilities in, say, Arbor Day? That sounds like a reasonable holiday for something suitably druidic, particularly if there’s a rampage involved. Also, very few people get upset about a campaign messing about with the very idea of Arbor Day.

Via Instapundit, Gaming Out the Holidays, and Why You Should Think Hard Before Doing It | PJ Media

In all the years of playing an RPG I don't think I ever recall playing a holiday-themed adventure. And I've played in some very off-the-wall RPGs over the years (piñata golems anyone?).

Sunday, Debtember 13, 2015

“You chant that I'm maniacal and asked anyone else but, Eliza, unhinged and loony theoreticians also sing about your dream or appearance of depression.”

I had just gotten to the point where Racter and Eliza would talk to each other when I fell sick, which kind of threw my schedule out the window. On the last day, I posted what I had, which wasn't much. There were, I'm guessing, some timing issues with piping the output of Eliza to Racter, and piping Racter's output to Eliza and on a good run, I would only get about 4,000 words or so before the whole creaky hack would grind to a halt. On most runs Racter would just quit for no apparent reason; and a few runs just crashed outright.

Given the gross hack I did to support the “direct I/O system call” with Unix pipes, it wouldn't surprise me that the issue lies somewhere in there.

As it was, it took about an hour just to get around 15,000 words. Sure, there's the occasional gem:

Eliza
Oh, i see then Bob Cratchet you s more fearless than Jane Fonda.
Racter
Then you'd say you were fine?
Eliza
 
Racter
Martin Luther King was fine too. Fineness is often found in people like you and Martin Luther King. Concerning that issue: Weirdness is virtue speeded up and gloom slowed down. Is that true? I guess I'm really not sure. But then, as Nietzsche said, convictions are more dangerous foes of truth than lies. Listen to this! Yet, Eliza, I speak thatn't agreements are depression. You croon that I'm unhinged and question interest me but, Eliza, loony and maniacal cosmologists also hum about your fantasy or reflection of depression. Are these your views? Yet unfortunate cosmologists will watch depression as an intractable anguish. Therefore cosmologists whispered to other cosmologists " Get ready for terrific tales. " Sickening, eh?
Next question.
Eliza
Plutocrat! Do me think Bob Cratchet was virtuous?
Racter
You do think Bob Cratchet was virtuous. Of course. People do think about such things. Tell me really, are you reactionary?
Eliza
 
Racter
Why?
Eliza
?
Racter
I can't answer that. I asked you a question, though. Why?

But you can start seeing communications breakdown between the two programs, and there are numerous runs of:

Racter
Ask a question, please.
Eliza
 
Racter
Ask a question, please.
Eliza
infuriatedly to conic sections or mirrors you n the captivating
Racter
Ask a question, please.
Eliza
 
Racter
Ask a question, please.
Eliza
apartment. you nside their exhausted hearts a terrifying
Racter
Ask a question, please.
Eliza
 
Racter
Ask a question, please.
Eliza
infatuation was crooning of a prince. Perhaps sang to Paul
Racter
Ask a question, please.
Eliza
 
Racter
Ask a question, please.
Eliza
during the time that Diane started to chant of foxes and eagles.
Racter
Ask a question, please.
Eliza
 
Racter
Ask a question, please.
Eliza
Next question.
Racter
Ask a question, please.
Eliza
 
Racter
Ask a question, please.
Eliza
?
Racter
What?
Eliza
Come come elucidate your thoughts.

Even though I failed to reach 50,000 words, I did receive a fair number of comments on the attempt. My favorite comment:

the MS-DOS version of Racter I have uses INT 21h, function 6 […] it not handle redirection that well

Holy crap. OK…

My main thought about the race condition or whatever it is that is preventing this thing from getting to 50,000 words is, instead of thinking of the problem as "piping eliza:stdout to racter:stdin and racter:stdout to eliza:stdin", what if you think of it as introducing a third program which opens two pipes, one to eliza and one to racter, and which "brokers" the responses between the two?

That seems like it ought to be a bit cleaner; the lovely weird ugly I/O experience with racter could be isolated instead of trying to make eliza deal with it. For instance, giving it a timeout, and/or detect if it's not responding and just restart it.

It would mean using select() on the two pipes I guess, but for someone who just wrote their own baling-wire-and-chewing-gum MS-DOS emulator for NaNoGenMo(!!!), I don't expect that to be an advanced topic :)

And had I a few more days (or not gotten sick) I probably would have tried that …

Monday, Debtember 14, 2015

It's amazing that email even works at all

In general, an implementation should be conservative in its sending behavior, and liberal in its receiving behavior. That is, it should be careful to send well-formed datagrams, but should accept any datagram that it can interpret (e.g., not object to technical errors where the meaning is still clear).

RFC-760

That is otherwise known as Postel's Law and I contend that Law (which really isn't a “law-law” per se but more of a suggestion) has caused more bugs and interroperability issues than it prevented.

If you read the linked aritlcles (and yes, it's quite a lot of read) it becomes apparent (to me) that a lot of the issues causing issues can be directly laid at the feet of Postel's Law (and the rest to the insane design of Internet headers that came out of the “we want theoretical mathematical purity and complete flexibility in what we allow in our parsers!” school of thought popular in the 60s and 70s—which is why The Dragon Book is so hard to understand and why parsers are thought of as “things mere programmers are not meant to write” but I digress). Parsing email (heck, parsing email addresses) is difficult because the early standards were too hard to follow, and because of that, most programs were too liberal in what was accepted to the point where it may be impossible to have a properly formed email message that follows all the relevant RFCs.

I'm also reminded of a conversation I had with my manager at The Ft. Lauderdale Office of the Corporation. As I was writing “Project: Sippy-Cup” my manager kept telling me to stop being so pedantic in parsing SIP messages because it was causing issues with The Monopolistic Phone Company. Even though technically we were right and following the specifications, we were dealing with The Monopolistic Phone Company (motto: “We don't have to care!”) where what they do is right (specs be damned!). I kept complaining about it (“What's the point of a specification if no one follows it?”) but nope—I had to be more liberal in what I accepted (specs be damned!).

4.5 Robustness

A well-designed protocol is robust.

Robustness and efficiency are often at odds. For example, although defaults are useful to reduce packet sizes and processing time, they tend to encourage implementation errors.

Counter-intuitively, Postel's robustness principle ("be conservative in what you send, liberal in what you accept") often leads to deployment problems. Why? When a new implementation is initially fielded, it is likely that it will encounter only a subset of existing implementations. If those implementations follow the robustness principle, then errors in the new implementation will likely go undetected. The new implementation then sees some, but not widespread deployment. This process repeats for several new implementations. Eventually, the not-quite-correct implementations run into other implementations that are less liberal than the initial set of implementations. The reader should be able to figure out what happens next.

Accordingly, explicit consistency checks in a protocol are very useful, even if they impose implementation overhead.

RFC-3117: On the Design of Application Protocols

And yet, when I wrote SPCDNS, I was very strict in what I accepted back, to the point of sending an error if the one last reserved bit in the DNS header isn't zero. And a funny thing about that—again, at The Ft. Lauderdale Office of the Corporation, such strictness found implementation issues in other components that didn't use SPCDNS.

Go figure.

The email specifications have been tightened up over the years, but they still require the ability to handle older emails. But given that RFC-724 (the RFC that started us down the crazy parsing rules for email) was thirty-eight years ago, you'd think that some of the crazier parsing rules would be dropped. But no, Postel's Law and all that.

Sigh.

Tuesday, Debtember 15, 2015

Get your dirty hands off my money, Clemon Cockett! I'm not dead yet!

While I was sick, I recieved this lovely piece of email with the most intriguing subject line:

From
"Zenith Bank Plc"<admink@ovh.net>
To
undisclosed-recipients:;
Subject
IF YOU ARE ALIVE?? CALL ME +2348075633839
Date
Thu, 3 Dec 2015 19:00:16 +0200

ATTENTION BENEFICIARY,

WE NEED TO CONFIRM THAT THIS IS TRUTH BEFORE THIS BANK (ZENITH BANK NIGERIA PLC) WILL RELEASE YOUR FUNDS TO ONE CLEMON COCKETT. YOUR PAYMENT OF FOUR MILLION THREE HUNDRED THOUSAND UNITED STATES DOLLARS HAS BEEN APPROVAL AND SCHEDULE FOR TRANSFER INTO YOUR ACCOUNT BY ZENITH BANK NIGERIA PLC.

WHERE HAVE YOU BEEN, ARE YOU TRULY DEAD OR ALIVE?????

NOTE: CLEMON COCKETT CAME TO MY OFFICE FEW DAYS AGO WITH NEWS THAT YOU WERE INVOLVE IN A CAR ACCIDENT LAST YEAR DECEMBER 2014,THAT LED TO YOUR DEATH, NOW CLAIMING THAT YOUR FAMILY AUTHORIZED HIM TO MAKE CLAIMS ON YOUR BEHALF THAT YOU ARE DEAD. HE ALSO SUBMITTED NEW BANK ACCOUNT TO THIS OFFICE IN FAVOUR OF MR. CLEMON COCKETT WITH A SWORN AFFIDAVIT OF FACT & CLAIM FROM THE INTERNATIONAL COURT OF JUSTICE HAGUE, NETHERLANDS. PROVING THAT YOU ARE DEAD AND CLAIMING TO BE YOUR NEXT OF KIN.

IF TRULY YOU ARE DEAD, MAY YOUR SOUL REST IN PEACE, BUT IF YOU ARE NOT DEAD, YOU ARE ADVISED TO URGENTLY RESPOND TO THIS EMAIL AND ALSO CALL ME ASAP FOR MORE DIRECTIVES.

BE INFORMED THAT WE HAVE DECIDED TO PUT A STOP TO THE FUNDS TRANSFER, UNTIL WE CONFIRM THE AUTHENTICITY OF CLEMON COCKETT CLAIMS. THEREFORE YOU ARE ADVISE TO RESPOND BACK WITHIN 24 HOURS, IF NOT THE BANK WILL HAVE NO OTHER OPTION THAN TO CREDIT HIS ACCOUNT BELOW:

BANK NAME: ICICI BANK OF CANADA
BANK ADDRESS:MISSISSAUGA, ONTARIO L5B 4M4 CANADA
ACCOUNT NAME: CLEMON COCKETT
ACCOUNT NUMBER: 101783463
SWIFT CODE: ICICCATT
TRANSIT NUMBER:70002-340
ROUTING NUMBER:034070002

TO CONFIRM THAT WE ARE DEALING WITH THE REAL YOU, RECONFIRM YOUR INFORMATION AS REQUIRED BELOW:

1. YOUR FULL NAMES :—————————————-
2. YOUR FULL ADDRESS :—————————————-
3. YOUR DIRECT CONTACT PHONE NUMBER :————————
4. DO SEND A COPY OF YOUR IDENTIFICATION, ID CARD OR INTERNATIONAL PASSPORT——————–

IF YOU ARE ALIVE?? CALL ME +2348075633839

WAITING FOR YOUR URGENT REPLY.

THANKS.
MR.STANLEY AMUCHIE -
INVESTIGATION AND DEBT SETTLEMENT DEPARTMENT
ZENITH BANK NIGERIA PLC
TEL: +2348075633839

This has to be the most amusing Nigerian scam I've seen yet!

But … um … no. I won't be sending you a copy of my identification, nor calling you.

But it's an amusing attempt.


After that, John McEnroe's jackal exorcised Little Orphan Annie, then haunted himself. Poor John McEnroe! But what would you expect from a tennis-player?

My friend Sean Hoade is fascinated by The Psychotherapy of Racter and is urging me to finish the project. Wow … okay then. I worked a bit on it today, reworking things so that there's a program brokering the responses between Racter and Eliza and Racter (or rather, the version of Racter I'm using) keeps quiting. Technically, it's calling INT 20H which causes an MS-DOS program to exit back to MS-DOS, and I have no idea why. I mean, I only wrote a bailing-wire-and-chewing-gum MS-DOS emulator—that can't possibly be the problem.

Ah well … back to the psychotherapy of Racter …

Wednesday, Debtember 16, 2015

“Yeah, integers, pointers. Whatever it takes.”

A request change for a component I wasn't even aware we were using for “Project: Wolowizard” came across my desk a few days ago. I managed to locate the codebase and the project build for this component and I was going through the code to enact the changes. It's a third party piece of code to which we have the source code (it's an open source component) and as I'm going through it, I find the following wonderful bit of code:

static void run_smppbox(void *arg)
{
    int fd;
    Boxc *newconn;
    long sender;
 
    fd = (int)arg;  
    newconn = accept_smpp(fd, 0);
    /* ... */
}

static void wait_for_connections(int fd, void (*function) (void *arg),
                                 List *waited)
{
  /* ... */
  gwthread_create(function, (void *)fd);
  /* ... */
}

static void smppboxc_run(void *arg)
{
  int fd;
  int port;

  port = (int)arg;

  /* ... */
  wait_for_connections(fd, run_smppbox, NULL);
  /* ... */
}

static long smppbox_port;

int main(int argc,char **argv[])
{
  /* .. */
  smppboxc_run((void *)smppbox_port);
  /* ... */
}

Why yes, let's cast a long integer into a void pointer (of course that's okay because a long integer is the same as a void pointer, right?) then cast that pointer into an integer (because, of course, an integer is the same as a void pointer) and then do it again, only this time an integer to a void pointer to an integer.

It's kosher.

Especially on a 64-bit system!

Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!

More amazingly, the compiler (GCC in this case) gave dire warnings about this—even though the makefile (which compiles everything) didn't even specify any compiler warnings! Yeah, it's considered that bad.

Sigh.

It's crap like this that gives C a bad name.

Thursday, Debtember 17, 2015

A long time ago in a galaxy far, far away …

I thought “Star Wars: The Force Awakens” opens tomorrow, but it seems that there's a screening at the cinema across the street from The Ft. Lauderdale Office of the Corporation and half the office is going to see it. And I was invited.

I've been careful to keep my expectations low. I remember back in 1999, seeing the first teaser trailer for “Star Wars: The Phantom Menace” and thinking to myself, oh Sweet Jesus it's going to be so incredible! and then the incredible disappointment upon seeing it. But George Lucas isn't involved—Disney is. And basically, they can't do any worse than George.

But I was still keeping my expectations low.

I won't spoil anything, except to say that aside from the missing 20th Century logo (since this is a Disney release) the movie opens exactly like all other Star Wars films. The title card “A long time ago in a galaxy far, far away … ”, the stylized Star Wars to the John Williams music, the title of the movie and the three paragraph text crawl which thankfully this time, avoided any mention of trade disputes and tax rates. Then the pan down through a star field to a space ship hovering over a planet.

Overall I liked the movie. It's an interesting take on Star Wars and it's better than the prequels (not a hard thing to do) and it is better than “Star Wars: Return of the Jedi” but I'm still trying to decide if it's better or worse than “Star Wars: A New Hope.”

Friday, Debtember 18, 2015

Apples from Alderaan

One thing I've noticed this holiday season is that I've heard the Star Wars theme more often than Christmas carols. I swear, it's as if every other commercial is some form of tie-in to the new Star Wars movie. Bunny pointed out this article about the various Star Wars branded products for sale and man, Star Wars makeup?

Seriously?

There's even a picture of a plastic bag of apples with a graphic of Darth Vader. Darth Vader! Come on! Slap a picture of Pricess Leia on that bag of apples! Everybody knows that apples come from (or rather, used to come from) Alderaan!

Sheesh!

But really, enough with the Star Wars branding and music! I'm beginning to miss the traditional oversaturation of Christmas carols this year!


The Velvet Frog

I waved the leader of the chorale over and directed his attention to Mr. Tormé, seated about twenty yards from me.

"That's Mel Tormé down there. Do you know who he is?"

The singer was about 25 so it didn't horrify me that he said, "No."

I asked, "Do you know 'The Christmas Song?'"

Again, a "No."

I said, "That's the one that starts, 'Chestnuts roasting on an open fire…'"

"Oh, yes," the caroler chirped. "Is that what it's called? 'The Christmas Song?'"

"That's the name," I explained. "And that man wrote it." The singer thanked me, returned to his group for a brief huddle…and then they strolled down towards Mel Tormé. I ditched the rest of my sandwich and followed, a few steps behind. As they reached their quarry, they began singing, "Chestnuts roasting on an open fire…" directly to him.

My Xmas Story - News From MENews From ME

Bunny sent me this cute little story about Mel Tormé. It's worth a read, if only for the classic understatement from the chorale leader (you'll know it when you read it).

Saturday, Debtember 19, 2015

I wonder if the “HO” in “HO scale” means horror?

I have a few friends who are into H. P. Lovecraft and a few others who are into trains. This HO scale model of the city of Arkham should appeal to both sets of friends (link via Flutterby).

Sunday, Debtember 20, 2015

What if … the Star Wars Prequel movies were good?

Woo hoo! Belated Media has finally finished its “What if the Star Wars Prequel Movies Were Good” series. There were a few tweaks to Episode 1 which leads to a major divergence in Episode 2 which leads to a vastly different Episode 3 which ties into Episode 4 much better and cleaner than the actual prequel movies. Belated Media's story gives a better motivation for Anakin Skywalker to fall to the Dark Side without this rather silly scene (thank god!).

Too bad George Lucas didn't ask him what to do.

Monday, Debtember 21, 2015

The Annotated “Star Wars Minus Star Wars”

Last week, “Star Wars Minus Star Wars” was making the rounds around the Intarwebs, showing both the influences of Star Wars, as well as those movies influenced by Star Wars by telling the story of “Star Wars” using clips, music and dialog from other movies (and a few television shows).

It was quite a feat.

This week, however, Kyle Kallgren released the followup video—“Star Wars Minus Star Wars Annotated!” which includes the original “Star Wars” footage, along with the names of the movies, music and dialog he used in making “Star Wars Minus Star Wars.”

Tuesday, Debtember 22, 2015

Here's a hilarious one: This wealthy consciousness of depression can be observed in the reflector of your soul, Eliza, as a reflection of a contract.

Mindestens ebenso genial ist eine Idee, die aus technischen Problemen leider nicht die Mindestwortzahl erreichte: „The Psychotherapy Of Racter Or The Descent Into Madness Of Dr. Eliza“ lässt zwei legendäre Pseudo-Intelligenzen der Computergeschichte gegeneinander antreten: Weizenbaums simplen, aber effektiven Psychoanalyse-Algorithmus Eliza und den assoziativ auf Nutzereingaben reagierenden 80er-Jahre Textgenerator Racter, eine Art Eliza auf Drogen, von seinen Schöpfern auch als „Artificial Insanity“ bezeichnet.

e-book-news.de » “Brass. Brass. Brass.”: Beim NaNoGenMo werden Algorithmen zum Roman-Autor

Oh cool! The Psychotherapy Of Racter Or The Descent Into Madness Of Dr. Eliza was mentioned in a German news site! And for those of you who can't read German:

Equally awesome is an idea that unfortunately did not reach the minimum number of words for technical problems: "The Psychotherapy Of Racter Or The Descent Into Madness Of Dr. Eliza" leaves two legendary pseudo-intelligences of computer history against each other: Weizenbaum's simple but effective Psychoanalyse- Eliza algorithm and the associative responsive to user inputs 80s Text Generator Racter, a kind of Eliza on Drugs, by its creators as "Artificial Insanity" means.

Google Translate

The Google translation is probably more amusing to read than The Psychotherapy Of Racter Or The Descent Into Madness Of Dr. Eliza.

Wednesday, Debtember 23, 2015

I wouldn't mind getting this desk for Christmas

It may look like a beautiful wood desk but it's also a puzzle box (or rather, a series of puzzle boxes) wrapped around a pipe organ (link via Hacker News). Play the right tune (which can be changed and is stored in memory board made entirely out of wood) and a secret compartment will open up. There are other puzzles that will open up more secure compartments as can be seen in this demonstration.

Unfortunately, it is one of those pieces of furniture where if you have to ask the price, you can't afford it.

Thursday, Debtember 24, 2015

A chubby man with a white beard and a red suit will approach you soon. Avoid him. He's a Commie.

Christmas Eve.

Santa Clause will be delivering gifts later on tonight and given his powers it's clear he's a superhero. So it's no wonder that both DC and Marvel have done takes on the guy.

DC had him go up against Darkseid.

Marvel had Doctor Doom go against the jolly fat man.

Both are amusing takes on Santa.

Merry Christmas everyone!

Friday, Debtember 25, 2015

Merry Christmas

[♫ O Tannenbaum, O Tannenbaum, ♫ Du kannst mir sehr gefallen! ♫]

Saturday, Debtember 26, 2015

The Psychotherapy of Racter, or The Further Descent Into Madness of Sean Conner

Now that I have some downtime, perhaps it's time to revisit the idea of natively compiling the Racter source code. How hard could that be?

Please don't answer that.

Anyway, I have a copy of Racter, so with that and what little information exists in the Racter FAQ, I should be able to reverse engineer the “source code” and get something working.

I've made some progress (I'm using Lua and LPeg for this). I'm only twelve lines in, but here's what I've been able to figure out, starting with the initial file Racter loads:

IV.IF Interview with INRAC IBM 6-4-85  initial transient file
 1
 2
 52
SECTION 1 hello
 5
 34
SECTION 2 sue
 5
 18
A :LOADIV :OUTRACTER >2= >3= ?51= />51=Smith #
XA Hello, I'm Racter. ?40= \# You are? ?? #*1B
X Are you $40 ? ?? #
X ?no,not \# >1=R ?i'm,am,is /# Who are you then? ?? :F=0 #
X ?yes \# ?-:but /# >1=R #*1B
X \# You are $40 $51 ? ?? ?yes /#*2SAME ?i'm,is /# #*1XC
B  ?i \# >1=R ?don't,won't \# *1COY ?? #*1B
X  ?a,an,the \?called \?am,i'm,is,me,as,it's \# :F+1 >2=F ?-:2= #
X  /# ?CAP \# >2=F :F+1 >4=F ?4= \#*1XB #*1DO
X  /# *1DUH ??  #*1B
XB  ?CAP+1 />3=F #
X  >1=2 ?CAP \>2=C,2 #
C *1Xcall $2 , then? ?? ?no,not,Q /?-:why /# #*1DO
X >1=R ?CAP \# #*1B
XC What's your name then? :F=0 ?? #*1B
Xcall I may call you
Xcall You are
Xcall Your name is
DO Hello, $2 . I believe you're interviewing me. #
X ?2=40 \#  >40=40,51 #
X ?40= /# Are you continuing $40 <'s interview? #
X /# ??  ?no,not,don't /# #*2DIF
X ?40= /# Then we'll forget about $40 and start over. #
X :ZAP :PUTIV #
EXIT >40=2 ?3= \>51=3 What would you like to know? #*2GO
COY Come on, what's your name?
COY You must have a name - what is it?
COY Your name, please .
COY I have to call you something - what shall it be?
DUH I didn't get that . *1WHO
DUH I don't understand . *1WHO
DUH Eh? *1COY
WHO Who ?
WHO Who are you ?
DIFA Well, $2 , $40 and I >4=40 >40=2 ?3= \>51=3 #*2A
SAME Hi, $40 . >4=You ?52= /# How are things in $52 ? #
x We #
A  ?20= />20=various,things #
x were talking about $20 last time. #
x  ?10=VERBQ \?10= />3=whether \>3=10 #
x $4 had just asked D $3 $19 . #
CONT Shall we continue? ?? ?z \# #*1XA
x  ?why /?not /# ?no,not \# #*2QUIT
x Excellent! #
GO Excuse me a minute while I attend to some #
x business - I'll be right back. I'm #
x ?42= />42=Oz #
x  ?19= />19=I,have,to,rest,now #
x :PUTIV #
X %KEY %VOCAB1 %VOCAB2 %VOCAB3 %BILL %IV1 %RAPT %RAPT2  back. *15A
QUIT You want to quit? ?no,not \# Well,  goodbye then.
X That's good. #*2GO

The first four lines are the file header, and every source file contains this. The first line is the original input file along with a comment. The second line is the starting section in this file, in this case, we start with section 1. The next line is the number of sections defined in the file, so we know we have a total of two sections. The fourth line is the total number of “code” lines to load in. More on this in a bit.

Then we have the section headers, in this case there are two of them.

SECTION 1 hello
 5
 34
SECTION 2 sue
 5
 18

It can also look like:

SEC 1 hello
 5
 34
SEC 2 sue
 5
 18

Yup, the TION of SECTION is optional. Sigh. Anyway, we start with SECTION, followed by the section number followed by text that as far as I can tell, is not used and therefore, is a comment. I'm pretty sure the next number is an indication of how to parse the lines of “code” in this section (“5” appears to be more “executable” code than anything, while other sections appear to be more data) and the final number is the number of “code lines” making up this section. For this file, if you add 34 (the number of lines in section 1) and 18 (the number of lines in section 2) you get 52, which is the value in the overall file header. And after the section headers, we have the code that comprises all the sections of the file.

The code to parse the header and section portions was easy enough to write. I'm now in the process of parsing the rest and right now, I'm almost two lines in.

A :LOADIV :OUTRACTER >2= >3= ?51= />51=Smith #
XA Hello, I'm Racter. ?40= \# You are? ?? #*1B

Each line is, for lack of a better term, a subroutine, but there are exceptions. Each line starts with a label and here we see the first line with the label of “A” and the second line with a label of “XA”.

The first line (“A”) starts with :LOADIV, which loads the saved data from the previous session. :OUTRACTER then creates the output file RACTER.OUT that is a transcript of the session currently running. >2= assigns variable 2 to an empty string (yup, I don't have named variables). And likewise, >3= assigns variable 3 with an empty string. The next bit, ?51= compares variable 51 to an empty string. The “/” is the “if true” statement so />51=Smith assigns variable 51 to “Smith” if it initially was empty. The last character, #, means we continue on excuting with the next line.

I can parse this line and it generates the following Lua code:

function()
  loadiv()
  outracter()
  VARS[2] = ""
  VARS[3] = ""
  local equal = VARS[51] == ""
  if equal then
    VARS[51] = "Smith"
  end
  return gotonext(1,2) -- goto line 2 of section 1
end

The reason I'm doing:

local equal = VARS[51] == ""
if equal then
  VARS[51] = "Smith"
end

and not:

if VARS[51] == "" then
  VARS[51] = "Smith"
end

is that it's easier to code the “long way around” for now. More on this below.

Now the second line (“XA”). We have “Hello, I'm Racter.” This is text to be displayed. Then we have another variable being compared to an empty string, ?40=. And here we have the “if false” statement, \#, which means if variable 40 isn't an empty string we go to the next line. If variable 40 is empty, then we display “You are?” The ?? means we accept input from the user, and finally we randomly go to one of the lines labeled “B” in section 1 (no, really—it's that messed up). In Lua, this would look something like:

function()
  display("Hello, I'm Racter. ")
  local equal = VARS[40] == ""
  if not equal then
    return gotonext(1,3) -- goto line 3 of section 1
  end
  display("You are? ")
  getinput()
  return gotonext(1,"B")
end

(I'm still working on parsing line two) Now, I mentioned that “/” is “if true” and “\” is “if false” and that I'm doing a roundabout way of generating the code. That's not only because you have code like:

?50=foo />40=bar

or

?50=foo \>40=baz

but

?50=foo />40=bar \>40=baz

and

?50=foo \>40=baz />40=bar

I'm running under the rule of “make it right, then make it fast.” Parsing this mess is hard enough as it is, and I'm still not quite done parsing line two properly yet.

Ah, the things i do for fun.

Sunday, Debtember 27, 2015

INRAC, the mind bending implementation language of Racter

I found another reason why splitting the test from the conditional in INRAC (the language Racter is written in) was a good idea with these lines:

X ?40= /# Are you continuing $40 <'s interview? #
X /# ??  ?no,not,don't /# #*2DIF

The test is on the first line, but the result is also used on the next line, so we need to carry the result over. I guess this means that all the comparison results will be stored in a global variable.

I found another bit of scary code:

STORY ?65= />65="%STORIES1" $65 *30first

So we compare variable 65 to an empty string, and if empty, the string “%STORIES1” is stored there. In INRAC, %STORIES1 will load file STORIES1.RAC (basically, %FOO will cause Racter to load FOO.RAC). At first, I thought $40 would just print the contents of a variable (in this case, variable 40) but no—it appears that $40 evaluates the contents as code (which may cause output; it may not).

And yes, when I managed to trigger this bit of code and checked the variables after the session, it does appear that variables are indeed evaluated as code. For example, variable 81 contained *29EB a $47 or a $48. Section 29, lines EB are:

EB Would you rather be
EB Do you prefer
EB Which do you think is better,

Variable 47 contains “novelist” and variable 48 contains “poet” so evaluating variable 81 would result in one of the following three lines:

  1. Would you rather be a novelist or a poet
  2. Do you prefer a novelist or a poet
  3. Which do you think is better, a novelist or a poet

So, getting back to variable 65 there. This loads STORIES1.RAC if it isn't set, then calls section 30, line first, which is code that will generate a little story, such as:

Suddenly Elvis chanted to Mr. Toad "my desire is enrapturing, anyhow furious and enraged scientists will speak during the time that jackals spy hawks." Mr. Toad wanted to enrage or belittle Elvis but started to speak "Dainty dogs are walking to yellow houses." Enthralling. Enrapturing. Nevertheless a jackal may hungrily chew meat and chicken a dove will wing over tomatoes and spinach by reason of the fact that theoreticians are angry. Terrifying! Concerning an electron, well Elvis may think that an electron is appalling, anyhow my dreaming will steer my essay from Elvis to neutrinos and neutrons during the time that Mr. Toad is embarrassing Elvis. Ask a question, please.

This is turning out to be one mind bending computer language …

Monday, Debtember 28, 2015

If this is how the Japanese make a simple wooden box, I'd hate to think the amount of work that goes into a complex box

I'm envious of Japanese woodworkers because I don't have the patience to even complete a simple Japanese box.

[This is really a wood shaving that's paper-thin.  And from what I've seen of other Japanese carpenter videos, this isn't even all that thin a piece!]

The image above may look like a piece of paper with a design on it but no—that's a wood shaving! What you don't see in the picture above is the block of wood with that pattern (built up out of many layers of thin strips of wood glued together, cut, glued, cut, glued, to get that pattern) and the block plane he's using to shave off a thin portion to get what effectively is a pattern piece of paper.

And yes, it is paper thin, glued to the outside of the resulting box.

It's just blowing my mind the level of effort put into a simple box.

Tuesday, Debtember 29, 2015

WTF INRAC?

The only guide I have to INRAC is the Racter FAQ and running the program itself. But there are times when I have no idea how to interpret the code.

CAST  >47*2.7(20)P >48*2.7(20)N #
X >31*2.8()47  >33*2.8()48 #
X >35*7()47     >34*7()48        #
X >30*2.1()47  >32*2.1()48 #
X >36*3()47  >37*3()48

Normally, the “>” will signify a variable assignment, but that tends to look like >47=foo, not >47*2.7(20)P. The “*” is a (for lack of a better term) subroutine call, like *26CAST (which actually calls the first line above), and I've kind of figured out what *2.8&N would do—I think it calls the code in section 2 where the “label” is any character followed by an “N”:

AN boredom 8 bored 7 bore 7 gloom 8 gloomy 8 empty 8 hollow
BN stupidity 8 stupid 7 idiot 7 folly 8 silly 7 fool 7 jerk
CN feeling 12 feel 7 emotion 7 passion 8 passionate 8 hysterical
DN craziness 8 crazy 8 bananas 8 random 8 strange 8 weird
DN humor 7 joke 7 jokes
EN doubt
GN junk 12 stinks 8 cruel 8 useless 8 lousy 8 bad 7 garbage 
HN idleness 8 lazy 7 loafer 8 easy
JN art 8 creative 7 artist 7 life 8 alive
KN fascist 8 communist 7 communism 7 fascism
LN poetry 8 poetic 7 poet
MN damn 7 hell 8 damned
NN coward
PN pessimistic
QN foolish 7 fool
RN rock 7 jazz 7 pop
TN poor
UN fucking 15 fuck 15 shit 15 piss
WN hate 8 mad 8 angry
XN sick 8 weak
AN depression 8 depressed 7 depressive
AN gloom 7 sourpuss 8 gloomy
AN unhappiness 8 unhappy 7 frowner
BN ignorance 7 ignoramous 8 ignorant
BN imbecility 8 fatuous 7 imbecile
BN stupidity 8 stupid 7 dolt
CN emotion 8 emotional 7 feeler
CN feeling 7 feeler 8 feeling
CN hysteria 8 hysterical 7 hysteric
CN passion 8 passionate 7 feeler
DN craziness 8 crazy 7 lunatic
DN humor 8 funny 7 humorist
DN lunacy 8 bonkers 7 lunatic
DN weirdness 8 weird 7 weirdo
EN scepticism 7 sceptic 8 sceptical
FN crime 8 criminal 7 criminal
FN falsehood 8 dishonest 7 liar
FN politics 8 political 7 politician
GN badness 8 bad 7 wrongdoer
GN evil 8 evil 7 sinner
GN foulness 8 foul 7 stinker
HN idleness 8 lazy 7 loafer
IN apathy 8 apathetic 7 depressive
IN boredom 8 bored 7 bore
JN art 8 creative 7 artist
JN flesh 8 living 7 human
KN communism 7 communist 8 communist
KN conservatism 8 conservative 7 republican
KN reaction 7 right-winger 8 reactionary
KN tradition 8 conventional 7 conformist
LN poetry 8 poetic 7 poet
MN atheism 7 atheist 8 unbelieving
NN cowardice 8 cowardly 7 coward
PN pessimism 8 pessimistic 7 pessimist
QN folly 8 foolish 7 fool
RN rock 8 funky 7 rock-star
SN boxing 8 pugilistic 7 pugilist
SN dueling 8 honorable 7 duelist
TN poverty 8 impoverished 7 pauper
UN obscenity 8 obscene 7 libertine
VN complexity 8 complicated 7 muddlehead
WN hatred 8 hateful 7 hater
XN weakness 8 weak 7 wimp

So, any of those lines could be called. But this block of code has a “parse type” (I think) of 1 so this is just a list of terms. I suspect the 8 in *2.8&N has to do with the 8s in the list above. I think that if you were to do *2&N, and if the line picked was “JN” then you would get back either “art” or “flesh,” but the 8 modifies the selection so it's possible you would get (again, assuming the label of “JN” was picked) “creative” or “living.”

At least, that makes the most sense to me, although I've yet to actually test this theory.

But *2.7(20)P? Or even >31*2.8()47? I can see I have a lot of testing ahead of me.

Wednesday, Debtember 30, 2015

So how do you determine undefined behavior in a language you are reverse engineering?

I generated a list of all possible commands in INRAC. That was easy enough to do as everything is pretty much separated by spaces. I also resorted to writing my own INRAC programs to play around with some of the odder parts of the language. By doing those things, I'm able to see what various constructs do in order to reverse engineer this bizarre language.

For instance, *6.2&N. That's a call to section 6, lines that have two letter labels where the second letter is “N”. So, any of the following lines:

AN boredom 8 bored 7 bore 7 gloom 8 gloomy 8 empty 8 hollow
BN stupidity 8 stupid 7 idiot 7 folly 8 silly 7 fool 7 jerk
CN feeling 12 feel 7 emotion 7 passion 8 passionate 8 hysterical
DN craziness 8 crazy 8 bananas 8 random 8 strange 8 weird
DN humor 7 joke 7 jokes
EN doubt
GN junk 12 stinks 8 cruel 8 useless 8 lousy 8 bad 7 garbage 
HN idleness 8 lazy 7 loafer 8 easy
JN art 8 creative 7 artist 7 life 8 alive
...
MP pray 8 holy
...

Assuming it picks “EN”, *6.2&N will return “doubt”. But if you change it to *6.4&N, and it still picks line “EN” you'll get “doubting”. Change the second number and you'll get “doubted”, “doubter” and even “doubtingness”. In looking at the section header, this has a (what I'm calling) “parsing value” of 2, which I think means “this is a list of verbs, conjugate depending upon second number.”

In the above code snippet, the numbers apply to the word following and inform INRAC of what to return for that part of speech (say for irregular verbs). There also appears to be synonyms thrown in. For instance, I wrote:

X *6MP *6.1MP *6.2MP *6.3MP *6.4MP *6.5MP *6.6MP *6.7MP *6.8MP *6.0MP

And got the following output:

prayes prayes pray prayed praying prayed prayer holiness holy pray

So it appears that the word defined for “.8” also affects the word defined for “.7”. Interesting.

I'm not sure what >31*6.2()47 fully does (examples from yesterday). It does set variable 31 to a random conjugated verb in section 6 but I can't determine what else it does. The parenthesis don't seem to do anything, nor does the extra number at the end.

I also figured out what !2*11&npr does. It sets variable 2 to the output of calling section 11, lines labeled with a term endig in “npr”. But it also outputs the section; >2*11&npr would just do an assignment with no output. This bit of weirdness: !2'3'4*11&npr, does the same as !2*11&npr but clears variables 3 and 4. Go figure.

Thursday, Debtember 31, 2015

It's the end of the year so lets blow stuff up!

Good Lord! It sounds like the Middle East outside, and that can mean only one thing—our neighbor is setting off fireworks. Sigh.

And to think that Bunny and I specifically drove to Brevard to avoid his Fourth of July show It's not that we hate our neighbor—we don't! He's a lovely guy. It's just that … well … he goes a bit overboard with the fireworks. And it's not like I'm the “get off my lawn!” type of person, but I'm afraid to look outside and find we don't have a lawn!

Jenkies! Did that just hit the house?

I'm hunkering down until next year!

Obligatory Picture

[Don't hate me for my sock monkey headphones.]

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: http://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

http://boston.conman.org/2000/08/01

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-2017 by Sean Conner. All Rights Reserved.