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-private.h"
 "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-private.h"

@interface CLICalc : NSObject

@property (retain) NSMutableArray *stack;

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

@end

and src/CLICalc.m:

// CLICalc.m
 "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;
}

@end

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

Hooray!

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.

python-foot

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 = 
normal-background = 
keyword-foreground = 
keyword-background = 
builtin-foreground = 
builtin-background = 
comment-foreground = 
comment-background = 
string-foreground = 
string-background = 
definition-foreground = 
definition-background = 
hilite-foreground = 
hilite-background = 
break-foreground = 
break-background = 
hit-foreground = 
hit-background = 
error-foreground = 
error-background = 
cursor-foreground = 
stdout-foreground = 
stdout-background = 
stderr-foreground = 
stderr-background = 
console-foreground = 
console-background = 
context-foreground = 
context-background = 

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

print("READY")

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 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 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
    au!
    autocmd BufRead,BufNewFile *.c set ai tw=0
augroup END

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

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

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

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

augroup python
    au!
    autocmd BufRead,BufNewFile *.py set ai tw=0
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!

mystic-dungeon-2019-02-23

Connect with: telnet mysticdungeon.club 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!

Dungeon-2019-02-23-23.56.20
Dungeon-2019-02-23-23.56.45

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?

Ready Player One

I loved the book of Ready Player One. It plays with deep matters of '80s nerdery, namely original and "Advanced" Dungeons & Dragons and especially S1 Tomb of Horrors, old microcomputer, arcade, and home video games (and the very different kinds of games on them), and Rush's more esoteric albums. It's kind of incomprehensible if you weren't alive in the '70s and '80s and into these specific things. It's pretty brilliant if you were. It's a story of logic puzzles, careful research, and follows much of the story structure of WarGames.
★★★★★

The movie is none of these things. It's a very pretty film, largely CGI inside the OASIS MMO, but replaces the intellectual challenges with a very stupid car race; a very precise and funny adaptation of a cinemaphile but not geek movie which was NOT in the book and very out of Halliday's interests; and a final battle, well adapted in scale and craziness, but the final key being in… is this a spoiler if it's in section 0000 of the book? Adventure for 2600. Well, it's kind of too obvious to even mention, if you're looking for an Easter Egg. Did IQs drop sharply in the Spielberg-verse?

SUPER picky detail (but this is in fact what the book is about, being super picky): In the funeral/contest video, the quarters on James Halliday's eyes in the movie were, if my eyes did not deceive me, from 1972. Book says:

"High-resolution scrutiny reveals that both quarters were minted in 1984."

Why change it? Because either they didn't care, or because Spielberg is literally older than dirt, older than rocks, older than "Steven Spielberg is old" jokes, so old that he thinks 1972 is "better" than 1984 (it is not). Everything else about the funeral video is wrong, too, but that's beside my point here about picky detail.

Ogden appears like a Willy Wonka at the end, in a fairly crappy, formulaic ending. It's fucking Spielberg, so you know it's going to be schmaltzy and fall apart at the end, but the extent of the failure is almost epic. The hobbits^W corporate research drones cheering Wade at the end is nonsense filmmaking.

The music varies from great '80s pop music, sometimes in appropriate places; a few pieces of '80s soundtrack music in exactly the right place; to poorly-timed, almost counterproductive incidental music. I loathe Saturday Night Fever, as previously mentioned, and having another dance scene based on it is annoying; the book does mention "Travoltra"[sic] dancing software, but you don't have to see or hear it. I felt nothing from the incidental music. Did Spielberg go deaf in his extreme old age? His old films at least had good scores, but this was vapid.

The final "rule" of disabling the OASIS, the global center of business, education, and entertainment, on Tuesday and Thursday is so stupid only a very stupid old filmmaker could conceive of it.

There is no Ferris scene after the credits, which would have been a great place to at least leave us smiling, instead of "huh, that was not good".

It lacks the brains, heart, and music of a classic '80s film. Go watch TRON or WarGames instead.

★★½☆☆ only because it is so very pretty, ★☆☆☆☆ for plot. Validates my movie policy that book adaptations are always worse than the book, and adds a new one: Don't watch anything by Steven Spielberg. Will some kind nursing home attendant not just put a pillow over his face and end our suffering?

How Much Computer?

I learned to program on a TRS-80 Model I. And for almost any normal need, you could get by just fine on it. You could program in BASIC, Pascal, or Z80 assembly, do word-processing, play amazing videogames and text adventures, or write your own.

There's still people using their TRS-80 as a hobby, TRS-80 Trash Talk podcast, TRS8BIT newsletter, making hardware like the MISE Model I System Expander. With the latter, it's possible to use it for some modern computing problems. I listen to the podcast out of nostalgia, but every time the urge to buy a Model I and MISE comes over me, I play with a TRS-80 emulator and remember why I shouldn't be doing that.

If that's too retro, you can get a complete Raspberry Pi setup for $100 or so, perfectly fine for some light coding (hope you like Vim, or maybe Emacs, because you're not going to run Atom on it), and most end-user tasks like word processing and email are fine. Web browsing is going to be a little challenging, you can't keep dozens or hundreds of tabs open (as I insanely do), and sites with creative modern JavaScript are going to eat it alive. It can play Minecraft, sorta; it's the crippled Pocket Edition with some Python APIs, but it's something.

