Getting Started with Zephir and PHP 7.2

Zephir is a new high level language that makes writing PHP extensions much easier than before, allowing one to create amazing performance enhancements by rapidly developing custom extensions for your application where processing power would otherwise be a bottleneck. But, Zephir taken a while to catch on because it is still a young project and not as easy to install as one might hope due mainly to fragmented documentation and lack of distribution packages at this point.

Zephir Installation Overview

  1. Install Zephir Parser first! – The Zephir parser is a PHP extension that needs to be installed on your development machines php-cli. You must install the extension before you can install the Zephir compiler. The Zephir compiler documentation does not say this explicitly enough. There is a dependency by the Zephir compiler that requires the Zephir Parser PHP extension to be installed and working for the compiler to install and run properly. Like any extension, it is basically a matter of dropping the into the right directory, and putting an `extension=zephir_parser` directive into the right .ini file. Now, here’s the tricky part.

    When you run the install script that compiles the Zephir Parser extension and should place the .so file in the right place, but you really benefit from running the installation script with the correct flags pointing to the target version of PHP that you’ll be using for development. So, run the installation script with the following flags adapted for your version:

    sudo ./install –phpize /usr/bin/phpize7.2 –php-config /usr/bin/php-config7.2

    That’s the trick to getting Zephir Parser to compile on Ubuntu 16.04 against PHP 7.2 as of February 2018. I suspect it may be blocking potential users on other distributions as well. It is buried in the “Advanced Compilation” section of the readme, but the flags for the install script currently have no documentation and the need in some instances to compile with the –phpize and –php-config flags needs to be more prominently stated.

  2. Install the Zephir compiler only after you’ve installed the PHP extension on the php-cli command line tool. Use `php -i | grep zephir` and look for evidence that the Zephir Parser extension is installed. Only then should you attempt to install the compiler.

That’s the high level process. Most everything else is obvious from the documentation. Hopefully, this overview helps at least one other PHP developer get up and running with Zephir toolkit and start learning the Zephir language, which is the fun part.

Zephir and PHP 7.2 Rule!

I’ve been working with PHP since 2000 and I still enjoy using it. And now, with the release of PHP 7.2, which has all the good parts of PHP 7, including increased performance and a better type hinting system, PHP 7.2 fixes a number of bugs that impact security, such as a broken random number generator that didn’t produce cryptographically useful random values. I think if developers begin utilizing the extension system more often through Zephir, the combination of improvements in PHP 7 and an easier path to developing language extensions, will allow the PHP community to build faster, more robust applications and the PHP platform may regain some of its respectability. Zephir and PHP 7.2 and bring new life to a development platform that deserves more respect than becoming yet another legacy language.


How to Hash a Long Password with bcrypt

Hashing is an important competent in securing any application that users will log into, such as a Web application or an API for an an app, particularly when authentication is done using passwords, and bcrypt is currently a standard, acceptable way to create a secure hash. bcrypt’s acceptability may change in the future, but what won’t change is the reality that no sane person stores user password values in a file or database. Let me say that again. No sane person stores user password values in a file or database. Instead, the current best practice is to store a one way cryptographic hash based on the password and later, when the user logs in, hash the password that the user supplies with the one previously stored on the system.

Beyond simple hashing of a user supplied password, there are other use cases for wanting to securely hash the entirety of an arbitrarily long string using bcrypt such as constructing authentication tokens. One may also wish to salt the password before passing it into bcrypt for an even higher level of entropy.

One algorithm I use to get around the character limit is to use an intermediate hash. So, instead of hashing the password directly, I use a weaker hashing mechanism that produces a shorter string within the length limitation of bcrypt and then hash that intermediate string using bcrypt. The intermediate hash needn’t be strong hash, like bcrypt, though if you use a highly randomized and long salt you will maximize the effectiveness of this approach. My current intermediate hash is sha512.

A Recipe for bcrypt Hashing Passwords Using and Intermediate Hash

