Categories
Faith Personal

The best defence is a good offence

You’ve probably heard people say

The best defence is a good offence!

But actually, Jesus said that if you live violently you’ll die violently. The best defence is probably nothing to do with fighting your adversary, but rather loving them. As a best case scenario, they’ll return the favour – and you both win. Worst case scenario, you love them, and they take advantage of you. Which sucks, true, but at least you’re behaving like God, and that is probably more important than winning anyway.

Categories
Faith Personal

“Nothing they plan to do will be impossible for them”

My favourite blog post ever (big call, I know) is titled “An Unexpected Ass Kicking“. You should read it.

A freelancer sits down in a coffee shop in Portland to get some work done, and finds himself distracted by a senior citizen wanting to talk about computers.  At this point I groaned, but, (spoiler alert), the old man turns out to be the most remarkable person this freelancer has ever met.  This old man was Russell Kirsch, whose team built the first internally programmable computer.  Him and his wife used to program the computer while standing inside it.  This man invented computers as we know them today. (He also invented digital photographs and the idea of a pixel. What a boss!)

When Joel the freelancer realized just how impressive Russell is, this conversation took place:

“You know Russell, that’s really impressive.”

“I guess, I’ve always believed that nothing is withheld from us what we have conceived to do. Most people think the opposite – that all things are withheld from them which they have conceived to do and they end up doing nothing.”

“Wait”, I said, pausing at his last sentence “What was that quote again?”

“Nothing is withheld from us what we have conceived to do.”That’s good, who said that?

“God did.”

“What?”

“God said it and there were only two people who believed it, you know who?”

“Nope, who?”

“God and me, so I went out and did it.”

What a life changing exchange!  Unbelievable.  When I read the blog I wanted to know if he was imagining God talking in the spiritual, pentecostal, voice-in-the-head sense, or something else.  It turns out he was quoting the story in Genesis 11 about the Tower of Babel.

The Lord said, “If as one people speaking the same language they have begun to do this, then nothing they plan to do will be impossible for them.

In the creation story, whether literal or metaphorical, there had been a flood, Noah’s family survived, and God had commanded them to spread out and fill the earth.  On the way they began developing culture and technology, songs and tools, and when they found a nice place, they stopped spreading.  Instead they settled and built a city.  In their pride they wanted to build a tower so tall that the world would always remember them.

The tower they were building was probably a Ziggurat, and the story of a giant tower in the area of Babylon (modern day Iraq) seems to be shared with other ancient cultures.  To me the confusing of languages could easily happen in the modern day world – a giant corporation or city gradually has multiple cultures rise up in it, they drift apart, can no longer work together, and so abandon the project to go their own ways.  It doesn’t necessarily seem to me like a divine punishment where they spoke one language one minute and all spoke different languages the next.

Let’s look back at God’s words: “nothing they plan to do will be impossible for them”.  The 400 year old King James translation swaps “plan to do” for “can imagine”: nothing they can imagine will be out of their reach.  Nothing they aspire to and plan for and set their mind on is out of reach.  God acknowledges the amazing potential of human creativity and ingenuity. They like to create new things, do things that have never been done before, and they’re good at it. In that way, they take after their creator.

I always used to read the story of Babel in a fairly negative light – God didn’t like the ingenuity, or saw it as a threat, and so shut it down. John Stott points out two things God may have been offended by: the disobedience of settling rather than spreading out to “fill the earth”, and the presumption that they could reach into Heaven, and be like God – the same as the original sin from the Adam and Eve story. So there’s the failure to explore the earth and develop it’s potential.  And there’s the pride and hubris, being concerned about our fame and wishing ourselves to be like God.

It wasn’t until reading Russell’s conversation that I began to read this statement differently.  Maybe it wasn’t the ingenuity God objected to, maybe he isn’t threatened by us building amazing things. It is, after all, part of our nature as creative beings. But our resourcefulness can be twisted and our inventions result in a world worse-off, not better. (Read the story of the Gatling Gun or Dynamite for examples). And this is all the more likely if we’re acting in our own self interest, for our own fame and power and comfort.  But if we were to instead align our efforts with the command of God – to fill the earth and subdue it, meaning to manage it responsibly and for the benefit of all – then perhaps our efforts would align with God and we could see truly astounding things accomplished.

It can go either way: jets for transport and jets for bombing, nuclear power or nuclear weapons, curing diseases or inventing new ones, programmable computers and systems of government. Humans have the creativity and the resolve to build incredible things. And that can work out really well or really horribly.

There are two questions to consider then: do you, like Russell Kirsch, believe God that what you can imagine and resolve, you can do? Because if you do, maybe you’ll go out there and do something that’s never been done.

The second question is, are you working towards your own fame, power and comfort, or towards the mission laid out by God: to responsibly manage and care for the earth we’ve inherited, and to care for the people we share it with?

Categories
Haxe

Juggling haxelibs between multiple projects

Once you have more than one project you’re building in Haxe, you tend to run into situations where you use different versions of dependencies.  Often you can get away with using the latest version on every project, but sometimes there are compatibility breaks, and you need different projects to use different versions.

There is a work-in-progress issue for Haxelib to get support for per-project repositories.  Until that is finished, here is what I do:

cd ~/workspace/project1/

mkdir haxelibs

haxelib setup haxelibs

haxelib install all

And then when I switch between projects:

cd ~/workspace/project2/

haxelib setup haxelibs

What this does:

  • Switch to your current project
  • Create a folder to store all of your haxelibs for this project in
  • Set haxelib to use that folder (and when I switch to a different project, I’ll use a different local folder).
  • Install all the dependencies for this project.

Doing this means that each project can have it’s own dependencies, and upgrading a library in one project doesn’t break the compile on another project.

Hopefully that helps someone else, and hopefully the built in support comes soon!

Categories
Haxe

Requiring a Class argument to have a certain constructor signiature

Haxe has a very powerful reflection API, allowing you to create objects of a class, which you don’t know until runtime.

