HNHacker News
TopNewBestAskShowJobs

pak

4,759 karma · joined March 29, 2010

Assistant Professor at University of California, Irvine

Opinions posted here are my strictly my own, and not representative of any employer or organization that I am a part of.

https://tedpak.com

[ my public key: https://keybase.io/powerpak; my proof: https://keybase.io/powerpak/sigs/fEW8iI_3tD3E9XjbSaPJTDOtaai7TXU6j1QAezE82Xc ]

submissionscomments
pak··on Cars kill cities
But where do you put the light rail? Put it on an elevated track, and that property value change goes the other way (noise, visual pollution, loss of sunlight). OK, so put it in the middle of the street. If it's a dedicated lane, not only do you suck up space from the cars, you have to figure out how to squeeze in platforms, and the light rail has to stop at both platforms and intersections making it painfully slow (take the Boston green lines as an example). If it isn't a dedicated lane, it's a streetcar and you have cars constantly squeezing around it and everybody has to stop to let people run into the middle of the street to get on, plus the odd traffic patterns created at every intersection (Toronto).

If you have the space for a dedicated right-of-way you might as well go full out and make high-cap rail. Otherwise, I see light rail as the worst compromise in-between subways and buses. There's a reason Manhattan has essentially eliminated all at-grade light rail, and elevated rail still exists only in the relatively poor neighborhoods: wherever the subway doesn't run, buses are best at filling the gap without destroying the street-level environment.

pak··on Javascript Best Practices
Neither is great practice, in my opinion. This page looks dated in its recommendations. Any sane JavaScript that works with DOM elements should use a DOM abstraction like jQuery. Leave document.forms.fooinput.parentNode.firstChild.nextSibling.godhelpme to die in the grave of DHTML and incompatible DOMs from the IE6 era.
pak··on Google+ relaxes real-name policy, allows pseudonyms
You don't even need to pick somebody popular, although I suppose it might make certain things easier. If you pick a plausible name and an attractive-looking profile picture, after a few hundred requests to people in the same location, you will have plenty of followers. Perhaps bootstrap with relationships amongst your bots so your profile doesn't look conspicuously vacant. It's not only spammers that do this... guess what, law enforcement does it too. Social networks have not changed how gullible the average internet user is.
pak··on Google+ relaxes real-name policy, allows pseudonyms
So because a spammer could use a data field as a method of communication, we should screen every possible entry in that data field? Perhaps G+ should substitute all comment boxes with dropdown menus... Seriously, this has nothing to do with spam and everything to do with preserving real identities, which have more value to Google's expected future revenue model.

Unverified usernames do not inevitably result in a site that is overrun by spam. Time-tested methods of downvoting, flagging, reporting, and semi-automated filtering can quickly dispatch such shell accounts. You only need to look to reddit for proof of this--a site where users sometimes employ their username as the punchline to the joke. That's right, a username can be an avenue of communication in itself that carries positive, non-spammy (and dare I say fun?) results. Another example: would @shitmydadsays have caught on fire the way it did if the account was named +Justin Halpern instead? I doubt it. The final obvious example: HN, which thankfully does not require "verified" identities.

When I read discourses from Google like the OP's it reminds me how right moot is when he says that creativity is only preserved in a culture that values privacy and anonymity. When everybody is permanently attached to every action, nobody bothers to test the norms, and all that's left is consumption of "safe" content from centralized producers. Of course that's what Google and Facebook, being glorified advertising networks, actually want. Your anonymous account has no money to buy anything, no predictable real-world holdings or credit score or behavior, and therefore no value to an advertiser.

pak··on Command and Conquer – Programming an RTS game in HTML5 and Javascript
I've had this happen to me on Chrome. It was definitely a browser bug, because restarting the browser resolved it. I first noticed it when I was working on a web page with complicated CSS rules for 'cursor'. If I had to guess, it has to do with loading custom .cur or .gif files as the cursor, since it didn't seem to happen unless I tried to do that. However, it was very sporadic and I could never get a reproducible minimal test case.
pak··on How Can A Free Conference Call Be Free?
It's not a simple thing to detect. Short of broad-scale wiretapping, if I bridge two calls on my office phone nobody will know except my in-house PBX. The telco sees two simultaneous calls into my PBX, but unless they are actively listening in on both lines, they can only guess whether these two callers are also talking to each other.
pak··on Google will protest SOPA using home page
There are many ways for a corporation to provide value to a candidate besides a cash donation. Some of these ways can translate readily into cash. For example, insider trading by congresspeople, which apparently is legal. http://www.cbsnews.com/video/watch/?id=7388130n http://www.cnbc.com/id/45249857
pak··on Google is Building an Email List Instead of Asking People to Call Congress
I do wonder what form Google's "online petition" will take.

Speaking optimistically, they do have both credibility and the power to publicize, so if they say e.g. "1 million Google users are against SOPA" perhaps it will be hard for the MSM not to pick it up and repeat the news. And the number could be very large.

pak··on The Fixie Bike Index
I'm with you on secondhand sales being a poor correlate for actual ownership. It's completely reasonable that more for-sale listings indicate cities or places where people don't want their fixie anymore. Additionally, Priceonomics only looks at sales taking place on eBay, Craigslist, etc. So, not only are the numbers skewed toward areas that have more active internet users, the buyer may not even be in the same region.

This is why data shows fixies selling so often in Manhattan: it's all the hipsters that moved to Manhattan, who found less use for their bike, and then sold it back to somebody else in Brooklyn.

pak··on SOPA 'shelved' until consensus is found
Isn't it ironic that the owner of hundreds of newspapers, magazines and TV channels decides to express his frustration over the "Silicon Valley paymasters" by posting his thoughts on... Twitter?

This guy can't recognize the value of freedom of expression on the internet when it is literally slapping him in the face.

pak··on Login to your Google account by scanning a QR code
There are other Google Apps that don't work as great on a mobile device. Try Docs on an iPhone, for example. Also, imagine you need to print out a 30 MB PDF that somebody just emailed to you.

Not enamored with QR codes as a solution, though; I still maintain that the vast majority of Americans have no idea what they are and find them, in general, to be a gimmicky pain in the rear. I agree that what you described would actually be more useful, but also probably harder to do (offline = native app).

pak··on DuckDuckGo gets a new look
I'll agree that it's about the right contrast for keyboard navigation, but a compromise is straightforward: show it only after pressing j/k (as with the current behavior), and use a much subtler effect for mouse hover.
pak··on DuckDuckGo gets a new look
I have to say, why such loud mouseover effects? It's distracting to have all these boxes popping in and out as I scroll through the results. I get that you're trying to show that the click area is that big, but it impairs readability--most of the time while using a search engine I am reading very quickly. Perhaps some people leave their mouse off to the side when they scroll, but many people "think with their mouse," pointing at stuff as they look at it.

I would personally tone them down to just the underline appearing on the result link (where that activates for the big click area, and not just when mousing over the link within the big click area).

pak··on JavaScript Needs Blocks
Of course there are scenarios that are difficult in either language. And lobbying to replace JavaScript with Ruby (I assume you mean in web browsers?) is simply madness for a host of reasons that aren't worth repeating. Lobbying for blocks in JavaScript is sensible, though, since it is actually being considered for the new spec.

It sounds like you think my requirements are contrived. If you prefer to use functions as iterators in JavaScript, and who doesn't (unless you like polluting methods with counter variables?) ... there is no way to have iterators halt early without throwing exceptions or coming up with special return values. Every programmer needs to iterate and break out of loops. It is easy to break from iterator functions in Python and Ruby, since the languages natively support this concept. JavaScript doesn't--that's all we're saying, and it would be nice.

pak··on JavaScript Needs Blocks
Well, now you're dodging the spirit of the problem, which was to work through a single generalization of "map" (or, as tweaked in the second try, "map_unless_test") that is responsible for executing the callback and collecting the results into a new array. Here you are doing the result-collection on your own. You can't express these functions elegantly if you are required to silo the .push(cb(item))-ing into a separate "map" or map-like function.

That's not an outlandish requirement; imagine that the callback can be expensive, and we would like to be able to adjust a centralized "map" function later so it farms things out to different processes/workers/etc.

To solve this for map_first_innermost, you'd have to throw an exception with the nested array, but this is just getting hideously ugly.

  function map_first_innermost(arr, callback) {
    try {
      return map(arr, function(v) { 
        if (v instanceof Array) throw {itWasNested: v}; 
        return callback(v);
      });
    } catch (e) {
      if (e.itWasNested) { 
        return map_first_innermost(e.itWasNested, callback); 
      }
      throw e;
    }
  }
pak··on Raspberry Pi: We’ve started manufacture
If you are looking for a standalone Linux box just to turn on a lamp I think you are over-thinking things. Check out X10 automation kits: here's one for ~$24.

http://www.google.com/products/catalog?hl=en&q=x10+pc+in...

You should be able to control that with a small script (python, perl, etc. anything that can write to a serial port) that you keep running on any computer in your parents' or your own home. X10's advertising is notoriously lowbrow, but the hardware itself is decent and a little googling will find you a lot of hackers that have done crazy stuff with it.

pak··on JavaScript Needs Blocks
Let's modify the GP's example--instead of checking if an array contains something, he wants to return a copy where a callback is applied to each element. Kind of like "map". However, if the array contains other arrays, he wants to return an empty array.

No problemo in Ruby:

  def map_unless_nested(arr)
    arr.map {|v| return [] if v.is_a? Array; yield v}
  end

  map_unless_nested([2,3,4,5]) {|v| v+1 }
  # => [3,4,5,6]
  map_unless_nested([2,[3,4],5]) {|v| v+1 }
  # => []
This starts looking ugly in JavaScript if we want to generalize "map". Either we can keep "map" clean and wrap our callback so it throws exceptions on array input:

  function map(arr, callback) {
    var ret = [];
    for (var i = 0; i < arr.length; i++) {
      ret.push(callback(arr[i]));
    }
    return ret;
  }
  
  function map_unless_nested(arr, callback) {
    try {
      return map(arr, function(v) { 
        if (v instanceof Array) throw "nested!"; 
        return callback(v);
      });
    } catch (e) {
      if (e==="nested!") { return []; }
      throw e;
    }
  }

  map_unless_nested([2,3,4,5], function(v){ return v + 1; })
  // => [3,4,5,6]
  map_unless_nested([2,[3,4],5], function(v){ return v + 1; })
  // => []
Or, if we want to keep the callback clean, we have to start fiddling with map, and then it's no longer really just map (it's map with halting parameters), and then you're using special return values to inform calling functions that the halting condition was met.

  function map_unless_test(arr, callback, test) {
    var ret = [];
    for (var i = 0; i < arr.length; i++) {
      if (test(arr[i])) { return false; }
      ret.push(callback(arr[i]));
    }
    return ret;
  }
  
  function map_unless_nested(arr, callback) {
    return map_unless_test(arr, callback, function(v) { 
      return v instanceof Array;
    }) || [];
  }
