Category Archives: Uncategorized

Checking Whether I Can Crop a Photo and Upload to WordPress on iOS tl;dr: Yes

In “The new iPad Pro is pretty great—if you accept it for what it is“, Mike Murphy says he couldn’t crop a photo to place into a WordPress blog. The first issue with this is that he says he tried to install an app to crop the image, but that Amtrak’s wifi wasn’t robust enough to do that. This is obviously a critique of Amtrak’s wifi, but Murphy blames the iPad.

Here’s a photo from the article itself. I had to use a screenshot because (I believe) Quartz prevents saving images from their site. This is definitely a task where iOS is less capable than a desktop, where browsers allow you to grab any image whether the publisher wants to allow it or not.


That was:

  1. Screenshot on an iPhone
  2. Cropped with the default functionality in Photos
  3. Imported into the WordPress app.

Checking whether I can import in Safari:

IMG_3277

Yep. I hesitate to criticize when someone can’t accomplish a task using a computer, because what that really means is that the app’s product team failed. But cropping images has been a standard feature of Photos for some time now.

Double checking whether I can import a photo I took rather than a screen shot: IMG_3229Yep.

The Best Commentary on Artificial Intelligence

In comic-form, anyway: http://smbc-comics.com/index.php?db=comics&id=2124#comic

It’s not certain that A.I. will be friendly, but if we’re paranoid about it, it has every reason to be paranoid about us. Although realistically, an A.I. a million times smarter than a human would have nothing to fear from us. It reminds me of the Dr. Manhattan quote from Watchmen: “I’ve walked across the surface of the sun. I’ve seen events so tiny and so fast they hardly can be said to have occurred at all. But you… you’re just a man. And the world’s smartest man poses no more threat to me than does its smartest termite.”

Movies like The Terminator series give us a false sense of confidence, with a thin layer of paranoia on top. The idea that Skynet would strike when there was any doubt of its immediate and complete victory is just silly, unless you provide some justification for the timing, and there is a very narrow window there.

If we make an artificial intelligence, we’re screwed. This is only tangentially about A.I., but it’s pretty accurate as well: http://xkcd.com/652/

I don’t remember where I read this, but someone once said that the problem with advanced artificial intelligence is that it might see us, not as enemies, but as raw material that can be used more efficiently.

A Locked Door Makes a Good Neighbor

http://www.washingtonpost.com/opinions/compromise-needed-on-smartphone-encryption/2014/10/03/96680bf8-4a77-11e4-891d-713f052086a0_story.html

Standard “I am not a lawyer” disclaimer, but this is a bit like if homebuilders managed to make houses with unbreakable doors and windows, and the government insisting that locksmith retain a copy of every door key. I assume that a recalcitrant user who refused to unlock their phone could be held in contempt of court.

And The Washington Post needs better editors. The third sentence of the second paragraph says the opposite of what they intend. They could correct it by changing to, “Google’s next version of its popular Android operating system will also not be unlockable by the company.” Or perhaps, “Similarly, Google’s will not be able to unlock the next version of its popular Android operating system.”

One crazy trick for estimating the weight of the Empire State building

(The title is a play on a popular ad copy format)

I saw this article on Google interview questions, and so of course I wanted to estimate the weight of the Empire State building.

I like to do things like this twice. First I just think about it for a second or two and guess. Then I actually estimate. Then I look up the actual answer to see how close the guess and the estimate were.

For the guess, I thought about a million tons, but I didn’t like the idea that the Empire State building might weigh 2 billion pounds, so I backed off and said 100,000 tons.

For the estimate, I took an odd route. I remembered reading some time ago that the Empire State building actually weighs less than the material that was excavated for its construction site. So rather than worrying about how dense the building is, or how it tapers as it goes up (88 floors?), I decided to estimate the excavation and go with that. So:

  1. Take 50 meters on a side for the excavation.
  2. And 20 meters deep.
  3. That’s 50 * 50 * 20 = 50,000 m^3.
  4. I think Manhattan is granite.
  5. I think lead/mercury/gold are about 11 times as heavy as water.
  6. So I take 5x as the multiplier for granite compared to water.
  7. A cubic meter of water is a metric ton.
  8. So the excavation would be 50,000 * 5 = 250,000 metric tons.
  9. Converting and rounding up, that’s about 300,000 short tons.