var u:User = Type.createInstance(User, [“jason”,”mypass”]);
u.save();

Sometimes, you have a method where you want to create a class, but which class is created is specified by the user:

function createUser( cls:Class<User>, u:String, p:String ) {

var u:User = Type.createInstance( cls, [u,p]);
u.save();

}
createUser( StaffMember, “jack”, “mypass” );
createUser( Subscriber, “aaron”, “mypass” );

So far so good.  But what if we have a 3rd user class, “Moderator”, that actually has a constructor that requires 3 arguments, not just the username and password.

createUser( Moderator, “bernadette”, “mypass” );

This compiles okay, but will fail at runtime – it tries to call the constructor for Moderator with 2 arguments, but 3 are required.

My first thought was, can we use an interface and specify the constructor:

interface IUser {

public function new( user:String, pass:String ):Void

}

Sadly in Haxe, an interface cannot define the constructor.  I’m pretty sure the reason for this is to avoid you creating an object with no idea which implementation you are using.  Now that would work for reflection, but wouldn’t make sense for normal object oriented programming:

function createUser( cls:Class<IUser>, u:String, p:String ) {

var u:IUser = new cls(u,p); // What implementation does this use?

}

So it can’t be interfaces… what does work?  Typedefs:

typedef ConstructableUser = {
function new( u:String, p:String ):Void,
function save():Void
}

And then we can use it like so:

function createUser( cls:Class<ConstructableUser>, u:String, p:String ) {

var u:ConstructableUser = Type.createInstance( cls, [u,p]);
u.save();

}
createUser( StaffMember, “jack”, “mypass” );
createUser( Subscriber, “aaron”, “mypass” );
createUser( Moderator, “bernadette”, “mypass” ); // ERROR – Moderator should be ConstructableUser

In honesty I was surprised that “Class<SomeTypedef>” worked, but I’m glad it does.  It provides a good mix of compile time safety and runtime reflection.  Go Haxe!

Categories
Haxe

Accept either String or Int, without resorting to Dynamic

A quick code sample:

`AcceptEither`, a way to accept either one type or another, without resorting to “Dynamic”, and still have the compiler type-check everything and make sure you correctly handle every situation.

Try it on try.haxe.org

The next step would be having Accept2Types, Accept3Types etc, and have a macro automatically build the code for whichever option you ask for.

Categories
Edtech

Why Education? Why Edtech? (My personal story of why)

Not being a teacher or a parent (yet…), people sometimes ask why I decided to make my life’s work about using technology to improve education. I made that decision while in rural Cambodia in 2010. In a country still struggling to recover from the brutal genocide 40 years earlier, we were visiting a learning centre that ran afternoon classes and learning activities, complimenting the local school’s morning-only classes.

The centre was run by Sonai, an incredibly entrepreneurial lady only a few years my senior. She was the first person in her village ever to graduate high school. (She jokes that she only did it because she couldn’t bear the thought of being a farmer the rest of her life. I don’t blame her!)

Together with a team of other young teachers and mentors, they were providing food, learning and leadership development to hundreds of students in that village. She is determined to lift her village out of subsistence living through her brilliant mix of education and entrepreneurship. It worked for her, it can work for these kids too.

When I got back to Australia, I began chatting with teachers, and my admiration for the profession grew more and more. These people were fiercely determined to provide their students with the best opportunities for a life worth living. Even in a country as wealthy as Australia, a good education often makes the difference between a life shaped by hope and opportunity, and a life that just scrapes by. And we weren’t without our own educational struggles: remote indigenous education, catering to special needs, struggling with new national standards and international competition.

I don’t have the personal make-up to be an effective classroom teacher, and I don’t pretend to know all the best practices or solutions to all of these problems. What I can do, is work with the most innovative teachers to craft solutions to the most difficult problems. They bring their teaching expertise, I bring the design, tech and startup know-how. (The idea for ClassHomie came out of one such meeting with Aaron Gregory, a teacher I have so much respect for. It has since been refined by input from dozens of teachers).

I strongly believe that entrepreneurs and teachers can, and should, work together to solve the difficult problems of education. By improving learning, we improve lives. This work matters, and that’s why I’m building educational apps, starting with ClassHomie.

Categories
Faith Personal

Preaching about the undead

Preaching about a man who died and then began showing up again, evidently no longer dead, with a new evolution of the human body, and claiming this resurrection as validation of his claims to be king of his nation, saviour of humanity, and founder of a new world order where humans live empowered by a supernatural spirit to live an entirely different style of life which occasionally ignores the realities of physics or biology or politics…. I feel it should carry a whole different level of energy, challenge, hope, discomfort and urgency than it normally does.

And yet if I was preaching, I have no idea what that would look like.

Maybe I need to explore the reality (or unreality) of this story in my own existence first.

Categories
Faith Personal

Get Analoguer This Advent

(Disclaimer: My startup journey and my faith overlap in this post. For those of you who want to avoid the theology stop reading now!)

I’m almost at the end of PhDo, a 6 week startup night class that I have been LOVING. One of the key lessons has been about getting your idea started in the quickest, cheapest, fastest way possible.

The idea is that if you wait too long, you work on your idea in secret, you never put it in front of customers, it’s just an idea. You don’t know if it’s something they’ll want or need or appreciate. Until you reach out and touch a human being, you might as well not have done anything.

Sam, the guy running the course, coined a word. Rather than planning a digital masterpiece of an app that might take years to build, is there a simple, manual, analogue way you can solve the same problem for the same person, now.  Not once you have all the resources and the app and the staff team and investment and… No. Can you help meet a need today? Start meeting a need now, help someone out, see if it’s well received, then worry about scaling the solution up for more people.

Get analoguer. Get dirty. Get doing – solve a problem today. Scale later.

I did this wrong with my School Management System app. I never met with the staff, and completely underestimated how complex the problem of tracking student attendance is.  My solution was way too simplistic, and would never be adequate. The project blew out by 10 months and caused a lot of frustration as a result.

