British Pathé random video viewer

British Pathé recently released 90,000 videos on to YouTube (though I could only find 82058 of them) - I wanted to make some kind of mashup art with it, but was not creative enough to think of anything interesting. So, instead I present: Random video player! Randomly (and pretty-much-endlessly) play through the collection, marveling at the wonders of the not-so distant past.

If you want to play with the code, check out the repo... it's an ES6 React app, that uses RxJS to create and consume a stream of video ids based on button clicks & pop state events.

mrspeaker's head in a monitorYou find yourself at the entrance to the Hompage of Mr Speaker. In a darkened corner sits a trunk containing HTML5 games and some JavaScript tidbits. In a dark corner you spy a Twitter account. Exits are North, East, and .

?> _

Functions as RxJS Subjects

Here's a nifty trick if you're using RxJS, and want to subscribe to plain ol' function invocation. This is especially useful if you want to use React, and don't want to bind with Rx.Observable.fromEvent with standard DOM event listeners.

import Rx from 'rx';

const RxFuncSubject = () => {
  const subject = Object.assign(
    (...args) => subject.onNext(...args),
    Rx.Observable.prototype,
    Rx.Subject.prototype);

  Rx.Subject.call(subject);

  return subject;
};

export default RxFuncSubject;

We create a regular function that we extend with both Rx.Observable and Rx.Subject (you need to mix in Rx.Observable as this is extended by Rx.Subject internally).

The function passes its arguments along to the internal onNext function: so it can be called as a regular function but still act like a Subject:

const clicker = RxFuncSubject();
clicker.subscribe(() => console.log('clicked!'));
clicker(); // clicked!

Now it can be used in a normal React component, wherever a function call would be expected!

<MyComponent onClick={clicker} />

Five short years

On Friday, October 22, 2010 I conducted a scientific experiment: if one URL shortener can make a URL shorter, then fifteen URL shorteners can make it reaaaally short. The results were quite as you'd expect: the resulting link was longer than source, and browsers would go into convolutions trying to resolve the chain of shortened shorteners.

2010 was a big year for people who thought it would be a good idea to make smaller URLs. All it took was a rudimentary knowledge of a hash map and an hour of coding and suddenly you had a viable startup on your hands. There are a lot of URLs out there, so the thinking went, and people need a place to make them shorter. Phase 1: Shorten URLs...

So now it's 5 years later, and I thought it would be interesting to see what become of that unraveling chain of hopes and dreams. Here they are, in reverese order of resolve-y-ness:

  1. http://bit.ly/6YuThD ALIVE. Correctly resolves to mrspeaker.net
  2. http://goo.gl/oZrv ALIVE. Correctly resolves to mrspeaker.net
  3. http://tinyurl.com/34ve64r ALIVE. Correctly resolves to mrspeaker.net
  4. http://w8jyd.tk Service: ? Link: DEAD. I'm not even sure how this one ever worked!
  5. http://nik.im/4iB1 DEAD. Domain squatter-ed
  6. http://vbly.us/2ew7 ALIVE. "The internet's first and only sex-positive url shortener".
  7. http://alturl.com/gv49t ALIVE "Free short URLS since 1999"
  8. http://is.gd/gaWwV Service: ALIVE Link: DEAD. This looks reasonable though: "Link Disabled because of T&C violation".
  9. http://xrl.in/6jbi DEAD. Domain squatter-ed
  10. http://wurl.ca/?r=4oe DEAD. "Wurl Redirection Service is permanently closed."
  11. http://eweri.com/Eh1u DEAD. Domain squatter-ed
  12. http://snurl.com/1bmlco ALIVE. "Snippety snip snip". Whatever that means.
  13. http://lnk.nu/snurl.com/1g6o DEAD. Redirects link to a google.com 404.
  14. http://liteURL.com/?116051 DEAD. Domain squatter-ed. Also, my office router warns "Gateway BOTNET Filter Alert".
  15. http://linkzip.net/F/4JC ALIVE. Resolves correctly, but the service has a lovely broken image gif as a logo now.

I was quite impressed to discover that 8 out 15 still resolve the links correctly (counting the T&C violation). That means that only around half of world's shortened URLs now 404: much better than I thought! I'll revisit this post in 2020, so be sure to come back then to see how it goes - just keeping this handy 8x shortened link lying around. I've run it through all the remaining contenders, so I see no reason it won't resolve in another 5 years.

Explostyx: explody 3D french fries

Some more crazy 3D action in the form of Explostyx: explody 3D french fries thing. It's what happens when you make one simple thing and then just repeat it a whole stack of times. Like all good pop art.

It's using Three.js, and 100-odd lines of ES2015 - so it's a pretty simple example if you want to delve into either.

explostyx

Wanna do new JavaScript + React?

