How to Work from Home

I've been working from home for years, and I've got a whole process:

  1. It's fine to wear bathrobe (or pajamas) for a while. Naked people get very little done.
  2. Breakfast and coffee time can be extended by playing videogames, watching TV, or reading comics.
  3. Switch to your work environment. If you have a home office, go there; if not, use multiple desktops to at least not work on the same screen as your browser or chat windows. Select appropriate work music.
  4. Try to get at least one item from your task list done. It's OK to take the lowest-hours problem if you think you can knock it out.
  5. Time for a little reward slacking off.
  6. OK, now it's lunchtime. Now you may need to be professional and wear pants/dress/kilt after lunch, or before if you're ordering in or going out. However, unless you go outside there's no reason to change out of slippers.
  7. Spend too long staring at your task list, going "uuuuugh."
  8. Say "good enough for one day!", check in/archive work.
  9. Goofing off time. Possibly time for a nap before dinner.
  10. If you think about the project, and record some tasks, that counts as "working late" and you can take any reward you want.
  11. Whiskey time.

There's all kinds of sanctimonious blowhards who tell you how to "be productive", "wear pants", "always be shipping". Forget them, this is a realistic schedule you can live by.

Writing Objective-C with Mulle-Objc

mkdir CLICalc
cd CLICalc
mulle-sde init -m foundation/objc-developer executable

This takes more or less forever.

… Still going. OK, finally done. I hate to think it's gonna do that every new project? Or whenever it updates?

Anyway, bbedit . (fuck Xcode), and add at the bottom of import.h and import-private.h:

#import <Foundation/Foundation.h>

Make src/main.m useful:

// main.m
#import "import-private.h"
#import "CLICalc.h"

int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    CLICalc *calc = [[CLICalc alloc] init];
    [calc push:42.0];
    [calc push:69.0];
    double a = [calc pop];
    double b = [calc pop];
    NSLog(@"a=%f, b=%f", a, b);

    [pool release];
    return 0;

Create an Objective-C class, src/CLICalc.h:

// CLICalc.h
#import "import-private.h"

@interface CLICalc : NSObject

@property (retain) NSMutableArray *stack;

- (void)push:(double)n;
- (double)pop;


and src/CLICalc.m:

// CLICalc.m
#import "CLICalc.h"

@implementation CLICalc

@synthesize stack = _stack;

