Coffee. Coding Soundtracks. Atom started up. Hit it.
Author: mdhughes
Zombie Sunday Music
- Astro-Creep 2000, by White Zombie
- La Sexorcisto, by White Zombie
- Screaming Down the Gravity Well, by Death Ride 69: A little light palate cleanser, and then:
- Previously: Monday Music, All Zombie Edition
Shitty Robots
- Beer robot
- Hammer robot: "I feel like this would be so much easier if I knew what I was doing!"
- Shitty Westworld robot
- Simone Giertz channel
I'm just laughing at the shitty robots, but there's some scary and then better news at the top of the channel.
Weird Saturday Music
- Traveller, by The Lord Weird Slough Feg
- Twilight of the Idols, by The Lord Weird Slough Feg
- Hardworlder, by Slough Feg: Shorter name, same weirdos
- Spaceship Zero, by The Darkest of the Hillside Thickets
- Great Old Ones, by The Darkest of the Hillside Thickets
- Jess and the Ancient Ones
- The Horse and Other Weird Tales, by Jess and the Ancient Ones
Traveller is, of course, the classic science fiction RPG. And you'll find a ton of other SF references on Slough Feg.
Darkest are a Cthulhu Mythos punk band. The concept album Spaceship Zero is from the fantastic RPG Spaceship Zero designed by the band, about a defunct German radio show of dubious existence, about a starship which, every time it uses the "BTL" drive, destroys the universe and recreates it as more Lovecraftian horror.
Jess and the Ancient Ones is new to me, but kinda Fleetwood Mac with magic and Mythos? Good stuff.
Julia
Interesting language, originally a math/statistics package but now as general-purpose as any lang. More or less Pythonic, though it has some type-annotation stuff, and heavily-optimized Julia looks like a mess of annotations with your code buried somewhere inside.
The Mac version comes as a dmg with an app (which I'd prefer for easy install/uninstall), or brew (which I prefer not to use). The app just launches a single command in a new Terminal window; add that path/bin to the PATH in your .profile, e.g.:
export JULIA_HOME="$HOME/Applications/Julia-1.0.app/Contents/Resources/julia"
export MANPATH="$MANPATH:$JULIA_HOME/share/man"
export PATH="$PATH:$JULIA_HOME/bin"
And now in Terminal:
% echo 'println("Hello, world!")' >hello.jl
% julia hello.jl
Hello, world!
The only way I can see to make it compile to a binary is embedding, and I'm not clear on how you package that with a full Julia distribution yet. That's unfortunate. I like REPL workflows as much as anyone, but binaries are what "normal" people run.
Getting Started
<voice tone="excessively chipper"> Let's read the manual! </voice>
Syntax is nicer than usual: function/end, if/elseif/else/end, for/end, while/end, begin/end, let/end, which beats the hell out of Python's def, if/elif/else; to say nothing of abominations like Swift's "func". No do/while loop, which is annoying especially for file processing, but I suspect that can be fixed with macros.
There's a lot of ways to write functions, which is nice but allows some ugly choices. Anonymous functions are x->x^2
or function(x) x^2 end
; named functions can just be assigned f(x)=x^2
or written in full:
function f(x)
return x^2
end
Whitespace is not significant, and indentation is not enforced, which is a major bummer for style-enforcing-structure, but I'm sure sloppy jerks will love that.
You can use tuples for multiple returns, or as ad-hoc structures:
> point(x, y) = (x=x, y=y)
point (generic function with 1 method)
> p = point(13, 2)
(x = 13, y = 2)
> a, b = p
(x = 13, y = 2)
> a
13
It's pass-by-reference, not copying, so be careful with mutable data.
My only real kvetch so far is that arrays are 1-indexed and column-major, like FORTRAN, not 0-indexed and row-major, like C. For a numeric package, that makes sense, but for other programming tasks it's frustrating and error-prone, see EWD 831.
This is a functional language, and there are no classes/inheritance/methods, however "methods" are functions which are overloaded based on types, and can be used like class methods:
> quack(x::Int64) = "int $x"
> quack(x::Float64) = "float $x"
> quack(1)
"int 1"
> quack(6.66)
"float 6.66"
As well, you can use closures to make pseudo-classes, the same way you do in Scheme:
let state = 0
global counter() = (state += 1)
global counterReset() = (state = 0)
end
struct
(immutable) and mutable struct
make "Composite types", and can make objects the usual way:
struct Point
x
y
end
pointDist(p::Point) = sqrt(p.x^2 + p.y^2)
Base.show(io::IO, p::Point) = print(io, "{$(p.x),$(p.y)}")
> p = Point(6, 6)
{6,6}
> pointDist(p)
8.48528137423857
The default constructor can be overridden at the end of the field list, it's defined as Point(x,y) = new(x,y)
. The "toString" equivalent there is ugly as hell, but there's a ton of options for overloading it by type of output.
There's a lot of fucking around with generics and strong typing (for weak minds), but ignore all that crap.
Interfaces are a somewhat messy use of several methods to create pseudo-types; define the basic interface methods for your type, and most things calling those interface methods will work. So, a couple iter() functions and you have an iterable, and so on. This would work much better if Julia had an actual OOP class system and real interfaces, but Python half-asses interfaces the same way and aside from being 1000x slower than you'd like, it gets by.
Quickly skimming modules, seems pretty standard import mechanism, but I don't see any way to make something private. OK, I'm bored of reading docs. Let's do something. Something semi-practical here, my standard RPN calculator, one command per line.
Docs/libraries are kind of a mess, Vector is discussed in Base.Arrays, push!/pop! methods are discussed in Collections (an interface). parse is under Numbers, not Strings, as one might expect.
eof() does the extremely unfortunate thing of blocking for input, so it's utterly useless in a main interactive loop.
… About 30 minutes later, I have a working, final version. Well, that was pretty easy, and it's a clean implementation, other than the interactive loop.
Next time I open this, I'll put it in a module, and tokenize the line instead of requiring just one token per line, and have some command-line argument to suppress help and prompts.
I should also investigate IJulia which is a Jupyter notebook, which seems like the "expected" way to make it interactive and handle graphics or media.
RPNCalc.jl
#!/usr/bin/env julia
# RPNCalc.jl
# Copyright ©2018 by Mark Damon Hughes. All Rights Reserved.
stack = Vector()
function checkStack(n)
if length(stack) < n
error("Stack underflow: Needs $n values")
end
end
function parseLine(s)
s = strip(s)
if s == "+"
checkStack(2)
b = pop!(stack); a = pop!(stack)
push!(stack, a + b)
elseif s == "-"
checkStack(2)
b = pop!(stack); a = pop!(stack)
push!(stack, a - b)
elseif s == "*"
checkStack(2)
b = pop!(stack); a = pop!(stack)
push!(stack, a * b)
elseif s == "/"
checkStack(2)
b = pop!(stack); a = pop!(stack)
push!(stack, a / b)
elseif s == "="
checkStack(1)
println(stack[end])
else
push!(stack, parse(Float64, s) )
end
end
function main()
println("RPN Calc: Type numbers or operators (+, -, *, /) one at a time, = to show top of the stack, ^D to end.")
while true
print("> "); flush(stdout)
s = readline(stdin, keep=true)
if s == ""
println("Goodbye")
break
end
try
parseLine(s)
catch e
println(e.msg)
end
end
end
main()
Techno Thursday Music
Beyond Cyberpunk Web Design
- Beyond Cyberpunk: 1991 Hypercard stack
- BCP web version
- Cyberpunk, by Billy Idol: I like it, I don't care if he's a cheesy little idiot.
- Billy Idol's Cyberpunk Mac app: I can't find an emulator of it, but it's just interactive liner notes and a couple screen savers. Enjoy.
- Archive of Hotwired.com from 1997: Most of the art wasn't saved, it's often broken, but you can get some idea of what it was like.
What I want to note here is the UI in the original BCP and Billy's app. Borders filled with wiring and lights. Knobs and switches. Big chunky click areas. Punk rock, graffiti art. When you click things, audio and animations tell you something happened. Not so much the "Jacking into the Matrix. Into the FUTURE!" clip.
It's much easier to find and read information in the web version, but it's not fun. It's ugly and boring. Like almost everything on the web and apps these days, from Jony IVE-1138's sterile white room prisons where you're tortured for daring to have a personality, to all these endless linkblogs.
There are places with personality, but not many. The web looks like shit. Update: Brutalist Websites has some GeoCities-like aesthetics in a few. Others are sterile voids.
And that's bothering me about this blog. It looks OK, the stolen Midgar art and my '80s neon colors set some kind of tone, but it can be so much more. So in the weeks and months to come, I'm gonna be doing some redesign, make this into something weirder, if not full-on GeoCities. The RSS feed should be uninterrupted, but I'm going to put a lot more resources on the front page.
Just One Fix Wednesday Music
- Psalm 69, by Ministry
- The Mind is a Terrible Thing to Taste, by Ministry
- Ænima, by Tool: Still not on Apple Music, because they like their cover art too much. So instead they get nothing from this YT rip.
- Lateralus, by Tool
- Big Hit, by Nitzer Ebb
- Showtime, by Nitzer Ebb
Mellow & Blitzed Tuesday Music
- Secret Messages, by Electric Light Orchestra
- The Albums 1971-1982, by Marvin Gaye
- A Kind of Magic, by Queen
- The Long Run, by Eagles
- After Hours, by Glenn Frey
It's OK to get your drink on early today.
Kronar returns in a 24-page comic Dark Miasma! Oglaf is super NSFW, tho this one is pretty tame, but if you read the previous Kronar stories be prepared for… well, be prepared.