Horrible Software

computers barely even work

JS: Date()

In JS, objects are normally constructed using the new operator:

new Blob()
// Blob { ... }

new Number(7)
// Number { 7 }

This is useful for constructing lots of things: Blob, MutationObserver, Date, and much more.

Different built-in types will do different things if their constructors are invoked without new:

// Most new types will return an error
Blob()
// Error: Failed to construct 'Blob': Please use the 'new' operator,
// this DOM object constructor cannot be called as a function.

// Some other types roll with the punches
Array()
// []

// JavaScript's boxed primitive types return the underlying primitive instead
Number(7)
// 7

Date is not one of these types.

new Date()
// Tue Dec 22 2020 01:01:16 GMT-0800 (Pacific Standard Time)

typeof new Date()
// object

Date()
// "Tue Dec 22 2020 01:01:26 GMT-0800 (Pacific Standard Time)"

typeof Date()
// string

Lua: debug.traceback

Lua has a function to capture stack traces. You can pass in a thread to capture the stack trace from, a message to prepend, and how many levels of the stack to skip. It returns a string.

The signature from the Lua 5.1 reference manual is:

debug.traceback ([thread,] [message [, level]])

We’ve got optional argument soup here, which is a recipe for disaster. Let’s open my trusty Lua 5.1 REPL and see what happens!

Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> =debug.traceback()
stack traceback:
        stdin:1: in main chunk
        [C]: ?

So far so good.

> =debug.traceback(1)
1
stack traceback:
        stdin:1: in main chunk
        [C]: ?

Okay, that’s kind of annoying – a numeric argument gets coerced into a string as message field. No big deal, we’ll just pass nil in for message.

> =debug.traceback(nil, 1)
nil

That’s interesting. Maybe nil is being interpreted as the thread argument. Let’s pass in the empty string instead.

> =debug.traceback("", 1)

stack traceback:
        stdin:1: in main chunk
        [C]: ?

It inserted a leading newline. Alright, that’s fine. Let’s put in nil for both thread and message.

> =debug.traceback(nil, nil, 1)
1

Wait, hold on, what?

> =type(debug.traceback(nil, nil, 1))
number
> =type(debug.traceback(nil, nil, {}))
table

Oof.

Boost: BOOST_FUNCTION_50

Check out this Boost source:

#if BOOST_FUNCTION_NUM_ARGS == 0
#  ifndef BOOST_FUNCTION_0
#    define BOOST_FUNCTION_0
#    include <boost/function/function_template.hpp>
#  endif
#elif BOOST_FUNCTION_NUM_ARGS == 1
#  ifndef BOOST_FUNCTION_1
#    define BOOST_FUNCTION_1
#    include <boost/function/function_template.hpp>
#  endif
#elif BOOST_FUNCTION_NUM_ARGS == 2
#  ifndef BOOST_FUNCTION_2
#    define BOOST_FUNCTION_2
#    include <boost/function/function_template.hpp>
#  endif

// ...
// this continues for some time
// ...

#elif BOOST_FUNCTION_NUM_ARGS == 49
#  ifndef BOOST_FUNCTION_49
#    define BOOST_FUNCTION_49
#    include <boost/function/function_template.hpp>
#  endif
#elif BOOST_FUNCTION_NUM_ARGS == 50
#  ifndef BOOST_FUNCTION_50
#    define BOOST_FUNCTION_50
#    include <boost/function/function_template.hpp>
#  endif
#else
#  error Cannot handle Boost.Function objects that accept more than 50 arguments!
#endif

PHP: Execution Operator

PHP has a shorthand form to execute shell commands and get their result.

<?php
$contents = `ls -a`;
echo $contents;

The manual says:

Use of the backtick operator is identical to shell_exec().

Why is it an operator?

You can even use backticks with interpolation to get bugs for free:

<?php
$files = "";
echo `rm -rf {$files}/*`;

PHP: String Increment

In PHP, what do you expect the following to output?

<?php
$x = "12a";
$x++;
echo $x;

If you guessed “error” or 12a, then you’re still sane, but sadly wrong.

The answer is 12b, due to PHP’s hybrid base-26/base-10 numeric system in strings.

Let’s try another one:

<?php
$x = "12z";
$x++;
echo $x;

Any guesses?

The answer is 13a. z wraps over to a (base 26), and then carries over to change 2 to 3. Of course!

Last one:

<?php
$x = "0d9";
$x++;
$x++;

echo $x;
echo gettype($x);

The answer is 1, and the type is double.

The first increment operator wraps 0d9 into 0e0 by the rules above. This happens to be the scientific notation for 0, unfortunately.

When we increment a string that looks like a number in scientific notation, PHP instead juggles it to be a number, then performs the operation on that!

This isn’t likely to come up in any real code, but that doesn’t stop this from being one of those bizarre features in PHP.

Blu-ray: oh no