Here's the "easiest" way to get started with the latest version of JavaScript (so much new stuff in es2105!) and the most popular kid (for this week, at least) in the JS framework playground: React.

This approach uses the wonderful new JSPM package manager... so if you're not willing to place your bet on this particular horse, then head over to WebPack land to see if they have a similar guide. Also, if you want to see the final product - here's my "ES2015+React boilerplate".

  1. Create a new project with jspm install (and install JSPM if you haven't).

  2. Hit enter over all the defaults, except for Transpiler: traceur/babel?. Change this to Babel. It's more cool this week, and supports JSX.

  3. But it doesn't support JSX by default. To allow it, we need to tweak the babelOptions in the config.js file. Add the option "blacklist": [] to remove react from the blacklist.

  4. Next we need a simple index.html page. Inside the body tag:

    <body>
      <div id="app"></div>
      <script src="jspm_packages/system.js"></script>
      <script src="config.js"></script>
      <script>
        System.import('src/main');
      </script>
    </body>

    This loads the "System" module loader polyfill so we can load modules. The config file specifies a bunch of modules to load (such as React!). Finally, we do our own System.import and call our own file at /src/main.js.

  5. Add a script at /src/main.js. Make it look like this:

    import React from 'react';
    
    export default React.render(
      <div>Hello World </div>,
      document.querySelector('#app')
    );
  6. Serve it up. Use the simple web server of your choice (I like http-server) to serve the page, and test all is well.

Phew, quite a lot still - but worth it to get all the magical goodness. Plus it's all in the boilerplate repo if you don't want to do these steps every new project.

Alien vs Joy Division

Above is from "Alien" released in May 1979. Below is from Joy Division’s "Unknown Pleasures", April 1979.

Screenshot from Aliens, contrasted with the classic Joy Division album cover

Announcing JS.scala v0.1

I'm pleased to announce the initial releas of JS.scala. JS.scala compiles JavaScript source code to Scala source code, allowing you to write your web application entirely in JavaScript! Finally, the expressive power of JavaScript available on the JVM via Scala (some call it "the bytecode of the JVM bytecode").

How does it work? Well, given the JavaScript input:

const a = 42
const b = "Hello, World"
const sq = x => x * x
const dsq = x => {
  const dx = sq(x)
  return dx * dx
};
const d = dsq(a)

const exclaimer = {
  apply: name => name + "!"
}

exclaimer.apply("Hello, World")

We get the lovely Scala output:

val a = 42
val b = "Hello, World"
def sq (x:HandHolder) = x * x
def dsq (x:HandHolder) = {
  val dx = sq(x)
  dx * dx
}
val d = dsq(a)
object exclaimer {
  def apply (name:HandHolder) = name + "!"
}

exclaimer("Hello, World")

You can then compile this and deploy to production.

What about types?

Those who rely on their IDE for autocompletion, or their compiler for type-checking get nervous when they have to know the types of things, so the next step is to add Flow type inference (https://github.com/facebook/flow) types to AST to restrict the expressive power of JavaScript, but export valid Scala.

That's for v0.2 though (keep an eye on the repo)... for now it just replaces types with a "HandHolder" placeholder.

Oculus Rift Reddit Internet Explorer

Recently both Firefox and Chrome released VR-enabled version of their browsers. Just as Lawnmower Man predicted.

I decided to test them out with the Rift, by hacking together "Mr Speaker's Internet Explorer" (or the repo): It loads any ImgUr images in a sub, and finds related subs mentioned in the "about" info.

gallery view

To load new subreddits, either hit "/" and type the name of your favourite time-wasting spot, or, better, look for the small obelisks around the space that contain a "/r/sub" title. If you look at these and hit enter, it will load automagically - so you can walk around exploring the space.

load sub view

I'm still just messing around with it, but it's kind of useful/interesting enough that you can almost feel the metaverse approaching.

“let” is the new “with”. But good.

The ES2015's let and const keywords give us better (actually useful!) control over variable scope. We can use this to write code in a more terse, cleaner manner.

Mozilla's original implementation of let had support for non-standard let blocks that looked like this:

let (x = x+10, y = 12) {
  console.log(x+y); // 27
}

Let blocks also allowed us to define blocks similar to how we used to write with in the olden days: let (pos = obj.position) { pos.x++; }. I don't know why this got the boot from the final ES6 spec (I quite like the syntax), but we can recreate the idea using empty blocks and defining the variables like normal:

const stats = new Stats();
{
  const dom = stats.domElement;
  const style = dom.style;
  stats.setMode( 0 );
  style.left = "0px";
  style.top = "0px";
  document.body.appendChild( dom );
}

Thanks to const and let behaving sensibly, the dom and style are only defined inside the block. This gives us all the power of the let block, and none of the problems of the old school with statement.