Why the Pomodoro technique doesn’t work for me

My friend Amanda writes a great blog over at Capture30Days. Her recent post “getting stuff done” outlines the Pomodoro technique: work for 25 minutes uninterrupted, take a 5 minute break, start again. I think it works great for some sorts of work.

It doesn’t work for me.

I had tried this technique, but I found for my sort of work it sometimes was in fact harmful.  I guess my work (designing educational apps) swings between product design (creative, collaborative) and programming (a different sort of creative, lots of problem solving, often on my own) and so I sometimes need to just work through a task list and have lots of interactions with others, and I sometimes need to have long periods of uninterrupted focus.

For the programming especially (and to an extent the design also), I have to work hard to get into a “flow” state, where I get the entire mental model of what I’m creating in my head, so that I can work and create efficiently, remembering how all of the different pieces of my app are supposed to fit together.  It can take me a couple of hours to get into this state.  And when I’m in this state, I don’t want to stop.

And knowing I have to stop, because my 25 minutes is up and it’s time for a 5 minute break, or because I have a meeting, or because it’s lunch time, can seriously throw me off.  I’m not the only one.  Paul Graham contrasts the “managers schedule” (1 hour blocks, optimised for meetings) and the “makers schedule” (usually blocks into “morning”, “afternoon” and “working into the night”, optimised for creative work).  He makes the point that for a creative, a single meeting can destroy a whole afternoon.  I definitely have experienced that.

So, alternative to the Pomodoro technique?  I personally go for the 1-3-5 technique.  It goes like this:

Today I will achieve:

  • 1 Big Things:
    _______________
  • 3 Medium Things
    _______________
    _______________
    _______________
  • 5 Small Things
    _______________
    _______________
    _______________
    _______________
    _______________

I find this gives me the flexibility I need to work on big tasks that require long periods of focus, as well as help me not forget the small things that also need doing.  In reality, a day may end up looking like this

  • Morning:
    Small task 1 – emails
    Small task 3 – voicemails and phone calls
    Small task 4 – fix small bug
    Medium Task 1 – draw interface designs for a new feature
  • Afternoon:
    Small Task 5 – responding to support questions
    Big Task – programming a new feature
    Medium Task 2 – got started finding a bug, did not finish.

If I’m having trouble getting into “the zone” or “flow”, I start with the small tasks and work my way up to the big ones.  If I get stuck on one task, I jump to a different one.  Then anything I don’t get done, goes on to the list for the next day.

Finally, there’s a website which makes this easy: http://1-3-5.com/  I set that site as my homepage, so every time I open a new tab, rather than Google or Facebook, I see my task list.

Do you have any tips for staying focused and managing your time when working on creative or programming projects?  Especially when you don’t have a formal workplace to keep you accountable :)

Cowards

“All right, but let the one who has never sinned throw the first stone!” Then he stooped down again and wrote in the dust.

When the accusers heard this, they slipped away one by one, beginning with the oldest, until only Jesus was left in the middle of the crowd with the woman.

I used to notice 3 groups here: the accusers, the accused, the defender. I had a hard time imagining which group I would realistically fall into.

I’m not often confronted and threatened for my errors, I’m not the sort to condemn others for theirs either. Yet I usually lack the courage to defend the accused and stand up to the crowd, so I can’t honestly group myself with Jesus in this story.

I guess I fit with the group I never noticed before today: the onlookers. The crowd, drawn into the drama, not sure of what they think, but afraid to speak up, lest they say something wrong and find themselves the new target of the accusers.

Quote

Lord, thank you for using the foolish to confound the wise and the weak ones to shame the strong.  Help us live with the shrewdness of serpents and the innocence of doves.  Keep our feet from fatigue, our spirits from despair, our hands from failing to love and our mouths from failing to sing in praise to you.  Amen.

Smaller miracles

It was haunting last night to walk into the hospital and see my Grandpa.

I watched my Dad pray for his Dad. As a pastor he’s prayed for many people. It’s hard to pray for someone who may well be on their deathbed. I imagine it’s harder still when it’s your dad. “Father of mercies…” he prayed.

What mercy can you ask for? It felt too late to pray for a miracle. At that age, and with cancers already leaving visible scars all over the body, you only ask for small miracles. For relief from pain, for peace, for comfort for our family.

Yet even a healing at this late stage, miraculous as it would be, would only be a small miracle.

The bigger miracle is the one that already happened. In my 26 years I’ve only ever known my Gramps as fun loving, and family loving. When he’d play jokes on us, (which he did often, he loved it), his heart was always warm, and it was fun. It wasn’t always that way apparently. I don’t know the full story, but there was alcohol, there was aggression, and he was described, light on the details, as “not a very nice person”. Until Jesus changed him. A change in personality and in heart, of that magnitude, is not common. It’s a miracle, a redemptive act of God that took something broken and made it better, made it beautiful. It is no small miracle that I only ever knew the beautiful heart of my Grandpa.

The other miracle is that the next time I see my Grandpa, the cancer will be gone from his body, his face will be young again (younger and stronger and happier than I’ve ever seen). The fragile, hurting body I saw last night will be restored and perfected. And he’ll be with his wife Shirley again, surely as happy in that moment as in the moment captured in the wedding photo on our family room. And his kids. And us grandkids. The redemption of people: our bodies, our hearts, our relationships. That miracle is huge.

After walking out last night I struggled with finding the mercy in an old man suffering. And my faith for miraculous healings isn’t what it used to be. Today when I got the call from my Dad though, amidst the tears was a gratefulness, and a hopefulness, for the greater miracles.

Language and API Design

Paul Graham has written some great essays over time, and most of them hold up surprisingly well as they age.  Take this article, “Five Questions About Language Design“.  Written in May 2001.  That’s over 12 years ago from today as I read it, and many of his predictions have come to pass (the dominance of web applications, the rise in popularity of niche programming languages), and most of his logic is still sound, and still insightful.

Two particular points I found interesting, and would be interesting to the Haxe community I spend most of my time in:

4. A Language Has to Be Good for Writing Throwaway Programs.

You know what a throwaway program is: something you write quickly for some limited task. I think if you looked around you’d find that a lot of big, serious programs started as throwaway programs. I would not be surprised if most programs started as throwaway programs. And so if you want to make a language that’s good for writing software in general, it has to be good for writing throwaway programs, because that is the larval stage of most software.

I think Haxe is beginning to show it’s strength here in gaming.  People are using it for Ludlam Dare (write a game in a single weekend), and then later the game scales up to be a full-featured, multi-platform, often commercial game.  Haxe is good for a quick win (especially when targetting flash), but then you have the options to target so many other platforms as your vision for your game/app expands.

I’d love to see ufront get this good.  I have so many things I would like to use as an app, but which I don’t feel justify an ongoing subscription to an online company.  Many of them could get an MVP (minimal viable product) out in a weekend, if the framework was good enough.  And it’s getting good enough, but still a little way to go :)

And then this:

2. Speed Comes from Profilers.

Language designers, or at least language implementors, like to write compilers that generate fast code. But I don’t think this is what makes languages fast for users. Knuth pointed out long ago that speed only matters in a few critical bottlenecks. And anyone who’s tried it knows that you can’t guess where these bottlenecks are. Profilers are the answer.

Language designers are solving the wrong problem. Users don’t need benchmarks to run fast. What they need is a language that can show them what parts of their own programs need to be rewritten. That’s where speed comes from in practice. So maybe it would be a net win if language implementors took half the time they would have spent doing compiler optimizations and spent it writing a good profiler instead.

Nice insight.  I sometimes worry that the code I’m writing will be slow.  It’s hard to know if optimisations are worth it, especially if it may compromise code readability etc.  A better solution would be to focus on making profiling easy.  On the JS target you can easily use the browser tools to show profiling information.  Another option is to bake it into your Haxe code, something that the “massivecover” lets you do.  Wiring that support from massivecover into ufront or other frameworks, and generating pretty reports, would be a very cool way to encourage people to write fast apps.

