Angersock

We should've stopped--but let's keep going and see what happens.

Hedging Bets

Introduction

This is a fun little thought-experiment. I’m not detailing anything our friends in finance and business don’t already know, but it might be something entertaining to chew on if you are (as I am at this moment) stuck on a bus and needing something to do.

A system for gambling

My mother had a rule for gambling, passed down through her family:

When you go into the casino, put the money you’re betting in your left pocket. Whenever you win, put the winnings in the right pocket. You can keep gambling as long as you have money in either pocket. Once your pockets are empty—you stop.

The intent of this system is to:

  • Prevent the mixture of winnings with principal.
  • Give the option of “reinvesting” winnings.
  • Most importantly, to place a hard limit on losses.

So, why do we care about this?

A worldwide casino

Let’s play with this system and see if we can get any insights for larger-scale gambling.

The game we play is simple. The player state is:

  • D0 the initial liquid funding of the player.
  • D the amount of liquid funds available.
  • N the number of tickets a player owns.

The game state is:

  • T the time elapsed in the game since the start time, T_0.
  • P_ticket the current purchase/selling price of a ticket.

The rules are:

  • Tickets are completely fungible—you can buy fractional tickets.
  • Every time period dt, you can buy zero or more tickets at price P_ticket(T), up until you’ve exceeded D. Each purchase is deducted from D.
  • Every time period dt, you can sell zero or more tickets at price P_ticket(T), until you’ve exceeded N. Each sale is credited to D.
  • Every time period dt, P_ticket will monotonically increase by some amount.
  • At some time T_ohshit, P_ticket will begin plummeting.

The goal conditions:

  • You win if you walk away with more money than you started with.
  • You lose if you walk away with less money than you started with.
  • You draw if you walk away with the same amount of money you started with.

Trivial strategies: not playing

So, the simplest strategy is to not play at all. Take the funds and walk.

This prevents any possible lose conditions, but similarly prevents a win. A draw is assured.

Alternately, immediately buy all of the shares possible (floor(D0/P_ticket)) and sell them on the subsequent timestep.

Unless T_ohshit is happens at T=dt, you’re guaranteed a neglible profit.

Stupid strategy: Ride the wave

The strategy

Until T_ohshit, you know that buying a ticket will only get more expensive than at T_0. Thus, it makes sense that the cheapest time to buy a ticket is at the very beginning, so you should do that.

Now, the best time to sell is going to be at T_ohshit—but you won’t know that time has come until T_ohshit + dt. At which point, since the price is plummeting, you know the best time to sell is as soon as possible.

So, you say “Aha angersock, I will buy at the first timestep and sell at the moment I think T_ohshit has passed.”

Analysis of the payout

The profit is going to be equal to the revenue of the tickets sold less the cost of the tickets purchased.

In our case, that is:

1
Profit = Revenue - Cost

We can expand that out:

1
2
Profit = ( N * P_ticket( T_ohshit + dt ) ) - ( P_ticket(0) * N )
Profit = N * ( P_ticket( T_ohshit + dt) - P_ticket(0) )

Now, given that we purchased all of our tickets at the beginning, we know N:

1
N = D / P_ticket(0)

And so:

1
2
Profit = D / P_ticket(0) * (P_ticket( T_ohshit + dt ) - P_ticket( 0 ) )
Profit = D * ( 1 - P_ticket( T_ohshit + dt ) / P_ticket(0))

Not super impressive, but it reassures us that rudimentary microeconmics still works. Note though that the profit is directly dependent on the amount of funds spent in the beginning!

Flaws and assumptions

There are some problems with this, in practice:

  • What if my cat eats my router and I don’t catch the timestep directly after the crash? How long do I have before I’m not longer profiting?

  • What if the ticket price changes really drastically in like one time step?

Conclusion

That’s it for now. Next time we’ll:

  • See what more conservative strategies we can play
  • See how to bound the risk of missing the T_ohshit event.
  • See if we can adapt to a removal of the monotonically increasing and decreasing assumptions.

It Could’ve Been Awesome, but Now It Sucks.

A fellow contractor, who had been functioning as effectively architect and back-end lead for a company that had also hired me for a while, said this one day in our back-channel.

Long story short, the business folks had an interesting problem, a potentially profitable business, and were doing pretty much everything they could think of to steal defeat from the jaws of victory.

It struck a chord with me, and perhaps it will with you: how many projects have we all worked on that could’ve been awesome, but then sucked?

Too many, in my experience. Too many.

Unreferenced Function Parameters and You

What is an URFP?

Oftentimes it is useful to declare a function to match a particular signature but without making use of the parameters it consumes. Inevitably, this causes a bunch of griping from static analysis tools and compilers.

A short example, urfp.c:

1
2
3
4
5
6
7
8
void foo( int bar ) {
    return;
}

int main (int argc, char** argv) {
    foo(42);
    return 0;
}

And when we feed it to gcc, we get:

1
2
3
4
5
6
7
8
9
10
11
12
13
angersock@devbox:~$ gcc urfp.c  -Wunused-parameter
urfp.c: In function foo:
urfp.c:1:15: warning: unused parameter bar [-Wunused-parameter]
 void foo( int bar ) {
                    ^
urfp.c: In function main:
fp.c:5:15: warning: unused parameter argc [-Wunused-parameter]
 int main( int argc, char** argv) {
                ^
urfp.c:5:28: warning: unused parameter argv [-Wunused-parameter]
 int main( int argc, char** argv) {
                            ^

Why does this happen—other than the compiler flag, I mean?

Most frequently in some kind of OOP language we find ourselves overriding a method on a class. That override may not use all of the arguments supplied by the caller: for example, a stub update( float dt) method in a game entity’s logic.

Fixing URFP In C/C++

So, to fix this, we define a simple macro:

1
#define URFP(x) ((void)x)

Then, we just use it at the top of a function to shut up the compiler.

1
2
3
4
5
6
7
8
9
10
void foo( int bar ) {
    URFP(bar);
    return;
}

int main( int argc, char** argv) {
    URFP(argc);
    URFP(argv);
    return 0;
}

Note that in C++ this isn’t always safe, because of type overloading. One can imagine a situation wherein some clever person has overridden the void typecast operator on their class, and so when you URFP it away it still does something unseemly instead of disappearing. This is a failure of the C++ language.

In Javascript

JSHint and JSLint will both complain to you if you don’t disable the behavior.

In JSHint, the appropriate line to use can be found in the docs:

1
2
3
4
5
6
{
"unused" : "strict"  // Unused variables:
                     //   true     : all variables, last function parameter
                     //   "vars"   : all variables only
                     //   "strict" : all variables, all function parameters
}

I tend to always leave this at strict, because I prefer to get any help from the linter that I can.

The problem is, of course, that this will make the linter scream bloody murder whenever you run it over your source code. So, a moral equivalent to the URFP above is:

1
function URFP( x ) { /* jshint expr:true */ x; }

This will let you consume the variable in the function and do nothing, and then the jshint expr directive will keep the linter from complaining about the lack of invocation or assignment.

HN/Lobsters: Good News, Bad News, How to Win Big (Part 3)

In part 1, we talked about HN/Lobsters-style sites and how their karma mechanics promoted good behavior and helped produce civility and discussion.

In part 2, we talked about how the same mechanisms could be gamed in ways that tended to corrupt and make those communities toxic.

In this final part, I’ll go over some strategies that I think can help mitigate these problems.

How to Win Big

Order posts randomly

One of the consistent themes from the previous section involves fiddling with the post order in order to get more upvotes. Even with several posts of isomorphic content, the first post will probably get more upvotes than the others.

So, in order to remove the entire category of “Hey, let’s play with the ordering of posts and reply to things that otherwise aren’t related”, sites should just display subthreads in randomized order. This would mean:

  • All child posts of a subthread at the same level should be displayed in random order.
  • Randomization shouldn’t occur per-pageload, because that’d be slow.
  • Randomization should occur per-user, so the same user can rapidly find things.

This does perhaps mean that bad posts show up at the top of the page, but that isn’t guaranteed to happen. An option for omitting posts below a certain threshold (say, 0 karma) might also solve this, but that introduces secondary effects that might be bad.

Throttle story submissions

In order to prevent spamming of the front page with little easy-upvote and click-bait stories, prevent users from submitting more than one or two stories over the course of some time interval. This also:

  • Prevents a handful of users from dominating the front page through sheer quantity.
  • Prevents users from being overloaded by constant churn of submissions and allows proper
  • Slows the effects of bad submissions (even if bad ones get in, it is at a slower rate so damage isn’t as acute).

Aggressively and transparently moderate your community

HN already does this, though the transparency is lacking. Lobsters is completely open about all moderation actions, and has a public log of what has occurred.

Aggressive moderation is not necessarily harsh moderation, but instead refers to admins and sysops keeping a close eye on the community and forums and making sure that bad actors are dealt with quickly. This means:

  • Identifying and dealing with abusive behavior.
  • Proactively organizing tags and titles for consistency.
  • Reminding users of community decorum as needed.

Moderation should never, though, exhibit the following behavior:

  • Editing user posts without explicit permission
  • Banning users with dissenting opinions but who are civil.
  • Removing stories or comments preemptively (censorship)

Note that there is seeming conflict here: how can a moderator both protect the community against abuse and also avoid censorship? That is the reason that frequent and close (aggressive) moderation is so important: done correctly, it allows the community to build up a set of standards and hold to them, and thus they learn to self-regulate to an extent.

Moderation is ultimately dependent on community cooperation and focus, and as long as the community hasn’t normalized into its culture abusive or disruptive behavior or submission strategies (as talked about in the previous article), then moderation itself can be done without devolving into strong-arming.

Conclusion

That’s it for this series. At this time, I don’t really feel like I’ve got better advice, and frankly I think I’m done writing about this topic for now. I’ll update this article as ideas occur to me later. Thanks for reading!

HN/Lobsters: Good News, Bad News, How to Win Big (Part 2)

In part 1, we talked about HN/Lobsters-style sites and how their karma mechanics promoted good behavior and helped produce civility and discussion.

Next, we’re going to cover how those same mechanics promote toxic behavior, and how a bad-faith poster can cynically exploit the system in order to gain standing.

Note that this is all going to be behavior accomplished by a normal user. No sockpuppeting, upvote ringing, or anything else sketchy needs be happening—this is just playing the game straight with a different value perspective. As such, this is also all behavior that plausibly a normal user may accidentally engage in.

Bad News

We’ve shown how to be a good poster, and how to really improve the community and get decent amounts of karma for little time investment.

Let’s assume though, in typical paperclip-making machine fashion, that we only care about increasing our karma. This assumption also means that we have extra time (perhaps a couple of hours a day) to spend…that being the case, every little trick we can use will help ratchet us to greatness.

The bad news is that there are people on HN and Lobsters that are like this and that, worse still, the same mechanisms that make normal posters good make bad posters really really toxic. These toxic posters take advantage of at least some of the following anti-patterns:

  • Strategic shitposting

  • Junk submissions

  • Post order manipulation

  • Post manipulation

Strategic shitposting

Strategic shitposting is a catch-all for purposefully making posts that gain karma without contributing to the discussion. Examples of such posts would be some of my earlier work on Hacker News. This behavior relies on throwaway jokes or snarky replies to comments, almost always able to produce a few more upvotes than downvotes. Properly formatted (in my case, leaving out all punctuation and capitalization to make it easier to parse as less thought-out than my normal work) these posts somehow manage to amuse more than they annoy, and in so doing they can reap a tidy profit.

The posts in question always need at least a little relevance, in order to prevent flagging (Lobsters) or downvoting (HN), but their main purpose is to get a visceral reaction (typically, humor and amusement) in the reader. Once that reaction occurs, they’ll probably get an upvote.

How does this work? Let’s talk about voting.

How voting works on HN/L sites

Why do people upvote things?

  • They just want to click on the little arrow.
  • They agree with the point the author is making.
  • They disagree with the point the author is making, but agree with the writeup of the point.
  • They want to reward everybody who has participated in a thread of conversation.
  • They want to manipulate the rankings (more on this later).
  • They assume that whatever the person is saying is correct (patio11, tptacek, pg) and want to reward them.
  • They want to downvote, but they missed on the touch interface. HN won’t let you correct a mistaken vote, though Lobsters will.
  • They want to reward the poster whenever possible.

Why do people downvote?

  • They disagree with the point made by the post (primarily HN, due to a misguided public policy statement by Paul Graham and parroted thereafter).
  • They believe the post is rude or uncivil (formerly on HN, now primarily Lobsters).
  • They want to pile on downvotes for already downvoted things (any posts that are greyed out tend to mark themselves as “downvote me”).
  • They meant to upvote, but missed on the interface (again, mainly an HN problem).
  • They want to manipulate the rankings (more on this later).
  • They want to punish the poster whenever possible.

In Hacker News, for a long time, downvoting was de facto reserved for marking comments as excessively hostile or rude or off-topic. Lobsters to this day tends to function that way and even has a more nuanced downvote system for showing why a given post was downvoted.

Using voting mechanisms to profitably shitpost

This standard means that—for a poster without a reputation, and for a post which is otherwise not abrasive—if a post gets any reaction, it’ll probably be an upvote. Thus, the winning shitposting strategy is to write posts that can cause a strong reaction without being too difficult to write. A few different types of posts have enhanced survival characteristics by leveraging that truth:

  • Posts that are primarily jokes, using the context of discussion as source material.

  • Posts that signal simple agreement with whatever the current zeitgeist of discussion is. They need not be long, but people react more strongly and much more positively to these than short disagreeing posts (which they may even downvote!).

  • Posts that are minor corrections (technically correct, the best kind of correct). The reaction is due to the thought process of the reader checking that the post is in fact correct, rewarding the correctness, and moving on, even though the post itself contributes little to the conversation. Think grammar or URL corrections.

  • Lampshaded off-topic rants that are tangentially related. Most HN/Lobsters readers seem to forgive a blatantly off-topic post if it contains an upfront admission that they are so.

  • Griping about injustice or outrage, the more entrenched the better. Pandering to injustice and impotent outrage evokes strong reactions and such posts can be easily tailored to match the overall views of the hivemind.

None of these posts actually tend to elevate the discussion or reveal new truths, but people will almost always upvote them more than they downvote them.

And that’s the source of their toxicity: shitposts do at least as well as quality posts, they don’t increase the signal of the community’s nominal area of discussion, and they are very easy to crank out even by idiots.

Junk submissions

Junk submissions are articles and stories that do well in karma but that again dilute the focus of the community. I suggest that the voting patterns for submissions mostly follow those mentioned above for normal posts and comments, so I won’t rehash that here.

To pick a good junk submission, you basically want something that:

  1. Doesn’t require an in-depth understanding of the subject matter to comment on. Some random user who sees an article on type algebras statistically isn’t going to be in the population who cares about such things, whereas bike-shedding on some Algol-derived language is fun for the whole family.

  2. Doesn’t take a long time to read, because people will be less likely to upvote it. The longer somebody takes to read an article, the more likely they are to move on to something else (or to disagree with it, or ignore it entirely). This is precisely the opposite behavior from giving your submission upvotes.

  3. Evokes a strong reaction in the reader. As with comments, the only bad reaction from a user is no reaction—so, pick a topic that demands to be felt strongly about. So, “C is Dead” is going to be a better article than “Subtle memory aliasing issues with legacy C99 code”. Similarly, “How We Prioritized Diversity” is going to do better than “Surveys of Hiring Practices and Diversity” or mundane bureau of labor reports, even though it may have objective information.

  4. Is likely to create a lot of discussion. Remember, the ranking algos slightly favor more discussion over less discussion. You want to pick an article that is hilariously one-sided, or that leaves out key details so as to provide speculation. Anything that is cut-and-dried is probably not going to get a lot of comments compared with proper bait.

In other words, you want news, gossip, and/or controversy. HN and Lobsters both have some measures in place to lower submissions that have a lot of discussion but few upvotes, but those aren’t always effective. Additionally, done properly, you can use a junk submission to create a loud discussion and then profit off your own posts and comments within that discussion even if the story itself gets torpedoed. Loud arguments may take several days to slide both off the front page and out of people’s minds.

Gossip is attractive but obvious

Gossip tends to get shut down on HN, mostly because the best gossip in our industry tends to run counter to the explicit goals and interests of the folks at Hacker News. They understand that frequently appearing as a clearinghouse for muckraking damages their reputation and their community, so mods will kill off stories that are primarily gossip.

Gossip about the community site itself (meta as it is known in other contexts like Stack Overflow) trips the same breakers. On the useful side, though, meta discussion easily hits all of the 4 criteria for a junk submission, least of all because it usually creates a lot of discussion and everyone has something to say.

Controversy is a reliable standby but self-limiting

Controversy is often overlooked by users as needing to be curtailed, but may fall prey to overzealous moderation. The same thing that causes people to upvote controversial articles tends to make them complete jerks in the threads, and rapidly the civility of such discussions tends to die out. Pre-emptively, mods may hide or nuke such threads to prevent them from dominating the front-page. While the articles rage on, though, you can expect a lot of votes—especially if you picked a submission that doesn’t blatantly appear to be using this tactic. It can often help to seed the discussion with a comment to highlight or bring out the controversy, and in so doing get better mileage out of a safer article that doesn’t at first glance appear incendiary.

As of the time of this writing, the most reliable form of outrage submission invokes social justice. Everybody on HN or Lobsters has known somebody who has been discriminated against unfairly, because we really do have a history of that in our industry. It’s a topic getting a lot of coverage in other sectors.

(Aside: I don’t mean to use social justice as a pejorative here: it’s a term I’ve seen used by both sides a great deal at this point, and it tends to be a good shorthand for the category of discussions of privilege, diversity, gender, equity, and similar issues. I think those issues are important to examine, but here we are only concerned with their utility for gaining karma.)

Let’s look at it under our four criteria:

  1. Social justice outrage is typically reported in either news or blog form. There is a large (and often impenetrable to the untrained novice) body of academic work on social justice concepts, but the majority of what is discussed online today is short-form and written to make people aware. Similarly, everyone has a least some opinion on the topic, even if it is as simple as “I hate political correctness!”.

  2. Social justice outrage often is event-based, using social media. Because a lot of material is sourced from Twitter or Medium, it tends to be pretty short and quickly-digestible. You don’t have to grep through more than a few tweets of content to get the meat of many posts.

  3. Social justice outrage lends itself exceptionally well to provoking a response. Because of the previously-mentioned history of discrimination in tech, and because everyone has felt excluded or slighted at one point or another, any user with any shred of decency or empathy will find some resonance with any material involving those topics. Additionally, there are people who are angered or feel persecuted whenever social justice articles show up—and they tend to either upvote an article to get it discussed or downvote so conspicuously as to garner sympathy upvotes from users not sharing their preferences.

  4. Social justice outrage always results in lots of discussion. Discussions on these articles tend to involve a lot of personal suffering (in which case people commiserate, question, or express sympathy) and argument (because people tend to hotly debate facts or deeply-held convictions). Even though the discussions themselves typically don’t enrich anybody’s life, they do generate a lot of opportunities for either quality commenting or shitposting.

All the same, a problem with these sorts of submissions is that are usually heavily moderated once the site admins catch on. HN, for example, seems to heavily monitor and remove these sorts of submissions once they pop up. The counter to this, of course, is to start with articles that aren’t directly about this, and slowly ease in more and more inflammatory social justice articles as the community standards normalize in that direction.

News articles are your secret weapon

News articles tend to be best form of junk submission.

What makes them so great? They map directly onto the four useful traits we talked about above:

  1. News articles are, by construction, easy to digest. To gain the widest-possible circulation and reach, news writing tends to be simple and accessible. For our purposes, that’s perfect.

  2. News articles are almost always relatively short. It’s hard to keep the TechCrunch pipeline flowing if every article is suitable for print in The New Yorker. It is also harder to keep on the bleeding edge if you post long analyses, and frankly it’s hard work. So, shorter articles with links to sponsors and relevant information carry the day.

  3. News articles are, by definition, novel. In addition to whatever feelings the articles promote, news always have a sense of novelty and discovery to them. Almost any user gets a mild rush from not having missed out when reading an article or by having their curiosity rewarded.

  4. News articles tend to create discussion. Everybody loves to show off their grasp of the nuances of a news story that others may lack, and they’ll happily chat about that. Or, they’ll complain about the rest of the story being left out. Either way, they’ll be talking.

There is a deeper toxicity to news, though, and one that only Lobsters so far even seems to acknowledge (through its tagging system):

Every time you post a news article, product announcement, or current events thing, you are creating a minor data point that says that the novelty of the article, and not the content of the article itself, is acceptable for the community. This is an important precedent to set, because it means that as you have a harder and harder time finding good submissions, you can fall back on novelty over quality.

Over time, this means that the front page (say, of HN) becomes filled with things that would otherwise be considered off-topic, including advertising and product releases and whatnot. This is not postulation—this has happened on HN.

On a site like Lobsters, this process absolutely destroys the uniqueness and educational value of the site.

Additionally, as this rot sets in, there is no going back—once the name of the game is “What is the most novel thing we can post?”, only news articles will be commonly successful. They have an entire industry of people behind them optimizing them for that niche, and simple links to other things have little chance.

Post order manipulation

By carefully upvoting and downvoting, as well as picking what you reply to, you can also improve your odds of getting karma.

Observations about how people read posts:

  • Early posts tend to get the most reactions, and stay wherever they’re ranked.

  • People tend to pay attention most to the top-most posts.

  • People tend to pay the next-most attention to the bottom posts, especially in long threads.

  • People skim over subthreads which are more than a couple of levels deep.

  • People may downvote entire subthreads if it turns into one or two posters bickering.

  • People notice early-on if the same poster is replying in all of the subthreads.

These observations suggest some tactics.

  • If a post is near the top of a thread and the thread is long, it is better to reply to that post than to create one at a sibling level. If yours is the only reply to a post at the top, you’ve basically assured your spot as the second post people encounter.

  • If a post is near the bottom of a thread, reply to it. This is again prime real-estate, and bottom posts tend to be blatantly bad—thus, a reply correcting them or mocking them tends to get additionally upvotes.

  • Don’t engage in pointless back-and-forth with another poster. Watch your per-post karma if available, as in Lobsters) and stop once you only are getting a vote or two per reply.

  • Early on, any post that isn’t yours that people agree with should be downvoted if it looks “strong”. Alternately, you should upvote a strong post and reply to it immediately, to help ensure a good spot in the reading order.

  • Resist the urge to reply to everything in a thread. Done too much, or too frequently, you will antagonize the other posters, and eventually they’ll downvote you on principal everywhere in a thread.

The reason that this behavior can be toxic to a community is that while it can help people act more civilly (as in the cases of avoiding back-and-forth and posting everywhere), the behavior itself can cause neglect of middle-quality and late posts. Rankings of posts also become suspect, because a post that is at the top may have only gotten there by the author downvoting more relevant posts and discussion baiting. Subthreads can also become cluttered up by virtue of people using the “post to a top thread” heuristic instead of the expected “engage with posts worth engaging with” metric.

Post Manipulation

Manipulating and editing your posts after the fact is an old technique, but still sometimes productive.

One thing to do is to edit posts for content after seeing a similar post get eviscerated. For example, one may tone down a post from being too aggressive after watching a somebody else get downvoted.

Another reason to edit posts is to remove content that others are using to call you out. This is doubly effective if a replying poster gets really agitated—if you remove inflammatory content after somebody has replied in kind, it appears to the outside observer that that the reply post is being overly mean.

Finally, and perhaps even in decent faith, editing to append additional context or corrections and acknowledgements to a post that was originally incorrect or poorly worded can actually result in more karma. People who may otherwise have been annoyed may say “Aha! They’ve corrected themselves and owned up to it—I shall reward this with an upvote (or perhaps remove a flagging).”)

This is toxic behavior because it tends to destroy the archival value of discussions—for this reason (I assume) Lobsters and Hacker News both disable editing of past posts. That said, if people delete old posts they can achieve similar outcomes. Additionally, it can be really gnarly when people are trying to follow a conversation or point and suddenly the original words that led to a disagreement are gone or are different from what they used to be.

Thoughts on negative strategies

Frankly, these strategies range from annoying to downright harmful. I’ve used a handful of these at various points in my posting career, and honestly I regret my small bit of negative influence on the communities where I practiced it. When I look at the practices on places like Hacker News nowadays, I can’t help but wonder how many people employ these or similar methods, and how much of the behavior is considered acceptable now because of the precedent set by me and others like me.

The worst part is, these strategies appear to work and work reliably. The first two, shitposts and junk submissions, are almost disgusting in how reliable they are after a bit of practice. They don’t educate anybody, they don’t elevate the conversation, but damned if they don’t increment that karma every time bit by bit

Hopefully, the techniques presented above will give everyone a clearer idea of the sorts of things they shouldn’t support and condone in their sites, and also help make it easier to detect when these things are being used in their presence. Ideally, if we are all so informed, we can stop ourselves from being exploited.

Also, as you may note, a lot of these behaviors with only slight modification can result in really helpful and engaging discussion. Posting articles that are relatable and educational instead of being clickbait, making jokes that rely on a technical knowledge and help illustrate points and teach—these are things that manage to help instead of hurt, but can so easily go the other way.

In the final part of this series, I’ll discuss the things that I think site maintainers can do to help encourage good behavior and to help limit the viability of these techniques.

HN/Lobsters: Good News, Bad News, How to Win Big (Part 1)

In this post, I’m going to talk about good and bad behaviors one can use to gain karma on sites like HN or Lobsters.

Most of the behaviors for these websites involve getting more karma. For those unfamiliar, karma/internet dollars/Paul Graham Funbucks is a system whereby a signed integer is incremented and decremented at the whims of the community. This integer is then used to rank comments, rank submitted stories, and generally provide access to the rarefied atmosphere of the Top Posters Club.

Why would we do this?

In the case of HN, I think it’s worth pointing out the flaws in the system so people don’t run the risk of losing actual money or getting screwed during their applications to YC (which requires your username on HN). Similarly, while I used to joke about Paul Graham funbucks (HN karma), the fact is that with the rise of “Apply HN” there are even more reasons to take a critical look at the rules and rewards of the site.

In the case of Lobsters, it’s been a damned fine community and it probably has at least another year or so before culture rot sets in. We’ve already had a couple of incursions, but we’ll see. For that community, I mean this to be a sort of “Hey, watch out, there can be problems with certain things we’ve flirted with normalizing”.

Okay, who’s this for?

My primary audience for this article are the moderators, sysops, and owners of these (and similar) communities. With any luck, the discussions of the mechanisms used in sites like Hacker News and Lobsters here will be useful for future community development.

My secondary audience for this article is fellow posters. I am going to try and explain how to best accrue karma on your aggregator of choice. You may already know one or all of these techniques, but I figure there’s a chance you’ll learn something or that you may find a way of improving on what I’ve documented here. More importantly, this series should help you develop a sense for how the system can be gamed and how to spot other posters doing so. Note that, if you decide to use the techniques in the next “Bad News” post, you are part of the problem. Please, follow the good parts here, and avoid the bad parts.

In this series I’ll be using a mental model of those two communities and their subject matter as well as occasionally illustrating examples with users or events. I neither condemn nor endorse any of the users or stories mentioned, bringing them up solely to provide context. Much of my discussion assumes that I have an accurate picture of what the communities care about; this may not be the case at all, but I have to start somewhere.

This post may not apply at all into other communities. Reddit, despite having a superficially similar karma mechanism, has very different moderation and other factors that prevent these writings from mapping over automatically.

The Good News

The good news is that most of the behaviors that are good for karma are good for the community:

  • Submitting interesting stories

  • Making insightful comments

  • Asking useful questions

  • Being polite to other posters

Interesting stories

Submitting interesting stories is the best low-volume way to get karma. After an initial burst of upvotes, a story tends to get a long-tail of karma over time. If your comments are only averaging, say, 2-3 points each, submitting stories is a better investment.

In a system like HN or Lobsters, stories that are off-topic or bad tend to get flagkilled by the hiveminds (communities of posters) or nuked/removed by the admins. So, they tend to have a limited amount of harm they can do to your karma (unless you egregiously screw up, but if you submit links to Stormfront or something you should expect that kind of reaction). This is much safer than comments, which can be continually downvoted and drain karma.

Insightful comments

Making insightful comments is the next best way to get karma. If you politely reason through a post and make an effort to stay on-topic or share relevant experiences then you will have a successful posting career. Somebody posting their own stories about a startup, being on a development team, or whatever else will almost always get karma because they’ve added to the conversation.

One has to be careful: the hivemind may well disagree with a clearly-reasoned comment regardless of politeness if it goes against the grain. HN has gotten particularly bad about this in the last couple of years, while Lobsters still seems to reward civility. Things likely to trigger the hivemind:

  • Rehashing a common sentiment frequently in post (as, say, michaelochurch does talking about their views on the startup ecosystem)

  • Being overly verbose or meandering (as, say, I do from time to time)

  • Being overly critical without padding with friendly reassurance

  • Defending American conservative positions (on HN, sometimes on Lobsters) without sources

  • Defending American socialist positions (HN and Lobsters, especially regarding Labor organization of devs)

  • Defending superficially abhorrent claims (anything involving, say, Moldbug) without sources

  • Attacking any sort of minority (deservedly or not) especially without really solid sources

  • Discussing the mokitas (purposefully-ignored truths) of the ecosystem

  • Posting in a way that gives the industry a bad name (almost everyone de facto agrees that exploiting users is okay, but don’t ever mention that on HN)

(Aside: I really should do a post on the mokitas of these communities.)

Useful questions

Asking useful questions is another great way to gain karma. If you ask for clarification in a discussion thread, it is very difficult to antagonize anybody else (unless you’re trying). Additionally, people will often upvote you in appreciation for the additional insights you were able to coax out. In general, questions tend to increase the value of the discussions for everyone and are just a really good idea.

I’ve found that asking for specific experiences or techniques does better than asking broad questions, unless you are willing to “prime” the responses a little bit by explaining the sort of answer you’re looking for. For an example:

How do you feel about your job?

The above can be vastly improved with a little context:

How do you feel about your job (at Bobco)? Like, what managerial stuff bothers you?

This sets the stage a bit better and helps a prospective answerer actually give the information you need. More specific information gives better discussion, and better discussion gives better karma.

Being polite

Being polite to other users is perhaps the least-profitable way of making karma. It does, however, prevent the loss of karma. Karma lost is basically karma you’ll have to earn back later, and when you are impolite people tend to downvote you far in excess of what you would’ve deserved had you merely been wrong.

Being polite doesn’t mean agreeing. Being polite doesn’t mean being respectful. Being polite doesn’t even mean being nice. Those are all things that are come after, but if you can’t be polite you won’t even get that far.

So, here are some of the ways I’ve found to be polite (without accidentally being any of those other things):

  • Always use the first-person plural (“we”) instead of the second-person anything. This makes it seem like you are on the same side as the other person, and reminds both of you that whatever the current disagreement, you probably just need to clarify your positions. The use of “you” tends to read as overly divisive and aggressive. This habit can be misinterpreted, but overall it makes things nicer.

  • Use “one would” instead of “you would” for speculating on a general case. This prevents some very messy misunderstandings.

  • Never, ever, ever make an obvious personal attack. They are rhetorically difficult to defend, and they just piss people off. Similarly, never call other people names.

  • Always be aware what you are stating as fact and as opinion. “X is rubbish” is similar to name-calling, but “I find X to be rubbish” is a matter of opinion, and at least on Lobsters people pick up on that and make allowances.

  • Never project behaviors or motivations onto other people. “You are a misogynist” leaves one open to factual critique (“Then why did I donate to Feminist Frequency?”)—prefer clarification like “This thing you said appears misogynistic…is that what you meant?”. Doing so elevates the discussion, and makes you seem more thoughtful than you would if you just label things.

  • Assume good-faith when replying to others. If somebody says something really upsetting, seek clarification (as above) in hopes than understand their position better. It may turn out that they just had a typo; even if they double-down, asking clarification is tantamount to asking a question, which is the third best way to get karma!

  • Avoid summarization, prefer direct quotes. Especially in divisive areas, people tend to use biased summaries of what their perceived opponent is saying. So, use direct quotes to avoid things devolving into you and your opponent arguing about positions neither of you hold.

There are other ways to be polite, of course, but the above are some of the most common and troublesome things I’ve run into in my posting career.

Looking Back on Malloc()

A friend of mine is currently doing a class assignment—one I too attempted years ago—and in the process of talking about it with him I’ve been going back down memory lane.

When I tried it my partner and I ended up failing miserably because of a few things, least of which being a complete lapse in judgement and deciding not to use source control. We also tried doing some cleverness with segmented best-fit lists, and it basically just ended in tears.

But, I’m older (hah) and wiser (hah hah) and so I’ve got a few more interesting things to say about it now. I might even go and throw up some code snippets on Github and relive my traumatic past. Anyways, onwards.

Basic of memory allocation in ‘nix

So, assume that we’ve got a process running with some heap. In this process, we decide that we want to allocate additional memory on the heap (maybe because we don’t have TCO or something—we don’t want to just extend the stack indefinitely).

Anyways, there’s an ending to the heap segment, and any attempts to access memory past this point are going to result in a segfault. To extend this segment, we use the brk or sbrk call (here is the wiki article on these). Note that on Windows you’ll be using the HeapAlloc() and related functions, and never have to actually deal with this sort of nonsense (see here). Note also that in modern ‘nix you’ll probably be using mmap() instead. For learning, though, let’s ignore those other more reasonable functions.

Last note—sbrk and family is not thread-safe, hence the use of other functions. So, unless we’re writing a custom allocator for Ruby or Node (lol), we won’t want to use it.

Malloc, version 0.0

The most brain-dead version of malloc() and free() would look like this (ignoring some of the additional functions posted here):

1
2
3
4
5
6
7
8
9
#define URFP(x) ((void)x)

void* malloc( size_t len ) {
    return sbrk( len );
}

void free( void* ptr) {
    URFP(ptr); /* do nothing */
}

The obvious problem with this, though, is that it will merrily leak memory and eventually fail. It’s also slow, because it has to hit a system call boundary.

This is also not great, because we want to actually track allocations, and this won’t let us do anything. So, where can we stash that information?

Malloc, version 0.5

So, let’s go and update our malloc to do a bit of extra tracking. This is a good way of showing a trick we’ll be making a lot of use of—writing hidden headers for our bookkeeping while still returning a pointer that is useful to the users. This same style of trick, incidentally, is used by Redis!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
typedef struct {
    size_t allocation_size;
} alloc_record_t;


void* malloc( size_t len ) {
    /* allocate enough room for the requested allocation plus its record */
    alloc_record_t* rec = (alloc_record_t*) sbrk( len + sizeof(alloc_record_t));

    /* set the length */
    rec->allocation_size = len;

    /* return a pointer to the user-space view of the allocation */
    return ((char*)rec) + sizeof(alloc_record_t);
}

void free( void* ptr) {
    /* note that we offset the supplied user-space
       pointer to get the allocation record header */
    alloc_record_t* rec = (alloc_record_t*) (ptr - sizeof(alloc_record_t));

    /* do something to show the allocation */
    printf("Would've freed allocation at %p of size %z\n", ptr, rec->allocation_size);
}

Ideally you’d want to check for weird edge cases, like passing in a NULL ptr to free(), or a length to malloc() so large that it causes the arithmetic on sbrk() to overflow. In our case, though, we’ll be ignoring those practical issues so we can focus on the allocation theory.

Now, we still have a useless free(), and you might wonder why we don’t attempt to use sbrk() with a negative length in order to shrink the heap back down. We can do this, but we’d need to only free allocations at the end of the heap for that to work properly—if you freed an allocation in the middle somewhere naively, you’d end up shrinking the heap into actively used memory.

In order to do the correct thing we’d need to keep a list of deallocated blocks, only deallocate blocks located at the end of the heap, and continue shrinking only as long as the list of deallocated blocks contains a block adjacent to the end of the heap. Such a list, incidentally, we’ll call a free list from here on out.

Anyways, it’d be a pain in the ass, and wouldn’t help us.

Wrapping up

Next time, I’ll talk about implementing a free list and basically creating a memoized version of sbrk(). I’ll also talk about some other ways of improving our allocation library to be faster and more interesting.

Further reading

Dynamic Storage Allocation: A Survey and Critical Review has a really thorough review of different allocation methods and bookkeeping techniques.

Thoughts on Streaming Signal Services, Pt. 1

So, let’s think about the next interesting form of data processing for a bit.

We’ve done RDBMSes to death; lots of very clever people have done some excellent work to make it easy to query related data. NoSQL exists for varying degrees of easily-horizontally scalable data, and also for certain types of exotic data query (think something like Neo4J and graph DBs).

So, we’re going to be dealing with a lot of real-time events and data, right? All the loud money is toting “Internet of Things” and whatnot, massive sensor networks creating lots and lots of bytes of data and streaming it in to some system to digest and analyze.

These data streams can be visualized as flowing from a sensor, to a recorder, to a transform network, to a display device. There’s sort of two workflows you want to accomplish with this: real-time transformation and visualization, and also batch processing rifling through all the available data for trends.

A common problem is also that you’ve got a lot of cases where the same conceptual data source is moving across several data sensors—the usual mistake (at least, it’s a mistake in my opinion) is that people tend to lump the handling of the “what data source generated this data” along with the “this sensor generated this data, from some source” problems.

Really, you just want a very (simple!) service to pull records corresponding to one or more sensors, and then-a separate service for saying “Oh, this data source? Yeah, was tracked by thus-and-such sensors at the requested time…go bug them”.

First Impressions on Octopress

So, I’m starting over and going to try actually blogging—goal is a simple once-a-week, and if the chain builds, maybe we’ll see what happens.

First thing: making a new post is annoying: rake new_post is cool and all, but you really need to modify the Rakefile to automatically fire up a text editor once it’s been run, like so:

1
2
# at the end of writing the file in the new_post task:
Kernel.system('vim', filename)

Et voila, a text editor appears once you make a new post!

Next thing to worry about is deployment—the smart thing to do would be throwing this up on Github pages or Cloudflare, but let’s be honest: that’s not really my style.

Sooooo, I think the answer is a dumb little cronjob to pull the repo every half day and update.

Or, y’know, just manually update the damned thing until I’ve been hit with some divine inspiration.

EDIT:

Derp derp derp I should probably put a bit to commit to Github after I’m done writing—now wouldn’t that be something.

Hello

This is the first post on the new Octopress.