To implement a conformant Blu-ray player, you need to implement something called BDJ, or Blu-ray Disc Java. This means that Blu-ray menu systems and special features are implemented as Java ME Xlets.

The specification requires that players provide local storage and network access to the content, alongside a standard UI toolkit and BDJ process management routines. This is intended to be used for optional content, like subtitles in obscure languages and advertising.

This is a physical media format that requires an implementation of Java ME and network access. Let that sink in.

PHP and ==: it gets worse

I found a Security StackExchange comment today that shows how PHP’s == operator can be legitimately dangerous.

It says:

md5('aabg7XSs') == md5('aabC9RqS') (-> true) is a good example why using == is a bad idea.

Another comment then goes on to explain in more detail:

For others’ benefit, this failure case occurs because the first byte of the resultant hash for each is 0e, which is considered to be a “float number format string” by PHP, and type coercion causes them to be compared as numbers.

Are there any cases where "0e04" == "0e08" makes sense to be true?

PHP: fputcsv

PHP has a function to format some input as a comma-separated sequence of values and write it to an open file handle.

It’s called fputcsv.

PHP does not have a function to perform this same operation without writing it to a file handle.

Python: Division

Python 2

5 / 2  # 2
5 // 2 # 2
5 / 2. # 2.5

Python 2 has integer division by default. That’s fine, if not a little bit odd for a dynamic language. Ruby does this too.

Python 3

5 / 2  # 2.5
5 // 2 # 2
5 / 2. # 2.5

Python 3 breaks compatibility with Python 2 by having floating-point division by default. This is also fine. Lua does this too.

Python 2 (again)

from __future__ import division

5 / 2  # 2.5
5 // 2 # 2
5 / 2. # 2.5

Python 2 can change the semantics of the division operator with an import.

Yes, this is for writing code that runs on both Python 2 and 3.

Yes, this is still kind of a scary prospect.

That word you're using: ES7

I don’t think you know what it means.

ES2016 (ES7) has a very well-defined set of features. The edition is shipped! Finalized! Implemented, even!

These features are not part of ES2016:

  • async/await
  • decorators
  • object spread
  • bind operator

The widespread labeling of these features as “ES7 features” is strange.

PHP: == is always wrong

JavaScript has some niche uses for ==, like checking for null or undefined in one check:

undefined == null; // true

It handles plenty of other cases with == just like you’d expect:

5 == true; // false
0 == null; // false
5 == "5 maids milking"; // false

A few other cases are kind of strange due to type juggling, which is why === is almost always better:

0 == false; // true
1 == true; // true! What is this, C?
1 == "1"; // true

PHP, however, takes the idea of type juggling a step further:

<?php

// Same as JS above
0 == false; // true
1 == true; // true
1 == "1"; // true

// ???
0 == null; // true
5 == true; // true
0 == "hello"; // true
5 == "5 jacks jumping"; // true
"0e04" == "0e08"; // WHAT!?

PHP’s == operator is never the correct choice. There’s no undefined vs nil to work with, and the comparisons that pass are nonsensical!

PHP: Variable Variables

PHP has a unique and (hopefully) seldom-used feature: variable variables.

<?php

$x = "Hello, world!";
$y = "x";

echo $$y; // Hello, world!

I hope never to find a design pattern where this makes sense as such a concise language-level feature. Some other languages have similar features, but all of them are either much more clunky or more explicit as to what’s happening.

Lua’s version only works on global variables, and is more explicit:

x = "Hello, world!"
y = "x"

print(_G[y]) -- Hello, world!

Python has a similar capability with dynamically-generated globals, but it’s still not a good idea:

globals()["x"] = "Hello, world!"
y = "x"

print(x) # Hello, world!
print(globals()[y]) # Hello, world!

Stay safe, stay statically-named.

PHP: Function Chaining

PHP has no notion of function chaining like most other languages, which nukes the idea of having clean function currying.

An idiomatic, but contrived Lua example:

local function add(x)
	return function(y)
		return x + y
	end
end

print(add(2)(2)) // 4

In PHP (5.6), this is a syntax error:

<?php

function add($x) {
	return function($y) use ($x) {
		return $x + $y;
	};
}

echo add(2)(2); // Error: parse error

There’s an RFC open from 2009 that has no activity. Cool.

PHP: Functions are Strings

PHP function references are just strings.

<?php

function abc() {
	echo "Hello, world!";
}

$myFun = "abc";
$myFun(); // "Hello, world!"

Yes, this is definitely a good idea.

JS: Array.prototype.sort

Sorting arrays of numbers in JavaScript is lexicographic:

const numbers = [20, 1, 100];
numbers.sort();

numbers; // [1, 100, 20]

This is surprising for lists of numbers, but makes some sense for lists of mixed types.

Giving JS a spaceship operator would yield a concise and only mildly hideous solution:

numbers.sort((a, b) => a <=> b);

numbers; // [1, 20, 100]