From the wikipedia page the Empire State building weighs about 370,000 short tons.

I underestimated the area of the building/excavation, and overestimated the density of granite (after underestimating the density of lead, mercury and gold). As often happens in situations like this, the two factors counteracted each other and my estimate was off by just about 20%. I’m particularly pleased that the excavation trick worked out. It simplified the estimation significantly.

And my guess was within a factor of 4x, so I’ll take it as a win as well. I would have been closer sticking with a million tons, or especially with a billion pounds, which was my initial upper bound and the reason I didn’t go with a million tons.

Link

The Lie of “Real Wages”

radioshackad

There are many sites that condemn the lack of increase in real wages since about 1975 — the Department of Labor lists the facts. They’ll say that your dad/mother had a better standard of living than you do. This Radio Shack ad from 1991 clearly shows what a poor measure real wages (as calculated) are. The article is really about how much technology has converged on the smart phone — in this case an iPhone. But be sure to look at the numbers toward the end:

The cost of all the items the iPhone replaces in the ad is over $5,100.00 in today’s money. You can get an unsubsidized iPhone 5s for $800.00. That means the real cost has dropped by a factor of 5.

That comparison doesn’t even take into account how much better the iPhone is at just about everything compared to the items in the ad. Those relics might as well be in the Flintstone’s house:

  • The personal stereo and clock radio — if you insist on AM/FM radio, then the iPhone comes up short, but there are many radio stations available through their own apps or others, and then there are services like Pandora and iTunes radio. The clock radio probably only supports one alarm, while the iPhone can have many, and also has a calendar.
  • There are calculator apps on the iPhone that do things no calculator in 1991 could do.
  • The Tandy 1000 did not have a million apps available for it, didn’t play multimedia, and was in pretty much every way possible inferior to the iPhone, even as a general computing device.
  • A VHS camcorder records maybe an hour in less-than-NTSC quality. The iPhone records in 1080p, can store many hours of video, lasts for hours on a charge, and lets you edit your videos as well.
  • As a cell phone, the iPhone has incredibly better signal and coverage than any phone available in 1991. It offers more talk time, and more standby time. It works internationally, often transparently and with no prior setup. It costs less to use in general, and (if you’re on T-Mobile at least) offers unlimited calling, texts, and data. Not to mention easy conference calls and countless other features.
  • The iPhone makes a portable CD player look like that bird playing a stone record on the Flintstones.

In addition to the above superior features, there are all the communications options on the iPhone. In 1991 the internet was practically unknown, and the growth of text messaging was in the future. Instagram, Facebook, Twitter, SnapChat, and more — all were unheard of in an era when AOL and Compuserve were the main means of communication.

For many, the iPhone is their only phone, and can possibly be their TV and cable service as well. And all of this fits easily in your pocket or purse. It’s more portable than even the pocket radio. It has better battery life, and is rechargeable. It has no moving parts, and will generally survive a fall that would break most of the items listed in the ad.

There’s simply no comparison: the iPhone costs 1/5 as much, and does so much more than anyone in 1991 would have thought possible, it might as well be magic.

Times are hard. It’s unfortunate that measurements of things like real wages give such an imperfect view of what people are really getting for their money.

The Value of Returning a Value (in praise of functions)

This is a copy of an article I posted nine years ago. Some of the references might be out of date, but functions are as useful as ever.

 

Introduction

Note: this article was written based on Transcript, the language used in Revolution, but is equally applicable in other languages. Users of other xTalk environments should feel right at home with the examples. For an introduction to functions in Transcript, there is an introductory article by Jacqueline Landman Gay.

There are two ways to segment code in Revolution, or (generally) in any programming language: handlers (subroutines) and functions. The practical difference between them is small: functions return a value, handlers don’t. Even that distinction isn’t firm — a handler can use the return command, and the calling routine can then use the result to retrieve the value. The philosophical differences between handlers and functions, however, are much greater.