I tried to be a messiah and solve this problem, thinking it would be easy.  But I never entered in and felt / understood the pain first. How can you offer help if you have not stood with people and felt their pain and understood the complexity of the problem first?

This is the difference with how Jesus chose to work. He could try solve the world’s problems from in Heaven. Or send some prophet to do the dirty work. Instead he chose to get dirty, get personal, and get in touch with those he was trying to help. Understand their pain and show his solidarity, feel the full weight and complexity of the problem, and show those facing it that you are eager to help, in any way you can, even if you get dirty doing so. Even if it means suffering with them. Even if it means dying with them.

Jesus left the ivory tower of Heaven. He was God, but put his rights as God and abilities as God behind him, he became an ordinary human, wrapped in ordinary human flesh. He got analogue.

Today is the first day of Advent – the season where we anticipate the coming of Jesus to earth, culminating in Christmas.

We join Mary in expecting the birth of the baby Messiah, the God who gave it all up to come and understand our problems and join us in this often-painful world, and resolved to help us in any way he could, no matter the cost.

And we join with the people of faith around the world expecting the second time Jesus will come, having grasped the full complexity and pain of the human condition, and having felt it for himself, he’ll be back with a solution that scales.

Until then, let’s get analoguer and show love to people, not waiting for the perfect plan, strategy or opportunity, but starting right now in a way where you get as close to the problem as you can, and give what you can today, even if it’s not a full and perfect solution.

Categories
Personal Work Habits

Loved it, Loathed it

I’ve mentioned it a few times, but I’ve found Marcus Buckingham’s Standout profile and website really helpful.  The profile for me was accurate and insightful, and the tips I get sent each week are great.

One of them encouraged you to log the things in a week that you love (that leave you energized, strengthened) and the things that you loathed (that leave you drained, weakened).  This wasn’t about what other people do to you (a police officer gave me a fine – I loathed it, my boss gave me a pay rise, I loved it).  Rather this is about the work you’re doing, and what parts of your work energize you and what drains you.

Here’s my list.

Loved It

  • Working on new business strategy, or figuring out the brand/story that makes a new product have meaning.
  • Writing code for new APIs or frameworks that will be well designed, get use by many people, speed up development.  While I’m doing this I’m engaged, I’m learning and tweaking my skills, and I’m making something for that benefits both me and others.
  • Delivering a feature that has immediate customer benefit
  • Meeting people, getting them on board with a new idea.  This week it was a friend (and possibly future business partner), a learning support officer (who is an aspiring entrepreneur) and a friend who is wanting to get into graphic design.
  • Trying to consider how my faith world mixes with my business world.  Particularly this week: how can I see people as people, not resources or assets.  How can I help them find their particular spot in the world, and help them grow into it, rather than “how can I get you to do what I want”.
  • Wireframing, prototyping, design reference scouting

Loathed It

  • Maintaining old projects. Especially if it’s something I didn’t care for to begin. (For me this week, that includes Koha, Canvas, and Moodle to a lesser degree)
  • Being apart from Anna for too much of the week
  • Working on projects that feel like they will never end or progress.  I need a sense of momentum and an expectation that one thing will finish so that new things can start.
  • Having to report to (and problem solve with) a group of people who don’t understand the technical nature of the problem.
  • Having to answer questions where the “correct” answer is “drop quality, deliver faster”
  • Avoiding answering / helping people, because other deadlines are too heavy
  • Having to pretend something is good/ready when it’s not. I’d rather be honest. Drop projects if they suck, or at least admit it.

There’s my list for this week.  I’m in the middle of an extremely busy work season, so this is mostly focused on work and doesn’t touch much into my family life or faith life – both of which also have strengthening moments and weakening moments.  Still, a great exercise.

Categories
Haxe

Super Quick Haxe Abstracts Example

I just posted a quick gist to the Haxe mailing list showing how one way that abstracts work.

They’re a great way to wrap a native API object (in this case, js.html.AnchorElement) without having to create a new wrapper object every single time. Which means they’re great for performance, the end result code looks clean, and thanks to some of the other abstract magic (implicit casts, operator overloading etc) there is a lot of cool things you can do.

Have a look at the sample, read the Haxe manual, and let me know what you think or if you have questions :)

Categories
Personal

Unsolicited Emails from Australian Labor

I just sent an email abuse report to MailChimp, documenting the unsolicited emails I have been receiving from the Australian Labor party.  I understand that one of their members may have accidentally entered the wrong email address once, but it is unfair that they have subscribed me to 8 separate email lists so far, and I have to take the time to unsubscribe from each one – when I never subscribed in the first place.  This is illegal under the SPAM ACT 2003.

Here is the email I sent them:

Hi

In Australia we have 2 main political parties, one of them being Labor. They’ve recently been voting for a new leader. I’m not a member of the party, but I’ve received an email from Labor people almost every week for the last month – all from different lists, and I have unsubscribed every single time, choosing the “I never subscribed” option.

5 of the 8 lists I received unsolicited email from were hosted by MailChimp, the remainder by NationBuilder (good luck competing! As a web developer I like your product better)

EMAIL 1
Subject: Party. Policy. People.
Sender: MailChimp
X-campaignid: mailchimpd1d04c8e8a8375877ba044bc4.be6aae17ed

EMAIL 2
Subject: Why I’m Standing
Sender: NationBuilder

EMAIL 3
Subject: I want to make a difference
Sender: NationBuilder

EMAIL 4
Subject: Join Bill Shorten for a conversation with country members tonight
Sender: MailChimp
X-campaignid: mailchimp2a0336f66d93a2c444ff3d779.ed092fdc95

EMAIL 5
Subject: Make your vote count
Sender: NationBuilder

EMAIL 6
Subject: I’m supporting Bill
Sender: MailChimp
X-campaignid: mailchimpd1d04c8e8a8375877ba044bc4.1636a97be2

EMAIL 7
Subject: Labor eNews
Sender: MailChimp
X-campaignid: mailchimpb6a6fa942a4870ed76b06bc02.4f94c686b5