You cannot use @:build inside a macro : make sure that your enum is not used in macro

If you ever come across this error, it can be a bit cryptic to understand.

Here’s some sample code that produces the error:

import haxe.macro.Expr;
import haxe.macro.Context;
import neko.Lib;

class BuildInMacroTests 
{
    public static function main() {
        var s:MyModel = new MyModel();
        MyMacro.doSomething( s );
    }
}

class MyModel extends sys.db.Object // has a build macro
{
    var id:Int;
    var name:String;
}

private class MyMacro 
{
    public static macro function doSomething(output : Expr) : Expr {
        return output;
    }
}

I’m still not sure I have a full grasp on it, but here’s a few pointers:

  • It’s not necessarily an enum – it can happen with a class or interface that has a “@:build” macro also.
  • The basic sequence happens in this order:
    • BuildInMacrosTest.main() is the entry point, so the compiler starts there and starts processing.
    • When it hits “var s:MyModel”, it does a lookup of that type, realizes the class needs a build macro to run, and runs the build macro.
    • When it hits “MyMacro.doSomething()”, it types the expression, and realizes that it is a macro call.  To run the macro, it must find the macro class, load it into the macro context, and execute it.
    • It finds the macro class, it’s in this file.
    • It tries to load this module (hx file) into the macro context, so it goes through the whole process of typing it again.
    • As it’s loading it into the macro context, it hits the “MyModel” build macro again, which it can’t do at macro time, so it spews out the error.
  • The basic solutions:
    • Wrap your build macro declarations in conditionals:
      #if !macro @:build(MyMacro.build()) #end class Object { ... }
    • Wrap anything that is not a macro in conditionals:
      #if !macro 
        class BuildInMacroTests {}
        class MyModel {}
      #else
        class MyMacro {}
      #end
    • Keep your macros in seperate files:
      BuildInMacroTests.hx:
          class BuildInMacroTests {
              public static function main() {
                  var s:MyModel = new MyModel();
                  MyMacro.doSomething( s );
              }
          }
      
          class MyModel extends sys.db.Object {
              var id:Int;
              var name:String;
          }
      
      MyMacro.hx:
          import haxe.macro.Expr;
          import haxe.macro.Context;
          class MyMacro {
              public static macro function doSomething(output : Expr) : Expr {
                  return output;
              }
          }

A combination of the 1st and 3rd solutions is probably usually the cleanest.

Good luck!

A Haxe/JS Debugging Tip

When targetting Haxe JS in Haxe 3, the output is “modern” style, which means, to prevent polluting the global namespace or conflicting with other libraries, the output is wrapped in a simple function:

(function() {})()

Which is great.  And if you place breakpoints in your code, using:

js.Lib.debug();

Then your browser will launch the debugger inside this Haxe context, and you have access to all your classes etc.  But what if you want to fire up the browser’s JS console, and gain arbitrary access to something in your Haxe code?  Because it’s all hidden inside that function, you can’t.

Unless you have a workaround, which looks like this:

class Client 
{
    @:expose("haxedebug") @:keep
    public static function enterDebug()
    {
        js.Lib.debug();
    }
}

What’s going on: we have a class, and a function: “enterDebug”.  This function can go in any class that you use, really – it doesn’t have to be in Client or your Main class or anything.

The “js.Lib.debug()” statement launches the debugger in the haxe context, as described before.  But the “@:expose” metadata exposes this function outside of the Haxe context.  The string defines what we expose it as: rather than the default “Client.enterDebug()”, we’ll just have “haxedebug()”.  And the “@:keep” metadata makes sure this won’t get deleted by the compilers Dead Code Elimination, even though we may never explicitly call this function in our code.

Now that we’ve done that, recompile, and voilà!  You can type “haxedebug()” into the Javascript console and start fiddling around inside the Haxe context.  Enjoy.

 

Creating Complex URL Routing Schemes With haxe.web.Dispatch

Complex Routing Schemes with haxe.web.Dispatch

I’ve looked at haxe.web.Dispatch before, and I thought it looked really simple – in both a good and a bad way. It was easy to set up and fast. But at first it looked like you couldn’t do complex URL schemes with it.

Well, I was wrong.

At the WWX conference I presented some of the work I’ve done on Ufront, a web application framework built on top of Haxe. And I mentioned that I wanted to write a new Routing system for Ufront. Now, Ufront until now has had a pretty powerful routing system, but it was incredibly obese – using dozens of classes, thousands of lines of code and a lot of runtime type checking, which is usually pretty slow.

Dispatch on the other hand uses macros for a lot of the type checking, so it’s much faster, and it also weighs in at less than 500 lines of code (including the macros!), so it’s much easier to comprehend and maintain. To wrap my head around the ufront framework took me most of the day, following the code down the rabbit hole, but I was able to understand the entire Dispatch class in probably less than an hour. So that is good!

But there is still the question, is it versatile enough to handle complex URL routing schemes? After spending more time with it, and with the documentation, I found that it is a lot more flexible than I originally thought, and should work for the vast majority of use cases.

Learning by example

Take a look at the documentation to get an idea of general usage. There’s some stuff in there that I won’t cover here, so it’s well worht a read. Once you’ve got that understood, I will show how your API / Routing class might be structured to get various URL schemes:

If we want a default homepage:

function doDefault() trace ( "Welcome!" ); 

If we want to do a single page /about/:

function doAbout() trace ( "About us" ); 

If you would like to have an alias route, so a different URL that does the same thing:

inline function doAboutus() doAbout();

If we want a page with an argument in the route /help/{topic}/:

function doHelp( topic:String ) { 
 trace ( 'Info about $topic' ); 
} 

It’s worth noting here that if topic is not supplied, an empty string is used. So you can check for this:

function doHelp( topic:String ) { 
 if ( topic == "" ) { 
 trace ( 'Please select a help topic' ); 
 } 
 else { 
 trace ( 'Info about $topic' ); 
 } 
} 

Now, most projects get big enough that you might want more than one API project, and more than one level of routes. Let’s say we’re working on the haxelib website (a task I might take on soon), there are several pages to do with Projects (or haxelibs), so we might put them altogether in ProjectController, and we might want the routing to be available in /projects/{something}/.

If we want a sub-controller we use it like so:

/*
 /projects/ => projectController.doDefault("")
 /projects/{name}/ => projectController.doDefault(name)
 /projects/popular/ => projectController.doPopular
 /projects/bytag/{tag}/ => projectController.doByTag(tag) 
*/ 
function doProjects( d:Dispatch ) { 
 d.dispatch( new ProjectController() ); 
} 

As you can see, that gives a fairly easy way to organise both your code and your URLs: all the code goes in ProjectController and we access it from /projects/. Simple.

With that example however, all the variable capturing is at the end. Sometimes your URL routing scheme would make more sense if you were to capture a variable in the middle. Perhaps you would like:

/users/{username}/ 
/users/{username}/contact/ 
/users/{username}/{project}/ 

Even this can still be done with Dispatch (I told you it was flexible):

function doUsers( d:Dispatch, username:String ) { 
 if ( username == "" ) { 
 println("List of users"); 
 } 
 else { 
 d.dispatch( new UserController(username) ); 
 } 
} 

And then in your username class:

class UserController { 
 var username:String; 
 public function new( username:String ) { 
 this.username = username; 
 } 
 function doDefault( project:String ) { 
 if ( project == "") { 
 println('$username\'s projects'); 
 } 
 else { 
 println('$username\'s $project project'); 
 } 
 } 
 function doContact() { 
 println('Contact $username'); 
 } 
} 

So the username is captured in doUsers(), and then is passed on to the UserController, where it is available for all the possible controller actions. Nice!

As you can see, this better represents the heirarchy of your site – both your URL and your code are well structured.

Sometimes, it’s nice to give users a top-level directory. Github does this:

http://github.com/jasononeil/

We can too. The trick is to put it in your doDefault action:

function doDefault( d:Dispatch, username:String ) {
  if ( username == "" ) { 
 println("Welcome"); 
 } 
 else { 
 d.dispatch( new UserController(username) ); 
 } 
} 

Now we can do things like:

/ => doDefault() 
/jason/ => UserController("jason").doDefault("") 
/jason/detox => UserController("jason").doDefault("detox") 
/jason/contact => UserController("jason").doContact() 
/projects/ => ProjectController.doDefault("") 
/about/ => doAbout() 

You can see here that Dispatch is clever enough to know what is a special route, like “about” or “projects/something”, and what is a username to be passed on to the UserController.

Finally, it might be the case that you want to keep your code in a separate controller, but you want to have it stay in the top level routing namespace.

To use a sub-controller add methods to your Routes class:

inline function doSignUp() (new AuthController()).doSignUp(); 
inline function doSignIn() (new AuthController()).doSignIn(); 
inline function doSignOut() (new AuthController()).doSignOut(); 

This will let the route be defined at the top level, so you can use /signup/ rather than /auth/signup/. But you can still keep your code clean and separate. Winning. The inline will also help minimise any performance penalty for doing things this way.

Comparison to Ufront/MVC style routing

Dispatch is great. It’s light weight so it’s really fast, and will be easier to extend or modify the code base, because it’s easier to understand. And it’s flexible enough to cover all the common use cases I could think of.

I’m sure if I twisted my logic far enough, I could come up with a situation that doesn’t fit, but for me this is a pretty good start.

There are three things the old Ufront routing could do that this can’t:

  1. Filtering based on whether the request is Post / Get etc. It was possible to do some other filtering also, such as checking authentication. I think all of this can be better achieved with macros rather than the runtime solution in the existing ufront routing framework.
  2. LocalizedRoutes, but I’m sure with some more macro love we could make even that work. Besides, I’m not sure that localized routes ever functioned properly in Ufront anyway ;)
  3. Being able to capture “controller” and “action” as variables, so that you can set up an automatic /{controller}/{action}/{...} routing system. While this does make for a deceptively simple setup, it is in fact quite complex behind the scenes, and not very type-safe. I think the “Haxe way” is to make sure the compiler knows what’s going on, so any potential errors are captured at compile time, not left for a user to discover.

Future

I’ll definitely begin using this for my projects, and if I can convince Franco, I will make it the default for new Ufront projects. The old framework can be left in there in case people still want it, and so that we don’t break legacy code.

I’d like to implement a few macros to make things easier too.

So

var doUsers:UserController; 

Would automatically become:

function doUsers( ?d:Dispatch, username:String ) { 
 d.dispatch( new UserController(username) ); 
} 

The arguments for “doUsers()” would match the arguments in the constructor of “UserController”. If “username” was blank, it would still be passed to UserController.default, which could test for a blank username and take the appropriate action.

I’d also like:

@:forward(doSignup, doSignin, doSignout) var doAuth:AuthController; 

To become:

function doAuth( ?d:Dispatch ) { 
 d.dispatch( new AuthController() ); 
} 
inline function doSignup() (new AuthController()).doSignup(); 
inline function doSignin() (new AuthController()).doSignin(); 
inline function doSignout() (new AuthController()).doSignout(); 

Finally, it would be nice to have the ability to do different actions depending on the method. So something like:

@:method(GET) function doLogin() trace ("Please log in");

@:method(POST) function doLogin( args:{ user:String, pass:String } ) { 
 if ( attemptLogin(user,pass) ) { 
 trace ( 'Hello $user' ); 
 } 
 else { 
 trace ( 'Wrong password' ); 
 } 
}
 
function doLogin() { 
 trace ( "Why are you using a weird HTTP method?" ); 
} 

This would compile to code:

function get_doLogin() { 
 trace ("Please log in") 
} 

function post_doLogin( args:{ user:String, pass:String } ) { 
 if ( attemptLogin(user,pass) ) { 
 trace ( 'Hello $user' ); 
 } 
 else { 
 trace ( 'Wrong password' ); 
 } 
} 

function doLogin() { 
 trace ( "Why are you using a weird HTTP method?" ) 
} 

Then, if you do a GET request, it first attempts “get_doLogin”. If that fails, it tries “doLogin”.

The aim then, would be to write code as simple as:

class Routes { 
 function doDefault() trace ("Welcome!"); 
 var users:UserController; 
 var projects:ProjectController; 
 @:forward(doSignup, doSignin, doSignout) var doAuth:AuthController; 
} 

So that you have a very simple, readable structure that shows how the routing flows through your apps.

When I get these macros done I will include them in ufront for sure.

Example Code

I have a project which works with all of these examples, in case you have trouble seeing how it fits together.

It is on this gist.

In it, I don’t use real HTTP paths, I just loop through a bunch of test paths to check that everything is working properly. Which it is… Hooray for Haxe!

It’s free, but do you mind paying?

Here’s something I’d like to see more of: UberWriter is free (open source, GPL3), yet by default if you go to install it you’ll have to pay $5.  The old “free as in freedom of speech” rather than “free as in free beer”.

From the creator’s point of view, “Free as in speech” means several things:

  • The project is open to collaboration – if you have something to add, please do!
  • If you see a different future for this project than I do, you don’t have to ask my permission.  You can build on what I’ve started and do something new and different.  I may or may not want what to merge your changes back in.
  • If you’re not someone that’s likely to pay me money (you have a different native language, you live in an area I can’t sell to, you’re don’t have enough money…) then that’s okay, feel free to take what I’ve done anyway and see if you can build on it.
  • If you’re really poor (developing world, unfunded startup, student) then you can still use the software and pay it back (or pay it forward) later.  I’m just glad people are using (and enjoying) something I’ve made.
  • If you’re worried about security, you can know exactly what your software is doing by getting a developer to audit the code.  I promise I’m not working for your corrupt government.
  • If I ever close shop and discontinue the product, you can keep using it, without having to worry about where to get new copies.  Feel free to make new copies, or to hire a developer to maintain it, even to release your own version.  I promise not to get angry.

But from the creator’s point of view, “free as in beer” has several negative implications:

  • I don’t have a strong plan to make money off this, so it will remain a side-project or a hobby.  I might love it, but I’ll never give it the time, money and support it needs to be amazing.
  • I have to pay my bills.  So the work I do that pays bills will always be more important than the work I do for this project.

Commercial projects that succeed (especially software projects) often have a founder who is hugely passionate about it, and absolutely stoked that they get to work on their passion as their full time job.  For many open source developers, this isn’t a reality.

So what if you want to balance those two things:

  1. Create, invent, make art.  And give it away to the world in the most generous, considerate way possible.
  2. Make money so that I can continue to develop this, perfecting it and supporting it and giving it every opportunity to succeed.

Well, that’s what UberWriter is doing.  It has all the same freedoms as “free as in speech”.  And if you really don’t want to pay for it, you can find ways to get it for free, and that’s allowed too, it’s not illegal and it won’t make the creator cry.  But, if you want to get it the easiest way, and you want to support the developer, it’s $5.

I hope he does well, makes some money, maybe even is able to make it his main job – so that he is empowered to make some good software become really great software.  And I hope to see more people balance this act of being generous with earning a living… myself included.

20 Questions I Asked Myself

Bernadette Jiwa is a marketing / branding / idea-spreading expert, (and a Perth local!), and when you subscribe to her “The Story of Telling” she sends you a PDF with 20 questions to ask yourself before launching your next product or idea.

At WWX 2013, this year’s Haxe conference, I’ll be presenting a talk on developing Web Apps, and using “ufront” to do that.  Ufront is a framework made by mostly by Franco Ponticelli, and initially modelled on the .NET MVC framework.  Ufront is pretty powerful, but it’s lacked documentation and hasn’t had a lot of users.  I’ve used it for my last project, added a bunch of helpers, and think it’s ready for some more attention.  A re-launch, if you will.

