i used to be a programmer


archy_cover
archy_rats2


Yesterday I was at Owl & Company over on Piedmont Ave in Oakland and came across an interesting read by complete chance. It is a book of poetry and narrative of archy, who was a roach in 1920, and before that, a free verse poet. Archy hops from key to key on a typewriter leaving notes for his human ‘boss’ who owns the typewritter and ‘provides’ him with food in the garbage can. It is a real treat, and because of the whitespace, a real short treat at that. I finished it within a couple hours. The curious thing was that soon after reading this I found an untitled document open on TextEdit that I do not recall having anything to do with. I’m keeping it here so that I can document it.


i used to be a programmer
but now i am just a roach that had my soul transmigrated from
a programmer after i died
why a roach you ask well if you must know
it is for my programmer sins like
using so much indirection and so many underscores
oh the irony
i can t even press the shift key being a roach
can t even make an underscore much less
left parenthesis right parenthesis

the funny thing is
being a roach now
i have many ideas
but can t code any more left parenthesis
i had some ideas while human
they all made money
like the one to drive cars
with mustaches or umlauts
can t remember same thing really
they all take thirty percent right parenthesis

when you die and turn into a roach
they give you all your money
it carries over so to say
but as a roach it is hard to pick up
a dollar bill and
they don t make credit cards for us
but now i have no rent to worry about
i live in a lovely victorian
and the food is good as ever

now i have time to think
come up with some real good ones
but since money doesn t mean anything now
i think of programs to make abstract art
i described it to the venture capitalist
he said people don t want roach art apps
they hate things that are ugly and free
or maybe just things that are free that are made by a roach
i told him i don t need money
he said why dont you need money
i said i m a roach
he said lol i should have known
i am hiring a taskrabbit to step on you
and another to save you to make it a fair game
because they call me an angel investor
and i want to disrupt the world
anyway i decided to leave then

only a few problems for roaches
there is a programmer rat here named steve
code reviewing my text
bad indentation he says
its not even code i say
he says you got that right
what a jerk

Untitled

Here’s my .emacs file in all its unedited glory. May it be a light in your time of google searching or a darkness in your time of trying to understand how to configure emacs.

It’s also in a gist.