EMAIL 8
Subject: Thank you for your support
Sender: MailChimp
X-campaignid: mailchimp429f4375fe72549c8e09fe0fd.53fef0c08a

As you can see, the Australian Labor party is creating many different lists, and is subscribing my email address to each of them without my permission. I am assuming another Jason O’Neil entered an incorrect email address (this happens often), but as it stands I can only assume the Labor party is importing a bulk list of email addresses into MailChimp, and while I can unsubscribe from each individual mailing list, they will just create new lists and re-import my address.

Unsolicited email is illegal in Australia under the SPAM ACT 2003. I have attempted to contact them but was unable to resolve the issue, and I have received multiple emails since then.

I guess what I am asking:

– Can you contact the owners of these lists and remind them of their responsibilities under law and under your terms and conditions?

– Is there a way to prevent my address from being imported into new lists during a bulk import?

Thank you for your time!
Jason

Categories
Faith Justice and Politics Personal

Human Faces

When I see the human face behind a political issue, the emotions of apathy, indignation or anger become less.  Then empathy (understanding their suffering), sorrow (grieving with them), remorse (that collectively, the humans in my country did this to other humans) – these emotions become stronger.  Finally, there is hope – these people have courage, and see a better future.  They want to fight injustice, and fight for the rights of those who follow.  I hope, at the end of my life, I can say that I partnered with these guys, not the powers that locked them up and stole their childhood.

Refugee looks back on ordeal of seeking asylum and being detained in Nauru

(God, have mercy, do not treat us as our sins deserve.)

Categories
Edtech

Humans of New York (reblog)

Wow, just wow.

I struck up a conversation with him, and he casually mentioned that he was having trouble adjusting to Columbia, due to his “previous situation.” So I asked him to elaborate.

“I was born in Egypt,” he said. “I worked on a farm until 3rd grade with no education. I came to the US for one year, started 4th grade, but was pulled out because my father couldn’t find work and returned to Egypt for a year. The first time I went to an actual school was middle school, but the whole school was in one classroom, and I was working as a delivery boy to help the family. It was illegal for me to be working that young, but I did. When I finally got into high school, my house burned down. We moved into a Red Cross Shelter, and the only way we could live there is if we all worked as volunteers. I got through high school by watching every single video on Khan Academy, and teaching myself everything that I had missed during the last nine years. Eventually I got into Queens College. I went there for two years and I just now transferred to Columbia on a scholarship provided by the New York Housing Association for people who live in the projects. It’s intimidating, because everyone else who goes to Columbia went to the best schools, and have had the best education their entire lives.”

 

From: Humans of New York

Categories
Faith Personal Reading & Inspiration

I’m not lapsed. I am a Catholic in waiting — waiting for my church to remember the Gospels, to be a justice and peace-seeking community, to be fully inclusive of women and to be welcoming to people who are not hetero-normative.

Read more: What should church look like

Categories
Edtech Faith Personal

Redefining Entrepreneurship

I want to be an Entrepreneur.  So do a lot of people these days.

It’s been made famous by the likes of Steve Jobs, Bill Gates, and Mark Zuckerburg and more recently startups like AirBNB, DropBox, Instagram and Roxio (Angry Birds) have painted the vivid portrait of the glorious life of a founder: working on something you’re passionate about, creating wealth, pleasing users and making your mark on the world.

People like Paul Graham, whose startup school “Y-Combinator” has funded over 800 startups, argue strongly that startups are the best model for business and innovation, and I tend to agree.  They also point out how hard it all is.

While on holiday, I was thinking about what it means to live subversively – inside one world, with it’s values (being cool, making money, making a mark on the world) while belonging to another reality (living selflessly, trying to bring justice, hope and love into the world, trusting God to help you do things you couldn’t do on your own).

For most people, startups are about one of these things:

  1. Making your mark on the world (“leaving a dent in the universe”, to quote Steve Jobs)
  2. Making a lot of money very quickly
  3. Getting paid to do something you love doing
  4. The thrill of doing something risky.  Not choosing a boring life.

I have no problem with any of these motivations, other than the possible vanity and self absorption that could come with success.  But I wanted to think about what the drive is to run a startup when you come at it from a Christian world-view.

I came up with this line:

“An Exploration of Grace”

(Note: this was an unpublished draft from September 2013. I had a few extra sentences and probably intended to write more, but I can’t remember where it was going. Publishing this in 2023, a decade later, I love this line and will choose to leave it there, and let the sentence speak for itself and evoke what it will).

Categories
Personal Work Habits

How to get the best work out of me

According to Marcus Buckingham’s StandOut profile, this is how to get me doing my best work when I’m working with you:

I am resourceful and can fill the gaps quicker than most. If there’s a project to begin that lacks details or data, I can get it off to a good start.

Tell me that if I try to serve everyone I wind up serving no-one. I must make a choice about who to serve well, and then serve them well. Know that I will be sensitive to any criticisms.

If you’d like to grab my attention, tell me I am not moving boldly enough. Tell me that you expect me to be the first person to challenge an existing way of doing things, the first person to spot, bump into, and report back on a new threat, or a new opportunity.

The overall StandOut profile was disturbingly accurate for me and a friend who took it with me, and this tip also resonates strongly.  I would recommend the profile to anyone seeking to understand their work self better, and I’d recommend this advice to people trying to work better with me :)

Categories
Haxe

Web.cacheModule and Expiring DB connections

The Story

A while ago I posted about neko.web.cacheModule, a way to make your site run dramatically faster on mod_neko or mod_tora. After spending some time making ufront compatible with this mode of running, I was excited to deploy my app to our schools with the increased performance.

I deployed, ran some tests, seemed happy, went home and slept well. And woke up the next morning to a bunch of 501 errors.

The Error

The error message was coming from the MySQL connection: “Failed to send packet”.

At first I just disabled caching, got everyone back online, and then went about trying to isolate the issue. It took a while before I could reproduce it and pinpoint it. I figured it was to do with my DB connection staying open between requests, thanks to the new module caching.