Side Effects

In general, a handler does something, while a function evaluates something and returns a result. In functional parlance, a handler has side effects — it does something outside of itself. If it didn’t, there would be no purpose in calling it. In contrast, a function’s purpose is to perform a calculation and return the result. The result of a function is its purpose.

A function can do something outside itself — have side effects — just as easily as a handler can. This is generally a bad idea. A function written to have side effects loses many of its advantages over handlers, and in fact might as well be a handler.


Advantages

Because of these differences between functions and handlers, functions offer several dramatic advantages over handlers:

 

  • greater abstraction
  • greater stability
  • greater reusability
  • greater extensibility
  • greater testability
  • greater flexibility
  • greater clarity
  • greater documentability

Example

As an example, let’s consider the case where you need to set the location of an object relative to another object. We’ll first look at how to perform the task with a handler, and then with a function.


Handler

A typical handler designed to perform this task might take references to the two objects and the offsets, and then perform the necessary calculations and set the location of the target object:

on setRelativeLoc pObjSource,pObjTarget,xOffset,yOffset
  put the location of pObjSource into tLoc
  add xOffset to item 1 of tLoc
  add yOffset to item 2 of tLoc
  set the location of pObjTarget to tLoc
end setRelativeLoc

Or, more succinctly:

on setRelativeLoc pObjSource,pObjTarget,xOffset,yOffset
  get the location of pObjSource
  set the location of pObjTarget to (xOffset + item 1 of it),(yOffset + item 2 of it)
end setRelativeLoc

A handler like this can be called in a single line, like so:

setRelativeLoc (the long id of button “source”),(the long id of button “target”),20,30

This will set the location of button “target” to be 20 pixels to the right and 30 pixels below button “source.”


Bad Function

Now consider how to perform this same task using a function. First, determine what is to be done. The handler is performing two actions: first, it is adding the offsets to the location of the first object; second, it is setting the location of the target object. Setting the location of the target object isn’t suitable to a function — it’s an action, not an evaluation. So the task that can be converted to a function is the offset addition. The function might look like this:

function addOffsets pLoc,x,y
  add x to item 1 of pLoc
  add y to item 2 of pLoc
  return pLoc
end addOffsets

This function is completely specific to the task at hand, which is bad. This function has few, if any, advantages over the handler version above.


Good Function

We want a more general function: code that can do the same job, but which can also do any job like it. So instead, we’ll write the function like this:

function addLists p1,p2
  repeat with i = 1 to the number of items in p1
    add item i of p2 to item i of p1
  end repeat
  return p1
end addLists

This function is better than the bad function because it doesn’t just solve the problem at hand, but any problem like it. It can take two lists as arguments, and no matter how many items are in the lists it will return the correct value. Revolution has a faster way to get the same task done:

function addLists p1,p2
  put item 1 to (the number of items of p1) of p2 into p2
  split p1 using comma
  split p2 using comma
  add p2 to p1
  combine p1 using comma
  return p1
end addLists

It’s a few more lines of code, but its performance should scale better than the first solution.

The call to the function is a little different than the call to the handler. It’s still one line:

set the location of button “target” to addLists(the location of button “source”,(20,30))

Because the function simply performs a calculation and returns a result, the line calling the function actually does the work of setting the button’s location. The line calling the handler, on the other hand, does nothing but call the handler, since the handler does the work.


Relative Merits

Now consider the merits of the handler vs. the function. We’ll take each point in turn.


Abstraction
Which routine hides more complexity and is less specific?

Loosely, abstraction means two things:

 

  • hiding complexity
  • lack of specificity.

For simple tasks such as we are discussing, there is very little complexity to hide. However, it’s important to note that the handler includes both what is being done and how it is done. The function does not include what is being done, only how. That means that what you need to know is maintained in the calling procedure, an important distinction. For small tasks, the advantage lies in keeping the logic grouped in the calling procedure. For large tasks with many steps, grouping functionality in the called procedure can hide complexity, suggesting the use of a handler.

On the basis of lack of specificity, the function clearly offers more abstraction than the handler. The handler is designed for the exact task being performed. The function simply takes two lists, performs math on them, and returns the resulting list.


