I will often find myself exhausted at the end of the day, despite not accomplishing much of anything. This used to frustrate me, but I think I've discovered why. Hacking in and of itself is not difficult. Rather, it's the getting there that becomes a problem.
Imagine a starship at rest in hard vacuum. In order to accelerate, the starship must fire its rockets but when an acceptable velocity is reached, the rocket will be able to cease acceleration. In the same way, it takes concentrated effort to get into the zone of coding but when the zen is reached, coding happens in an almost weightless manner.
That is, until something gets in the way. Meetings, class, or other interruptions can sideswipe the coding zone with the same impact as a small moon colliding with our starship. All velocity is lost and we're left off-course and disoriented. We must bring our starship back on course and fire the rockets again, this time with damaged motors.
On a good day, I can make it past one, maybe two major interruptions. After that, I'm pretty much out of my own rocket fuel. There are a few extra boosts I can add (coffee works once and then ruins my sleep). Most literature on this topic is focused around eliminating the interruptions, but I don't have that option. My college has seen it fit to schedule my classes so the provide maximum interference to my productivity. Some of you out there might be able to sympathize with meetings or other frustrations.
So what's a guy who just wants to hack away to do? "Not hacking" isn't an option. I'm drawn to it like our starship would be drawn to a black hole. Reading seems to be the only acceptable substitute my brain will take, and only sometimes. It also might be possible to get there faster and burn less fuel. Most of the advice here is psychobabble, self-help profiteering or both.
I could not go to class. Failing out of colleges seems to be something of a tradition among the greats of hackerdom. In fact, I don't plan to return to college if YCombinator accepts us. In the meantime, I'm taking the reasonable option of staying in school, so no regular skipping of class.
I've also tried moving my creative hacking work to later at night but it's difficult to start that late. The only good solution is to spend my weekends coding, when they're not already booked with homework or other events. This does open another possibility: train myself to get into the zone faster by associating a non-zone thing (like time of day) with good work.
This is an ongoing experiment. It may turn out that there's no right answer and I need to be patient until the semester's over. Until then, I'd love to hear your thoughts, either here or at Hacker News.
Monday, March 4, 2013
Friday, March 1, 2013
What Hackers Need
As a senior Computer Science student, it's hard to miss the absolutely abysmal education that hackers get. Instead of spending my time in all-night coding sessions, I find my time disrupted by homework and classes that are tangentially related to my career at best, horrible time sucks at worst. I'm not here to discuss why this horrible tragedy has occurred, but rather to investigate what I think makes for a good environment to learn hacking in. Just a note, this isn't to say that you aren't a hacker if you lack these (I missed a few myself) but to investigate the "hacker primordial soup."
First and foremost, I think that good hackers need access to a free coding environment from a young age. "Free" has multiple meanings here. The environment needs to be free of charge (at least to the aspiring hacker) as well as free from rules. The average full-time programmer began learning at 13. It's amazing that such a useful skill can be learned at such a young age.
It's hugely important that the environment be as free from rules as possible. Mistakes should be both allowed and appreciated. Too often we create narrow-minded tutorials that teach, but never allow room to hack.
I think that starting young is important because us adults haven't ruined the child's mind yet with their silly rules. The forced conformity (at least from adults) starts at around 9th grade when we begin to pester the child about college. The free flow of imagination is incredibly important to the magic that is hacking and early experimentation can cement the fairy dust before grownups can blow it away.
Secondly, our young hacker needs a mentor. I have several friends who found their mentor in their programming classes in high school, while others just found an older student to learn from. Personally, I think that the best place to find a mentor is in an active online community. The mentor can provide direction and provide feedback far beyond what a compiler can provide.
Finally, our hacker should have a job. I can't decide if the job should be a grueling minimum-wage one or entry-level programming. Either way, this teaches what the "real world" is like and just how much a job sucks. The burger-flipping level shows just how little those above you care about anything other than your ability to produce. The programming intern position also teaches that to a lesser extent, but more importantly, it teaches us how much fun is lost when the coding is entirely directed by someone else.
I think that these three things will give any hacker-in-training a great head start. There are many other things that I haven't delved into here (a passionate willingness to learn), but that's a topic for future essays.
I'd love it if you joined in on the conversation at Hacker News.
First and foremost, I think that good hackers need access to a free coding environment from a young age. "Free" has multiple meanings here. The environment needs to be free of charge (at least to the aspiring hacker) as well as free from rules. The average full-time programmer began learning at 13. It's amazing that such a useful skill can be learned at such a young age.
It's hugely important that the environment be as free from rules as possible. Mistakes should be both allowed and appreciated. Too often we create narrow-minded tutorials that teach, but never allow room to hack.
I think that starting young is important because us adults haven't ruined the child's mind yet with their silly rules. The forced conformity (at least from adults) starts at around 9th grade when we begin to pester the child about college. The free flow of imagination is incredibly important to the magic that is hacking and early experimentation can cement the fairy dust before grownups can blow it away.
Secondly, our young hacker needs a mentor. I have several friends who found their mentor in their programming classes in high school, while others just found an older student to learn from. Personally, I think that the best place to find a mentor is in an active online community. The mentor can provide direction and provide feedback far beyond what a compiler can provide.
Finally, our hacker should have a job. I can't decide if the job should be a grueling minimum-wage one or entry-level programming. Either way, this teaches what the "real world" is like and just how much a job sucks. The burger-flipping level shows just how little those above you care about anything other than your ability to produce. The programming intern position also teaches that to a lesser extent, but more importantly, it teaches us how much fun is lost when the coding is entirely directed by someone else.
I think that these three things will give any hacker-in-training a great head start. There are many other things that I haven't delved into here (a passionate willingness to learn), but that's a topic for future essays.
I'd love it if you joined in on the conversation at Hacker News.
Wednesday, February 27, 2013
Looking to learn something new? Try Rebol
Rebol is an odd language with an odd history. It was originally put together in 1997 as an answer to the many things that plague modern programmers. The goal was to create a language construction set using what we've learned from all the crazy trial-and-error in other languages. For instance, have you ever wondered why we use curly braces? In Rebol, square brackets are used (saving your shift key a lot of work [0]).
Alright, enough semantics, let's get into the real part of coding. Download the Rebol binary. While you're waiting, notice that you're not waiting, because the binaries are only half a megabyte. This gets really impressive when you realize just how much is in Rebol. Anyway, don't forget to chmod +x if you're on a good operating system.
So let's run through a basic "Hello World." Step one:
Well, that was boring. How's about instead of going through the same boring syntactical tutorials, we check out the constructing power of Rebol and write helloworld in our own language? Alright, now we're cooking.
To do this, I'll need to get a bit academic for a second (sorry, it'll be quick). Everything you punch into the interactive shell (also known as REPL) is evaluated in Rebol's DO dialect. In Rebol, a dialect consists of a set of instructions to work with a given input [1]. Let's take a look at the PARSE dialect, which takes the following format:
Let's ignore /all and /case for now and focus on the cool part. Let's make an incredibly basic language where "a" is syntax for sending the string "Hello " to system.out and "b" does the same, but with the string "World!\n". We could implement something like this in JavaScript like so:
While it's only a couple lines, it's still very difficult to extend. In Rebol, it looks something like this:
The first two bits are simple: parse enters the PARSE dialect and "abc" is the input we're passing in. The rules section is what we're really after.. Let's break it down:
There you have it, your own special language (an incredibly contrived one, to be sure, but one nonetheless). However, that's nowhere near as powerful as PARSE gets. Let's taken on an interesting problem: determining if a mathematical equation is valid. Benjamin Gruenbaum provides the following example in JS:
As you can see, this task is much more difficult for JS to express. It's a tad harder in Rebol, but not nearly as much. To simplify things, we're going to do some assignment (using a colon instead of the equals sign, example taken from the Rebol docs slightly modified to reflect the latest version of Rebol):
The important thing to notice here is the recursive nature of the instructions. "expr" is the top-level one you'll pass to the parse command:
There's much more in Rebol, so come to our our chat room and find out! (This is a StackExchange chat, so you'll need 20 reputation on StackOverflow to talk).
[0] US keyboard only (sorry!)
[1] It's like a function, only more powerful. Every expression runs in a dialect. You can read about dialects in the docs or Wikipedia.
Alright, enough semantics, let's get into the real part of coding. Download the Rebol binary. While you're waiting, notice that you're not waiting, because the binaries are only half a megabyte. This gets really impressive when you realize just how much is in Rebol. Anyway, don't forget to chmod +x if you're on a good operating system.
So let's run through a basic "Hello World." Step one:
>> print "Hello World!"
Well, that was boring. How's about instead of going through the same boring syntactical tutorials, we check out the constructing power of Rebol and write helloworld in our own language? Alright, now we're cooking.
To do this, I'll need to get a bit academic for a second (sorry, it'll be quick). Everything you punch into the interactive shell (also known as REPL) is evaluated in Rebol's DO dialect. In Rebol, a dialect consists of a set of instructions to work with a given input [1]. Let's take a look at the PARSE dialect, which takes the following format:
parse input rules /all /case
Let's ignore /all and /case for now and focus on the cool part. Let's make an incredibly basic language where "a" is syntax for sending the string "Hello " to system.out and "b" does the same, but with the string "World!\n". We could implement something like this in JavaScript like so:
While it's only a couple lines, it's still very difficult to extend. In Rebol, it looks something like this:
parse "abc" [any ["b" (print "world!") | "a" (prin "Hello ")]]
The first two bits are simple: parse enters the PARSE dialect and "abc" is the input we're passing in. The rules section is what we're really after.. Let's break it down:
[any ;If the parser finds any of the following
["b" ;an instance of "b"
(print "world!") ;Output "world!" with a newline
;parens mean that this code block will be executed in the DO dialect
| "a" (prin "Hello ")] ;Same as above, but using prin, which doesn't output a newline
]
There you have it, your own special language (an incredibly contrived one, to be sure, but one nonetheless). However, that's nowhere near as powerful as PARSE gets. Let's taken on an interesting problem: determining if a mathematical equation is valid. Benjamin Gruenbaum provides the following example in JS:
As you can see, this task is much more difficult for JS to express. It's a tad harder in Rebol, but not nearly as much. To simplify things, we're going to do some assignment (using a colon instead of the equals sign, example taken from the Rebol docs slightly modified to reflect the latest version of Rebol):
expr: [term ["+" | "-"] expr | term]
term: [factor ["*" | "/"] term | factor]
factor: [primary "**" factor | primary]
primary: [some digit | "(" expr ")"]
digit: charset "0123456789"
The important thing to notice here is the recursive nature of the instructions. "expr" is the top-level one you'll pass to the parse command:
parse "1+2*(3-2)/4" expr
== true
parse trim/all "1 + 2 * ( 3 - 2 ) / 4" expr ;use "trim/all" to remove whitespace
== true
There's much more in Rebol, so come to our our chat room and find out! (This is a StackExchange chat, so you'll need 20 reputation on StackOverflow to talk).
[0] US keyboard only (sorry!)
[1] It's like a function, only more powerful. Every expression runs in a dialect. You can read about dialects in the docs or Wikipedia.
Monday, February 25, 2013
The hardest question on the YCombinator application
For the past two years, I've worked at becoming a better programmer, all with one goal: my own startup. After lots of work, learning, and discussion, my friend and I have an idea and a half-done prototype. It's finally time to do what I've been waiting for all this time: Go to YCombinator.
Well, we have to apply first. Naively, I thought the application would be like anything else I've ever applied for. I'd fill out my name, answer a few questions about myself and my idea. I was incredibly mistaken. Writing up answers took up four days of writing, editing, and thinking. It forced us to finally look into how we'd split up equity, made us think through our entire pitch (four times), and had one really, really hard question.
No, it wasn't the money one (though I'm still not sure how to answer). Nor was it "What is your company going to make?" (though that was the second hardest). Surprisingly, the most difficult question for me was:
Every startup founder has an incredibly tempting out: the day job. As Dilbert-esqe as they are, a day job is a siren call to the guy who has been subsiding on Ramen singing the promise of a salary and a solid night's sleep. I know at any time, I could drop the whole pretentious startup thing, finish my degree, and get a nice comfy job somewhere where someone else will make all the decisions.
Answering yes means that I'm giving up on finishing my degree in a timely manner, if at all. It means I'm accepting one of the most stressful jobs I could have. I spent a lot of time staring at the screen, wondering if I could be daring enough to put down an emphatic YES. I almost didn't do it. I almost said "I'd like to work on a startup, but..."
You may not be an entrepreneur. In fact, you don't even need a job to hit a decision like this. Our culture (and parents) emphasize a conservative lifestyle, playing it safe at every turn. Today, take a risk. Do something different. Don't let yourself worm out of it. You'll be surprised at the results.
If you've read this far, you probably should join the discussion on Hacker News.
Well, we have to apply first. Naively, I thought the application would be like anything else I've ever applied for. I'd fill out my name, answer a few questions about myself and my idea. I was incredibly mistaken. Writing up answers took up four days of writing, editing, and thinking. It forced us to finally look into how we'd split up equity, made us think through our entire pitch (four times), and had one really, really hard question.
No, it wasn't the money one (though I'm still not sure how to answer). Nor was it "What is your company going to make?" (though that was the second hardest). Surprisingly, the most difficult question for me was:
If we fund you, which of the founders will commit to working exclusively (no school, no other jobs) on this project for the next year?Founding a startup is a big risk. I could find myself penniless in two years with no property and fewer prospects. I owe it to my parents to finish my degree, and to my fiancee to have a secure job after we get married. The startup life can't promise either of those.
Every startup founder has an incredibly tempting out: the day job. As Dilbert-esqe as they are, a day job is a siren call to the guy who has been subsiding on Ramen singing the promise of a salary and a solid night's sleep. I know at any time, I could drop the whole pretentious startup thing, finish my degree, and get a nice comfy job somewhere where someone else will make all the decisions.
Answering yes means that I'm giving up on finishing my degree in a timely manner, if at all. It means I'm accepting one of the most stressful jobs I could have. I spent a lot of time staring at the screen, wondering if I could be daring enough to put down an emphatic YES. I almost didn't do it. I almost said "I'd like to work on a startup, but..."
You may not be an entrepreneur. In fact, you don't even need a job to hit a decision like this. Our culture (and parents) emphasize a conservative lifestyle, playing it safe at every turn. Today, take a risk. Do something different. Don't let yourself worm out of it. You'll be surprised at the results.
If you've read this far, you probably should join the discussion on Hacker News.
Friday, February 22, 2013
Is JavaScript's ubiquity a bad thing for Node?
There's no doubt about it, JavaScript is as close to a universal language as one can get, at least in terms of developers with passing knowledge about it. Regardless of server-side language preference, virtually all web developers know some level of JavaScript. Unfortunately, most only have a very basic level of JS ability, instead using jQuery or the like.
The truth is, it's pretty easy to write bad code in JavaScript. Consider the following:
This isn't a rant about terrible software. Instead, let's talk about one of my favorite technologies: Node.js. One of the biggest advantages that Node brings to the table is the ability to use one language across the board in your project, but Node is a lot less forgiving of poor code. The big question is this: will the use of JS for node help or hinder the Node ecosystem?
As a part-time optimist, I see this adaptation of a universal language as a net benefit for Node. Many great programmers attempt to be always learning new things. Why not chose that cool new framework that's in a language that you already know? That's how I got sucked into Node awesomeness.
Others think that bad programmers will give Node a reputation for being incredibly difficult (even though it's pretty simple) as they try to build a Node app and fail. They'll spread the word that Node is a harsh language and "totally unradical" (or whatever dialect they use).
What do you think? Post your opinion in the comments here or at Hacker News.
The truth is, it's pretty easy to write bad code in JavaScript. Consider the following:
$(document).ready(function(){
$(document).ready(function(){
a = $("*").find("*").find("#myDiv")
a.onclick=function(){
alert("U CLIKD")
}
})
})
Ouch. Two document.ready, horrid abuse of jQuery's universal selector and not a semicolon in sight. I don't know what's worse, the code itself or the fact that it'll work on every major browser. The web's been incredibly forgiving to programming mistakes and it's showing.This isn't a rant about terrible software. Instead, let's talk about one of my favorite technologies: Node.js. One of the biggest advantages that Node brings to the table is the ability to use one language across the board in your project, but Node is a lot less forgiving of poor code. The big question is this: will the use of JS for node help or hinder the Node ecosystem?
As a part-time optimist, I see this adaptation of a universal language as a net benefit for Node. Many great programmers attempt to be always learning new things. Why not chose that cool new framework that's in a language that you already know? That's how I got sucked into Node awesomeness.
Others think that bad programmers will give Node a reputation for being incredibly difficult (even though it's pretty simple) as they try to build a Node app and fail. They'll spread the word that Node is a harsh language and "totally unradical" (or whatever dialect they use).
What do you think? Post your opinion in the comments here or at Hacker News.
Wednesday, February 20, 2013
My dumbest productivity hack yet
I've talked about productivity before. Figuring out new ways to work harder is almost always more fun than actually working harder. For bonus points, you can efficiently organize how you read all your productivity blogs.
Enough editorializing. Remember when I wrote about to-do lists? Yeah, those are still important. But behind every item on a list is a greater goal that you want to achieve. "Mop floor", "Do dishes" and "Dust cupboards" all have the goal of a clean, livable kitchen. A more difficult challenge is determining what the overarching goal of "Organize Database", "Fix bug #133", and "Check analytics" is. Clearly one wants to have good code and a better product, but what's the point?
Google knows what their point is, and it isn't "Don't be evil." It's to organize and index all of the world's information, be it websites, books, or photos. Whatever you do, there should be a goal. Currently, our startup is looking at the state of education and saying "Yeah, we can fix that." But "do something 'bout that" isn't a goal unto itself. Acknowledging that something needs to be done and actually finding something to do about it are worlds apart (unless you're in politics - then the second bit is irrelevant).
So we've got a subset of the problem identified and are attacking it, slowly but surely. We already had two pivots, one tech and one ideological. The problem is that the answer to our Big Question [0] of "Heck, is this even possible?" is quite clearly no. No matter what action movies say, two guys with computers simply can't change the world.
Our big ideological pivot has been from "Hey, let's build a thing" to "Hey, let's try and create something that other people will want to join." Our startup will almost certainly fail unless we bring others on. These others don't have to be additional co-founders (too may cooks will spoil the broth) but investors, supporters, and early clients.
So we now have a goal that all of our to-do items can point towards: Get others on board. Despite arguments to the contrary, we still think that an accelerator is the best place for us as it will provide "others" better than we could solicit on our own. Any accelerator worth it's salt will also know what others we need much better than we could.
We won't accept anything less than the best, and the best accelerator is without question YCombinator. If you need any evidence of that, just read through Paul Graham's essays. I certainly have, and it's made a world of difference.
The funny thing is that it's not the content of the essays that makes the difference (though it's immensely helpful). Remember what I said about goals? It's very easy to lose sight of the overall goal as you're closing bugs and documenting. When I feel exacerbated and miss the whole point of what I'm doing, I can look at that tab and remember why it's all happening.
So there you have it folks: The dumbest productivity hack to date: A tab in a browser. It's also one of the smartest - Set up your work environment so you remember why you're working.
[0] The reason that particular post is so poorly-constructed is due to the fact that I was confronting the reality that all startups must face (we'll fail at it alone) with the mentality that we must do it alone. Die Hard, you're a great movie but you give terrible startup advice.
Enough editorializing. Remember when I wrote about to-do lists? Yeah, those are still important. But behind every item on a list is a greater goal that you want to achieve. "Mop floor", "Do dishes" and "Dust cupboards" all have the goal of a clean, livable kitchen. A more difficult challenge is determining what the overarching goal of "Organize Database", "Fix bug #133", and "Check analytics" is. Clearly one wants to have good code and a better product, but what's the point?
Google knows what their point is, and it isn't "Don't be evil." It's to organize and index all of the world's information, be it websites, books, or photos. Whatever you do, there should be a goal. Currently, our startup is looking at the state of education and saying "Yeah, we can fix that." But "do something 'bout that" isn't a goal unto itself. Acknowledging that something needs to be done and actually finding something to do about it are worlds apart (unless you're in politics - then the second bit is irrelevant).
So we've got a subset of the problem identified and are attacking it, slowly but surely. We already had two pivots, one tech and one ideological. The problem is that the answer to our Big Question [0] of "Heck, is this even possible?" is quite clearly no. No matter what action movies say, two guys with computers simply can't change the world.
Our big ideological pivot has been from "Hey, let's build a thing" to "Hey, let's try and create something that other people will want to join." Our startup will almost certainly fail unless we bring others on. These others don't have to be additional co-founders (too may cooks will spoil the broth) but investors, supporters, and early clients.
So we now have a goal that all of our to-do items can point towards: Get others on board. Despite arguments to the contrary, we still think that an accelerator is the best place for us as it will provide "others" better than we could solicit on our own. Any accelerator worth it's salt will also know what others we need much better than we could.
We won't accept anything less than the best, and the best accelerator is without question YCombinator. If you need any evidence of that, just read through Paul Graham's essays. I certainly have, and it's made a world of difference.
The funny thing is that it's not the content of the essays that makes the difference (though it's immensely helpful). Remember what I said about goals? It's very easy to lose sight of the overall goal as you're closing bugs and documenting. When I feel exacerbated and miss the whole point of what I'm doing, I can look at that tab and remember why it's all happening.
So there you have it folks: The dumbest productivity hack to date: A tab in a browser. It's also one of the smartest - Set up your work environment so you remember why you're working.
[0] The reason that particular post is so poorly-constructed is due to the fact that I was confronting the reality that all startups must face (we'll fail at it alone) with the mentality that we must do it alone. Die Hard, you're a great movie but you give terrible startup advice.
Monday, February 18, 2013
Winning is easy, you just have to try
I've noticed an odd phenomenon among people in general - they're afraid of failure. Yeah. Me too. So much so that I'd often rather do nothing than risk failure.
Let's move on from the "well duh" department. There have been plenty of studies, blog articles, and crazy uncles telling you to try something because Failure Isn't Bad. Bah. Failure is bad. Otherwise, it wouldn't be failure. There are many different good things that can result from something going wrong (say, vulcanized rubber) but on the whole, one wants to succeed.
Learning how something doesn't work is often a step on the path to discovering what does, but we've lost sight of what the whole point is. Instead of seeing failure for what it is (a step on the path to success), we have made it into an end of itself. Failure isn't something to be proud of. Instead, be glad you're further along the road to success. Focusing on failure tends to create a more-permanent failure.
When I try something new, I want to learn, and I want to win. I accept that work needs to be done and things will never work out the way I want them to on the first time. That doesn't mean that success can't be easy. Instead of looking at failure as the metric, why not break success down into smaller parts? (astute readers will notice that this is the basis behind A/B testing and to-do lists).
For instance, I've been working to make myself a more sociable person. I could list off the many times I've "failed" and what I learned from that, or I could look at just how easy small changes for the better can be. As it turns out, saying "hi" as you walk past someone makes them feel a lot better and more likely to reciprocate. Making that change was a small success, but it was a success nonetheless.
Not all changes can be as small and simple as that, but when I run git commit for something as basic as adding a <br />, I could let it roll pass me and move on to the next thing. Instead, I choose to see that as my product becoming one step better, no matter how small that step is.
Let's move on from the "well duh" department. There have been plenty of studies, blog articles, and crazy uncles telling you to try something because Failure Isn't Bad. Bah. Failure is bad. Otherwise, it wouldn't be failure. There are many different good things that can result from something going wrong (say, vulcanized rubber) but on the whole, one wants to succeed.
Learning how something doesn't work is often a step on the path to discovering what does, but we've lost sight of what the whole point is. Instead of seeing failure for what it is (a step on the path to success), we have made it into an end of itself. Failure isn't something to be proud of. Instead, be glad you're further along the road to success. Focusing on failure tends to create a more-permanent failure.
When I try something new, I want to learn, and I want to win. I accept that work needs to be done and things will never work out the way I want them to on the first time. That doesn't mean that success can't be easy. Instead of looking at failure as the metric, why not break success down into smaller parts? (astute readers will notice that this is the basis behind A/B testing and to-do lists).
For instance, I've been working to make myself a more sociable person. I could list off the many times I've "failed" and what I learned from that, or I could look at just how easy small changes for the better can be. As it turns out, saying "hi" as you walk past someone makes them feel a lot better and more likely to reciprocate. Making that change was a small success, but it was a success nonetheless.
Not all changes can be as small and simple as that, but when I run git commit for something as basic as adding a <br />, I could let it roll pass me and move on to the next thing. Instead, I choose to see that as my product becoming one step better, no matter how small that step is.
Subscribe to:
Posts (Atom)