So I went through the 20 questions Bernadette gives in her PDF, and tried to apply it to ufront, Haxe and web-apps.

My answers to the “20 questions” for ufront (PDF)

It was pretty eye-opening, and really helped me zero in on why I think this approach is better than rails, django, node/express or other frameworks.  I came up with this tagline:

ufront: the client / server framework for Haxe that lets you write the next big (website/web-app/mobile-app/game/thing)

People are clueing on…

VentureBeat has a write up on Why Venture Capitalists can’t afford to ignore EdTech any longer. The wider world is waking up to the fact that something needs to change.

I just hope the change is for something more open.  They compare it to the changes in enterprise – where people where locked on expensive propriety software, and the escape has come in the form of cloud computing and software-as-a-service. This is more open in some ways (You don’t have to use a Windows machine any more, you could use a Mac or Linux or your phone or tablet or internet-powered-fridge), but in other ways, it’s more locked.  You have to keep paying the monthly bill, with no promise it won’t increase later.  You have to trust that the company will never go bankrupt, or never go evil.  And even if the company has open APIs or let’s you download your data, it usually is hard to migrate over to a competitor later.

I’d hate to see education locked up like that.  You can have these amazing learning resources – but they’ll stay on our servers, thank-you-very-much.  We’ll help you define all your lesson plans, but it’s on the condition that they never leave our app, so you’ll keep coming back.  We’ll help analyse the data about how all your students are learning and performing, but that data stays on our servers and we might use it for something else later, and there’s not much you can do about that.

I want to fight for the upcoming EdTech revolution to be open:

  • The school stays in control, and isn’t held ransom to their software suppliers
  • The content teachers create is theirs, and they can hold onto it, share it, and take it with them if they switch to a different software product.  They don’t have to write everything all over again because their school switched providers.
  • People see the value of creative commons – and they gladly cooperate in developing the best educational materials, rather than hoarding what they do for their own benefit.  (I think the teachers creating great material tend to be generous, it’s the business people that they work with that might not be).
  • When someone goes to the effort to create amazing content, and they want to share it, they should be able to.  For example, an e-book shouldn’t be stuck on iPad only.  It should work on phones (cheap ones included), computers, printouts (to whatever extent makes sense) and competing tablets.  And be future-proof and work on whatever the next-big-thing is.

Education is too important for it to be controlled by a small group of start-up shareholders.

If you’re poor, today is a good day.

Imagine your head of state getting up to make a speech.  Our own Julia Gillard isn’t the most inspiring, so I’ll imagine Barack Obama – who at least can give a moving speech.  He gets up on the podium, pauses while the photographers and journalists snap some pictures of him, waits for a quiet to descend, and addresses the nation.

Today is a good day if you are poor – this nation is yours, and today this nation commits to looking after you.

Today is a good day if you are too poor to keep the fridge stocked – from today onwards there will be plenty of food for you and for your family.

Today is a good day if you’re one of the people who quietly goes about your work diligently, and are sick of being trampled on by people louder, richer or more powerful than you.  From today onwards, your hard work will no longer be overlooked, you’ll be recognised, rewarded and given more opportunities for great things.

Today is a good day for those who feel like they’re fighting a losing battle to remain a good person.  Today we say this country values and rewards faithfulness, generosity and a good heart, rather than those who cheat, lie and abuse to get ahead.  You protect your motives and stay true to all that is pure and good about humanity.  Your life will be rich as a result.

Today is a good day if your life has been filled with sadness and grief.  As a country, a community and a family today we recognise your suffering, and say we will be there for you, and do everything we can to give you a brighter future.

Today is a good day for those of you who aren’t always hard-lined, but show mercy and give a second chance.  This is not weakness, but a strength and grace that can turn a fellow human being’s life around.  From today onwards, we are a country that promotes mercy over strict adherence to rules and punishments.  If you’re willing to give people who hurt you a second chance, recognising their humanity, we’re willing to give you a second chance too – and this takes effect in all our policies.  Mercy begets mercy, love begets love.

Today is a good day for everyone who has stood between two fighting parties, and brought calm and understanding, peace and unity.  Because of your commitment to us, to all of us – the worldwide family of humanity – we celebrate you, honour you, and publicly say that this world is better because of you, and because of the risky stand you have taken.

Today is a good day for all of those who have been punished for doing what is right.  Those who have been arrested for peaceful demonstrations, those who have been insulted for standing up for minorities, those who have been fired or sued or sidelined for choosing to do what is right, rather than do what they’re told.  To those who do the right thing, rather than the easy thing – we see you, we acknowledge you, and change our rhetoric.  You’re not a “rebel” or “lawbreaker” or “dissident”.  You are one of the greats, one whose conviction challenges our society and grows us.  You are in good company with the great men and women of history.  As a nation, we will no longer fight you, but recognise you and reward you and support you in every way that we can.  We need more people like you.

When a leader makes a public address like this, it isn’t just more campaigning, an attempt at securing more votes or support.  A speech like this is a turning point.  It says that as a nation we acted one way, now we’re going to act another.  It’s a statement of what’s important to the new leader, what their season of leadership is going to be focused on, and what people can expect to change.  One group of people was previously neglected, now they will not be.  It gives both a change of policy (what the leadership is doing to support the neglected) and a change of culture (as a people, we are now to think differently, act differently, treat people differently).

This is my re-imaging of “The Beatitudes”, part of a sermon Jesus delivered that can be looked at as his inauguration speech.  The crowds recognised that this man was a leader, pronouncing a new Kingdom, and with thousands of people gathering to listen to him, here is what he has to say:

Blessed are the poor,
for theirs is the Kingdom of God.
Blessed are the hungry,
for they shall be filled.
Blessed are the meek,
for they shall inherit the earth.
Blessed are the pure in heart,
for they shall see God.
Blessed are those who mourn,
for they shall be comforted.
Blessed are the merciful,
for they shall be shown mercy.
Blessed are the peacemakers,
for they are the children of God.
Blessed are those who are persecuted for righteousness and justice,
for great is their reward.
(Common Prayer, adapted from texts in Matthew 5 and Luke 6)

This isn’t about an normal country or community or kingdom.  This about the Kingdom of Heaven – the group of people throughout the world who recognise Jesus as the Son of God, and choose to live under his leadership rather than that of their geographic/economic leaders.  The people who submit to his way of doing things even over their own wants and desires.  Jesus is their leader, and this is his inauguration speech.

Part of it is encouragement – what he, as God and as King, is going to do for them.  Part of it is direction – how we, as his people, should change our attitudes, thought patterns, behaviours and processes to adapt to this new form of government, of kingdom.

And the vision laid out is still as confronting, appealing and diametrically opposed to it’s surrounding culture, as it was when Jesus first announced it on the hills of Palestine two thousand years ago.

The new Map syntax in Haxe 3

I was using the Haxe3 Release Candidate for well over a month before I realised that the new Map data structures could be created with a nice syntax.  The basic gist is this:

var map1 = [ 1=>"one", 2=>"two", 3=>"three" ];

Like Arrays, but you use the “=>” operator to define both the key and the value.  And Haxe’s type inference is as strong as ever.  Here’s what the compiler picks up:

var map1 = [ 1=>"one", 2=>"two", 3=>"three" ];
$type (map1); // Map<Int, String>

var map2 = [ "one"=>1, "two"=>2, "three"=>3 ];
$type (map2); // Map<String, Int>

var map3 = [
    Date.now() => "Today",
    Date.now().delta(24*60*60*1000) => "Tomorrow",
    Date.now().delta(-24*60*60*1000) => "Yesterday"
];
$type (map3); // Map<Date, String>

var map4 = [
    { name: "Tony Stark" } => "Iron Man",
    { name: "Peter Parker" } => "Spider Man"
];
$type (map4); // Map<{ name : String }, String>