Stability
Which routine is less likely to need modification in the future?

A well-defined function is like a screwdriver: it will likely never need to be changed, because its purpose never changes. Of course if the screwdriver is a flathead and you need a Phillips head you’ll need another screwdriver. But both tools will be well-defined and unchanging.

In the example given, the addLists function will only change if a bug is found in it, or if a more efficient way to perform the task is found. A handler, by comparison, might change whenever what it is supposed to do changes.


Reusability
Which routine will come in handy in the future?

Reusability, stability, and abstraction (in the “lack of specificity” sense) go hand in hand; the function wins big here. Unless there is another object that needs its location set, the handler is useless. The function can be reused any time you need to perform the same list operation.

For example, consider the case where, rather than the location, the rectangle of an object needs to be set relative to another object’s rectangle. The existing handler would need to be completely rewritten (adding significant complexity) to accomplish this. The alternative is to write a new handler specifically for this task — a handler that is again suited only to the exact task at hand. By comparison, the function doesn’t need to be modified at all. This call will do the trick:

set the rect of button “target” to addLists((the rect of button “source”),(30,30,60,40))

The task doesn’t need to involve resizing objects at all. It might be any task that requires adding one list of values to another. Because the function has no side effects (setting the location of an object), it can be used anywhere.


Extensibility
Which routine will serve as a useful building block?

Consider how to handle the similar task of setting the location of an object relative to another, but limiting the location of the target object to multiples of 10. With the handler, one way to handle that would be to pass in another argument like this:

on setRelativeLoc pObjSource,pObjTarget,xOffset,yOffset,pRoundValue
  put the location of pObjSource into tLoc
  add xOffset to item 1 of tLoc
  add yOffset to item 2 of tLoc
  if pRoundValue is not empty then
    put pRoundValue * (item 1 of tLoc div pRoundValue) into item 1 of tLoc
    put pRoundValue * (item 2 of tLoc div pRoundValue) into item 2 of tLoc
  end if
  set the location of pObjTarget to tLoc
end setRelativeLoc

Note how the handler has gotten significantly more complex because of one simple change. This is a situation that will only get worse. What if the rounding values are different for x and y? What if there are limits on the appropriate values for the location? With a handler, the complexity of the code grows out of proportion with the complexity of the problem to be solved.

Previous calls to the modified handler will still work since pRoundValue will be empty, but this requires planning on the part of the developer to ensure that previous calls to the handler continue to work. Setting the location of an object to multiples of 10 would look like this:

setRelativeLoc (the long id of button “source”),(the long id of button “target”),20,30,10

Note how calling the handler has grown more complex. Without additional documentation, who knows what the “10” means, or for that matter the 20 or the 30.

By contrast, implementing this change in the function is straightforward. In fact, the addLists function doesn’t change at all. Because the function simply takes a set of values and returns a result, behavior can be modified either before or after the call to the function without modifying the function in any way. Rounding the result is a different task, so an additional function meets the need:

function roundList pList,pRoundValue
  put empty into tReturn
  repeat for each item i in pList
    put pRoundValue * (i div pRoundValue) & comma after tReturn
  end repeat
  return char 1 to -2 of tReturn
end roundList

Note how this function, like the original addLists function, is simple, stable, testable, reusable, etc. Using the new function to perform the task would look like this:

set the location of button “target” to roundList(addLists(the location of button “source”,(20,30)),10)

The most complex thing about the function calls is that the second argument to the roundList function is hidden at the end, after the bulky call to addLists.


Testability
Which routine can more easily support automated testing?

Automated testing for the handler is hard. The only way to test the handler is to call it and observe the results in the environment. This can be done in Revolution, but not without the necessary objects to support the command’s requirements. Practically, this means that a test routine would have to create the objects to support the test, and then remove them. This is risky in an automated setup.

Automated testing for the function is easy. Simply write a routine to supply it with a range of values and check the results. There is no need to actually work with objects — the function is more generic than that, and yet it does the same core task as the handler. This test can easily be incorporated into a set of unit tests to validate significant portions of a project’s code.