I'm planning to pick one up, case-mod it inside a keyboard, and make myself a retro '80s cyberdeck, more as an art project than a practical system, but I'll make things work on it, and I want to ship something on Raspbian.

"It was hot, the night we burned Chrome. Out in the malls and plazas, moths were batting themselves to death against the neon, but in Bobby's loft the only light came from a monitor screen and the green and red LEDs on the face of the matrix simulator. I knew every chip in Bobby's simulator by heart; it looked like your workaday Ono-Sendai VII, the "Cyberspace Seven", but I'd rebuilt it so many times that you'd have had a hard time finding a square millimeter of factory circuitry in all that silicon."
—William Gibson, "Burning Chrome" (1985)

Back in the day, I would work on Pascal, C, or Scheme code in a plain text editor (ed, vi (Bill Joy's version), or steVIe) all morning, start a compile, go to lunch, come back and read the error log, go through and fix everything, recompile and go do something else, repeat until I got a good build for the day. Certainly this encouraged better code hygiene and thinking through problems instead of just hitting build, but it wasn't fun or rapid development. So that's a problem with these retro systems; the tools I use take all RAM and CPU and want more.

"Are you stealing those LCDs?" "Yeah, but I'm doing it while my code compiles."

These days, I mostly code in Atom, which is the most wasteful editor ever made but great when it's working. I expect my compiles to take seconds or less (and I don't even use the ironically-named Swift). When I do any audio editing (in theory, I might do some 3D in Unity, or video editing, but in practice I barely touch those), I can't sit there trying an effect and waiting minutes for it to burn the CPU. And I'm still and forever hooked on Elder Scrolls Online, which runs OK but not highest-FPS on my now-3-year-old iMac 5k.

For mobile text editing and a little browsing or video watching, I can use a cheap iPad, which happily gets me out of burning a pile of money on laptops. But I'm still stuck on the desktop work machine, I budget $2000 or more every 4 years for a dev and gaming Mac. Given the baseline of $8000 for an iMac Pro I'd consider useful, and whatever more the Mac Pro is going to cost, I'd better get some money put together for that.

I can already hear the cheapest-possible-computer whine of "PC Master Race" whom I consider to be literal trailer trash Nazis in need of a beating, and I'd sooner gnaw off a leg than run Windows; and Lindorks with dumpster-dived garbage computers may be fine for a little hobby coding, but useless for games, the productivity software's terrible (Gimp and OpenOffice, ugh), and the audio and graphics support are shit. The RasPi is no worse than any "real" computer running Linux.

'80s low-end computers barely more than game consoles were $200, and "high-end" with almost the same specs other than floppy disks and maybe an 80-column display were $2500 ($7921 in 2017 money!!!), but you simply couldn't do professional work on the low-end machines. Now there's a vast gulf of capability between the low-end and high-end, the price difference is the same, and I still need an expensive machine for professional work. Is that progress?

Data and Reality (William Kent)

A book that's eternally useful to me in modelling data is William Kent's Data and Reality. Written in what we might call the dark ages of computing, it's not about specific technologies, but about unchanging but ever-changing reality, and strategies to represent it. Any time I get confused about how to model something or how to untangle someone else's representation, I reread a relevant section.

The third ambiguity has to do with thing and symbol, and my new terms
didn’t help in this respect either. When I explore some definitions of
the target part of an attribute, I get the impression (which I can’t
verify from the definitions given!) that the authors are referring to
the representations, e.g., the actual four letter sequence “b-l-u-e”,
or to the specific character sequence “6 feet”. (Terms like “value”,
or “data item”, occur in these definitions, without adequate further
definition.) If I were to take that literally, then expressing my
height as “72 inches” would be to express a different attribute from
“six feet”, since the “value” (?) or “data item” (?) is different. And
a German describing my car as “blau”, or a Frenchman calling it
“bleu”, would be expressing a different attribute from “my car is
blue”. Maybe the authors don’t really mean that; maybe they really are
willing to think of my height as the space between two points, to
which many symbols might correspond as representations. But I can’t be
sure what they intend.
—Bill Kent

I originally read the 1978 edition in a library, eventually got the 1998 ebook, and as of 2012 there's a posthumous 3rd edition which I haven't seen; I would worry that "updated examples" would change the prose for the worse, and without Bill having the chance to stop an editor.

See also Bill Kent's website for some of his photography and other papers.

This book projects a philosophy that life and reality are at bottom
amorphous, disordered, contradictory, inconsistent, non- rational, and
non-objective. Science and much of western philosophy have in the past
presented us with the illusion that things are otherwise. Rational views
of the universe are idealized models that only approximate reality. The
approximations are useful. The models are successful often enough in
predicting the behavior of things that they provide a useful foundation
for science and technology. But they are ultimately only approximations
of reality, and non-unique at that.

This bothers many of us. We don’t want to confront the unreality of
reality. It frightens, like the shifting ground in an earthquake. We are
abruptly left without reference points, without foundations, with
nothing to stand on but our imaginations, our ethereal self-awareness.

So we shrug it off, shake it away as nonsense, philosophy, fantasy. What
good is it? Maybe if we shut our eyes the notion will go away.
—Bill Kent

★★★★★