A google search showed only one Haxe related result – someone on IRC that mentioned when they sent too many SQL queries it sometimes bombed out with this error message. Perhaps leaving it open eventually overran some buffer and caused it to stop working? Turns out this was not the case, I used `ab` (Apache Benchmark tool) to query a page 100,000 times and still didn’t see the error.

Eventually I realised it was to do with the MySQL Server dropping the connection after a period of inactivity. The `wait_timeout` variable was set to 28800 by default: so after 8 hours of inactivity.  So long enough that I didn’t notice it the night before, but short enough that the timeout occured overnight while all the staff were at home or asleep… So the MySQL server dropped the connection, and my Haxe code did not know to reconnect it. Whoops.

The Solution

I looked at Nicolas’s hxwiki source code, which runs the current Haxe site for some inspiration on the proper way to approach this for `neko.Web.cacheModule`. His solution: use http://api.haxe.org/sys/db/Transaction.html#main. By the looks of it, this will wrap your entire request in an SQL transaction, and should an error be thrown, it will rollback the transaction. Beyond that, it will close the DB connection after each request. So we have a unique DB connection for each request, and close it as soon as the request is done.

My source code looks like this:

class Server
{
  static var ufApp:UfrontApplication;

  static function main() {
    #if (neko && !debug) neko.Web.cacheModule(main); #end
    
    // Wrap all my execution inside a transaction
    sys.db.Transaction.main( Mysql.connect(Config.db), function() {
      init();
      ufApp.execute();
    });
  }

  static function init() {
    // If cacheModule is working, this will only run once
    if (ufApp==null) {
      UFAdminController.addModule( "db", "Database", new DBAdminController() );
      ufApp = new UfrontApplication({
        dispatchConfig: Dispatch.make( new Routes() ),
        remotingContext: Api,
        urlRewrite: true,
        logFile: "log/ufront.log"
      });
    }
  }
}
Categories
Faith Personal

My Life’s Work

Here is my servant whom I have chosen
the one I love, in whom I delight;
I will put my Spirit on him,
and he will proclaim justice to the nations.
He will not quarrel or cry out;
no one will hear his voice in the streets.
A bruised reed he will not break,
and a smoldering wick he will not snuff out,
till he leads justice to victory.
In his name the nations will put their hope.

Matthew 12:18-21

—–

my servant

Jesus was a servant, and as his disciples, we are his.  Have no illusions, we are here to serve, not to be served.

I have chosen

Each person chosen and assigned their role in ushering in God’s Kingdom, according to their unique God-given skills, strengths and gifts.

I love

Our strength and courage draws on this love God has for us.

in whom I delight

Our motivation is his delight.  Not to earn it, but to revel in it and enjoy it and immerse ourselves in it.

my Spirit on him

This isn’t merely natural work and effort, this is work empowered and affirmed by God’s Holy Spirit.

proclaim justice

Equality, fairness, hope, safety, opportunity

will not quarrel or cry out

It’s not about the sport, spectacle or stardom of society’s idea of success.

no one will hear his voice

Less talk, more action.  Less brand and perception and posturing, more life change.

bruised reed… smoldering wick

The hurt, oppressed, poor, hopeless and helpless, sick, overlooked.

till

Mercy is the strategy and the game plan.  We hold to the strategy until the end.

leads justice to victory

Justice will win out, but it’s slow and requires action, leadership.

In his name the nations will put their hope

This is my life’s work:

to offer Jesus’ hope to all that you can,
to work as he did,
empowered as he was,
with the values he carried
and the strategy he adopted
to the same end he strived for:
   the victory of justice,
   the hope of the nations,
   the delight of the Father.

Categories
Haxe Haxe Log

My Haxe Log: Week #2

This week:

  • My token one day a week I continued on my Node-Webkit project.  This time I made externs for Kue (externs, which appear to be working) and FFMpeg (externs, not functional just yet).  Still enjoying working with Node-Webkit, and with the Node-API library especially.  Sad I didn’t get to make more progress on it this week.
  •  Ufront:
      • Make tracing / logging work reliably between multiple requests. After enabling neko.Web.cacheModule(), I began to find areas where Ufront was not very multiple-request-friendly. These would have surfaced later with a port to Client JS or Node JS, but it’s good to find them now.One problem was that our tracing and logging modules were behaving as if there was only one request at a time. This could result in a trace message for one request ending up being output to somebody else’s request, which is obviously bad.

        The problem is a tricky one, as trace() always translates to haxe.Log.trace(), and you with Ufront’s multiple-request-at-a-time design, you can’t know which request is the current one from a static method. If I think of a clever way to do it, possibly involving cookies and sessions, then I might include a HttpContext.getCurrentContext() static method. This would probably have to be implemented separately for each supported platform.

        The solution for now, however, was to not keep track of log messages in the TraceModule, but in the HttpContext. Then on the onLogRequest event, the trace modules get access to the log messages for the current context, and can output them to the browser, to a file, or whichever they choose.

        The downside is that you have to use httpContext.ufTrace() rather than trace(). I added a shortcut for this in both ufront.web.Controller and ufront.remoting.RemotingApiClass, so that in your controllers or APIs you can call uftrace() and it will be associated with the current request. There is also ufLog, ufWarn and ufError.

        I also made RemotingModule work similarly with tracing and logging – so logs go to both the log file and the remoting call to the browser.

      • Fix logging in ErrorModule. One of the things that made debugging the new ufront really hard was that when there was an Error, the ErrorModule displayed, but the trace messages did not get sent to the browser or the log file. I did a bit of code cleanup and got this working now.
      • Fixed File Sessions / EasyAuth. Once able to get my traces and logs working more consistently, I was able to debug and fix the remaining issues in FileSession, so now EasyAuth is working reliably, which is great.
      • Added Login / Logout for UF-Admin. With UF-Admin, I added a login screen and logout, that works with EasyAuth for now. I guess I will make it pluggable later… For now though it means you can set up a simple website, not worry about auth for the front end, but have the backend password protected. If you use EasyAuth for your website / app, the same session will work on the ufadmin page.
      • Created uf-content for app-generated files. I moved all app-generated files (sessions, logs, temp files etc) into a folder called “uf-content”. Then I made this configurable, and relative to httpContext.request.scriptDirectory. You can configure it by changing the contentDirectory option in your UfrontConfiguration. This will make it easier when deploying, we can have instructions to make that single directory writeable but not accessible via the web, and then everything that requires FileSystem access can work reliably from there.
      • Pushed new versions of the libraries. Now that the basics are working, I pushed new versions of the libraries to Haxelib. They are marked as ufront-* with version 1.0.0-beta.1. From here it will be easy to update them individually and move towards a final release.
      • Demo Blog App. To demonstrate the basics of how it works, and a kind of “best practices” for project structure, I created a demo app, and thought I would start with a blog. I started, and the basic setup is there, including the config structure and each of the controller actions, and the “ufadmin” integration. But it’s not working just yet, needs more work.
      • Identified Hair website. I have a website for a friend’s small business that I’ve been procrastinating working on for a long time. On Saturday I finally got started on it, and set up the basic project and routes in Ufront. In about 4 hours I managed to get the project set up, all the controllers / routes working, all the content in place and a basic responsive design with CSS positioning working. All the data is either HTML, Markdown or Database Models (which get inserted into views). Once I’ve got their branding/graphics included, I’ll use ufront to provide a basic way to change data in their database. And then if they’re lucky, I might look at doing some Facebook integration to show their photo galleries on the site.