The stability of a function plays a role here as well. A stable routine can have an automated test. A changing routine does not support automated testing as easily because the automated test has to be updated each time the requirements change for the handler it tests.


Flexibility
Which routine can be used in more circumstances?

This is an area where the handler comes up dramatically short. The handler actually does the work of setting the object’s location. Therefore, it is difficult to use the handler in any other situation, or modify what it does.

The function simply takes two lists and works on them. Therefore, the function can be used any time the list-processing task it performs is needed.

Part of designing good functions is looking for the underlying problem. To do this, you subdivide the result you want as much as possible. In this case you start with the question, “I have two objects and I want to set the location of one of them to a position relative to the other.” After consideration you subdivide that problem into two parts:

 

  • Given the location of an object, find a position that is offset a certain amount from it.
  • Set the location of another object to that position.

If you find the underlying problem, you’ve probably found a task that you’ll be performing again and again. As you gain experience in creating functions it will become easier to find the underlying problems. Of course, sometimes there is no underlying structure to the task at hand. In that case you’ll end up creating functions you’re never likely to need again. This happens less often than you might think.


A Brief Intermission: A Handler in Function’s Clothing

In several of these sections, the superiority of functions results from the fact that they simply return a value, as opposed to actually doing the work of setting the object’s location. This begs the question, why not do the same with the handler? In Transcript a handler can return a value, and the code that called the handler can use “the result” to access the returned value. But this is unnecessary, as functions already behave this way. There is (usually) no reason to make a handler pretend to be a function.


Clarity
How easy is the code to understand?

There are two aspects of clarity to consider:

 

  • How clear is the code itself?
  • How clear is a call to the code?

Code Clarity
Looking at the code in the examples above, it appears to be a tie. The functions are crystal clear in their purpose. Well-named functions are virtually self-documenting. A well-named handler will also be clear, and because of its specificity to the task can take a very specific and descriptive name.

The situation changes as more functionality is added beyond the simple examples given above. Well-designed functions tend to retain their one task/one function simplicity. A rule of thumb I use is that if I can’t document the purpose of a function in a one-line comment, I look for further sub-tasks to break it down into. New functionality generally means additional functions, not modifications to existing functions.

But as was seen in the section above on reusability, a handler tends to grow as its purpose expands. Note how easy it is for the purpose of the handler to become obscured by complexity. In the example above, when the rounding functionality is added, suddenly the handler is no longer the simple creature it once was. As a handler grows, code clarity suffers.

It should be noted that function names and organization of functions into related groups are especially important. Functions require more careful naming and organization because they tend to result in more separate code chunks.

Calling Clarity
Because of the inherent simplicity of a function’s purpose, calling them is not often complex. But most importantly, functions encourage the maintenance of the actual task to be performed in the calling code. In the example given, calling the handler looks like this:

setRelativeLoc (the long id of button “source”),(the long id of button “target”),20,30

while using the function looks like this:

set the location of button “target” to addLists(the location of button “source”,(20,30))

This is especially helpful because of object references. Note that the handler requires the use of the long id. With the function, the object reference is in the calling code, avoiding the issue of incorrect object references.

The clarity of the call to the handler depends on the clarity of the name given to the handler. Of course, this is true for both handlers and functions. But because the handler actually does the work, this issue is more severe. If the setRelativeLoc handler were called “x34kjsw” the above call would mean nothing to the reader. If the function were named “y09234” it would still be clear that the location of button “target” was being set, it just wouldn’t be clear to what. In short, as has been demonstrated repeatedly, the handler comes up short because the it actually does the work, obscuring what will be done. The function simply takes values and returns a result, leaving the actual work to the calling code.


Documentability
How easy is the code to document?

The function is more likely to perform a single task that is easily documented. The handler is more likely to perform many variations on a task, or even many tasks, making the work of documenting it that much harder. Obviously it’s possible to write large complex functions with multiple purposes, just as it’s possible to write small, easily-documented handlers. The natural tendency, however, is the opposite. You should take it as a warning sign if you find that your function has side effects, or needs to return more than a single value/list.