var map5 = [
    [1,2] => ["one","two"],
    [3,4] => ["three","four"],
];
$type (map5); // Map<Array<Int>, Array<String>>

So it’s pretty clever.  If for some reason you need to type explicitly to StringMap, IntMap, or ObjectMap, you can:

var stringMap:StringMap<Int> = [
    "One" => 1,
    "Two" => 2
];
$type(stringMap); // haxe.ds.StringMap<Int>

var intMap:IntMap<String> = [
    1 => "One",
    2 => "Two"
];
$type(intMap); // haxe.ds.IntMap<String>

var objectMap:ObjectMap<{ name:String }, String> = [
    { name: "Tony Stark" } => "Iron Man",
    { name: "Peter Parker" } => "Spider Man"
];
$type(objectMap); // haxe.ds.ObjectMap<{ name : String }, String>

But if you try to do anything too funky with types, the compiler will complain.  Haxe likes to keep things strictly typed:

var funkyMap = [
    { name: "Tony Stark" } => "Iron Man",
    { value: "Age" } => 25
]; // Error: { value : String } has no field name ... 
   // you are a bad person, and your items are not comprehensible 
   // to Haxe's typing system

Finally, Haxe won’t let you do define duplicate keys using this syntax:

var mapWithDuplicates = [
    1 => "One",
    2 => "Two",
    1 => "uno"
]; // Error: Duplicate Key ... previously defined (somewhere)

If you’re using an object map, it’s only a duplicate if you’re dealing with the exact same object, not a similar one.  For example, this is allowed:

var similarObjectKeys:ObjectMap<Array<Int>, String> = [
    [0] => "First Array object",
    [0] => "Second Array object"
]; // Works, you now have 2 items in your map.

But if you use the exact same object, Haxe will pick it up:

var key = [0];
var sameObjectKey = [
    key => "First Array object",
    key => "Second Array object"
]; // Error: Duplicate Key ...

So there you have it.  A nice feature that I didn’t see mentioned anywhere else.  Thanks Haxe team!

….

Update:

It’s worth mentioning that once you have created your map, you can use array access (“[” and “]”) to read or modify entries in your map.

var map = [ 1=>"one", 2=>"two", 3=>"three" ];

// Reading a value
map[1];   "one"
var i = 2;
map[i];   "two"
map[++i]; "three"

// Setting a value
map[4] = "four";
map[1] = "uno";
map[i] = "THREE";
map;   // [ 1=>"uno", 2=>"two", 3=>"THREE", 4=>"four" ]

Trying to understand dependency injection

Coming closer to the end of writing my first really complex app, I’m beginning to wish I’d taken the time at the start to properly learn and grasp some of the concepts that I see other programmers using.  My client-side code uses a basic MVC pattern, but a bunch of Flash Developers use something that to me comes across as much more complex – as seen in RobotLegs or some of the Haxe ports, such as MMVC.

These frameworks are all about Inversion Of Control (and because we love acronyms: IOC).  And they use Dependency Injection (DI) to do this.  You can see already why the learning curve can be steep, especially if you haven’t come across this pattern before.

So today I googled “I don’t understand dependency injection” and got this fantastic explanation by Kevin William Pang.  I found that really helpful, and I’m sold.  I’d been wondering how the hell I was supposed to unit-test some of my more complex client code anyway… If you’re one that, like me, hasn’t understood this concept in much detail: his article is well worth a read, I won’t bother to try and explain it here.

But, I’m still not sure where the fancy dependency injection tools and frameworks come in.  I see the value in it, and I think “injecting” it into the constructor by using arguments given to the constructor seems just fine.  Meanwhile, the tools which are supposed to help, such as SwiftSuspenders or Minject seem to me to be really verbose, and not offer a lot more than the constructor method.

Maybe that style is more relevant for gaming.  Or maybe it’s benefits show up with more complex projects.  Or maybe I just haven’t been enlightened.

Either way, I’ll try to get enlightened… I think it’s worth spending time learning these patterns.  They’ve obviously gained traction for a reason, and a lot of better developers than me swear by them, so I’ll try wrap my head around it.  Maybe one day it’ll seem as clear to me as MVC, or even OOP do now (both of which took me a while at first).

If you have any suggestions / comments / explanations – I’d love to hear them in the comments section.

Haxe3 Features: Variable Substitution in Haxe3 (aka String Interpolation)

One of my favourite features in the upcoming Haxe3 is also one of the simplest: String Interpolation (also called variable substitution).  If you were using Std.format() in Haxe2, you’ll recognise it.  It lets you do this:

var name = "Jason";
var age = 25;
trace ('My name is $name, I am $age years old.');
// My name is Jason, I am 25 years old

The first point to make is that it is triggered by using single quotation marks (‘), rather than double (“).  If you use double quotes, everything is treated as a plain string:

trace ("My name is $name, I am $age years old.");
// My name is $name, I am $age years old

The next point to make is that this all happens at compile time.  So the trace we made above, in Javascript, would output as:

console.log("My name is " + name + ", I am " + age + " years old");

So you can only do this with strings you have at compile time, as you’re writing the code.  If you want Strings that are given at runtime to have variable interpolation, you should use a templating library like erazor.

Now a few other things to note:

  1. If you want to put in a normal dollars sign, you can use two $, like this:
    trace ('The item costs $20');
    // "20" is not a valid variable name, so it is ignored.
    // Same as ("The " + item + " costs $20");
    
    trace ('That price is in $USD');
    // Error: Unknown Identifier "USD"
    trace ('That price is in $$USD');
    // Same as ("That price is in $" + "USD");
    
    var cost = 25;
    trace ('That item costs $$$cost');
    // The first two "$" are for the literal sign, the third is part of the variable.
    // Same as ("That item costs $" + cost);
  2. If you want to access anything more than a straight variable, use curly brackets:
    // Property access
    trace ('My name is ${user.name} and I am ${user.age} years old.');
    // Same as: "My name is " + user.name + " and I am " + user.age + " years old.";
    // Outputs: My name is jason and I am 25 years old.
    
    // A simple haxe expression
    trace ('$x + $y = ${x + y}');
    // Same as: "" + x + " + " + y + " = " + (x + y);
    // Outputs: 1 + 2 = 3
    
    // A function call 
    trace ('The closest Int to Pi is ${Math.round(3.14159)}');
    // Same as: "The closest Int to Pi is " + Math.round(3.14159);
    // Outputs: The closest Int to Pi is 3
  3. There is no HTML escaping, so be careful:
    var bold = "<b>Bold</b>";
    trace ('<i>Italic</i> $bold');
    // <i>Italic</i> <b>Bold</b>
    
    var safeBold = StringTools.htmlEscape("<b>Bold</b>");
    trace ('<i>Italic</i> $safeBold');
    // <i>Italic</i> &lt;b&gt;Bold&lt;/b&gt;
    
    var safeEverything = StringTools.htmlEscape('<i>Italic</i> $bold');
    trace (safeEverything);
    // &lt;i&gt;Italic&lt;/i&gt; &lt;b&gt;Bold&lt;/b&gt;

There you have it: String Interpolation, one of the most helpful (and easy to comprehend) features of the upcoming Haxe3 release.

Cloudy Mornings

I’ve been using a book called “Common Prayer“, which acts as a kind of guide to help me think of things to pray about and let my mind chew on each morning, lunch time and night.  (Example: when I usually get distracted by what I’ve got on for the day, it says “pray for others”.  Good idea!)

Anyway, each morning the prayers open with this line:

Lord, let me soul rise up to meet you

As the day rises to meet the sun

The last few weeks, I’ve mostly been reading this and praying this as I begin my walk to work, walking down the street, the morning is still cool, but the sun is shining, and I visualise it: the earth reorients itself once again, so my little corner is facing the sun.  Jason, your turn, reorient yourself, turn and face God.  Starting the day this way is good.