If you still think that exceptions are the best language feature to solve this example, consider the situation where you want to do something with those nested arrays. For example, let's take the Ruby example and modify it so it will return a copy of the first-encountered innermost array with the callback applied.

  def map_first_innermost(arr, &block)
    arr.map do |v|
      return map_first_innermost(v, &block) if v.is_a? Array
      yield v
    end
  end
That was easy. You can see that non-local returns become useful very quickly.
pak··on Always Innovating HDMI dongle brings Android to your 'dumb TV'
If you think Apple has something against selling dongles because they are ugly, have I got a page to show you. I think every Mac owner (including myself) winds up having 2 or 3 of these alternately sticking out of their computer or slowly disintegrating in the back of a desk drawer. http://store.apple.com/us/browse/home/shop_mac/mac_accessori...
pak··on Always Innovating HDMI dongle brings Android to your 'dumb TV'
If this device can stream 1080p content, the hardware is powerful enough to do anything you said. The rest is just software.

If you're implying that Android cannot get behind the iron curtain of iOS APIs, then you are missing the gist of GP's point, which is that this device suggests that Apple could make something smaller than Apple TV. (I didn't downvote you.)

pak··on Roboto: Android font explained By Glenn Fleishman
The article mentions "low 100s of ppi to 300 ppi," which is about the range for smartphone screens these days. Most desktops and notebooks still have displays at around 96 dpi.
pak··on Design to accommodate change: Table-driven programming [pdf]
Very cool, I did not know that somebody had already gone and made a programming language like this. In watching the first ~10 minutes of the demo video [1] my thoughts were "Yes, this is a perfect example of where a table could be better than if/else," then when the warning indicators popped up at 5:50 "hmm, boolean algebra is still hard," and then at 7:30 with the demo of fibonacci/recursion "exploded expression trees that must be manipulated by mouse... let's go shopping."

But still, a lot of interesting thinking went into something like this, and it makes you wonder if it would be appropriate to "embed" a similar interface into an IDE for manipulating complex switch case/elseif chains.

[1] http://subtextual.org/subtext2.html

pak··on Python-Dev: Adding braces to __future__
For a while I thought the OP was building up into a great argument about the loss of expression imposed by WSB, what with all the great rhetoric about patronizing the programmer (a smell that I will agree occasionally lingers around Python language design decisions). But then, the argument rapidly devolved into trifles over editor issues and code review tooling. Those are ultimately low-impact because Python people can always write better editor plugins and code review tools, just as people have had to do for any language that incorporates new syntax ideas.

Python's crippled lambdas, like you mentioned, are a much better illustration of where WSB causes irritation down the road. I was looking forward to comparisons with Ruby that highlight the expressiveness that blocks can provide, e.g.

  def gratuitous_callback_name(bar):
      while bar(): baz()
      return meh()
  foo(gratuitous_callback_name)
is clearly not preferable to

  foo {|bar| baz() while bar(); meh() }
and perhaps some demonstrations of how freedom with indentation can lead to more readable code, such as the XCode indentation style for Objective-C vs. the continuation line mess seen in PEP 8 [1]. Also, I would suggest that significant whitespace combined with docstring conventions lead to an unnecessarily complicated algorithm just to strip the whitespace back out [2]: that doesn't smell right either. Similar problems carry over to any Python code that involves defining lots of multiline strings within methods where the whitespace will be significant later (more often than you'd think).