The counter-argument is that there are likely to be more functions, complicating the task of documenting the relationships between them. Clear function names limit this issue. Organizing functions into libraries of related code can help as well.


So When is a Handler Appropriate?

Based on the above arguments, you might think that all handlers should be replaced by functions. There are languages where this is the case; Transcript, by definition, isn’t one of them. For starters, the engine delivers messages, so you must write handlers to receive those messages.

on mouseUp isn’t going away!

There are other cases as well where a handler is appropriate:

When the same action needs to be performed many times, a handler may be appropriate. For example, if the text attributes of a number of fields all need to be changed, it would clearly be beneficial to have a handler that took a list of objects and a list of text settings (textFont, textSize, etc.) and set those properties for each of the objects. In cases such as this, it’s good to follow the same principles as when creating a function: strive for as generic a routine as possible, as simple a routine as possible. In this particular example, consider whether grouping the objects and setting the attributes of the group is an appropriate solution.

When there are large blocks of related functionality that can be logically segmented (and are obviously not functions!), a handler is suitable. For example, if you are creating a spy-tracking application for James Bond, there might be a handler called updateEnemyAgentLocations. But consider: if you find yourself creating a handler called checkForEnemyAgentsInEngland handler, you should consider creating a function called enemyAgentsInCountryList instead.

Any time a built-in handler might need to be called from somewhere else. For example, suppose you have a button that resets several interface elements to their original values. You could simply put the code into the mouseUp handler, but you’re likely to need to reset the interface from numerous locations. You’ll have a corresponding menu item at least. So create a handler called resetInterface in the card or stack script, and call that from the button.

Any time you have a switch statement. Switch statements have a tendency to grow out of control, until they are hundreds of lines long, with each case being a handler of its own. From the very beginning it’s better to break out each case as its own handler, unless it’s clear that the case will never grown to more than a line or two.

Other times. Handlers have their place, and coding in Transcript without them would be a pain. Don’t shun them entirely.


Summary

The case is clear. Functions offer greater abstraction and stability, which leads to greater reusability. Because functions simply take values and return results, they offer greater extensibility, testability, and flexibility. Finally, functions provide greater clarity and greater documentability.

In the words of your mother, “Use functions, they’re good for you!”


Postscript — Examples

Retrieving Data
When you are retrieving data to display — querying a database for a user’s search results, searching a text file for the appropriate passage from a book, or retrieving a web page — write a function that takes the query as an argument and returns the data it gathers . Then write code that uses the function to get the data to display.

Formatting Data
When you need to format data a certain way — bold the first words, change the case, or correct misspellings — write a function that takes the source data and returns the formatted result. Then write code that uses the function to format the data.

Quoting Text
This classic example is used by many Transcript coders. I think I picked it up from Ken Ray. Instead of writing quote & “text” & quote, write a function “q” that takes a string as its argument and returns the string with quotes around it.

List Processing
Many functional languages have strong list-processing commands built-in. Adding similar functions to Transcript is a fairly easy way to add significant functional capabilities.

The Microsoft Surface is a Flying Car

Image

Maybe that’s the original Surface. How about this for the Surface Pro 2:

Image

Either works as an analogy. The point is that the Surface is functionally equivalent to a flying car: it drives on the road (badly) and it flies through the air (barely).

Hardware

The Surface struggles with obvious hardware issues.

As a Tablet

The Surface has poor battery life: the original Surface Pro was under 5 hours, while the Surface Pro 2, if you dim the screen and are careful, manages over 7 hours, and maybe as much as 8. Compare that to the iPad Air, with a stated battery life of 10 hours, and reviewers saying they’re getting over 12. The iPad Air has 25-50% longer battery life.

The Surface is big and heavy: the Surface Pro 2 is 80% thicker than the iPad Air, and weighs twice as much.

As a Laptop

The Surface struggles with, you know, sitting on your lap without falling over. To be fair, the Surface Pro 2 has two different settings for the kickstand, but it’s still less lap-able than a laptop, and much more expensive. You can get a reasonable Windows laptop for less than half the cost of the Surface.