The steps I use for hashing ginormous strings with bcrypt, such as heavily salted passwords, are as follows:

  1. 1. Generate a long, cryptographically secure salt using a source such as /dev/urandom. (Do this per user. You can also append an application-wide salt as well if you like.) You will need to store this salt if you plan to do password validation in the future.
  2. Concatenate the salt to the user supplied password.
  3. Feed the concatenated value to sha512 and capture the result, which will be a 128 character string representing a hexidecimal number.
  4. To add entropy and make use of the entire intermediate salt, loop through the entire sha512 hash taking pairs of hex digits, converting the pair’s value to an ascii character and using each character to build a compacted intermediate hash that is 64 characters long where there are 256 possible characters.
  5. Feed the final compacted intermediate hash into bcrypt with your preferred parameters (such as cost) and capture the resulting hash.
  6. You now have a secure hash that utilizes the entirety of the value of your long password.

This is a simple solution to the problem of limited string length support for the bcrypt hashing algorithm, but there is room for improvement. For instance, using some simple stupid math tricks, one could create variations in the length of the hashed string, which up to a minimum viable length could be used to produce a larger number of possible hash-able values. To the extent that variation and unpredictability continue to make hashed values harder to guess, adding procedural complexity to this solution is really up to the creativity of the individual implementing it.

PHP Sample bcrypt Intermediate Hash Code Example

 * A simple demonstration impementation in PHP.
 * This code snippet requires PHP version 7.2 or higher. Check
 * out PHP 7.2+'s improved encryption capabilities at

// This is the string that needs a one way hash. A clever user
// could make it longer than bcrypt can handle.
$password = 'spicy pony head rules';
echo "The example password is: {$password}\n\n";

// Create hypothetical cryptorgraphically secure random values for
// an application secret and a user secret. Secrets should be quite
// large so they cannot be easily guessed or brute forced.

// The application has a secret stored in a private file. It should
// be randomly generated.
$applicationSecret = base64_encode(random_bytes(2048));
echo 'Application Secret: ' . substr($applicationSecret, 0, 48) . "...\n";

// The user secret is stored with other user data. Each user gets
// their own random secret.
$userSecret = base64_encode(random_bytes(2048));
echo 'User Secret: ' . substr($userSecret, 0, 48) . "...\n";

// If you concatenate these strings, they are too long for bcrypt to use the
// entire string.
$stringToHash = $password . $userSecret . $applicationSecret;
$len = strlen($stringToHash);

echo "The hashable string is {$len} characters long.\n\n";

// So, lets use sha512 as our intermediate hash since it gives us 128 bytes
// of hexidecimal values.
$intermediateHashedString = hash('sha512', $stringToHash);
$len = strlen($intermediateHashedString);
echo "The sha512 string is {$len} characters long. SHA512:\n{$intermediateHashedString}\n\n";