Alas, the OP dropped off so fast before even mentioning any of the above--I suspect a troll.

[1]: http://www.python.org/dev/peps/pep-0008/

[2]: http://www.python.org/dev/peps/pep-0257/#handling-docstring-...

pak··on Design to accommodate change: Table-driven programming [pdf]
Hmm, I believe I've seen shades of this idea in Selenium's most basic test script format [1]. It isn't a decision table, per se, but it was designed to be as easy as possible for non-programmers to adjust. That said, I don't think table-driven programming is as widely useful as this author claims. Most of the testing engineers I know immediately moved away from Selenium script tables toward higher level constructs in JavaScript or Python. I don't think a table is great for expressing recursion or iteration.

[1] http://seleniumhq.org/docs/02_selenium_ide.html#test-suites

pak··on Dropbox: the new file system of the web
I'm with you; I've already experienced various spooky things with desktop applications on top of Dropbox (like the excellent Papers2 by mekentosj) because of file conflicts and latency. And that's not Papers2's fault, since it would have to be redesigned to be tolerant of such things. But it goes a long way toward showing that Dropbox is not a syncing FS that can put any local application data in the cloud. In particular, Dropbox is bad for typical database use patterns (simultaneous writes, transactions) and the versioning and locking are not tunable.
pak··on How can Skyrim be so unoptimized? Modders do better job than Bethesda
Because Bethesda has deadlines and P&L statements, and modders don't. It's as simple as that.