This morning however, it wasn’t sunny.  And I came to pray this line, and went to look up at the sun, to help visualise it, and I couldn’t see it.  It was gone.  The clouds had taken it away.

Now of course, the sun wasn’t gone.  It’s still there.  If it were not, it would be pitch black (not just a little grey), the temperature would be dropping so rapidly we would probably have frozen to death by now, and in general things would be falling apart.  I might not be able to see it, and I might be a little chilly, and a little wet with rain, but if the sun were not there, things would be far, far worse than they are.

This is helpful on the days that I feel a little uncomfortable spiritually, can’t see God and struggle to believe he’s there.  Or maybe I’m not struggling with his existence, but just wondering why he’s not doing anything helpful for me with everything I’m struggling with.  On those days, it’s not that God is gone.  He’s still there, and he’s still keeping the general universe running, even if it’s a little obscured, and even if I’m not as comfortable as I want to be.  If he was genuinely not there, or genuinely had ceased taking any interest in me, things would probably be far worse than they are*.

 

* footnote: I’m lucky enough to be healthy and live in a first world country.  My idea of struggles of course aren’t worth even mentioning when compared to what people in different circumstances.  Something else this prayer book is teaching me to be mindful of.  Is God still there for those people?  I hope so…

An old article, but a sad one

This post left me sad:

Pastor supporter of gay marriage out in the cold.

After affirming same sex marriage in an online post, his church met together (without telling him) and decided they didn’t want him any more.  They didn’t even give him the chance to talk over his view point.  Because his house was tied to the job with the church, him and his family were faced with having to find new accommodation on such short notice.

Rodney Croome, whose Australian Marriage Equality website ran Mr Glover’s statement affirming same-sex marriage, said two gay groups would try to provide financial support.

When a church can’t love their own, and the community they condemn as “sinful” steps in with love… I get sad at what the church is supposed to be and the ugly reality of what it sometimes is instead.

Note to self: act the way I think the church should.  If our love isn’t the most extravagant going around, we’re not doing enough.  If we’re too concerned about the purity of our doctrine, and forget to love, we’re not so different from those Jesus was so infuriated by.  I wonder what would have happened if he rocked up at this impromptu meeting.

Then Jesus asked them, “Which is lawful on the Sabbath: to do good or to do evil, to save life or to kill?” But they remained silent.  He looked around at them in anger and, deeply distressed at their stubborn hearts, said to the man, “Stretch out your hand.” He stretched it out, and his hand was completely restored.

Sad…

 

The Heist

Make the money, don’t let the money make you
Change the game, don’t let the game change you
Macklemore and Ryan Lewis

I’m listening to “The Heist” by Macklemore and Ryan Lewis. Loving the album… I’ve been laughing hard at Thrift Shop for a month or so now (it’s on the radio all the time at the moment), but I’m now listening to the rest of the album – really good stuff. They definitely follow the Mumford and Sons Theory:

MumfordAndSonsTheory: drop a few F-bombs & u can get away with more Christian imagery that a Billy Graham revival.
@jarrodmckenna

The quote above was from their song “Make the Money”. The song below, “Same Love” is a scathing look at homophobia. Reminds me of the stories of some of my friends… Take a minute to listen to it. Lyrics here.

The story of the millions of dollars

Matthew 25 contains one of Jesus’ most well known stories, and it goes like this:

There was a rich man who was about to go out on a long journey.  He called 3 of his workers to him, and entrusted them with his wealth.  He gave each of them a different amount depending on what he knew they were up for – the first he gave $5,000,000, the second he gave $2,000,000, the third he gave $1,000,000.  (A “talent” in the bible was 20 years wages.  20 years * average Perth salary of $50,000 = $1,000,000). Certainly a lot of money – even for the guy who got the least.  And apparently the rich man trusted each of their abilities enough that he thought it safe to leave it with them while he went away.

The first two went out, and put the money to work.  Whether they invested it, or started a business, or just did clever trading, I don’t know.  But whatever they did, worked – they doubled the money their boss had entrusted to them.

The third guy though was scared of screwing up.  In the story he says “I knew that you are a hard man, harvesting where you have not sown and gathering where you have not scattered seed. So I was afraid and went out and hid your gold in the ground.”  It seemed like this guy felt that no matter what he did, he couldn’t live up to the (in his mind) unrealistic expectations of his boss.

Needless to say, the rich man came back, and was pretty stoked with the results of the first two – and promised them bigger and better opportunities.  The third guy however he was angry with.  He didn’t challenge the accusation that he expects a lot – but he challenged the guys response.

The third man saw the high expectations, considered them unrealistic, panicked, and went with what he considered the least risky option.  Another possibility is that he was just lazy – and this whole thing was his excuse for not doing anything.

I’ve spent a bit of time tonight pondering this expectation from God.  In the Hebrew Bible harvesting what someone else planted was a form of oppression – you were getting rich from someone else’s hard work.  Is that what this man is accusing his boss of?  Is that what God does, comes in to profit from our hard work?

Well not quite, the boss did invest.  He didn’t come asking for money when he did nothing in the first place.  He gave the guy a million dollars, and entrusted it to him – presumably so that he would work with it and increase it.  From what I can tell, wealth is something we can generate, and it doesn’t have to be generated by stealing from other people.  And the boss gave him money because he knew this guy was capable of generating wealth, to the same capacity as the other two – he could get a 100% return on investment too.

God wasn’t selfishly coming to collect what he had no right to – he gave this guy something to work with, and the man did no work.

Whether he didn’t because he was honestly scared, and the fear of failure seized him, or whether it was laziness and the fear was merely an excuse – this man was capable of generating a return, but he didn’t. He was capable of doing equally great work with what he was entrusted with, but he didn’t.  And so he was shown the door.

We know from other parables that God isn’t concerned about financial return on investment.  Rather, he wants to see us doing good work, and wants to see us working faithfully with what he’s entrusted to us.

Think about an investor.  Some are out there to make a quick buck, but some are people who already have a lot of money, and they invest not to get more, (they already have enough), but instead they invest to set other people up for success. The money they give out is to help other people get off the ground and do amazing work.  But if the person they invest in squander the money, do you think they will continue to invest?  No, they’ll pull their money out.

I think that’s what’s happening here.  God wants to set us up for success.  He’s not in this to profit from us, rather, he’s in this to see us succeed. The first two guys in the story saw what God entrusted them with, and did amazing work.  The third guy was also entrusted with a lot, but he did nothing with it.  He ignored what the boss had entrusted to him, and so in a way, rejected the vote of confidence.  The boss gave him money because he knew he was good enough, but the man rejected that, and did nothing anyway.  When the time came to show where the money had gone, the boss saw it wasn’t getting used, he withdrew the investment – and put the money somewhere where he was confident it would be put to good use.

“From everyone who has been given much, much will be demanded; and from the one who has been entrusted with much, much more will be asked.”
Luke 12:48

Divided

“Every kingdom divided against itself will be ruined, and every city or household divided against itself will not stand.”

Matthew 12:25 NIV

The reality is the 6 Billion people on earth are so interconnected that this truth applies to us as an entire race.

We can no longer ignore the way our actions impact those in distant lands – because they’re not so distant anymore. Their future is tied to our future and if we’re divided against each other we will be ruined.

If our actions, attitudes, business plans and lifestyles achieve our gain at another person’s loss, then what we’re doing is not sustainable, healthy or honouring the humanity of those we live with. As the human community we’re divided against ourselves, and like that we cannot stand.

When you do good things and others see it

In the same address, Jesus is talking to the crowd and seems to offer two contradictory pieces of wisdom:

You are the light of the world.  A city on a hill cannot be hidden.  Neither do people light a lamp and put it under a bowl.  Instead they put it on its stand, and it gives light to everyone in the house.  In the same way, let your light shine before others, that they may see your good deeds and glorify your Father in heaven.