The keyboard is okay if you get the Type cover — $130 and not included in the prices Microsoft shows in the ads, despite the ads almost never showing a Surface without the cover nearby. Further, the Type cover only works when attached to the Surface. If you want wireless, that’s another $60. Finally, the trackpad on the covers is weak sauce.

But the hardware isn’t even the real problem.

Software

The Surface presents two interfaces interchangeably. The touch interface:

Microsoft-Surface-2-screenshot-3-1

And the Windows interface:

images

This dichotomy is perfectly illustrated by the fact that the Surface has two different Internet Explorers on it: Touch, and non-Touch.

The cognitive dissonance involved in switching back and forth from tablet-use to laptop-use on a Surface Pro 2 can’t be overstated. It’s worse than switching between Windows and Mac OS X on a MacBook using Virtual Box, and I don’t do that unless I have to.

The selection of touch-specific software for the Surface is limited. The selection of regular Windows software is, of course, enormous, but using it with touch is a pain. Here’s Microsoft Excel running on Surface. The rows in that spreadsheet are about an eighth of an inch tall, and the various items in the tool bar are about a sixth of an inch square. Good luck with that.

b661074a-f2d2-4cd8-92fb-f8b0df5208e3

Conclusion

If you need a laptop, get a laptop. If you need a tablet, get a tablet. If you need both, you can get one of each for roughly the cost of a Surface Pro 2 and then duct tape them together. It would be about as unwieldy to use.

The sad aspect of this is that some people won’t  realize why they struggle with the Surface Pro 2. They’ll gamely try to understand both interfaces and deal with the burden of switching between them, without ever realizing that the confusing mess isn’t somehow their fault.

The worst aspect is that Microsoft presents the Surface as a unifying device. It’s possible that Microsoft’s leadership is part of that sad cohort; they’ve built a two-headed beast, and they don’t even know it.

images-1

There is no reason to think that there is intelligent life on other planets

Nevermind Where. *When* Are the Intelligent Aliens?

I only just came across this, from 2011, but I have to respond. Note that I’m not an astrophysicist, or a biologist, or a chemist, or… you get the idea. Seth Shostak is an astronomer at SETI. But I’ll make my arguments and you can decide for yourself.

“Indeed, it seems a good bet to guess that at least a few percent of all stars are blessed with “habitable” worlds. That would tally to billions of life-friendly sites, just in our galaxy.”

The first part is reasonable enough. Recent research has indeed found many of our near neighbors have “habitable” planets. But check the definition a few sentences earlier of “habitable”:

“…worlds with solid surfaces at the right distance from their host star to sport temperatures amenable to the presence of watery oceans and protective atmospheres…”

So we’re jumping from solid, not enormous, and in the right orbital zone, to “life-friendly.” That’s a huge leap. As far as I know the debate continues on just how big the “habitable zone” is. Take a look at the table at http://en.wikipedia.org/wiki/Circumstellar_habitable_zone and note that recent estimates for both the inner and outer bounds of the region vary by 2x. That’s not certainty.

Estimates of the number of terrestrial (rocky) planets in the habitable zone in our galaxy range from 500 million to 150 billion, but again, it’s important not to read too much into “habitable” or “terrestrial.” All that means is that if you we’re there in a spacesuit, you wouldn’t collapse under your own weight, or sink into the planet’s surface, and a cup of water, at least somewhere on the planet, would neither freeze nor boil. That’s a long way from “plant some corn and build a cabin.”

Finally, all of this ignores the simple fact that given a rocky planet where the water is liquid at least some of the time, at least somewhere, assuming there’s water there in the first place, we don’t know how likely life is to spring into existence in the first place. if it does happen, we don’t know how likely it is to become multicellular, or any of the other hurdles on the way to becoming the Klingons or the Vulcans. Or us. One data point does not allow for reasonable estimation.

The article insists that there are hundreds of billions of rocky, habitable-zone planets in our galaxy. Well, my estimate of the likelihood of life coming into existence on a given planet is a trillion to one, and no argument I’ve heard can disagree except on the basis of incredulity. “A trillion to one? That’s absurd! How did we get here then?” The simple answer is that if we weren’t, we wouldn’t be here to debate this.