E.g., the Macintosh launched with a hard-crash bug in the Clipboard code in ROM [1]. When you're struggling to meet a tough date for a huge project, things fall through the cracks. They fixed it later with on-disk software.

[1] http://www.folklore.org/StoryView.py?project=Macintosh&s...

pak··on The amazing iOS 5 API and iPhone 4S hardware nobody talks about
Is it just me, or did the 5 use cases proposed in the article immediately give you the reaction "Yuck, I'm kind of glad that none of those things actually broadcast that crap (yet)."
pak··on RFC: Blanking all Wikipedia as SOPA protest
Eh, I would say (sadly) that the mainstream news media practically depends on Wikipedia to fill in background info for half of their stories. Gaffes by TV reporters have occasionally been traced back to Wikipedia vandalism. Sometimes Wikipedians then cite the misguided journalist(s) when adding the falsehood into the article [1], a circular phenomenon of "fact-creation" that has been lampooned by xkcd [2].

[1] http://tech.slashdot.org/story/09/02/10/2211220/false-fact-o...

[2] http://xkcd.com/978/

pak··on RFC: Blanking all Wikipedia as SOPA protest
Unfortunately (or fortunately, depending on your point of view), none of them can vote.
pak··on Hey Google, thanks for making my daughter cry.
This is a great idea, I just set it up on a spare box using Matt Cutts' instructions for getmail and POP3.

http://www.mattcutts.com/blog/backup-gmail-in-linux-with-get...

If anybody else tries this, I'd recommend sticking with POP3 as getmail's IMAP client seems to mark all your messages as read (not cool).

pak··on Porting to Python 3: An offer for you
> Functions implement the descriptor protocol so that when you access them as an attribute of a class they basically return a partially applied function.

Exactly. You just spoke like a true Pythonista: you used an implementation detail in the language to justify a language design decision. In my experience, people diving into Python will not care (or want to know) about the descriptor protocol (it's not mentioned in the majority of books about the language). They will not be messing with __get__ or __set__ the vast majority of the time. Only much later, when they want to start doing fairly magic things with attributes, will they even realize it exists. There is no analogue for the descriptor protocol in any other currently popular language. How can you consider a magic-method protocol that curries all functions when accessed as an attribute the "explicit" or "simple" way to design this?

I guess this is why proposing this is so hopeless. Methods do not have to be distinguished from functions to create an implicit self. Instead of having FooClass.bar() and foo_obj.bar() do any of this [1] (please tell me with a straight face that the average Python programmer knows or cares about any of that) have the former add to the local namespace FooClass as self and the latter add foo_obj as self when the function is called, defined as the behavior of the language's syntax. Like, I dunno, JavaScript, or PHP, or Java, or C#, or... For the 1% of people that care, allow it to be overridden by redefining __get__ and so on. Maybe even redefine the deprecated apply() [2] so people can specify a different self in the course of calling of function, like in JavaScript.

[1] http://docs.python.org/howto/descriptor.html#functions-and-m... [2] http://docs.python.org/library/functions.html#apply

← PreviousPage 8 of 26Next →