- (id)init {
    self = [super init];
    _stack = [[NSMutableArray alloc] init];
    return self;

- (void)dealloc {
    NSLog(@"CLICalc dealloc");
    [_stack release];
    [super dealloc];

- (void)push:(double)n {
    [_stack addObject:@(n)];

- (double)pop {
    if ( ! [_stack count]) {
        // ERROR: stack underflow
        return 0.0;
    double n = [[_stack lastObject] doubleValue];
    [_stack removeLastObject];
    return n;


Doing that without a template was a little hard on the old memory, and I had to use DDG to look up some method names without autocompletion. But I'm pretty sure that's fine.

In mulle-ide, type update to add the new class to cmake: If you look in cmake/_Sources.cmake you should now see CLICalc.m listed.

Now craft to compile. You'll get a spew of crap, but hopefully no errors.

I am getting this, which I can't resolve:

/Users/mdh/Code/CodeMac/CLICalc/src/main.m:21:55: warning: 'NSAutoreleasePool'
      may not respond to 'init'
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
                                   ~~~~~~~~~~~~~~~~~~~~~~~~~ ^
1 warning generated.

But NSAutoreleasePool certainly has init, and it seems to not die?

% ./build/Debug/CLICalc
a=69.000000, b=42.000000


Yeah, this isn't amazing. Except: It's supposedly portable now. I can maybe rebuild this on Linux, or Windows? I dunno.

This is almost classic Objective-C, slightly enhanced from 1.0: We didn't have property/synthesize, or nice object wrappers like @() when I were a lad. I typed so many [NSNumber numberWithInteger:n]. So get used to the retain/release/autorelease dance. There's no dot-syntax for property access, type them [] like old-school. But hey, it's a proper compiled language with a nice object system and no GC pausing.

I tried importing Cocoa and got a ludicrous spew of errors, so Mac GUI is gonna be a challenge. But I could import SDL and use that for portable UI, since Objective-C is just C.

Sweet. I'll finish up the calculator's parser in a bit, but then see about doing something useful in it.

Interactive Python IDLE

When using Python from a shell, the REPL is fairly awful and doesn't let you copy-paste or save, except through the shell itself. I especially find that copy-pasting functions in is error-prone. There's a nice interactive environment for Python called IDLE (after Eric ): It's probably an application in your /Applications/Python 3.7 folder, or whatever other OS's do, or can be run with IDLE3 from the shell. Other than using ^N/^P for next/previous history line, it works pretty much exactly as you'd expect a GUI REPL to work, and lets you save your session as a text file, easy to extract some functions from later or use as a doctest.

Trouble is, IDLE doesn't automatically pick up the ~/.pystartup script; I had to remember to call it with IDLE3 -s, and there's no easy way to do that from the desktop, where I'm often lazily clicking. This has been frustrating me very slightly for years.

So: open Automator, new Document, add Utilities/Run Shell Script, and paste in:

IDLE3 -s

Save as an Application, name it IdleStart. The icon's ugly and generic, so I made a half-assed icon, copy it from an image editor or Preview, and paste into the icon in Get Info on the application.


Now I have a nice stupid foot to click on, and get a proper REPL. The running program has a hideous 16x16 or 32x32 icon scaled up, which I don't think I can easily solve; I looked at the idlelib source and while I could patch it, it's not easily configured. Maybe later. There's also no way to specify the window location, which I'd like to have mid-left of my screen, but again, maybe later.

While I'm at it, the themes are garish, and the customizer is unpleasant. So I just edited this in ~/.idlerc/config-highlight.cfg, then picked Mark's Dark theme:

[Mark's Dark]
normal-foreground = #eeeeee
normal-background = #111111
keyword-foreground = #ff8000
keyword-background = #111111
builtin-foreground = #0099ff
builtin-background = #111111
comment-foreground = #dd0000
comment-background = #111111
string-foreground = #80ffdd
string-background = #111111
definition-foreground = #80ff80
definition-background = #111111
hilite-foreground = #ffffff
hilite-background = #808080
break-foreground = #ffffff
break-background = #808000
hit-foreground = #002040
hit-background = #ffffff
error-foreground = #ffffff
error-background = #cc6666
cursor-foreground = #ffffff
stdout-foreground = #ccddff
stdout-background = #111111
stderr-foreground = #ffbbbb
stderr-background = #111111
console-foreground = #ff4444
console-background = #111111
context-foreground = #ffffff
context-background = #444444

My current ~/.pystartup is short (in python2 it was much longer, since nothing worked right), just some common imports and functions I use enough to miss:

import os, sys
import math
import random as R
import re
import time
import turtle as T

def dice(n, s):
    t = 0
    for i in range(n):
        t += R.randint(1, s)
    return t

def roundup(n):
    return math.floor(n+0.5)

def sign(i):
    if i > 0: return 1
    elif i == 0: return 0
    return -1


Now if I click the foot and see "READY" above >>>, it's all working.

How to Configure Vim

I just had the unfortunate experience of using the standard vimrc on ubuntu (which I loathe, but it's the most stable OS on this VPS), and now I sympathize with people who think they can't use Vim. So here's my much less annoying vimrc. You'll want to make a ~/tmp folder if you don't have one. Adjust the augroups for the languages you use; I was forcing some syntax files to load because they had bad defaults like PHP as HTML, no idea if that's improved.

" Mark Damon Hughes vimrc file.
" To use it, copy it to ~/.vimrc

set nocompatible    " Use Vim defaults (much better!)
filetype plugin on
set magic
set nrformats=

set errorbells
set nomore wrapscan noignorecase noincsearch nohlsearch noshowmatch
set backspace=indent,eol,start

"set smarttab expandtab shiftwidth=4
set nosmarttab noexpandtab shiftwidth=8 tabstop=8

set encoding=utf-8 fileencoding=utf-8
set listchars=tab:__,eol:$,nbsp:@

set backup backupdir=~/tmp dir=~/tmp
set viminfo='100,f1,<100

set popt=header:2,number:y

set tw=80       " I use this default, and override it in the autogroups below

" ctrl-] is used by telnet/ssh, so tags are unusable; I use Ctrl-J instead.
map <C-J> <C-]>

" Don't use Ex mode, use Q for formatting
map Q gq

map <Tab> >>
vmap <Tab> >
map <S-Tab> <<
vmap <S-Tab> <

" Always have syntax highlighting on
syntax on
hi Identifier guifg=blue
hi Statement term=bold guifg=blue
set guifont=Menlo_Regular:h14
set guioptions=aAemr
set showtabline=2
set mousemodel=popup_setpos

augroup c
    autocmd BufRead,BufNewFile *.c set ai tw=0
augroup END

augroup html
    autocmd BufRead,BufNewFile *.html set tw=0 ai
    autocmd BufRead,BufNewFile *.html source $VIMRUNTIME/syntax/html.vim
augroup END

augroup java
    autocmd BufRead,BufNewFile *.java set tw=0 ai
augroup END

augroup objc
    autocmd BufRead,BufNewFile *.m,*.h set ai tw=0
augroup END

augroup php
    autocmd BufRead,BufNewFile *.php,*.inc set tw=0 ai et
    autocmd BufRead,BufNewFile *.php,*.inc source $VIMRUNTIME/syntax/php.vim
augroup END

augroup python
    autocmd BufRead,BufNewFile *.py set ai tw=0
augroup END

augroup scheme
    autocmd BufRead,BufNewFile *.scm,*.ss,*.rkt set ai tw=0 sw=4 ts=4
augroup END

Mystic Dungeon BBS

As previously mentioned, I'm interested in BBS's.
So I set mine up! After 30 years, The Dungeon is back as The Mystic Dungeon BBS!


Connect with: telnet 1666
(soon I'll have a proper domain, and SSL cert so you can ssh host 2666)

Set your terminal for black background, 80x25, and UTF-8, I dunno what it'll do to DOS CP, but everything's Unicode now.

If your Mac doesn't ship with a telnet anymore, you can grab the previous OS's one from a backup, or port install inetutils and then use gtelnet.

Of course visit the Doors to try the Mystic Dungeon doorgame!


I wrote the start of this last weekend in a Ballmer Peak, and have been adding to it since. Now it has a town and a dungeon with 8 levels, 24 kinds of monsters, combat, an innkeeper for resting, a merchant for buying equipment, and banker for saving money between deaths.

Coming up are potions and other useful items, traps, chests (which are often trapped), and magic.

Right now, only Fighters make any sense to play, though different races have some advantages (Dwarf especially for long-range darkvision in the dungeon, since I don't sell light sources yet!). The character shown is a bit cheaty on cash and XP; it'll take a long, long time to reach that level legit.

In Which N-Gate Reads the FOSDEM 2019 Schedule

Moments where I laughed out loud, scaring my dog:

"PostgreSQL Goes to 11!
A database management program has not yet ceased development. The speaker will read the version control commit log for one hour."

"Shouting at computers while some shoddy software desperately attempts to parse and respond to this input is apparently preferable to using any of the well-supported existing input devices that come with every single computer on earth, so this talk will be well-attended and extremely beneficial to anyone who has nothing better to do on Sunday afternoon."

"The Current and Future Tor Project
Updates from the Tor Project
The United States Defense Department's most successful honeypot sends its apex bureaucrat to reassure paranoid Europeans that they can still totally trust all this stuff, you guys. Everything's fine. We're on your side. Route all your traffic through us. It's for your own good."

And much more! Sounds better than a weekend in Reno with an ounce of coke and a stripper named Candy, and no more than twice as likely to leave you with a permanent infection!

Wake Up Light Up

I wake up, either to alarm or naturally (I'll sleep a random 4-8 hours and just blink be awake), turn off White Noise, play podcasts or music, read messages, usually play Animal Crossing or a gachapon game for a few minutes, then get up.

Before social media, say from 1999 to 2010, I had a Sharper Image white noise generator/travel alarm, and a GameBoy Color or DS.

Before that, all the way back to the '80s, I had my stereo playing softly, would crank it up and read or play Game & Watch type games. I can't remember what I did as a kid, I think I didn't sleep much.

How is it possible to sleep or wake up without electronics? Wouldn't the silence/incidental noises wake you up? Wouldn't the lack of stimulation make you fall back asleep?