Categories
Faith Personal

A Really Clean House

Imagine being married to someone who was absolutely intent on providing a nice home for you.  And by “intent”, I mean obsessive.  They clean everyday – and not just tidy, but dust, mop, scrub and disinfect, and then put nice smelling candles everywhere.  They constantly decorate and set things up just the way you like it.  They maintain the garden keep the yard orderly.  They put on an amazing dinner everyday, starting it early so that it finishes right on time as you get home.

And then the moment you walk through the door, they head off to their own section of the house.  No welcome, no eye contact, no hugs, no acknowledgement at all.  For the rest of the night, you try to enjoy the beautifully pristine house on your own.  Apparently they do it because they love you.  But you can’t help but feel if they really loved you they’d at least want to see you, talk to you, spend time with you and touch you.  The service is there, and it’s great – as good as you’d get in a hotel.  But, much like the hotel, this is not love, it’s not a relationship, it’s just service.

I imagine this is how God feels about people who are too busy being religious to spend time getting to know him.

For I desire mercy, not sacrifice.  And acknowledgement of God rather than burnt offerings.
Hosea 6:6

Categories
Haxe Haxe Log

My Haxe Log: Week #1

Hello! For a reason I can’t comprehend, this page is the most visited page on my blog. If you’re looking for information about logging in Haxe, the “Logging and Tracing” page in the manual is a good start.

If you can be bothered, leave a comment and let me know what you’re looking for or how you came to be here. I’d love to know!

Jason.

Every week as part of my work and as part of my free time I get to work on Haxe code, and a lot of that is contributing to libraries, code, blog posts etc.  Yesterday was one of those frustrating days where I told someone I’d finish a demo ufront app and show them how it works, but I just ran into problem after problem and didn’t get it done, and was feeling pretty crap about it.

After chatting it out I looked back at my week and realised: I have done alot.  So I thought I should start keeping a log of what I’ve been working on – mostly for my own sake, so I can be encouraged by the progress I have made, even if I haven’t finished stuff yet.  But also in case anything I’m working on sparks interest or discussion – it’s cool to have people know what I’m up to.

So I’d like to start a weekly log.  It may be one of those things I do once and never again, or it may be something I make regular: but there’s no harm in doing it once.