Matthew 5:14-16

 

Be careful not to do your ‘acts of righteousness’ in front of others, to be seen by them.  If you do, you will have no reward from your Father in heaven.  So when you give to the needy, do not announce it with trumpets, as the hypocrites do in the synagogues and on the streets, to be honoured by others.  Truly I tell you, they have received their reward in full.

Matthew 6:1-2

There are plenty of people in the world who want to do good.  But often if someone asks you for a favour, or you see an opportunity to help, your response is “what’s in this for me?”  You might not ask it out loud, but your mind is scouting out potential benefits for doing this: this person now owes you a favour, while you’re doing it that girl you think is cute might see you and be impressed, doing this might be able to go on your résumé when you begin your job search later this month, your company could really use a PR boost and this donation could be just the thing…  You wouldn’t be so rude to ask it, but secretly, you’re weighing up if it’s worth your time, effort or money to help out in this situation.

Jesus says that if you’re just helping out for the reward you can imagine just around the corner, then when you get that reward, you’re paid in full.  Even though the work you’re doing is good, you’ve done it more as a business transaction than as an act of love.  I’ll help you with this… and I’ll get this (from you or someone else) in return.

A truly transformed life, the kind of “kingdom” life Jesus is encouraging people to step into, will sooner or later result in the person wanting to do good… and not just as part of a business transaction.  When a life is transformed by receiving grace, it goes on to want to give grace – you want to give to people who don’t deserve it, people who’ll never be able to pay you back.

Once this grace overtakes you and motivates you, it’s no longer about what you will get out of it.  And you’ll start doing things and helping people where “the deal” clearly isn’t worth it for you – you’re giving a lot more than you’re getting.  Perhaps you’re getting nothing, no one will even know.  Jesus is saying that God loves it when we do this.  When we give with no expectation of reward – at least not in any way we can imagine.  When we do this – God promises to reward us generously later.

Ironically enough, it’s the person that cares least about public approval (and doesn’t give for that reason at all) that God wants to show off to the world.  You see, people doing good is nothing to write home about.  People do good all the time – most business deals are essentially someone helping someone else and being rewarded in return.

It’s the people who give and give with no expectation of repayment or reward – whose lives have been transformed by grace – that God wants to show off to the world.  Their lives Jesus calls “light”, it contrasts the give/take nature of the world, and forces people to see that these people live life differently: they are no longer driven by what they get out of something, they are driven by love and by grace.

When people see this, they can’t help but glorify God in Heaven, whose undeserved love changes a life so radically that the person lives, gives and works because it’s right and because it’s good, not because of expected returns.

If most of the good you do will pay off, in recognition, in returned favours, in some round-a-bout way, then maybe you haven’t let your life be transformed enough yet.  This is me at the moment.  The cure then, is to deliberately try to do good, but in secret – not thinking about how you will be repaid for this, but focusing on the grace you’ve already received.  And as you do this (and as I do), hopefully our attitude will change and the grace we’ve received will overflow into grace we give out.

And most things will remain under the surface – no one but you and God need to know about them.  But a few will float to the top – like an iceberg, the majority of what you do will be unseen, but a small fraction pokes out above the water.  When people see these, they’ll see that it’s different.  These are not good things done for an expected return, these are good things done as an act of love – and that realisation will help them see God’s grace at work in your life, and lead them to glorify him.

 

Win when your customers win

In announcing several new tablets yesterday, Amazon CEO Jeff Bezos dropped some wonderful quotes. One was, “Above all else, align with customers. Win when they win. Win only when they win.”

Bezos went on to say, “We want to make money when people use our devices, not when they buy our devices. If someone buys one of our devices and puts it in a desk drawer and never uses it, we don’t deserve to make any money.”

Amen. I think the lesson is exactly the same for open educational resources. If we’re really trying to help learners “win,” an OER provider hasn’t finished their job when they’ve published content. They’re succeeding when someone benefits from what they’ve done – and only then. We need to think harder about how to make this happen, and how to do it sustainably.

David on the Open Content Blog

I love this sentiment.

How can you set up your business so that the better it is for your customers the better it is for you.

Examples of people doing this:

  • Amazon, mentioned above – sells their hardware at low profits, expecting to generate further money as the user benefits from getting more content. The more content they get, the more they use it.
  • Dropbox lowers the price for you the more friends you send invites. You get more customers, they get cheaper prices and more convenience sharing with friends.
  • Some restaraunts have a “pay what you think the meal was worth” policy, some software follows the same model. The better you perform, the higher your pay. Another variant is an “unlimited trial” on software, that gives you as long as you need to see if the software is “worth it” to you.

Examples of people who do it wrong:

  • Phone companies use “cap plans” which give average users a cheap price, but the biggest users – who could be your biggest fans – get charged exorbitantly more, punished for using your product the most.
  • Gym memberships – here you pay a large fee no matter how often you use it. This may be viewed as motivation – go lots to get your moneys worth – but the reality is that it can make for a business model which separates the interests of the gym from the interests of the patron. The gym may avoid encouraging patrons to come regularly, because it means they can have more people enrolled and still not reach capacity. To take it differently however, there is no extra cost (no punishment) for using the gym as much as you desire.

Further possible examples:

  • A service such as Vimeo or Flickr, but if you achieve a certain level of popularity, they give you your account for free – for bringing so many new people to the site.
  • On signup, your client sets a target (to lose 10kg, to post a blog everyday, to finish a course). You only get paid as they achieve milestones on their way to this target. You are now motivated to help them achieve.

Of course, one problem with that last strategy is that it provides a financial disincentive to not finish – the further you get the more you have to pay.  In a way, this is then becoming similar again to the phone companies – you are charging people more for successfully engaging with you.

A different strategy again might be that of Fog Creek Software – your money back for any reason.  You pay full price up front, so you’ve already overcome the difficulty of paying money for something.  However, as a business you remain committed to making the whole experience worthwhile, or you risk them asking for their money back – and you’ve committed to give it to them, no questions asked.

It looks like a tricky balance, but one well worth pursuing.

Mapping any SSH Server to a Network Drive in Ubuntu

My friend Justin showed me a cool trick this week – mapping any SSH server as a network drive in Ubuntu.  This is really useful for web development, where you have a whole bunch of servers that you have to connect to, transfer files to and from, and make small edits.

The integration is pretty seamless – it shows up in my file browser (just like a local USB drive), I can open files in any app I want, and every time I save the changes are synced back.  Pretty cool.

Here’s how:

  1. Open your Home Folder
  2. In the menu, choose “File -> Connect to Server”
  3. Change the type to “SSH”
  4. Enter the address of your server.
    eg. myvps.mydomain.com or 192.168.1.5
  5. Enter your username and password.
    (Note: If you have public / private keys set up, just enter the username.)
  6. Click Connect

This all comes built in with Ubuntu 12.04.

This is me browsing files on an Amazon EC2 instance, opening a few of them and editing them. Sweet!

Long Term Thinking

Here’s another thought provoking quote from Peter Thiel’s Lectures (or Blake Master’s notes on Peter’s lectures):

But there’s an alternative math metaphor we might use: calculus. The calculus metaphor asks whether and how we can figure out exactly what’s going to happen. Take NASA and the Apollo missions, for instance. You have to figure out where the moon is going to be, exactly. You have to plan whether a rocket has enough fuel to reach it. And so on. The point is that no one would want to ride in a statistically, probabilistically-informed spaceship.

Peter Thiel’s CS183: Startup – Class 1 Notes Essay

It’s been a long time since I did Calculus in high school, but I remember the task of taking multiple points and applying a gradient or a curve to them: you looked for a pattern, developed an equation and you used that to guess at where future points might show up.