It’s a franken.emacs from lots of sources on the net. I’ve forgot them all, but almost none of this functionality originated with me and thus you should give your thanks to the anonymous internet. I wanted to document it for a while because it’s helpful when I switch to a new computer. It’s so messy that I put off documenting it. I’ve decided to share it anyways.
Features are

  • ctrl-x ctrl-o to switch between a .m, .mm, .c, .cpp file to corresponding .h file if it is nearby
  • ctrl-arrow to switch between multiple buffers/windows that you split horizontally or vertically (e.g. with ‘ctrl-x ctrl-3’
  • auto reverts when file changes on disk (e.g. when you git checkout) – note this can be a little dangerous, but I believe it doesn’t do this if you have local modifications
  • copy and paste works with os-x clipboard and vice-versa with your yank/copy/kill ring
  • other stuff

pop quiz: why are my parameters zero when I pass them in with non-zero values

This one had me stuck for a number of minutes. It’s not hard, but it got me. See if you can spot it:

say you create a new class that is inited like so:

@interface YoDogWhatsWrong
@property (nonatomic) float aValue;
@end
@implementation YoDogWhatsWrong
- (id)initWithAValue:(float)aFloat anotherValue:(float)someOtherValue
{
    if ((self = [super init])) {
        self.aValue = aFloat;
    }
    return self;
}
@end

and you call it somewhere with

    YoDogWhatsWrong *notCreatedProperly = [[YoDogWhatsWrong alloc] initWithAValue:180 anotherValue: 0];
    NSLog(@"aValue is %f", notCreatedProperly.aValue);

and you find that to your dismay that ‘aValue is 0.0’. There’s something wrong here, and it is worse than your lack of creative variable names.

Did you spot it?

Did you?

Well, Obj-C doesn’t have a compilation error if you don’t have a method declared in the interface and you still call it, but it does give you a warning. If you’re anything like me, you’ve probably abused this before when you’re hacking away at the implementation, with the intent of adding the methods that are used publicly. Well, most of the time you can get away with this, because many of the times the parameters are objective-C objects. In this case they were floats, and unfortunately, either the obj-c spec the compiler assumes a default calling convention that was of type ‘id’ instead of float, and sizeof ‘id’ was larger than sizeof(float) here. The rest of the story should be clear now: the first parameter in the init method got the upper half of the bits of ‘180.f’ which is just zeros, and the next parameter got the lower half.

This weird behavior will also happen if you forget to include a header for a method that uses (float) or some other primitive type. A lot of bad stuff can be avoided by keeping a zero warning count, or at least, looking at your warnings regularly.

So to fix the problem, simply add the method declaration to the interface, like you (I) should have been doing all along:

@interface YoDogWhatsWrong
@property (nonatomic) float aValue;
- (id)initWithAValue:(float)aFloat anotherValue:(float)someOtherValue;
@end

FYI this was on the iOS simulator 7.0 4 inch (not 64 bit) and (disclaimer) I haven’t compiled any of the code on this post.

Android Dev Console Wallet Registration: Error 400

If you’re setting up IAP for the first time on your google dev console, you will probably need to setup google wallet for merchants.

I ran into a silly bug where I fill out the form and always got a message that read:

An error occurred {“type”:”PLATFORM_ERROR”, “payload”:”400″, “request_id”:”4EDF17245AA00.A803E4F.6DB2″}

Emailed support a couple times, turns out to be that you can’t have a P.O. box address listed as your address on this form. It would be nicer if they could just say that in an error message. Hope this saves someone a day.

Namespacing a framework in objective-c, @compatibility_alias, and #defines

Shakespeare said something about roses and names smelling nice, but if you’re Outkast you know that sometimes, roses really smell like poo. Additionally, if you’re a programmer, you sometimes need to get another set of better spelling roses to set the world right. Far-fetched metaphors aside, namespacing issues come up less than I would expect. For one, most people know better than to call their classes ‘Object’, and everyone has their own novel solutions to the problem – be it prefixing every class with their initials or a swear word. This week I came across a project that required two implementations of the same framework to be present in the same iOS app. The frameworks had the same, or very similar headers, but the implementations were quite different. The use case in question was for migrating data from one implementation of the framework to another. Objective-C doesn’t have the namespace keyword magic that would make this problem a little faster.

My thought process evolved like this:

  1. My first thought was to rename everything in the old framework by adding a new ‘OLD’ prefix. However, this is quite a lot of work, depending on the size of the framework, and it can be tricky to come up with the right sed command that does everything you wanted.
  2. My next thought was to use #defines for everything I wanted to namespace in the headers only. However, this poses some serious problems for class naming conventions, even if you only conditionally define it within the framework compilation unit. Consider a class called ‘MyClass’. You might have MyClassDelegate, eTargetTypeMyClass, and even other classes with the same prefix or suffix, like MyClassManager or ComplicatedMyClass. #defines might or might not expand in the way you want here – but you can see the risk: it’s easy to end up with half of the file containing ComplicatedOLDMyClass in one compilation unit and OLDComplicatedMyClass in the other.
  3. 3. I found out about @compatibility_alias, which solves the problems with #2 for classes (and nothing else). However, this actually solved most of my problems and was fairly compatible with doing non-class namespacing as mentioned in 2.
  4. @interface OLDMyClass
    ...
    @end
    
    @protocol OLDMyProtocol
    @end
    
    #ifdef COMPILING_MYCLASS
    @compatibility_alias MyClass OLDMyClass; // this tricks the MyClass.m file to use the OLDMyClass interface
    #define MyProtocol OLDMyProtocol
    #endif
    

Limitations of @compatibility_alias:

  1. You can only use it with a real class to an aliased class. You can use it before the real class is declared (but the compiler will emit a warning). If the alias class is already declared, it will cause an error.
  2. You can only use it once per compilation unit for a given alias (you can’t use it liberally like you can with forward declares).
  3. You cannot use it with protocols, typdefs, enums, or anything besides an objective-c class.
  4. All @class MyClass forward decl’s will need to either be swapped out for an #import “MyClass.h” or changing the forward decl to @class OLDMyClass and all occurrances in the header to OLDMyClass.

So how do you namespace the protocols, typedefs, and enums? You could rename everything in the .h and .m files, but it is a lot less work to just ‘#define originalprotocol OLDoriginalprotocol’ and declare OLDProtocol in the header.

You can then #ifdef the #defines and @compatibility_alias’s on the condition that you are compiling the framework itself. This trick is similar to exporting only certain symbols when building a library, and allows for the framework’s implementation (.m files) to be remain almost entirely unchanged (using the ‘originalclass’ form), and when compiling the app, the app only sees the OLD_originalclass form, and also the #defines won’t be able to accidentally expand strings that it happens to match.

I ended up using a sed command only to change the #import to #import.

I did the above for the older version of the framework, and left the newer one unchanged. This allows them to both be used simultaneously. There are other tricks you might be able to do like dynamic loading, but if you need classes from both at the same time, this is probably the way to go.

For reference, here’s a file that I used to test the edge cases. You can compile with ‘clang -framework Foundation compatibility_alias_test.m’, or see the errors caused by wrong usage with ‘clang -DWONT_COMPILE -framework Foundation compatibility_alias_test.m’ :

#include <Foundation/Foundation.h>
#include <stdio.h>

// 1.Only classes work with @compatibility_alias:
// 2. Protocols, typedef, enums and other things are out.
// 3. You might be able to use a #define with #undef for those
// 3.1. If that would interfere with the original namespace you are colliding with,
//      you might try conditionally defining it where it is needed, probably similar
//      to exporting only some symbols when building a lib (if just including headers it would be hidden)

#ifdef WONT_COMPILE
// forward declare of aliased name conflicts with alias
@class SpecificClass; // error: conflicting types for alias 'SpecificClass'
#endif

@protocol NonColiding_BeerHolder
@property (nonatomic, assign) int beers;
@end
#ifdef WONT_COMPILE
@compatibility_alias BeerHolder NonColiding_BeerHolder; // warning: cannot find interface declaration for 'NonColiding_BeerHolder'
// also, later: error: cannot find protocol declaration for 'BeerHolder'
#else
#define BeerHolder NonColiding_BeerHolder
#endif

@interface NonColiding_SpecificClass : NSObject <BeerHolder>
@property (nonatomic, assign) int beers;
@end

@implementation NonColiding_SpecificClass
- (id)initWithBeers:(int)beers
{
    if ((self = [super init])) {
        self.beers = beers;
    }
    return self;
}
@end

@compatibility_alias SpecificClass NonColiding_SpecificClass;

#ifdef WONT_COMPILE
// you also can't double up on compatibility_alias like you can with forward decls.
@compatibility_alias SpecificClass NonColiding_SpecificClass;
#endif

int main(int argc, const char* argv[])
{
    SpecificClass* bob = [[SpecificClass alloc] initWithBeers:5];
    NSObject<BeerHolder>* bh = bob;

    // sanity
    printf("yo dog i'm bob and i have %d beers.\n", bob.beers);
    printf("yo dog i'm a beer holder and i have %d beers.\n", bh.beers);
    [bob release];
}