So here we go, my first log.  In this case, it’s not just this week, some of it requires me to go back further to include things I’ve been working on, so it’s a pretty massive list:

  • Node Webkit: On Monday’s I work at Vose Seminary, a tertiary college, and I help them get their online / distance education stuff going.  Editing videos, setting up online Learning Management Systems etc.  I have a bunch of command line utils that make the video editing / exporting / transcoding / uploading process easier, but I want to get these into graphics so other staff can use it.  Originally I was thinking of using OpenFL / StablexUI.  I’m far more comfortable with the JS / Browser API than the Flash API however, and so Node-Webkit looked appealing.  On Monday I made my first Haxe-NodeJS project in over a year, using Clement’s new Node-API repo.  It’s beautiful to work with, and within an hour and a half I had written some externs and had my first “hello-world” Node-Webkit app.  I’ll be working on it again this coming Monday.
  • neko.Web.cacheModule: I discovered a way to get a significant speed-up in your web-apps.  I wrote a blog post about it.
  • Ufront: I’ve done a lot of work on Ufront this week.  After my talk at WWXthis year, I had some good chats with people and basically decided I was going to undertake a major refactor of ufront.  I’m almost done!  Things I’ve been working on this week (and the last several weeks, since it all ties in together):
    • Extending haxe.web.Dispatch (which itself required a pull request) to be subclassed, and allowing you to 1) execute the ‘dispatch’ and ‘executeAction’ steps separately and 2) allow returning a result, so that you can get the result of your dispatch methods.  This works much nicer with Ufront’s event based processing, and allows for better unit testing / module integration etc.  The next step is allowing dispatch to have asynchronous handlers (for Browser JS and Node JS).  I began thinking through how to implement this also.
    • After discovering neko.Web.cacheModule, I realised that it had many implications for Ufront.  Basically: You can use static properties for anything that is generic to the whole application, but you cannot use it for anything specific to a request.  This led to several things breaking – but also the opportunity for a much better (and very optimised) design.
    • IHttpSessionState, FileSession: the first thing that was broken was the FileSession module.  The neko version was implemented entirely using static methods, which led to some pretty broken behaviour once caching between requests was introduced.  In the end I re-worked the interface “IHttpSessionState” to be fairly minimal, and was extended by the “IHttpSessionStateSync” and “IHttpSessionStateAsync” interfaces, so that we can begin to cater for Async platforms.  I then wrote a fresh FileSession implementation that uses cookies and flat-files, and should work across both PHP and Neko (and in Future, Java/C#).  The JS target would need a FileSessionAsync implementation.
    • IAuthHandler / EasyAuth: At the conference I talked about how I had an EasyAuth library that implemented a basic User – Group – Permission model.  At the time, this also was implemented with Static methods.  Now I have created a generic interface (IAuthHandler) so that if someone comes up with an auth system other than EasyAuth, it can be compatible.  I also reworked EasyAuth to be able to work with different a) IHttpSessionState implementations and b) different IAuthAdapter’s – basically, this is an interface that just has a single method: `authenticate()`.  And it tells you if the user is logged in or not.  EasyAuth by default uses EasyAuthDBAuthAdapter, which compares a username and password against those in the database.  You could also implement something that uses OpenID, or a social media logon, or LDAP, or anything.  All this work trying to make it generic enough that different implementations can co-exist I think will definitely pay off, but for now it helps to have a well thought out API for EasyAuth :)
    • YesBoss: Sometimes you don’t want to worry about authentication.  Ufront has the ability to create a “tasks.n” command line file, which runs tasks through a Command Line Interface, rather than over the web.  When doing this, you kind of want to assume that if someone has access to run arbitrary shell commands, they’re allowed to do what they want with your app.  So now that I have a generic interface for checking authentication, I created the “YesBossAuthHandler” – a simple class that can be used wherever an authentication system is needed, but any permission check it always lets you pass.  You’re the boss, after all.
    • Dependency Injection: A while ago, I was having trouble understanding the need for Dependency Injection.  Ufront has now helped me see the need for it.  In the first app I started making with the “new” ufront, I wanted to write unit tests.  I needed to be able to jump to a piece of code – say, a method on a controller – and test it as if it was in a real request, but using a fake request.  Dependency injection was the answer, and so in that project I started using Minject.  This week, realising I had to stop using statics and singletons in things like sessions and auth handling, I needed a way to get hold of the right objects, and dependency injection was the answer.  I’ve now added it as standard in Ufront.  There is an `appInjector`, which defines things that should be injected everywhere (modules, controllers, APIs etc).  For example, injecting app configuration or a caching module or an analytics API.  Then there is the dispatchInjector, which is used to inject things into controllers, and the remotingInjector, which is used to inject things into APIs during remoting calls.  You can define things you want to make available at your app entry point (or your unit test entry point, or your standalone task runner entry point), and they will be available when you need them.  (As a side note, I now also have some great tools for mocking requests and HttpContexts using Mockatoo).
    • Tracing: Ufront uses Trace Modules.  By default it comes with two: TraceToBrowser and TraceToFile.  Both are useful, but I hadn’t anticipated some problems with the way they were designed.  In the ufront stack, modules exist at the HttpApplication level, not at the HttpRequest level.  On PHP (or uncached neko), there is little difference.  Once you introduce caching, or move to a platform like NodeJS – this becomes a dangerous assumption.  Your traces could end up displaying on somebody else’s request.  In light of this, I have implemented a way of keeping track of trace messages in the HttpContext.  My idea was to then have the Controller and RemotingApiClass have a trace() method, which would use the HttpContext’s queue.  Sadly, an instance `trace()` method currently does not override the global `haxe.Log.trace()`, so unless we can get that fixed (I’m chatting with Simon about it on IRC), it might be better to use a different name, like `uftrace()`.  For now, I’ve also made a way for TraceToBrowser to try guess the current HttpContext, but if multiple requests are executing simultaneously this might break.  I’m still not sure what the best solution is here.
    • Error Handling: I tried to improve the error handling in HttpApplication.  It was quite confusing and sometimes resulted in recursive calls through the error stack.  I also tried to improve the visual appearance of the error page.
    • Configuration / Defaults:The UfrontApplication constructor was getting absurd, with something like 6 optional parameters.  I’ve moved instead to having a `UfrontConfiguration` typedef, with all of the parameters, and you can supply, all, some or none of the parameters, and fall-backs will be used if needed.  This also improves the appearance of the code from:new UfrontApplication( true, “log.txt”, Dispatch.make(new Routes()) );

      to

      new UfrontApplication({
      urlRewrite: true,
      dispatchConf: Dispatch.make( new Routes() ),
      logFile: “log.txt”
      });

    • More ideas: last night I had trouble getting to sleep.  Too many ideas.  I sent myself 6 emails (yes 6) all containing new ideas for Ufront.  I’ll put them on the Ufront Trello Board soon to keep track of them.  The ideas were about Templating (similar abstractions and interfaces I have here, as well as ways of optimising them using caching / macros), an analytics module, a request caching module and setting up EasyAuth to work not only for global permissions (CanAccessAdminArea), but also for item-specific permissions: do you have permission to edit this blog post?
    • NodeJS / ClientJS: after using NodeJS earlier in the week, I had some email conversations with both Clement and Eric about using Ufront on NodeJS.  After this week it’s becoming a lot more obvious how this would work, and I’m getting close.  The main remaining task is to support asynchronous calls in these 3 things: Dispatch action execution calls, HttpRemotingConnection calls, and database calls – bringing some of the DB Macros magic to async connections.  But it’s looking possibly now, where as it looked very difficult only 3 months ago.
  • CompileTime: I added a simple CompileTime.interpolateFile() macro.  It basically reads the contents of the file at macro time, and inserts it directly into the code, but it inserts it using String Interpolation, as if you had used single quotes.  This means you can insert basic variables or function calls, and they will all go in.  It’s like a super-quick and super-basic poor-man’s templating system.  I’m already using it for Ufront’s default error page and default controller page.
  • Detox: this one wasn’t this week, but a couple of weeks ago.  I am working on refactoring my Detox (DOM / Xml Manipulation) library to use Abstracts.  It will make for a much more consistent API, better performance, and some cool things, like auto-casting strings to DOM elements:”div.content”.find().append( “<h1>My Content</h1>” );
  • My Work Project: Over the last two weeks I’ve updated SMS (my School Management System project, the main app I’ve been working on) to use the new Ufront.  This is the reason I’ve been finding so much that needs to be updated, especially trying to get my app to work with “ufront.Web.cacheModule”.