// Now, let's get full use of this string by taking pairs and using
// their numeric value to create a string of one byte characters.
// Effectively, we've created a base 256 modal number that fits
// the entire intermediate hash into bcrypt's input length constraint.
// (Don't output this to your terminal. It's likely full of control
// characters).
$base256HashedString = '';
for ($i = 0; $i < $len; $i += 2) {
    $base256HashedString .= chr(hexdec(substr($intermediateHashedString, $i, 2)));

$len = strlen($base256HashedString);
echo "The base 256 compacted sha512 string is {$len} characters long. \n\n";

// Finally, let's serve up our bcrypt hash.
$bcryptHash = password_hash($base256HashedString, PASSWORD_BCRYPT);
echo "Out final bcrypt hash is: {$bcryptHash}\n";

Sportsball... Sportsball everywhere!


I like to go and take a hike,
and sometimes go and ride a bike,
And though I do not fish for pike,
It’s sportsball that I do not like.

I do not like it on a hat,
Nor tattooed boldly on my cat,
And if I owned a sportsball jacket,
Into the trash I would pack it!

When I go to cast my ballot,
A horrid taste forms on my pallet,
Who there dares to go beg for money?
Rich sportsball pricks and it’s not funny.

And when the people pay their bond,
How do these ingrates then respond?
They move their teams and thus abscond
with peoples’ taxes far beyond.

And at the start of sportsball season,
Most people seem to loose their reason,
Because they fear to dream or think,
They fish used sportballs from the drink.

I find it sad that thought reform
has always been our culture’s norm,
Just watch the fans and soon you’ll know
that sportsball is just mind control.

And if this screed leaves you irate,
A sportsball fan I irritate,
Then keep on cheering corporate theft
and sportsball will be all that’s left.

Corporate Shuttle

To breathe is to suffer always said father.
Now that I’m him
this dull malaise kicks me
like the morning coffee.

Sitting on this asphalt ribbon to nowhere,
this bus is full of mistakes;
Together and silent,
Parched for sleep, we all sing this hymn:
We didn’t consent to this,
We never wanted to breathe.


Listing the Current Branches of Multiple Git Repositories Under a Singe Parent Directory Using Bash

440px-strom_roka_borovica_velke_borove_03An interesting problem came up a work where I am maintaining a couple of legacy enterprise applications written in PHP. These applications were first developed over a decade ago and the version control was originally managed in SVN. Later they were moved to Git. I do not know the full reason why, though I have a theory, but both applications break down into multiple components, each of which is managed in a separate Git repository. This isn’t a huge issue, but it does create headaches when working on multiple tickets that impact multiple components. I want to make my changes for each ticket on a new Git branch for that ticket while leaving unmodified components on their master branch in Git. Unfortunately, there isn’t an easy solution to figure out what branch each Git repository is pointed at, a problem when there are perhaps ten separate repositories that all interact with each other.

Anyhow, yesterday I wrote a Bash script to address the issue, so I can now get a quick summary of what branch each repository is currently pointed at. Since writing the Bash script took a bit of research, trial and error (as Bash does), and was generally a bit of a pain in the ass (as Bash scripting is), I figured I’d publish my Bash script so that someone else out there might benefit from what otherwise would be a single use tool written for myself, and possibly a few interested team members working with these clusters of Git repos.


# Get all the repo paths for opsdb and store them in an array.
while IFS= read -r -d $'\0'; do
done < <(find ${app_path} -maxdepth 1 -mindepth 1 -type d -print0)

#echo ${#repo_paths[@]} # DEBUG Print the legth of the arrray.

# For each array, write the path and output the current branch.
for component_path in ${repo_paths[@]}; do
    echo -n "${component_path}: "
    git --git-dir=${component_path}/.git --work-tree=${component_path} rev-parse --abbrev-ref HEAD

SSHFS on OS X via Fuse and the Horrible Dot Underscore Turd Files

Once again, I have been issued a Mac to do development work, and as usual everything unixish on OS X almost works. To my delight, when faced with having to code against a Linux environment that I access via SSH, I found that since I last faced this situation, someone had made and is maintaining a port of Fuse for OS X with easy support for SSHFS. This discovery was a really great way to start the morning. I downloaded the installers, ran them, wrote my script to mount my remote machine to my filesystem, and had it working by the time I finished my first cup of coffee. Kudos to the team who maintain that port!

Of course, with the OS X filesystem in the mix, network attached filesystems never just work the way you want them to. In this case, the problem I ran into was the presence of files beginning with ._ the moment I created a new file in my repository and ran git status. I’ve seen these before. They pollute the files of most every filesystem ever touched remotely by a Mac, and they are totally invisible to the Mac user. They are used to store metadata for OS X, and are totally useless for any other computer. One Stack Overflow commenter deemed these dot underscore files “turd files”, which I consider an apt description. Apple calls the double underscore files “Apple Double” files. Whatever you want to call them, when being introduced into a client’s code repository on a Linux OS, these files beginning with ._ are turds and I want to prevent them from ever being created on my remote system.

It took some digging using a brand-name search engine, the name of which I will not disclose, but I was eventually directed back to the OSXFuse documentation, which, with a little reading, gave me a solution. (Cheers to working documentation!)

In the SSHFS connection string there are several options that can impact the creation of Apple Double (._) files. The two that I wound up using were noapplexattr and noappledouble. noapplexattr prevents OSX from even attempting to apply its extended attribute shenanigans to the SSHFS mounted operating system and noappledouble explicitly prevents the creation of any file beginning with a dot underscore as well as the also very annoying .DS_Store file. I’m not certain that both options were needed for my situation, but I used both and tested the result, and it seems to be working. Not almost working, just working.

My command for mounting my SSHFS looks like this (with sensitive bits redacted, of course):

sudo sshfs -o allow_other,defer_permissions,noapplexattr,noappledouble,IdentityFile=~/.ssh/id_rsa myusername@clientsserverhostname:/home/myusername /mnt/sshfs/mymountpoint

So long ._ files!

Server-Side Swift on Linux

“Can I write Web applications in Swift?” was a random question that popped into my head a few weeks ago after discovering, a project that moves Swift programming language out of the domain specific role of replacing Objective C as the defacto language for building apps targeting Apple’s iOS and OS X platforms and into the Open Source ecosystem. The answer is, yes, thanks to the work being done by Perfect.

I have been curious about Swift since it first came out, though I am not a mobile developer. Recently, in a job interview, I spoke to the mobile team at a digital media company, and the iOS developer raved about the language, which led me down the rabbit hole. Seeing that Swift is capable of being a general purpose programming language, and that it can run on Linux makes me optimistic that organizations with strong iOS offerings may be able to run full-stack Swift applications similar to what Node.js / Web developers currently enjoy. The core advantage of Swift, of course, being not JavaScript. Whether Swift becomes a mainstream server-side language outside of the Apple fanpeople’s realm is anyone’s guess, but it is intriguing enough that I will be giving it a try over the next couple of weeks.

Today’s effort was seeing if I could get Swift and Perfect up and running on my Ubuntu 16.04 machine. offers binary downloads for Ubuntu 14 and 15, but not 16, as of today. However, being lazy (or arguably organized) and wanting to used apt to manage the installation, I instead found this Swift package for Ubuntu 16.04, which, following the instructions, worked flawlessly, though it did involve editing my .bashrc file to include the package’s binary directory in my user’s PATH variable.

After installing the Swift compiler, I downloaded the Perfect sample project and built it, as per Perfect’s instructions. My first attempt at compilation failed, as I received the error:

/home/david/swift/PerfectTemplate/PerfectTemplate/Packages/LinuxBridge-2.0.1/LinuxBridge/include/LinuxBridge.h:6:10: fatal error: 'uuid/uuid.h' file not found
#include <uuid/uuid.h>
1 error generated.
<unknown>:0: error: build had 1 command failures

This seems to be a common dependency problem, and after a little digging, I was able to get the compilation to complete by running the command sudo apt-get install uuid-dev to install the uuid development package for Ubuntu. Easy peasy, right?


Great success!

The next step for me will be to try and build a working Web app on Linux in Swift using the Perfect library. Whether I find the language as pleasant as some iOS developers remains to be seen, but it seems like it is an experiment worth trying.



STEEL_RESERVE_40_A-500x500I’m 40 years old, and in less than a month my 40th year will be in the rear view mirror. I remember one day, when I was 25, when I had the realization that forty was only fifteen years away. I remember exactly where I was too. I remember cringing a little because being ten years old still felt recent and forty felt impossibly old. In an instant I realized that youth had a shelf life, and that sooner than I would like it would expire.

Thirty was a great year. My twenties were full of Sehnsucht, a portmanteau of undefined longing and lingering illness that only the mind of a German could condense into a single, two syllable word. I was relieved, despite the negative buzz about flipping that significant digit, to ditch the twentysomething angst for the decade of hustle that any responsible thirtysomething must endure. In my thirties my career finally hit its stride. I spent the decade in a more or less stable relationship. I learned to drink wine and spent romantic weekends in Mendocino, getting massages and sampling artisanal whatnots. I worked hard and took up running. I skipped some of the responsibilities that my peers took on; kids, mortgage. But I played harder than I did in my twenties. I had fun. And then life happened.

Forty is a canonical number. When Noah took his cruise, it rained for forty days and forty nights. Moses roamed the desert with his people for forty years. Jesus fasted in the desert and was tempted by Satan for forty days. Forty is big. It is more than the literal bundling of forty individual things. It’s something that’s not exactly quantifiable. How big was that thing? I don’t know, like forty.

Forty was a transformative year for me. The relationship that had been the bedrock of my life eroded from the Heraclitian constant – change, and I found myself thrust into the dating world as a forty year old man; the optics of which are not good. There are 38 year old women who will not date a forty year old man. I am too old and settling for me means admitting that one has past one’s “best by date” on the early side. I would write this off as a purely psychological phenomena,  but for the fact that I am not 39. I am forty.

I drink less now. Bars are noisy and crowded, and I am happier when I go several weeks without so much as a beer. My bottles of scotch and tequila sit on the shelf gathering dust. They are nice to look at. I like their aesthetics, but they make me happier as art objects than having their contents poured into shot glasses. I don’t work a program. I didn’t make some great effort to stop drinking. One day I just lost interest. Most of the time a good night’s rest is more appealing than a cocktail.

Work is interesting. My professional life has become less of a mystery. I understand everyone’s role better; their concerns, why they show up in the morning, and where they are headed at the end of the day. There aren’t as many puzzles to be solved. I watch the more junior people make the same mistakes I made and hack the same lessons that I hacked. Sometimes I have to watch them and let them do their thing. I try and give them encouragement, but some things are just best learned through experience. It’s a weird feeling observing their struggles, one that I might have felt earlier had I not opted out of parenthood.

I feel more too. In my thirties everything had to be rational. It had to fit in place. It had to be just so. Now I look at my thoughts and have a much better sense of what is a reality-based idea backed by logic and what is a feeling. I have stopped calling my feelings “wrong ideas” and tossing them in the bad pile. Now I divide them between rational and irrational, and try to keep them sorted that way. I choose my words more carefully too. I don’t just “think” everything anymore. I think rational things, I feel non-rational things. I try and modulate my decisions accordingly. I try and bring more mindfulness to how my decisions make me feel. I don’t always get it right but sometimes I do. And sometimes the result is boring. I may be happier, but happy and well balanced feels tedious a lot of the time.

I don’t want forty. I want to kick it down the street a few decades. I like the hustle. I want to make big deals, found a successful company, and swim in an Olympic sized swimming pool of my own money. And I miss that undefined longing that felt like a low grade infection. I don’t want to give up on the idea that there is something bigger and better out there for me than I can possibly imagine. But I’m forty. Forty is big. Forty is heavy. It is a wall; a boulder so big that Moses or Jesus or the Big Sky Man Himself can’t move it. Forty is the reality that I am just another human being passing through this insignificant speck in a vast but impermanent universe on my way, soon, to shuffle off this mortal coil.

Are Millennials Being Helicopter Parented at Work?

If you listen to the buzz about the Millennial Generation, you will generally here the same story of how never before has such a brilliant and talented generation been given so little opportunity and such tough circumstances. Not that I believe it’s the Millennials themselves saying these things. Yes, Generation Y, the children born to the Reagan Era, got the shaft when they entered the workforce during the recession and general economic downturn, and that coupled with huge student loan debt really did give them a raw deal that wasn’t anything they had control over. It was just bad luck.

But the rest of the narrative, about these hyper-talented young adults that would be taking over the world but for annoying, lazy, and incompetent old people, doesn’t seem to be coming from the typical Millennial themselves, but rather from a few media and Internet famous pundits with rather loud voices, many of whom seem to have been born some time between 1950 and 1965; namely the Millennial’s Baby Boomer parents.

Here, I cite a specific example. An article on LinkeIn entitled, Why Millennials Keep Dumping You: An Open Letter to Management. Written in typical clickbait fashion, this bit of embellished fluff portends to enlighten us as to why the average, everyday, overachieving, and hyper-talented Millennial isn’t living up to their full potential at work. (Spoiler alert: It’s your fault.) The funny thing is, the author, a “sales leadership consultant” by the name of Lisa Earl McLeod, isn’t even a Millennial. She appears to have been born some time in the mid 1960s. In fact the whole piece appears to be cribbed from a conversation with her cum laude daughter and then pureed with a healthy dose of Baby Boomer, “The man is keeping us down,” rhetoric. The fact that the alleged informant’s LinkedIn profile is in no way associated with the article makes me believe that she is embarrassed by her mother’s drivel. I certainly would be.

The article itself seems to boil down to four, very false, unprofessional, and pretty dangerous statements about work:

  1. The people who sit next to me and do not perform according to my standards are preventing me from doing my best work, which is unimaginably awesome.
  2. Things like profit and revenue are boring. My job needs to define me and your key performance indicators do not fulfill my need for self-actualization
  3. Thanks for for the free lunch and the comfortable office, boss, but I hate how boring you are
  4. My boss’ job is to make me feel like I’m changing the world, which I was raised to believe is my destiny. In absence of validation of that belief, it’s perfectly reasonable for me to drink to excess in the evenings and throw a slow-burn tantrum that ends in an early departure from my current position

Obviously I’m paraphrasing, but the gut-fee I get from this article, and what I get from most of the buzz about Millennials, is narcissism and blaming other people for ones shortcomings. If so and so behaved better or did this or that or made me feel good, then I would do what I’m supposed to do, not what I’m actually doing. But are narcissism and deflecting blame unique to Millennials? I don’t think so.

What I’m actually hearing from the Millennials I know is different. Many of them reject this way of thinking altogether. And many of them are the victims of helicopter parenting, where they were constantly monitored and reassured that when things didn’t go their way, that it was a temporary setback and that they were still awesome, and ultimately, if they stuck to the program, they would still be more awesomer! I think many of them, as adults, are unhappy about their upbringing, and struggle with reconciling that message with the stark reality of adulthood, just like every other generation before them. Anyone fortunate enough to have had parents has eventually had to deprogram themselves.

But the pundit class will keep beating the drum. And right now the pundits the narrative are closer in age to the elder McLeod than the younger McLeod. They are concerned parents who can’t quite grok why their kids aren’t happy and why their parenting philosophy didn’t produce the outcome that they expected. The Millennial generation isn’t any better or worse than any other generation, and that drives their parents crazy. So now the late era Baby Boomers are extending the range of their helicopter parenting to the media. They take to the screens, on television and online, and complain about how their kids’ careers are being sabotaged by lazy coworkers and lackluster bosses, because the reality that their kid didn’t grow up to become a superstar, despite the unreasonable level of effort they put into engineering the perfect child, is more than they are yet able to accept.

Boycott San Francisco!

People love San Francisco. There’s the great food, the proximity to wine country, and a general lack of snow. San Francisco has a rich heritage of counter culture, dreamers, homosexual poets, hippies, hipsters, and yuppies. Yes, I said it: yuppies. Not that yuppies are inherently bad. Okay, yuppies are inherently bad, but having a few bad apples around helps remind you how good the good apples really are. Having a lot of bad apples, though, means that you just have a lot of bad apples.

I’ve lived in the Bay Area for almost 30 years, San Francisco for six, and never before have I seen things get so bad and desperate. In a time when most regional US economies are not producing enough jobs, the Bay Area seems to have done the opposite. We have overproduced jobs to the point where there is no more housing for all the people who are coming here to fill those jobs. It has gotten so bad that I have begun looking for jobs elsewhere, in places where it might snow even, because I cannot afford to live here anymore. But I can’t find jobs in tech, outside of the few core hubs, that pay a competitive salary or match my level of skills and seniority. What I do find on sites like Craigslist are companies posting in other regions ads that beg developers to COME TO SAN FRANCISCO.

Well, here’s a news flash for all those employers. About fifteen years ago broadband Internet became a thing for middle class consumers. You do not need to bring any more warm bodies into your offices to create synergy. Those warm coding bodies would be happy to take 80% of what you’re offering an on-site employee and quietly code at home in Denver or Minneapolis or damn near anywhere else you can think of. And they will be more efficient, because the last thing you ever want your software engineer doing when they’re hacking on your core product offering is worrying about the increasingly realistic possibility that they may be homeless while earning a low six-figure salary, because a low six figure salary will not pay for a modest apartment in San Francisco these days.

And if you’re a programmer on the outside of Babylon looking in, dreaming of taco trucks, cheap cabernet, and enlightened free spiritedness, think twice. The people who are making what elsewhere would be very generous salaries by moving here are subsidizing their lifestyles. They’re going into debt, living off of trust funds, or growing weed in their closet. No one here has a retirement fund.

Maybe this is where the VCs are. Maybe this is where the intellectual ferment of the digital age starts, but it doesn’t have to end at the edges of the Bay, or even at the city limits of (gasp) Oakland. You can take it home. You can tell that VC that you’re going to start your company in your home town and save tons of their capital in the process. You can create jobs in your community. And if all you want is a job, you can tell Robollox or whomever is poaching for talent in your community that you would love to join their development team and you’d be happy to fly in once a month for the requisite face time, but you would rather rot in Hades than to give all of what should be your discretionary income to a scum sucking absentee landlord in the most screwed up housing market in these United States of America. Please, take those companies jobs and money, but also, please don’t come here. There is nowhere to live here. There are people renting tents in their back yards for $1,000 a month. There are people renting those tents. You will pretend to have fun for a while even though you will have no time or money to enjoy this once fabulous city. Then you will get sick of all of it and leave. The actually fun people can’t afford to live here anymore. The ones left, the odd indigenous San Franciscan excepted, are the die hard core of uptight yuppie scum who enjoy the smell of their own farts and will pay infinite amounts of rent for the status of having the correct zip code.

Move here at your own peril. I recommend an all out boycott. San Francisco has ceased to be livable and no one can afford flowers to wear in their hair.