While at the moment I have two projects I’m working on (Enthral.us, and OurSchoolDiary), long term, there’s so much room for expansion. Seth Godin in his book Purple cow talks about how after a product has been developed and reach critical success, it’s crucial for the inventors to move on, and leave maintaining and “milking” the product for a team that’s better at maintainance. An inventor will just keep trying to break stuff – better to get them developing the next big hit.

Trends and Opportunities

So if I try to think long term, till after these projects, what trends do I see? And what opportunities do these open?

  • Decreasing price of technology (trend) -> Availability in developing world (opportunity)
  • Digital connectedness is increasing (trend) -> not being in the same physical space (or even the same point in time) as your teacher will seem less weird (opportunity)
  • Availability of stored content approaches infinite (trend) -> Every niche in content, and every variety in learning styles (or media types) can be catered to. (opportunity)
  • Computer profiling approaches scarily accurate (trend) -> Career / Interest prediction, based on passion, not assessment grades. (opportunity)
  • Ability to track behaviour, A/B testing procedures get really powerful (trend) -> Get statistics on the actual best practices for teaching – which way of teaching content is the most accurate? Improve the pedagogical effectiveness of your materials through data analysis. (opportunity)
  • IT specialist tools become more user friendly, accepted by other industries (trend) -> The incredible power of Git, and Github in particular, to co-ordinate teams of creators could be utilised in the creation (and modification) of educational media.

Planning to be “ahead of the game”

Given these trends, and the likely opportunities that will develop, can I position my products to be embracing these trends just as they hit critical mass?

Just a few thoughts:

  • Be working on a “normal person friendly” interface to GIT – possibly changing mental models / system models to match.
  • Don’t tie to a single platform – with the rise of the developing world, there is a high chance that the current big players (Apple, Samsung, Microsoft etc) will not carry over. New markets = new giants. So plan software and media that can adapt.
  • Get as much experience with A/B testing as possible, so that I can transfer those skills to educational media later.
  • Find teachers who are willing to experiment with out-of-class teaching, and work with them to pioneer online lessons.
  • etc…

Admittedly, these trends/predictions are not very long term. Most will probably be well underway within 5 years, some will be underway even sooner. Still, it’s a useful exercise, and thinking 5 years ahead of the competition is still better than chasing the competition. A good exercise to revisit.

Most people believe in X. But the truth is (something other than X)

Peter Thiel, the founder of PayPal, runs a unit at Stanford on business start-ups.  Blake Masters was in the class, and took a whole bunch of notes, which he then re-wrote as essays and shared with the world.  Reading them feels like I’m back at uni – lots of learning, lots of new ideas, and a whole bunch of things to think about.  I’ll probably have a few posts that come out of reading these.

In the first essay, he says:

You know you’re on the right track when your answer takes the following form:

“Most people believe in X. But the truth is !X.”

For OurSchoolDiary, my tag line might be:

Most people are trying to get technology into the classroom.  Meanwhile, we’re using technology to get parents into the classroom.

Copying the Best Ideas (from other industries)

I’m reading a classic for inventors and entrepreneurs: Purple Cow

One of his suggestions is:

Copy. Not from your industry, but from any other industry. Find an industry more dull than yours, discover who’s remarkable (it won’t take long), and do what they did.

I’m going to do just that.  The applications are for education.  Not any specific product, just ideas to upset everything in general.

Fast Food: Subway

What they did: made their main marketing campaign about an obese guy who ate only Subway and lost a huge amount of weight.

What education could do: get a struggling student to use your textbooks / media to catch up, and document their success story.  It doesn’t just show that your product works as advertised, it also provides hope to those who need it – they too can catch up.

Music Industry: iTunes

What they did: They made it possible to get pretty much any song, ever, at a moments notice.  If you wanted to hear a song, you could buy it.  Right now.

What education could do: When someone has a moment of curiosity – satisfy it.  No matter what the topic, have a quick explanation (with links to more in depth reading / watching) available at a moments notice.  Like Wikipedia, but more teaching oriented.  Possibly even have multiple versions of the same article (a 9th Grade student will want a very different summary of Newton’s laws to a Physics Major).

ISP: iiNet

What they did: Organised their entire branding around a persona (the friendly nerd), and hired an actor who played it perfectly.  Even when he’s not on screen, their communication follows the personality of the (lovable) persona.

What education could do: It’s known that students respond better to some teachers than others.  It’s also known that if a student feels the teacher “likes” them, they will work harder.  With education materials, the “narrator”, rather than adopting a dry persona, could adopt the persona of a teacher that will actually motivate students to study diligently.

Computers: Apple

What they did: They mastered the art of emotional design: approaching the design of everyday objects and optimising for positive emotions.  This massively increased loyalty to their product range.  See Donald Norman’s book Emotional Design for an exploration of this.

What education could do: Hire an interior designer to deck out every aspect of the classroom – walls, seats, lighting, decoration.  Plan lessons to appeal to each of the levels of design: visceral (Sight, sound, touch, smell, taste), behavioural (Is the content relevant?  Is it well structured and well presented?  Am I learning?) and reflective (Is this experience challenging me personally?  Am I creating memories? Does it make me feel good about myself and my choices? Does it have special emotional attachment?

Blogging Software: WordPress

What they did: Created some software which web designers could utilise for their clients – adding a huge diversity and richness to the ecosystem.  Meanwhile they offered a hosted service that anyone could use without the help of a web designer, and could be set up in minutes – giving them an income stream and a wide range of content (blog posts on all sorts of topics).

What education could do: Have a system that acts as a great base for Instructional Designers.  Take some of the grunt work out of the way, so they can focus on great learning experiences.  Meanwhile have a hosted service for a teacher with no budget to hire an instructional designer.  They can still add their content and benefit from some of the same tools, even if their usage is a little more limited.

Photography: Instagram

What they did: Encouraged people to see (and share!) the beauty in the world.

What education could do: Encourage people to apply their learning all around the world.  Imagine a website called “in-the-wild.com”, where people try to post a scientific phenomena they see in their day-to-day life (“in the wild”) and link it to a topic they are learning, with a brief explanation.  For example, a student could post about their car windscreen which fogs up when it’s cold, and give a simple explanation based on what they’ve been learning in class.

As many students do this, you build up a library of great examples.  (There may be some not great examples, but you could let a “like” or “rate” button raise the good ones to the top).

More importantly, it will encourage students to approach their everyday life on the lookout for how the things they have been learning about play out in the real world.  It will hopefully encourage them to approach life more thoughtfully and inquisitively.

This could also be used for other subjects:

  • English – examples persuasive writing / speaking (link to websites & videos)
  • English – examples of bad grammar and spelling
  • Science – experiments you can conduct at home
  • History – examples of history repeating itself
  • Geography – urban morphology patterns & google maps
  • Maths – everyday problems where maths proved useful (with or without a calculator/computer)
  • etc…

Coffee Shops: Greens and Co.

What they did: Greens and Co. is a coffee shop in Leederville near where I work.  They bought the biggest building on the strip, filled it with couches, music and cool decorations.  It’s big enough, open enough, and casual enough that it’s become the default hangout place for many people.  They sometimes even buy coffee.

What education could do: Set up the coolest hangout around.  Make the environment sweet, and convince them to come to this place.  Then while they’re there, have something beneficial for them to do. They come for the cool vibe, but while they’re there, they might get some coffee (or some education).  This could be more tutoring oriented (cool place to do homework, hey, we have some tutors around!).  It could be more exploring oriented (like Sci-Tech, with hands on learning environments.  Completely optional, of course).  Or it could be more to do with extra-curricular activities: leadership training, music shows (bands the kids are in!), drama productions, or even a chance for chaplains to catch up with students and encourage them in their holistic development.

Conclusions

I have no idea if any of these ideas will come to fruition.  Or if they do, if it’ll be me or someone else. But what I’m realising is that this piece of advice from Godin is priceless.  Copy the best ideas from other industries, and apply them to your own.  Great thinking.

(If you want to use any of these, go right ahead! Would love to see any implemented.  Let me know how it goes!)