Categories
Haxe

neko.Web.cacheModule()

Until now I haven’t had to worry much about the speed of sites made using Haxe / Ufront,  – none of the sites or apps I’ve made have anywhere near the volume for it to be a problem, and the general performance was fast enough that no one asked questions. But I’m going to soon be a part of building the new Haxe website, which will have significant volume.

So I ran some benchmarks using ab (Apache’s benchmarking tool), and wasn’t initially happy with the results. They were okay, but not significantly faster than your average PHP framework. Maybe I would have to look at mod_tora or NodeJS for deployment.

Then I remembered something: a single line of code you can add that vastly increases the speed: neko.Web.cacheModule(main).

Benchmarks

Here is some super dumb sample code:

class Server {
  static var staticInt = 0;
  static function main() {
    #if neko
      neko.Web.cacheModule(main); // comment out to test the difference
    #end 
    var localInt = 0; 
    trace ( ++staticInt ); 
    trace ( ++localInt ); 
  } 
} 

And I am testing with this command:

ab -n 1000 -c 20 http://localhost/ 

Here are my results (in requests/second on my laptop):

  • Apache/mod_php (no cache): 161.89
  • NekoTools server: 687.49
  • Apache/mod_neko (no cache): 1054.70
  • Apache/mod_tora (no cache): 745.94
  • Apache/mod_neko (cacheModule): 3516.04
  • Apache/mod_tora (cacheModule): 2185.30

First up: I assume mod_tora has advantages on sites that use more memory, but a dummy sample like this is more overhead than it’s worth.

Second, and related: I know these tests are almost worthless, we really need to be testing a real app, with file access and template processing and database calls.

Let’s do that, same command, same benchmark parameters:

  • Apache/mod_php (no cache): 3.6 (ouch!)
  • NekoTools server: 20.11
  • Apache/mod_neko (no cache): 48.74
  • Apache/mod_tora (no cache): 33.29
  • Apache/mod_neko (cacheModule): 351.42
  • Apache/mod_tora (cacheModule): 402.76

(Note: PHP has similar caching, using modules like PHP-APC. I’m not experienced setting these up however, and am happy with the neko performances I’m seeing so I won’t investigate further)

Conclusions:

  • the biggest speed up (in my case) seems to come from cacheModule(), not mod_tora. I believe once memory usage increases significantly, tora brings advantages in that arena, and so will be faster due to less garbage collection.
  • this could be made faster, my app currently has very little optimisation:
    • the template system uses Xml, which I assume isn’t very fast.
    • a database connection is required for every request
    • there is no caching (memcached, redis etc)
    • I think I have some terribly ineffecient database queries that I’m sure I could optimise
  • Ufront targeting Haxe/PHP is not very fast out-of-the-box. I’m sure you could optimise it, but it’s not there yet.
  • This is running on my laptop, not a fast server. Then again, my laptop may be faster than a low end server, not sure.

Usage

So, how does it work?

#if neko neko.Web.cacheModule( main ); #end 

The conditional compilation (#if neko and #end) is just there so that you can still compile to other targets without getting errors. The cacheModule function has the following documentation:

Set the main entry point function used to handle requests.
Setting it back to null will disable code caching.

By entry point, it is usually going to mean the main() function that is called when your code first runs. So when the docs ask for a function to use as the entry point, I just use main, meaning, the static function main() that I am currently in.

I’m unsure of the impact of having multiple “.n” files or a different entry point.

The cache is reset whenever the file timestamp changes: so when you re-compile, or when you load a new “.n” file in place.

If you wanted to manually disable the cache for some reason, you use cacheModule(null). I’m not sure what the use case is for this though… why disable the cache?

Gotchas (Static variable traps with cacheModule)

The biggest gotcha is that static variables persist in your module. They are initialized just once, which is a big part of the speed increase. Let’s look at the example code I posted before:

class Server {
  static var staticInt = 0;
  static function main() {
    #if neko
      neko.Web.cacheModule(main); // comment out to test the difference
    #end 
    var localInt = 0; 
    trace ( ++staticInt ); 
    trace ( ++localInt ); 
  } 
} 

With caching disabled, both trace statements will print “0” every time. With caching enabled, the staticInt variable does not get reset – it initializes at 0, and then every single page load will continue to increment it, it will go up and up and up.

What does this mean practically:

  • If you want to cache stuff, put it in a static variable. For example:
    • Database connections: store them in a static variable and the connection will persist.
    • Templates: read from disk once, store them in a static variable
    • App Config, especially if you’re passing JSON or Xml, put it in a static and it stays cached.
  • Things which should be unique to a request, don’t store in a static variable. For example:
    • Ufront has a class called NekoSession, which was entirely static methods and variables, and made assumptions that the statics would be reset between requests. Wrong! Having the session cached between different requests (by different users) was a disaster – everytime you click a link you would find yourself logged in as a different user. Needless to say we needed to refactor this and not use statics :) To approach it differently, you could use a static var sessions:StringMap<SessionID, SessionData> and actually have it work appropriately as long as the cache stayed alive.
    • Avoid singletons like Server.currentUser, or even User.current – these static variables are most likely going to be cached between requests leading to unusual results.
Categories
Edtech Haxe

Cross post: Why the Pomodoro technique doesn’t work for me

In case you’re interested, on my Personal Blog I have a post “Why the Pomodoro Technique Doesn’t Work For Me”.  It’s about time management for creative workers.  Have a look if you’re interested…

Categories
Personal Work Habits

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 :)

Categories
Faith Justice and Politics Personal

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.

Categories
Faith

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.

Categories
Faith Personal

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.

Categories
Haxe

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.

Categories
Haxe

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!

Categories
Haxe

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.