Data denormalization is broken - <AUTHOR> https://hackernoon.com/data-denormalization-is-broken-7b697352f405#.cxyg11a3r <comment><USER2> I'm usually the guy arguing against microservices, but I think this is a good example of why they shine. It's much easier to manage the updating of these synthesized numbers if you have a discrete service that limits the things you can do at a higher level. So instead of worrying about who is updating the data store directly, you push it up to a higher service-level interface where you have a finite list of operations that are supported, and the scope is small enough that one architect can understand the system in its entirety and make smart decisions about how to compute/store/cache these synthesized data.

That said, if you have less than 10 engineers this shouldn't even be thinking about this. Way too many young engineers get hung up on scalability when they don't even have anything on the horizon that will require scaling. Couple that with a general ignorance of SQL because it's old and boring, and not realizing how much performance you can eke out of a well tuned RDBMS with proper schema and queries. A SQL DB is an incredible hedge against an uncertain future, keep your data tidy and you can keep pivoting until you find something you actually _have_ to scale.

<comment><USER3> Speaking of RDBMSes, you can achieve this "limited API" by just creating an RDBMS user with limited privileges (can query a subset of tables; can make changes through a fixed set of stored procedures.)

Personally, I never understood why everyone thought it was necessary to create HTTP API layers in front of every database, rather than just standardizing a public-Internet SQL wire-protocol between different RDBMSes and giving them all the ability to enforce per-user constraints on things like maximum query execution cost.

<comment><USER4> > I never understood why everyone thought it was necessary to create HTTP API > layers in front of every database

Mostly because you usually need to do some kind of logic that's either difficult or impossible to represent in SQL views or functions. For example, how would your SQL view access something like redis? or any kind of external cache? or an HTTP service? This is the kind of stuff that's pretty common in HTTP Controller functions, and would be a nightmare to move into the database.

(Note: I'm generally in favor of using SQL views/functions for data-facing logic, just, y'know, not a silver bullet.)

<comment><USER3> > For example, how would your SQL view access something like redis? or any > kind of external cache? or an HTTP service?

Smug comeback: [https://wiki.postgresql.org/wiki/Foreign_data_wrappers](https://wiki.postgresql.org/wiki/Foreign_data_wrappers)

But your point still stands; no _other_ RDBMS has those, so it can't really be an assumption.

Still, there is a mismatch of paradigms here. The people who built the RDBMSes assumed that everyone would _import_ data into them from wherever else. _You_ , the user (or you, the application developer) shouldn't need to query a third-party web service when doing your database query; something _else_ was supposed to do that query in expectation of your need, and shove the results _into_ the database, so you could just treat that data as another table of useful information to JOIN on.

People who front databases with web APIs tend to treat the database itself as a dumb store—one among many—that's supposed to quickly return "raw" data from single tables so that the _web service_ can chew it together with other data to compute answers to questions. But, by doing so, they're in effect _creating_ their own bespoke Database Management System: the web service becomes the thing that does efficient OnLine Analytical Processing of manifold backing datasets. (Or, at least, _attempts_ to.)

A DBMS's job is to ingest data and process queries to spit out answers. It's not your job; it's not your app's job; it's the DBMS's job. The DBMS has decades of optimization for that use-case; and in fact, that's the meaning of the word "database management system", when defined in opposition to a "flat- file database" like BDB or LevelDB. The fact that there's a _daemon_ sitting there between you and your databases allows the daemon to _index_ and _join_ and _expose views_ and _run checks_ and _enforce rules_ and on and on and on. It allows the daemon to do _asynchronous, streaming imports_ of data-sets from remote sources, so that its data is always up-to-date. It allows the daemon to be there for things like _crawler agents_ to dump their results into, rather than dumping them to something like an S3 bucket where _you_ later have to be the one to _import_ them in. In other words, being a daemon allows the DBMS to be the service that you just come to and _ask questions_ —arbitrarily-complex analytical queries—and get answers.

But that only works if the database management system itself is given access methods to all the _databases_ that contain the data to answer your question. And, in modern practice, we've essentially forgotten that that is a thing that we ever wanted to do. Who would teach a _database management system_ anything? Database connector libraries don't belong in DBMSes; they belong scattered throughout our toppling edifice of _RESTful API microservices_!

(And if you argue that we still need those RESTful APIs for things like browser-clients wanting to do queries using AJAX: there's no reason DBMSes—not just document stores but full-fledged OLAP DBMSes—can't speak HTTP as well. CouchDB is a great but strangely-unique example. Adapter gateways also exist, like PostgREST.)

</comment></comment></comment></comment><comment><USER5> Interestingly, this article reflects a really common misconception about database normalization:

 _The relational algebra that normal forms are expressed in has no concept of aggregate functions._

The example the article gives uses fields like numUnreadRooms or lastSeenTimestamp. These are derivable from the contents of other tables with SQL aggregates like COUNT() or MAX(), but the relational algebra itself would treat them as facts of the relation itself, dependent upon the primary key. And they'd be updated by the application itself.

In other words, _having numUnreadRooms or lastSeenTimestamp in your schema does not make it denormalized_.

I was under a similar misconception for the first 5-6 years of my career, and then when I realized that it's perfectly fine to store these aggregates inline, my database queries suddenly started performing acceptably.

As for how to update them - in non-broken databases, the solution is usually _triggers_. A trigger is a stored procedure that executes when a database operation makes some condition true, and then is executed entirely in the DB, with full transactional awareness. So you could listen for inserts and deletes and then update the count on them, and if your insert failed or the transaction was rolled back, your trigger would never be executed. This keeps data integrity in the database, but still gives you efficient queries and an application interface that's consistent.

<comment><USER6> Materialized views are a superior, or at least less error-prone alternative to triggers, since they don't depend on the programmer's ability to get state transitions right (whenever you manually update aggregates).

<comment><USER5> What's the performance characteristics of materialized views? My understanding is that they require running & storing the full query. For a SELECT COUNT(star) FROM TableName this is trivial, but if it's SELECT COUNT(star) FROM BigTableName WHERE ComplexWhereCondition it can get very expensive.

For the simple count/max aggregates on a single relation that the blog post is talking about, the trigger logic seems straightforward - you just need a trigger on a single table, for insert/delete/truncate, + update for max or if there are conditions. If there's more than one relation involved or if the condition is complex, then it can get pretty complicated.

<comment><USER6> > My understanding is that they require running & storing the full query.

This is right. Having a single materialized view containing nested queries is not a good idea. But you can factor out the nested queries into their own materialized views. The propagation of updates between materialized views can achieve an effect similar to that of complex triggers.

I should've been more careful with my original comment, though. I'm not saying triggers are worthless. But, whenever a materialized view can do the job, it's usually preferable.

</comment></comment></comment></comment><comment><USER7> TLDR: cache invalidation is hard, even if you don't call it cache invalidation.

More seriously there are plenty of ways to make this less painful, eg, adding a "lastMessageTime" to the Room table, which would reduce the work to a simple intersection of RoomUser and Room. Facebook uses a more complicated system involving "graph" relations and a global ID space, but it's more or less the same thing.

Also, "normalized" is not a binary thing. There are several levels from 1NF (flat file, fully denorm) on through 3NF and BCNF (what the SQL books usually call "normalized") on up to 4th, 5th, and 6th normal forms, some of which are academic party tricks but sometimes see use in production.

<comment><USER7> To add to this: every serious production system tends toward a slurry of 2NF-3NF-BCNF models, mostly for performance reasons. The case of lastMessageTime is a simpler one, as it might drift out of date but generally you get false positives but never a false negative. Note that people complain about Facebook message jewels showing up when there's nothing new but seldom complain about _not_ getting notified.

Another curious example is columnar databases. They are basically a 4NF storage layout with a veneer of 3NF syntax for ease of querying.

</comment></comment><comment><USER8> I don't think, as the article claims, data denormalization is broken. I think most programmer's knowledge of SQL is scrawny --- unexpectedly so for a language that's 30 years old and underpins most applications. SQL was obviously meant to be simple, almost declarative, and resembling plain-English sentences. And yet it's the first thing that developers abstract away with an Object Relational Mapping, much to their loss.

The article's example is one-to-one chat with millions of users. It says that counting unread messages is too slow unless you denormalize it.

First of all, the Rooms aren't a core table. If each Room has just two people, as the article says, then all you need is one table, messages:

        a  |   b   |        sent         |      body      |        read
      -----+</comment><comment>-+</comment><comment></comment><comment></comment><comment>---+</comment><comment></comment><comment>----+</comment><comment></comment><comment></comment><comment>---
       ed  | tom   | 09/29/2016 14:22:10 | Hi             | 09/30/2016 02:02:15
       tom | ed    | 09/30/2016 02:03:15 | What up?       | 09/30/2016 02:04:03
       sue | sally | 09/30/2016 08:19:20 | Catch ya later |

So the count of unread rooms is:

      select count(1) from (select distinct a from messages where b = :user and read is null) t;

If the columns are indexed, I would think PostgreSQL could handle such queries in a split second, even with millions of rows.

At Facebook's scale, where you have hundreds of millions of users, then you will have hundreds of billions or rows, maybe trillions. Okay, so it might start to get slow that this point. But let's stop for a second and remember that 99.999% of web applications will never reach Facebook's scale.

In Facebook's case, I read a long time ago that they make a database for each user. If so, the aforementioned table and query would still work --- in fact without the need for the b column.

<comment><USER9> I agree with most of what you said, but one thing bothers me:

> And yet [SQL]'s the first thing that developers abstract away with an Object > Relational Mapping, much to their loss.

I see that sentiment repeated often, but I really don't understand it. A decent ORM does two things:

1) It makes writing simple queries better – more maintainable, easier to compose, easier to secure against injection, smoother to write without constantly translating between your domain language and SQL.

2) It gets out of your way when you need to take the reins. If it is difficult to make your ORM run raw SQL queries and map the results back into domain models and primitives like array, hash, whatevs – it's time to find a better ORM.

For me and many decent devs I've worked with, an ORM is not about hiding SQL. It's about automating the simple, routine stuff and letting me focus on the important, complicated parts – including highly-optimized SQL queries, at times.

<comment><USER10> If someone's primary perspective of the database is through the lens of an OO graph, they will write code that performs abysmally. Graph navigation from row to row is antithetical to all the power relational algebra gives you. That's the biggest risk: viewing the DB primarily as an object store.

For the app I work on, the DB is only viewed as an object store for very small sets of data - configuration, specifically. It's impossible to map it to objects in any realistically performant way for our user's data, not least because that would require the data round-tripping through the application. It's much, much more efficient to execute my multi-million row updates and inserts on the database server directly rather than drag the data down to the app, tweak it slightly, then persist it back.

<comment><USER11> On the other hand, isn't that just a sign of a weak ORM? For example, in the platform I use, when I "fetch" some records by ID, it doesn't actually issue a SELECT; it just collects the ID and returns a proxy object. Only when I access an attribute of that object, it'll issue a SELECT for all the IDs in question.

One could extend that for more complex operations - instead of immediately executing the operations, it'd collect the operations and convert them into efficient queries. In a way, this is already done in "fluent interfaces" like LINQ, but with a more flexible language (Lisp?), I'm sure one could use standard control flow instead of a custom layer.

<comment><USER12> _> For example, in the platform I use, when I "fetch" some records by ID, it doesn't actually issue a SELECT; it just collects the ID and returns a proxy object. Only when I access an attribute of that object, it'll issue a SELECT for all the IDs in question._

I'm my opinion this is the least desirable behavior. It abstracts the data layer away to the point where you don't think about what's happening under the hood when you type foo = Klazz.new("id"); foo.bar; foo.baz;

Was that one, two or three separate queries ? Did a query run at all? Does it matter, after all you have an object to work on, right in your language of choice.

Sure the ORM may be smart about it and do the right thing - I have no doubt that most decent ones day. But that misses the point - as the person using this interface you get divorced from the direct awareness that this data has an origin, and there is a cost to access it. After all, you're just instantiating an object.

Patterns that use interfaces that make it so simple to do a thing that you don't need awareness that you're doing it tend to degrade quickly after the original engineers who _did_ have that understanding leave a project.

<comment><USER11> That's a fair point; on the other hand, aren't SQL queries themselves divorced from the actual data layer? Knowing whether the ORM issued one or two queries doesn't tell you if you're fetching data from disk or memory, whether it's making an index scan or full table scan, whether the join fits in working memory or will hit the disk, etc.

Isn't knowing what queries are issued giving you a false sense of knowledge about how the data is actually fetched?

And much the same way you can request a query plan, the ORM could provide the list of queries issued for a given piece of code.

</comment></comment></comment></comment></comment></comment><comment><USER13> So I'm doing a lot of academic reading around databases, and people have been thinking about this sort of thing for a while. Here's one approach:

> In this paper, we study the complementary approach, addressing index > maintenance as part of query processing using continuous physical > reorganization, i.e., cracking the database into manageable pieces. The > motivation is that by automatically organizing data the way users request > it, we can achieve fast access and the much desired self-organized behavior.

> The cracking approach is based on the hypothesis that index maintenance > should be a byproduct of query processing, not of updates. Each query is > interpreted not only as a request for a particular result set, but also as > an advice to crack the physical database store into smaller pieces.

[http://stratos.seas.harvard.edu/files/IKM_CIDR07.pdf](http://stratos.seas.harvard.edu/files/IKM_CIDR07.pdf)

The references are also pretty good.

edit:

Here's one more specifically about (de)normalization:

[http://stratos.seas.harvard.edu/publications/main-memory- ada...](http://stratos.seas.harvard.edu/publications/main-memory-adaptive- denormalization)

But it's much newer and lighter on info.

<comment><USER14> Interesting read, thank you.

Where can I track recent interesting papers in databases?

<comment><USER13> Unfortunately I'm as clueless on this as you - I'm mostly going on the papers that my professor suggests (cs165 and cs265 at harvard, the syllabus is public). Though VLDB and cidrdb seems like two conferences that seem to publish the most famous papers. Eventually you start learning the names of the authors, etc.

</comment></comment></comment><comment><USER15> Martin Kleppmann was presenting architectures that solve this problem:

[http://www.confluent.io/blog/turning-the-database-inside- out...](http://www.confluent.io/blog/turning-the-database-inside-out-with- apache-samza/)

[http://www.confluent.io/blog/bottled-water-real-time- integra...](http://www.confluent.io/blog/bottled-water-real-time-integration- of-postgresql-and-kafka/)

He does not just identify secondary indices and materialized views as possible candidates, but also other applications such as caching and search indexing as within the same class of problem.

Here, rather than trying to figure out a tradeoff between normalized and denormalized views, Samza and Kafka are used as the heart of what the above article was talking about as "generalized denormalization engine". It's done by capturing data change as a stream to incrementally build whatever denormalized view you want.

The downside is that this is still fairly clunky, if you have this expectation that this should be built into the database. Kleppmann's ideas breaks it out into a whole infrastructure to support that. On the other hand, if you do have a full time ops team, it sounds like it can work very well at scale.

</comment><comment><USER16> I skipped around a bit in the article, but didn't see them consider having database updates simply trigger a cache invalidation (i.e. set it null) of the denormalized data instead of doing a full recomputation every time the data changes. That way you only pay the price when you need it, and it still allows for caching. You can prewarm the cache with a cron while still allowing for ondemand calculation if the cache is cold.

<comment><USER17> I think TFA was more about "when to invalidate/recompute" than "how to invalidate/update" \-- that you need to take care to enumerate all of the times the denormalized value may get out of sync with the rest of the data.

(This is a reasonable idea though, depending on access patterns. Can increase latency, can decrease computation.)

</comment></comment><comment><USER18> I've been thinking about this a lot recently, and I'm convinced we need a Storm[1]-like architecture for databases. Something which would allow views / denormalization / indexing to run in separate processes. Preferably in the same language the app developers speak. And at the same time be part of the database transaction logic - triggered idempotently _by the database_ so you always see a consistent view of the data no matter how you update & query it. (You can do this efficiently with MVCC if you proxy queries through the indexer / denormalizer / view logic / whatever you want to call it).

I've scattered some more thoughts about this here, but its a big topic: [https://josephg.com/blog/composing- databases/](https://josephg.com/blog/composing-databases/)

[1] [http://storm.apache.org/](http://storm.apache.org/)

<comment><USER19> "triggered idempotently by the database so you always see a consistent view of the data no matter how you update & query it"

As I sit here trying to build the thing in my head that would do that, I see some major performance issues arising. Specifying how you want the data denormalized isn't that big a deal. Taking a frozen normalized database and denormalizing it according to that spec is a somewhat bigger deal; the performance implications are non-obvious because the denormalization can invoke arbitrary amounts of data in arbitrary combinations in arbitrary orders, even _before_ we let the denormalization specification be Turing complete. Mathematically it all works but if in practice my denormalization pass is randomly accessing huge swathes of the database every time I insert a row that's not going to work very well.

If we're trying to avoid slow queries when the user asks for data, and we're trying to denormalize in advance, we're basically trying to have our already- presumably-pretty-busy database pre-emptively _guess_ all possible slow queries it _might_ run in the future, and run them now.

And then run them again when a small change comes in, having possibly never used the first set of denormalized, expensive queries I just ran.

That seems... likely to generate performance problems, to understate my case by a lot. Even accounting for possible efficiencies the denormalizer might be able to take advantage of; there's still the bound of what has to be written out.

OK, so that doesn't really work. But it doesn't need to; the database could do this more lazily. But, doing it fully lazily is just the same as the case where you use the normalized data, so we can't do it fully lazily. Somehow the database needs to figure out what it should and should not precompute. Well, that doesn't sound like _that_ big a deal, right? No, it's a nightmare to even begin to specify what that might be, in the face of full Turing chaos. I can almost see how one might try to apply some basic "learning" algorithms to the task of pre-computing things partially, but it's getting pretty complicated in the backend there. There's an awful lot of symbolic computation there where I really want things to just be computing for performance.

Furthermore, if one insists on consistency in the denormalized fields... yeow, that's complicated. Again, it's not hard to specify the math but making it happen would be crazy insane. Oh, and I don't mean _distributed_ consistency... I mean even consistency on a single busy host is going to be a challenge. A feasible challenge, certainly, but a challenge that shouldn't be ignored.

It seems to me there might be a use case for this to be a bullet-point feature for a database, for developers to very, very carefully use on very high-use fields. But it wouldn't be very hard for a real-world denormalization engine to become a performance nightmare. Or to end up taking more "index tuning" to be usable engine than the code we already have.

<comment><USER18> When an update happens the trick is going to be figuring out an update mechanism for the derived data without needing to run more queries. You're probably right - in the general case thats really hard to do automatically. But lots of aggregate values can be calculated based on an update without reference to the original set. `SUM()` and `MEAN()` are easy. `MAX()` and `MEDIAN()` are hard. In the case of the notification count query from blog post, you can do that efficiently with 3 map reduces:

1\. Given a list of `(message, room, timestamp)` triples, generate `(room, max(timestamp))` tuples. In general max is expensive to calculate, but in this case the message collection is immutable, and the rule to update max(timestamp) when an edit happens doesn't need any extra processing based on an insert.

2\. Given `(room, message_timestamp, read_timestamp)` generate `(room, message_timestamp > read_timestamp)`. Easy.

3\. Then a reduce to calculate the sum.

One of the things I really like about the multi-process architecture is the diversity of solutions we should have access to here. Right now your data lives in one vendor's system. Its really hard to use a map-reduce job if your primary data store doesn't support it. And map reduces might be too complicated for simple workloads - so with small data sets you might want something simpler. With this architecture different vendors could provide different indexing systems and you could swap them out as your requirements / data size changes.

Finally as for consistency, I've got a bunch of ideas of different ways to make it work. Its not so bad because its not a generic graph or consensus problem. Its just a DAG. You can give each primary store a unique name and version using vector clocks. (If each primary store is itself distributed thats fine - just use whatever versioning system the primary store uses as the value for that database in the vector clock.) Then when a query comes in that needs to hit both an index and a primary store, pick the most recent database version and query asking for the result set at that version. You'll need some MVCC to make it work - but thats a solvable problem. If the named version is too new for the index, the query stalls until the index sees the corresponding update from the primary store. If the version is too old (and its expired out of the MVCC working set) then we punt back to whatever is running the query and it retries. The whole system is much simpler than a distributed consensus problem because each node in the DAG can be thought of as authoritative, even if they're individually implemented as a small redundant set.

</comment></comment></comment><comment><USER20> If I've understood correctly, it feels like what the author wants is a DSL for event-driven FRP[0]. If so, I'm 100% on board. It's something I've wanted for a long time.

I've found it easy enough to implement a naive version. The tricky part, unsurprisingly, is making it performant.

[0] [https://en.wikipedia.org/wiki/Functional_reactive_programmin...](https://en.wikipedia.org/wiki/Functional_reactive_programming)

<comment><USER21> Author here. Yep, I basically want my database to be a giant Excel spreadsheet that includes formula cells (a.k.a. denormalized fields).

</comment></comment><comment><USER22> To some degree, this looks like premature optimization. That query (on the normalized tables), with the proper indexes and decent hardware, should be plenty fast, even with millions of rows. I would potentially start my optimization by considering if messages could be 'archived' to other tables or considering how long I could cache the query results vs. how often the client would poll.

I've seen small-medium sized systems go way overboard with complicated mechanisms for handling performance problems that they don't, and may never, have.

<comment><USER23> So I agree, premature optimization can often not be necessary.

But let's be crazy for a minute. How much CPU/RAM/disk IO does that query on normalized tables end up using? How much electricity does that query use?

Maybe from a pure efficiency perspective, it takes less energy to query the pre-computed value, than to constantly be recalculating it on every query.

<comment><USER24> Craziness comes later. Usually few years after several developers added not normalized tables, and it all grew organically with multiple apps depending on the data.

When it comes to rdbms shema, you want it optimized and enforced from day one, or the price paid later will be significant.

</comment></comment></comment><comment><USER25> One technique that can be useful is imposing domain-specific restrictions, then passing responsibility down the chain.

For example, most people only have a handful of recent conversations; can you get away with ignoring distant-past conversations when it comes to read/unread marking? If so, you could send recent normalized data to the frontend and let it derive the unread state client-side. React has some nice tools for efficiently deriving state from server-sent data.

This isn't always the best solution, but it's something to consider.

<comment><USER26> Unless the amount of data you need to transmit is large, I always prefer that approach as it enables other UI features without any additional network trips by the client. Also, it lets one use the same mechanism for multiple uses (in this case, get latest messages), so it adds less complexity to the app.

In the articles example application, you can transmit the top X oldest messages after the last seen timestamp for each room, then have the client derive the unreadness of each room. You then can use that same info to do things like preview the oldest unread message for each room and hide latency when opening a room as you already have a screens worth of messages in hand. One doesn't need to get more recent messages as UIs generally don't have room to display large numbers and should switch to a "lots" indicator.

<comment><USER27> Sure, denormalize working storage in the app, fight to keep the "system of record" / "operational data store" clean.

</comment></comment></comment><comment><USER28> Smart people already have developed general solutions to this problem- This problem is the main reason "graph queries" were independently invented by both Facebook and Netflix.

See here for an exact solution to the problem posed in OP, using the OmNext graph query language: [https://github.com/omcljs/om/wiki/Components,-Identity-&-Nor...](https://github.com/omcljs/om/wiki/Components,-Identity-&-Normalization)

<comment><USER29> "Smart people already have developed general solutions to this problem"

Yes, they did, 50 years ago :) The article behind link refers to several- decades-old concepts of identity and normalization. That was not invented by Facebook or Netflix.

</comment></comment><comment><USER27> META:

When did we all start saying "performant", instead of "fast [enough]"? Was it about 5 years ago??? _Maybe_ 10?

English, like SQL, is passe`.

<comment><USER30> I hate the word performant. People may argue that "fast" is a simpleton of a word, however "performant" is ambiguous as to what characteristic is performing well.

</comment></comment><comment><USER31> I can see why the normalized approach is difficult to make performant, but it seems much simpler.

<comment><USER32> Broadly: Normalised data is more performant on _write_ , because for each piece of state, there will be one and _only_ one place to store it.

It's less performant on _read_ because you are constructing logical deductions out of a lattice of tiny pebbles of truth. It takes time to find, filter, sort and project those.

Denormalisation "works" by skipping to a read-optimised schema for those applications where reads greatly outnumber writes. Which is very many.

As an aside, "denormalised" doesn't have to mean "unstructured chaos". Do As Thou Wilt isn't necessarily the law of denormalising. There are well-studied, widely-used denormalisation techniques under the heading of "dimensional modelling".

It's just that most of these discussions are dominated by web folk, not data warehouse folk.

The shoutout to Event Sourcing is promising, given the interaction with the CQRS pattern. In short: read schema and write schema have different demand and performance characteristics. _So split them up_.

<comment><USER33> I don't know that you can always conclude that normalized data is more performant for writes.

Take for example the case where your normalized write consists of 5 insert statements into 5 tables, instead of 1 insert into 1 table that you'd do with a denormalized write.

<comment><USER32> As always, consult your doctor, accountant, lawyer and profiler.

</comment></comment></comment></comment><comment><USER34> What we need to solve this is a cell aggregation dependency function in the database.

Where we define a column and a query that will be used to define the values in the cells of the column. The database would use its planer to figure out what the dependency's are and update the cell every time one of the dependencys are changed.

That dependency thing is very complex but very necessary. If you dont have it you might as well just make a normal view.

<comment><USER21> Author here. Yep, I think you're getting to the heart of what characterizes a "denormalization engine".

</comment></comment><comment><USER35> What are the tradeoffs of making the data denormalization happen in database triggers? Fundamentally, you want to update certain fields whenever certain other fields get changed, and that's exactly what database triggers do. I'm not enough of a database wizard to know if there's good reasons why this isn't more popular, though.

<comment><USER36> Too many people argue "code doesn't belong in the database", but honestly, with everyone circling around to FRP it honestly makes me think maybe stored procedures and database triggers are going to make a comeback again. I never really bought into the whole "but you can't version stored procedures!" bit because that's precisely what schemas and the search path in PostgreSQL are for (triggers are another matter entirely, but I avoid those whenever possible - though it's exactly what I would use for a task like this).

<comment><USER37> Triggers are synchronous and is not much different than the application updating this value when the underlying data is updated, except for the reliability that always when the data is updated the trigger will for sure fire.

Postgres triggers are row by row so depending on your use cases they can be quite slow.

Ideally I'd cache all these values and invalidate the global cache through the application. This would require one set of services or each set of services managing their own cache. Anytime a room is updated, boot and reload the cache for that room.

Let the db stay normalized.

</comment></comment></comment><comment><USER6> There's a lot of confusion in this article. The author doesn't seem to be able to distinguish the logical view of data (in which we distinguish between primitive and derived data) from its physical representation (in which derived data may be physically stored redundantly for efficiency reasons).

</comment><comment><USER38> ProxySQL has a mirroring feature that can act like a trigger on a separate thread: [https://github.com/sysown/proxysql/blob/master/doc/mirroring...](https://github.com/sysown/proxysql/blob/master/doc/mirroring.md#rewrite- mirror-query-only) Add a cronjob to refresh results if you are worried about skews over time. Problem solved.

</comment><comment><USER39> I identify with the problems this article eloquently describes. I think GraphQL could be a first piece of the solution.

<comment><USER21> I'm a fan of GraphQL, but that's like saying "object-oriented programming is the solution to people leaving variables on the heap after they go out of scope". No, the solution is managed memory. OOP is a higher level of abstraction that happens to work better with managed memory.

See the analogy?

</comment></comment><comment><USER14> One way to solve this particular problem of "number of unread rooms" is not to persist it in database at all. Send push notifications of new messages and have client app to compute it client-side.

</comment><comment><USER40> Wasn't this essentially what CouchDB did?

</comment><comment><USER41> Can someone explain why you wouldn't use a "read_at" flag on the message entity in this example?

<comment><USER42> which User read the Message?

</comment></comment><comment><USER43> Yup, that's the job!

</comment><comment><USER44> I very much enjoyed reading this article, it explains a lot of the pain and calls out a lot of the current broken designs.

While the conclusions are correct, I feel like they could be simplified. If you try to use the vocabulary of the broken system you will get complicated phrases like "denormalization engines" (which I very much hope does not catch on despite agreeing with it).

Instead, if you look at correct systems - like Elm, Rx, Datomic.com , or [https://github.com/amark/gun](https://github.com/amark/gun) (my own, obviously I am biased) you get less complicated ideas:

\- Event Driven. \- Data Streams. \- Data Flow. \- Data Pipeline. \- Reactive Programming.

All of these, despite "FRP" itself being jargony, solve the majority of the article's complaints. Largely because the solution he comes to at the end is the same thing as FRP.

Don't we wish we had all listened to Alan Kay now?</comment>


Ask HN: Offer of Employment retracted - <AUTHOR> I was offered a Senior RoR dev position at a 50-ppl funded and revenue-generating bay area company last week. I accepted, signed, and was excited to join this company. Subsequently I gave my two-week notice at my current job (not in the bay area). They have started my exit process here.
This afternoon I got a call from the HR that they are retracting my offer as "circumstances have changed and they are eliminating the position". I am literally shocked as I have a perfectly good, well-paying job at a Fortune 500 company where I've worked for 5+ yrs that I resigned from to join this small company.
What is my recourse in this situation? I was told by the Engineering Manager in this company that I got two thumbs up from all the interviewers and they were looking forward to me joining. He even sent me tech documents to go over a couple days ago.
I don't know what to do. Not only does this affect my employment situation but also my immigration situation. Not having a job impacts my ability to stay in the US.
I can't go back to my current team now as it will not only look ridiculous but my commitment will be questioned as well.
Please advise. I'm just really distressed and upset right now. <comment><USER4> Talk to a lawyer and ask what "detrimental reliance" means. (Short version: what you just did owing to representation that they had a job for you. Comes with damages.)

Let your old company tell you you can't have your job back, don't make that decision for them.

<comment><AUTHOR> I don't want to make a decision for my current company. They may even let me have it back. I'm on very good terms with my team too and they were in fact, disappointed to see me go.

I'd just hate myself to go back with my head hung in shame telling them that 'oh my job didn't work out'...take me back. I had a farewell lunch yesterday. Everyone in my extended team knows I'm leaving. My exit interview is planned for early next week and they're processing my final paystubs.

I can't believe this level of unprofessionalism exists.

<comment><USER5> _I had a farewell lunch yesterday._

Make a joke of it. If you get your job back, take all the same people out to lunch. Play up the funny side. Give a "take me back" speech, "what was I thinking" etc etc.

Laugh at yourself, and the world with laugh with you. With your immigration status at stake, this is not the time to stand on some misplaced ego thing.

<comment><USER6> Better yet, who cares? Take your chances and apply to YC. This must be your calling.

<comment><USER7> Did you miss the part about OP's immigration status?

</comment></comment></comment></comment></comment><comment><USER8> Posterous is hiring, and we love Ruby on Rails. Let me know if you'd like to talk. Perhaps we can make lemonade from these lemons. <http://posterous.com/jobs>

<comment><AUTHOR> Sent you an email. Thanks for reaching out.

<comment><USER8> Awesome, we will be in touch!

</comment></comment></comment><comment><USER9> That really really sucks. This happens, fortunately not frequently. I take it you have copies of all the documents and the preceding correspondence as well.

First order of battle is to be candid with your current employer to see if you can get your old job back, you may have to promise them not to leave within the next six months or so, conversely you can expect to be let go at any moment.

Think of it as a stopgap measure.

Next stop after that is the office of a lawyer specializing in HR affairs.

Don't worry too much about looking ridiculous, you would look a lot more ridiculous losing your dwelling or having no food on the table.

Pride is a virtue but fairly useless at this point in time.

</comment><comment><USER10> I've been a hiring manager for hundreds of programmers over the years at several companies. With the exception of maybe one or two people I was preparing to get rid of anyway, if any one of the people who quit came back during their notice period with this story I would insist that they stay and fight fiercely with any other forces in the company that might resist it. It also wouldn't lower my esteem for the person. I'd be happy that he or she felt that he or she could come back. I _have_ been happy when they've come back. It's never been as soon as this, but I've had people leave to try startups or other jobs and had them not work out. The good ones leave to try things sometimes. I'm happy to be good enough that when it sometimes doesn't work out, even though it is a time to consider many options, they elect to come back.

<comment><USER11> I think that it also depends on what terms people are leaving. It's one thing to say you're leaving because you're starting a company and another thing because you're sick of writing mundane database/web applications, using Waterfall instead of Agile etc. or even worse because almost everything is a mess.

<comment><USER10> It's certainly the case that if they're leaving because they're unhappy that something is true and it is still going to be true when they consider returning it would give me pause. :-)

Even then, it might be possible to convince me if they come back with a reason they were wrong and think the thing is good (e.g. I tried Agile and discovered it isn't better, and my actual problem was this...) rather than just, "I decided to put up with it here..."

</comment></comment></comment><comment><USER12> You should absolutely let it be known who this company is. If you're uncomfortable do it anonymously. Rescinding an offer after a candidate has quit an existing job is shameful and anyone doing it should be outed for all potential candidates to know of.

Don't be embarrassed about asking for your old job back.

And ask the 50 person company to reimburse you - they should pay you for the trouble they've caused. If they're not complete idiots they should agree to at least a month's worth of salary, possibly more. Have them do it as a consulting fee if they're not comfortable phrasing it as damages for their rescinded offer.

<comment><USER13> _You should absolutely let it be known who this company is. If you're uncomfortable do it anonymously. Rescinding an offer after a candidate has quit an existing job is shameful and anyone doing it should be outed for all potential candidates to know of._

What if a major funding event had fallen through, and the company rescinding all outstanding offers and cutting expenses allows half of those 50 employees to retain their jobs for another month? Truth is, you have no idea what's going on at that company. These decisions _usually_ aren't made lightly. I say this as someone that's been in the exact same position in the past. Move on, holding a grudge will only hurt the OP.

<comment><USER14> This exact situation happened with me prior to starting my current position. Let me tell a short story.

I received a formal offer from the new organization, gave my notice at the previous employer and closed out my projects, and made plans to spend a couple of weeks having a proper several-years-delayed honeymoon with my wife, and then a week visiting family and getting my head ready for the new role. As I was waiting to board the plane to visit my family, I saw on the news that the organization I was joining (government-funded) got a surprise during a weekend political negotiating session, and had their budget for the remainder of the year slashed by a ridiculous amount. This hit them hard enough that they were already talking about furloughs and layoffs to the media, and had an all-hands meeting about the issue scheduled.

By the time the plane landed, I had voicemail waiting for me from the fellow who was going to be my new boss; as soon as _he_ heard what was happening, he immediately started asking his superiors about outstanding offers, and was informed in no uncertain terms that already-issued offers were being honored (but obviously, no new offers would be issued), and he made sure I understood that he was available for any questions I might have. I, along with everyone else in the organization, experienced rolling furloughs for the next few quarters, and a round of voluntary layoffs and additional emergency funding finally helped them make it through until the next budget cycle.

That is precisely how you handle a situation like this: you honor your obligations, and preferably do so proactively, and with a keen eye to how you are impacting people who have placed their trust in you and your organization.

Reneging on your obligations, especially in a situation as nuanced as the posters' (a suggestion to simply "move on" is much easier said than done when you're on an H1B), is the definition of unprofessionalism, and is a direct reflection on them as businesspeople. While I don't recommend he "out" them because of how it might reflect on him later in his career, I'd be lying if I said there wasn't a little voice of schadenfreude in the back of my mind hoping he lets their name slip.

</comment></comment></comment><comment><USER15> This happened to me at Google pre-ipo:( You are out of luck. In California job positions are at-will... I'd most likely go back to your old company, look for another one or just start a new company.

I know a few good Bay Area companies that are hiring if you are interested...

<comment><USER16> You mind sharing the details of your story?

</comment></comment><comment><USER17> Might not have the taste any longer to join another startup, but Justin.tv is hiring engineers and if you want to continue on to move to the Bay Area you should check us out. /shameless plug

In any case remember tomorrow is another day and surely things will work out.

</comment><comment><USER18> One thing I would do is figure out whether they got some information about you that made them not want to bring you on or whether some disruptive event happened at the company. If there some information or misinformation out there that would cause someone to rescind a job offer, it's very important that you know about it.

Beyond that, it seems like you should find a job at another company or try to get your old job back. A lawsuit seems really complicated and unlikely to get much for you.

<comment><USER19> It's a nice idea and worth asking but many employers are loathed to give critical feedback these days for fear of being sued (and even more so if they rescinded the offer and so the individual might have a case for damages)

</comment></comment><comment><USER20> Hi joboffer,

I'm an engineer at comparably-sized RoR based company in SF, and we are looking for more people to join the team. If you'd like, please get in touch: email@example.com

I'd be interested in hearing about your goals and filling you in on the engineering culture here.

<comment><AUTHOR> Emailed you.

</comment></comment><comment><USER21> +1 more for trying to get your job back. When I left my corporatey job of 5+ years to join a 10 person startup in August 2008 as I walked out the door on my last day the CEO said something I'll never forget - "If you ever need a job, just call me." Total class. If you've done good work for someone and they aren't morons, of course they will want you back whether it's a year in the future or a week :)

</comment><comment><USER22> The startup has committed what is known legally as "Promissory estoppel", basically a broken promise. In general they are liable for any reasonable expenses that you have incurred with the assumption that they would keep the promise. If for example you had already moved to the bay area, you could file a lawsuit to recover the cost of the move and the cost of moving back.

If you do want to get any monetary compensation from the company, I would suggest bypassing the recruiter and speaking with a founder or executive at the company directly. Hopefully they will be motivated to do the "right thing", and they will certainly have an interest in preserving their reputation.

<comment><USER23> Good faith is usually an adequate defense to that, otherwise changing circumstances of any kind, in any situation would turn into legal liabilities universally, which is clearly untenable.

</comment></comment><comment><USER24> We're hiring, email us: email@example.com

<comment><USER25> i know working for the man isn't popular around these parts, but if someone is looking for a programming job in DC let me know. Its a govt job but I love working here. Lots of freedom to work on projects that you want.

<comment><USER11> Government job for aliens?!

<comment><USER26> Based on the parent comment's username, I'm going to guess it's the X-Files.

JD-Beast? Government alien jobs? Something spooky is happening in D.C.

</comment></comment></comment></comment><comment><USER27> This exact thing happened to someone I know. He got a call right as he was leaving his old job on his last day. The guy said something along the same lines - due to changing circumstances, the original position we were offering you has been eliminated. The guy was flabbergasted, of course, but just ended up going back to the old company anyway. I'm pretty sure if you want, you can get your job back. Unless you were leaving on bad terms or there's something more to the situation.

To make it a little easier, you can just join another team at the same company instead. That way it's a little less awkward.

</comment><comment><USER28> You really need to out the company that did this. If not for revenge, do it so that they can't screw anyone else over in a similar situation.

<comment><USER9> No, sorry he should not do that. His situation is precarious enough as it is, he should play his cards _very_ carefully and not do anything rash or out of revenge.

</comment></comment><comment><USER29> Stick your tail between your legs and ask for your old job back. - Like the old man always says: "It's best not to burn bridges".

<comment><USER30> Ask for the old job back... but explain the situation, it doesn't sound like there's any reason you need to 'stick your tail between your legs'.

</comment></comment><comment><USER31> Name and shame the buggers.

<comment><USER32> As much as I share this sentiment, I'd advise against it.

They were very unprofessional and left you in the lurch, but that's not a reason for you to hit the blogs and start throwing mud.

In a few years this company may not even be around any more, but naming and shaming with posts and comments on the net will be around long after this is all a distant memory and that will reflect very badly on you wrt future employers.

<comment><USER33> I see it differently, personally my allegiance lies with other developers, it is why I was respected even when I was in executive management. Personally, I would feel that it is my responsibility to not let this happen to other developers. Further it is not his responsibility to hid the actions of the wrong. They where in the wrong not him, he should not have to protect their reputation for fear of reprisal by some future employer. I would hire him if he named the name of the company because it is not his duty to protect and cover up their actions.

This is certainly a different case than airing a companies dirty laundry and creating a whinny bitch fest just because you are unhappy with a company for log hours, mismanagement or something similar. In this case a company showed a clear disregard for their actions.

Further outing the company would make this post real in my mind. Color me skeptical, but we all know that there is a lot of back room crap that goes on with getting low wage immigrants in to fill positions. They go to great lengths to do so. It would not at all surprise me if they are AstroTurf'ing boards to scare existing visa holders into "staying put" (HN would be a good place with our visa holder community). I would not put it past them and this is just the kind of post that would do so. So with some real facts the story becomes more credible until then I will remain at least partially skeptical.

</comment></comment></comment><comment><USER34> People quit jobs all the time. For you, this is a big deal because you don't quit jobs all that often. I suggest that you explain to your employer what happened, and ask for your current job back. Chances are they will be happy to have you back.

<comment><USER9> For him it is a big deal because his residence status depends on his employment.

</comment></comment><comment><USER35> > Stick to your existing employer. This event might be > embarrassing but > everyone will get over it.

I agree. Once a company has made the offer, it's not illegal to withdraw it, but it certainly shows a lack of organization and a scummy level of honesty. Next time you want to jump, have the new company pay for moving costs and immigration lawyer fees up front. That should stop them being such jerks again.

</comment><comment><USER36> If you have the job offer back from them, with their signature on it as well your own, then I would also recommend outing the offending company... That is probably one bridge you can afford to burn - and current and future employees of the company all will probably see the information as valuable.

If you never got a signed copy of the job offer, then I would think your options are fairly limited.

Best of luck, either way.

</comment><comment><USER37> For a start, you could publicize the name of the faithless company and give them some bad press (and prevent others here at HN from potentially encountering the same problem).

</comment><comment><USER38> I don't know the situation in the US (I'm from Israel) and frankly last time I was employee of someone others company was 8 years ago. But several times I was hired before it was like this:

* If you know a person who hiring you - you shake a hand and consider it done (you sign employment, NDA and stock options contracts on the first days of your work).

* Otherwise you don't give a notice at your current place of work, until you sign a contract. Contract specify a mutual notice period, which can be somewhere from 2 weeks to 2 months. Usually it's 1 month. Once both sides signed the contracts, even if they don't hire you at the end - they owe you the notice period salary.

Going to lawyers is never a good solution - better to explain to them your situation and ask for some compensation.

</comment><comment><USER39> I have seen something similar happen to a co-worker who was starting at the same time as me at a new job. When he was hired, he was promised a management position with a higher salary than other developers, including myself. After working at the company for a couple of weeks, the company said they did not need him as a manager and wanted to reduce his salary to be the same as other developers. The guy ended up going back to his old company and getting his old job back because he was not willing to drop his salary requirement at the new job.

</comment><comment><USER40> If possible, could you post the name of the company that "hired" you, maybe let others know so they'll think twice before joining that company?

Hopefully your old company will take you back!

</comment><comment><USER41> The first startup I worked at made an offer to a summer intern to start the following summer (after graduation). Then the economy went south and they had to do a layoff. So in this case, they had to retract the offer. But they gave the guy 1 or 2 months severance pay--same as they gave all the employees that got laid off. I thought they handled that pretty well. And we wound up hiring him a few years later when we were growing again.

</comment><comment><USER42> There is some great advice already here. But here are a few things to ponder: 1\. I say good riddance. Better not to be working at this place. 2\. More importantly, things could have been worse for your immigration status if you would have joined this company and they would have eliminated your position then. Now you at least have the option of going back to your current employer without any hassle of visa transfers.

</comment><comment><USER43> I can find you a position in less than a week. I work as an independent contractor doing sourcing for a consultant recruiter. We are currently hiring for several positions that your background would fit nicely with. Yammer, Turn, Inc., and Chomp, are all companies looking for top talent like you. Some of the companies we're hiring for relocate, some of them are down with telecommuting, all of them have no problem helping immigrant geniuses stay in the states. We find geeks their dream jobs, as my boss and I are both geeks ourselves, we just haven't yet learned to manipulate space and time with code like the people on this site have. You can find my LinkedIn profile @<http://www.linkedin.com/pub/stephen-adams/2/212/839>, or you can contact me direct at email@example.com. No matter what, keep your head up and know that with your background there's no reason to get discouraged about your job prospects in this market.

</comment><comment><AUTHOR> Thanks everyone for your supportive and helpful comments. I had interest from another company when I accepted from this company that rescinded the offer. I am following up with them to see if they're still interested.

I am also getting in touch with some of you who are hiring. The problem is I have very little time to go back and make amends at my existing job - <USER2> tomorrow.

This will be a long night...

<comment><USER44> Depending on what sort of VISA you are on, I think it's most likely H1B, You are fine. Don't worry so much. You have a 30 days window to find employment in the US. If you found something else in the next few days, you can effectively start working for the company with on the day you send in your new H1B transfer documents.

I'm not a lawyer but I know this from past experience.

</comment></comment><comment><USER45> Step one find something physical to do to burn off the stress.

After that, come back and read all of the great advice here.

I would go back to your boss, and say, "Hey I guess the offer really was too good to be true. Do you know of any openings at the company, and smile? Can I start Monday?"

Let's hope that works. As for SF I am not even a RoR developer and I get an email/phone call once a week looking for someone. So if you don't get your job back list SF as your home, and plan a trip out here. You should be able to line up 5-10 interviews during a 2 week trip.

You probably want to look at companies that are large enough to have HR and to cover relocation expenses.

I know that <http://www.castlighthealth.com/> is hiring RoR developers, and pays well. My roommate seems to be pretty happy there.

Good Luck, and remember that the engineering manager at that other company liked you, and may change companies at any time. Heck if this happens enough to him, he might be looking for a new job right away. Don't burn bridges.

</comment><comment><USER46> At my former employer (small one, ~80 employees) we had a similar situation. One of engineers left the company (with good-bye lunch and all) and showed up back 2 weeks later. I don't know what happened (we weren't close enough for me to ask just like that), and it was a basis for jokes for couple of weeks or so.

But after a month everybody almost forgot about it.

</comment><comment><USER47> I just wrote the following, but it doesn't really take into account your immigration status. That's tricky.

I don't agree with the prevailing sentiment. Obviously you left for a reason, and that reason still exists. It _would_ look ridiculous to go back.

I'm sure you'll get a few interviews out of this thread, and if you're good, a new job. There's always risk changing jobs.

For an entrepreneurial crowd, it seems everyone here is forgetting that it's risky to pursue something you want. I left a well paying job were I was liked and performed well to go to a start up who is still paying me by the hour. They even changed the start date a couple times after I already gave notice -- it was flaky behavior, and I told some people at my old job about it before I left. They looked at me like I was crazy, but I wanted the new challenge. I wanted to develop a product from the ground up, and if the new job hadn't panned out, I would have found a way to be OK.

</comment><comment><USER48> Almost the exact same thing happened to me about a year ago. Follow the advice of making a joke of it and keeping your current job. Don't waste your money on a lawyer. Almost every job offer is written with language indicating that it is by no means a contract and is merely an offer of employment which can be rescinded at any time.

</comment><comment> Be-The-Water Is there another side to this story, why did you quit your job in the first place? Was the other job that much better?

I agree if it is a time constraint thing you have no choice in approaching your prior company. But if not I would keep looking for something that fills your need, like the Posterous post you will learn a lot more than just RoR.

Good Luck!

</comment><comment><USER49> You should certainly have all your paperwork ready to take to an immigration lawyer specializing in employment cases. This is probably going to cost you several thousand dollars - sorry.

If you don't already have one because your current employer took care of that when you came, then hire one - even if you keep your current job, you should not assume the matter is resolved. Even if your current employer says they'll take care of the paperwork (or that no problem exists because you had not left before this happened), you triggered the situation and it's your visa which may be affected, so it's ultimately your responsibility to make sure it's cleared up. Your employer's attorney is paid to think about your employer's legal position, and may not be current or even conversant with handling such cases for individual immigrants.

Start looking for an attorney with the American Immigration Lawyer's Association, and talk to a few before you commit to an appointment - <USER3> they have experience in this area, and consider asking for references. You should also check with your employer about who their attorneys are, if only to avoid an accidental conflict of interest if they use an outside firm and you happen to call the same one! <http://www.ailalawyer.com/>

Technically your authorization to stay expires the day after you leave your current employer, although it may take months to process the paperwork. If they will take you back, that would of course be the best outcome. Put your request in the form of a letter and keep a copy for yourself. It should probably state honest credible reasons why you wanted to develop your career elsewhere (beyond mere $$$), and obviously it should be respectful and acknowledge what they've done for you in the past. Again, your attorney may have valuable input. Even if your boss senses something in your body language and asks you, then says you'd be welcome back, tell him you'd like to make a formal written request - much better to generate paperwork now which an immigration administrator can examine and approve at some future date, than to have a confusing absence of paperwork about the situation if your employer's records are inspected in the future.

As the company that let you down was smaller, it is possible they did not have experience with the immigration paperwork, and backed out for that reason - the rules are complex and are adjusted frequently. Do find out if they have already filed anything on your behalf or not. It might actually make your life simpler if they haven't, because generally the responsibility to straighten out any administrative oddities is yours, not the government's. Sometimes I read of people being placed in removal proceedings because of trivial errors or contradictions in their file that were not noticed or acted on until years later. There's no certainty of the HR manager or even the company in the Bay Area still being around in the future, so an abandoned or canceled application might come back to haunt you long after the firm had forgotten the whole episode. Whether paperwork was filed or not, get the answer from the Bay Area company _in writing_ \- indeed, it may be better to let the immigration attorney do that for you, since s/he will know exactly what information to request/confirm.

If your existing employer decides not to take you back, you _may_ be able to file for a temporary extension of your visa called an I-539 because of the unusual circumstances, which will cost at least $300 in filing fees. Again, you need to consult an attorney who specializes in this area, who might suggest a quite different strategy. I mention it only as an obvious possibility - do _not_ rely on this information!

I'm not an attorney, let alone an immigration attorney, nor am I qualified to give you any kind of legal advice. I just want to explain why it is so important for you to get professional help even though it will cost you some money.

Immigration matters have the potential to cause problems for you or a family member in unexpected ways because immigration law is complex and the usual assumptions about rights and obligations do not apply - your legal relationship with the US govt. as a non-citizen is _entirely_ different from that of a citizen. A regular employment attorney is not a good choice, and they would likely refer you to an immigration attorney anyway - at least, they should.

Also, the internet is a very poor source of information not just on legal matters in general, but immigration in particular - some people with a dislike of immigrants hang out on Q&A websites to give out deliberately misleading advice or abuse people who ask. After spending a good part of this summer in a law library, I'm horrified at how much misinformation is floating about. Hire a pro - much cheaper to fix it now than later.

Sort out the immigration end first, and worry about recovering damages later.

</comment><comment><USER50> [Removed bad advice about portraying this as a change of mind rather than a rescinded job offer to his current employer]

Talk to the manager at your current company and tell him that you want your job back or at least a longer notice period. They probably won't mind having you around to do more knowledge transfer for a few more weeks and look for another job.

Meanwhile, consider what patio11 said. IANAL and employment offers often have a clause saying something about how they are non-binding etc, but I am not sure how enforceable those terms are. You may indeed have a case.

Separately, start applying for jobs elsewhere. RoR is a valuable skill and fresh from a successful (although unfortunate) interview, you are well placed to ace more interviews.

Good luck!

<comment><USER51> Bad advice, no need to lie about the situation.

<comment><USER50> Upon reconsideration, yes this was bad advice. When I read he is on a "work visa" and in a bad situation due to job transfer problems, I automatically assumed he was dealing with the worst kind of employers waiting to exploit him. Clearly this is not the case most of the time.

So agreed, if he works for a good manager / employer, it is better to be forthright.

I rescind my advice.

<comment><USER9> Classy.

</comment></comment></comment></comment><comment><USER52> From my point of view as a business owner, if they haven't replaced you already, your old employer would likely welcome you back with open arms. Good people are hard to find - and ones that know all your systems and eccentricities are even harder to find. The biggest headache in hiring someone is getting them up to speed and integrated into your company culture. This is way more time and energy consuming than you might think. So if I was you old employer I would bring you back - the only headache would be if I had replaced you already or promoted one of your old co-workers. At a Fortune 500 company they should be able to find some parallel position at least for you.

</comment><comment><USER53> I agree with everyone else: try to get your old job back. Throw away the 'it will look ridiculous' idea - none of this will matter in a couple of months.

If they were disappointed to see you go, they will welcome your return.

As another person who has had a similar experience before, and whose immigration status is tied to employment, I can imagine how distressing this must be[1]. I hope the general outpouring of support on HN eases your mind a bit! Think it through clearly and move on.

1: In fact, I'm pretty much in the same situation as you were: accepted an offer with a bay area company and undergoing the visa process, and this post does give me pause. I'll respect your decision to not name names though.

</comment><comment><USER54> I'm sorry this happened to you, but you should realize it is a normal part of startup life. Don't take it personally.

I would guess your potential employers are as unhappy about the situation as you are. It's no fun to lay people off or rescind a job offer. It sucks almost as much as being on the receiving end.

If you want to work in a startup again, don't hire a lawyer, and don't make a huge deal out of it. There's only a miniscule chance you'll recover anything significant, and you will certainly incur ill will.

If job stability is very important to you, then you should probably stay away from smaller startups, where positions (and paychecks) can be very unstable.

</comment><comment><USER55> Don't worry so much about the "they will hate me" or "my team won't trust me" angle unless you know that to be a fact. Most people understand that business is business, management or not, and if you're a solid employee that your team could use they're not going to be pissed that you got a better offer and accepted. They'll just be happy to have you back so they don't have to replace you.

I like the "make a joke of it" angle, but if you can't pull that off you really should be fine with just being honest about what happened, assuming you work with decent human beings. Story seemed reasonable enough to me.

</comment><comment><USER56> I'll play devil's advocate and ask-- so if they just fired him on the 2nd day of work, it would have been kosher and everyone would go home happy? Where do you draw the line when there's no employment contract?

</comment><comment><USER57> So sorry to hear this. I don't know how the work situation is in the US, but here in Norway it's quite common to get positions, even the really good ones, thrown after you if you have the right resume.

Sit down and think what you want to do. If the position you were offered was the dream job; locate a similar company and send them your resume. Or even better, the best people is reading this very post. Put up a link to your resume right here, and see what'll happen. Couldn't hurt(?).

</comment><comment><USER58> I am a recruiter representing a few Ruby driven companies in SF. They can handle VISAs for the right people. If you want send me your resume and I can see if we can move fast. I have recruited 20 years and I have never had a company I worked for pull the Visa unless they had a serious layoff. Feel free to reach out to me on linkedin. <http://www.linkedin.com/in/markgentry/>

</comment><comment><USER59> See if you can go back to your job, hopefully earlier than later (as in, e-mail your boss if you have not already and tell him you have an important matter to discuss). It's probably best of the HR side of the house does not get too far along. That, or, you can respond to one of the many individuals that said they were hiring (I'm not sure how much time you have/how much time you can be without a job, in general).

Good luck and keep us posted.

</comment><comment><USER60> If you're good, I'm sure they'll take you back. The cost of hiring and ramping a new employee to replace you is much higher than the cost of bringing you back.

</comment><comment><USER61> I agree with everyone else: try to get your old job back. If they're professionals (and you didn't burn any bridges), then they should realize that it was nothing personal when you looked for other employment.

True, they may question your loyalty in the future, but if they like you, then they will probably be relieved that you're staying. They might even try to address whatever it was that made you look elsewhere to begin with...

</comment><comment><USER62> How is your relationship with your former boss?

When I switched jobs, my boss left me on leave for two months in case I changed my mind.

</comment><comment><USER16> What I would like to know is what is the name of this company that would hire then rescind immediately.

</comment><comment><USER63> Wildfire is hiring Ruby developers as well. Would love to chat with you about this. Apply here: [http://wildfireapp.jobscore.com/jobs/wildfireapp/ruby- develo...](http://wildfireapp.jobscore.com/jobs/wildfireapp/ruby- developer/da0N00BDOr34uTeJe4bk1X)

</comment><comment><USER58> I represent a company in California that needs top ruby people. Send me a resume and let me see what we can do. We can move fast for the right person. I also know other companies in SF that need Ruby guys if you are good there are opportunities out here.

</comment><comment><USER64> >my commitment will be questioned as well

Why? If they laid you off and then said "oh, we found the money and we need you to stay" would you doubt their commitment more? It should be the same before as after. We work to make money, you didn't marry this company.

</comment><comment><USER65> I doubt your current company will have any issues with you retracting your resignation, it costs them more to hire a new employee/train them up and so on, so just go and speak to them I'd imagine they'd be happy for you to stay

</comment><comment><USER66> 1\. Start looking. 2\. Explain to your manager your reasons for leaving and what actually happened. 3\. Tell the new company that you are politely calling out their name. And see what they think.

</comment><comment><USER67> Wow, I talked to a recruiter for startups and we're in the process of something similar. I too am risking my status in the states by switching.

So...anyone need a Django + front-end dev on a project basis?

</comment><comment><USER68> We're hiring a Rails backend developer too, working on dome really fun and social games on the iPhone. I'm guessing you 're not from the bay area and we're located in Pittsburgh PA.

</comment><comment><USER69> I know that you'll look ridiculous when you get back to your old job (if you did). But trust me, it's a lot better than staying JOBLESS especially in this economy.

<comment><USER9> Especially if it means being kicked out of the country. Being jobless is only a part of the problem here.

</comment></comment><comment> jeffrey-change Use your powers for something good. We're hiring:

<http://www.change.org/jobs_at_change#ruby-hacker>

</comment><comment><USER70> joboffer: CrowdFlower is hiring senior Ruby on Rails devs. I'd love to talk to you about your goals if you have time. Drop me a line email@example.com

</comment><comment><USER71> I agree with everyone here. Ask for you old job back, they should understand. If all works out, please blog about the experience in more detail...

</comment><comment><USER72>
        I can't go back to my current team now as it will not only look ridiculous

You need eat a humble pie and stick with the current team.

</comment><comment><USER73> there's no reason why you have to tell your current employer that your offer was retracted. tell them you've given the new job a second thought and that you feel that belong where you are.

you can't sue in this situation because i'm sure somewhere inside the offer letter it says the new job/company has the ability to terminate employment at will.

</comment><comment><USER74> Ya it's a pretty dick move, especially given your immigration situation. I'd out em... politely.

</comment><comment><USER75> I know ChallengePost is looking for a Sr Rails developer in NYC if you're up for relocation.

</comment><comment><USER76> Its just awesome to see people randomly offer to help. Speaks volumes of the people here !

Bravo Bravo

</comment><comment><USER77> Cultivating a thicker skin would be wise. Would you leave the US because you're embarrassed to go back to your old job?

Possibly if you're at a large enough company, you might be able to split the difference and find a job at another team within the same company...

</comment><comment> charlesju<AUTHOR>
Please email me ASAP, we're in desperate need of more RoR engineers.

<comment><AUTHOR> Your email isn't in the bio. Could you please reply with it?

</comment></comment><comment><USER79> After talking to a lawyer, burn the company. Post here and on a blog and email TC. Assholes should be called out, and fucking with someone's life like this is indefensible, doubly so when he or she has visa requirements. Remember in the US, truth is a defense to libel. And you're doing this not for yourself, but for karma, helping all the future employees this company will screw over.

Finally, if you want an sf area rails job, contact scribd -- I literally can't imagine them treating an employee this way. And some of the other big rails shops too; I can't give you an exhaustive list, but maybe start with hashrocket (this isn't a rec, I just know the name), pivotal (in the bay area, have a cool product we use at work), etc.

gl

<comment><USER80> It may be satisfying to, as you suggest, "burn" the company; but it's also unprofessional. Granted, the startup that rescinded the job offer was behaving unprofessionally, and may even be civilly liable for it's actions, but that does does not mean that you should respond in kind.

<comment><USER81> Huh? Why would he want to subject anyone else to the same thing he was subjected to? By not naming them, he just screws over the next guy.

<comment><USER82> +1

A rescinded job offer is a big deal, particularly given the guy's immigration status. I assume this was discussed and that he'd need to transfer his H1B. The company by then would've known he had handed in his notice and any HR person should know this potentially triggers immigration issues.

Name them and shame them I say.

Like you say, this may indicate the company is in trouble financially so any existing employees and potential applicants should be aware of this.

</comment></comment></comment></comment><comment><USER83> I know it is ridiculous but with your immigration status at stake, don't think of all these. Just go and talk to your current boss.

Also, once you get your job back, send [http://t1.gstatic.com/images?q=tbn:yR0N5a0R8puacM:http://www...](http://t1.gstatic.com/images?q=tbn:yR0N5a0R8puacM:http://www.biffbang.de/_myspace/fuck- you-guys.jpg&t=1) to the company who retracted the offer.

<comment><USER9> > send > [http://t1.gstatic.com/images?q=tbn:yR0N5a0R8puacM:http://www...](http://t1.gstatic.com/images?q=tbn:yR0N5a0R8puacM:http://www..). > to the company who retracted the offer.

That would be extremely unwise. If there is _one_ take home lesson from all of this, it is that you _NEVER_ burn your bridges, no matter what.

It's a small world, and you just might have to rely on that person you gave the finger last week tomorrow.

Spectacularly bad advice this.</comment></comment>


Generating Spherical Distance Fields from Polygons - <AUTHOR> http://experilous.com/1/blog/post/generating-spherical-distance-fields-from-polygons

<comment><USER2> This reminds me of the GPU technique to generate Voronoi diagrams by rendering conical geometry... And, sure enough, it looks like someone else already thought of using cones to generate distance fields:

[http://gamma.cs.unc.edu/DIFI/Sud-EG04-DiFi- Presentation.pdf](http://gamma.cs.unc.edu/DIFI/Sud-EG04-DiFi-Presentation.pdf)

The technique in the article is similar, but uses brightness and the minimum blending operator instead of depth -- which has the advantage that you can use it to generate distance fields over surfaces other than the plane, which is pretty cool.</comment>


Tablet Shipments To Grow 69.8% - <AUTHOR> http://techcrunch.com/2013/04/04/gartner-2012-2017-devices-forecast/

<comment><AUTHOR> What do others say about Ipad alternatives? Thinking about buysing one!</comment>


The Arctic is ablaze: Peat fires are the latest symptom of climate change - <AUTHOR> https://www.economist.com/europe/2019/08/01/the-arctic-is-ablaze <comment><USER2> Everyday we read a new story about how changes are accelerating, and none of these changes are accounted for in any of the traditionally accepted climate models.

I think it's time admit that the climate models that we've been relying on aren't accurately modeling the changes that are taking place.

I remember reading about models in the 80's and 90's that started showing significant change starting to take place in the early 2020's, which means we are running ahead of even those aggressive models. Sort of a hockey stick curve of changes. What I remember about those aggressive models is that things got bad real quick, like 2050 quick and real bad like stuff that the normal models didn't think would happen for a 3 or four hundred years bad.

Those more aggressive models just faded away because no one believed that things could change so quickly. Back in the day most scientists thought it was crazy to think that the permafrost would ever thaw on a large scale, let alone start burning on a massive scale.

Right now everyone is operating on the belief that we can slow the rate of climate change, but the earth and the climate are now locked in a number of positive feedback loops, warming oceans, phytoplankton population crashes, thawing permafrost, thawing glaciers, ocean salinity drops, seal level rise. These systems and feedback loops are much bigger that the fraction of change proposed by the Paris agreement, and usually feedback loops don't stop until resources are exhausted or the loop breaks. These loops have a massive amount of resources and they aren't going to stop anytime, nor be impacted but our minuscule proposed changes.

I think the learned climate scientists need to start scouring paper archives to start looking for those more aggressive models because it's clear the assumptions the current models use are badly flawed.</comment>


Robots playing angry birds - <AUTHOR> http://techcrunch.com/2011/05/06/click-here-if-youve-never-seen-a-robot-play-angry-birds-before-videos/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+Techcrunch+%28TechCrunch%29&utm_content=Google+Feedfetcher

<comment><USER2> Wow. Such a cool project and really, brilliant advertising.

I love how in the Making Of video, the second guy says, "The most difficult part of this project was to actually play through all the levels and get 3 stars." I don't feel so bad about my scores now.

</comment><comment><USER3> That is some amazing stuff. I never knew visual recondition technology has advanced so far!</comment>


The woman behind the Netflix Culture Doc - <AUTHOR> http://firstround.com/article/The-woman-behind-the-Netflix-Culture-doc <comment><USER2> Great insights! Definitely need more of these!</comment>


Show HN: Laravel 4 - This framework is revolutionizing PHP. - <AUTHOR> http://laravel.com/four <comment><USER2> I don't know why everyone it is so excited about this framework. I've had a quick look over the documentation a few months ago, when there was this hype around _this new kid from the block_ thinking that there must be something really interesting.

I stopped reading the minute I saw they are using a template engine for rendering the views. I simply don't get it. Why would someone use a separate template engine when PHP itself is a very good one to use ? Why to add an extra layer to the app ?

We don't have to recreate anything, the views should be pure PHP, not code written in some <insert template engine name here> that is then translated to PHP.

<comment><USER3> It is stated in Laravel's homepage that you can use either native PHP or Blade in your views

<comment><USER2> hmm...so in the docs they say about pure php views, but in the quick start guide they mention only about blade. since this is what I read, this has to be the cause for letting me believe the only way you can create views is with the template included in the framework.

</comment></comment></comment><comment><USER4> I used Laravel for a small project for the past couple months. Although I started web development in PHP, I am strictly a Ruby/Rails developer right now and I have to say working in Laravel felt very natural and right at home. I'm not saying that being Rails-like is merit in it's own right, but I had that same feeling with Laravel as I did when I first started using Rails. I'd highly recommend trying this framework and hope with more projects we can see some solid documentation grow.

<comment><USER5> The way I see it is that the problem with Laravel is it's core — PHP. If you want to use Rails-like framework — use Rails and you get Ruby for free!

</comment></comment><comment><USER6> I was heavy on CodeIgniter before and ever since I launched another website with Laravel I don't feel like going back to CI. In fact if I get time I wanted to relaunch my other sites with Laravel. If you closely follow the MVC frameworks and the way they are moving forward Laravel sounds like right on the track which CI lags big time. Give it a serious try and you will know. I got completely hooked with its robust Routing system.

</comment><comment><USER7> Very glad to see this on the front page. This is by far the best PHP framework out there. It still blows me away what it is capable of.

<comment><USER8> Hi, I'm currently a heavy codeigniter user, looking for a switch. Can you please give me some of these examples you speak of that blow you away? Thank you.

<comment><USER9> one that got me was in a controller you can:

         return Model::Find('asdf=1');

and it outputs a json serialized array as html. so your ajax action is like one line of code, yay. or you can $row = Model::Find('asdf=1'); and manipulate in php from there.

<http://www.youtube.com/watch?v=QSt9rBa_oUM> this guys series on laravel is really good.

<comment><USER10> > and it outputs a json serialized array as html

Actually, it renders a raw JSON response - a single object of 'unguarded' attributes (all by default) for the model with Content-Type: application/json set. It has nothing to do with HTML.

Your syntax is invalid too. To do what you want you'd actually call

        return Model::where('asdf', 1)->first();

</comment></comment></comment></comment><comment><USER11> Great work by Taylor and everyone else involved. PHP hasn't seen a framework quite like this before and it's refreshing using it.

</comment><comment><USER12> Such an awesome framework, many great features, fills in voids left by it's predecessors.

</comment><comment><USER13> Really sorry to say this, but my eyes hurt from the text contrast. Maybe you should consider changing the font size?

<comment><USER14> I'm pretty sure it would be fixed by changing the CSS font-weight directive; Lato is a great font, but they need to use 400 weight as normal, not 300, unless they're going to bump the font size up. (Personally I'd also darken the text color just a little, but it becomes surprisingly readable just by changing the weight with the Chrome/Safari CSS inspector.)

</comment></comment><comment><USER15> A new podcast on Laravel: <http://laravel.io/>

</comment><comment><AUTHOR> I don't get why this was removed from the front-page?

<comment><USER7> Kinda lame... Not sure why either.

</comment></comment><comment><USER16> > Just got four times better...

How?

<comment><USER8> I think its some sort of pun to the fact that it's Laravel "4"

</comment></comment><comment><USER17> congrats, L4 team!

</comment><comment><USER18> what's so revolutionizing about it?

<comment><USER19> Nothing. They use the word "artisan" which makes me think it's made for hipsters rather than programmers. Almost everything is static, libraries are named like "Illuminate" and "Elloquent", it's as if an art student has worked out how to write static classes.

<comment><USER20> The naming conventions are a bit pretentious, sure but it's being all static is apparently not so clear cut: [https://tutsplus.com/lesson/when-they-say- laravel-shouldnt-u...](https://tutsplus.com/lesson/when-they-say-laravel- shouldnt-use-static-methods/)

</comment></comment></comment><comment><USER21> "CodeIgniter is dead" - Phil Sturgeon</comment>


Ask HN: What are some fundamental principles to make a product successful? - <AUTHOR> I can think off one: A successful product solve's a genuine problem of a customer.<p>Besides that what are some principles that should always be followed? <comment><USER2> So I live in Jakarta and bike at the weekends. Theres this little stall that sells coconut water close to my house and I stop there on the way home.

They source and deliver the best coconuts they can find in the early morning, and spend the next few hours cracking them open to fulfil previously booked orders. People like me also come in to bring some home.

By 11am every morning, without fail, they are out of stock. They pack up and go home. Its a very successful business for them, and they have scaled to the point where they aren't bothered scaling further. Their coconut water is the best, they are orders of magnitude more successful than other stalls in the neighbourhood.

I asked the woman who ran the shop one day what her secret was. She said "Harus Murah! Harus Enak!". "It has to be cheap! it has to taste amazing!".

I run a tech startup but I swear this is still the best advice on product management Ive received.

\- Make something that solves a concrete need in a spectacular way (tastes great)

\- Make the difference between the price users pay and the value they receive huge (cheap)

Combined, you've created a proposition thats impossible to turn down.

</comment><comment><USER3> It might be obvious to state this, but I would say it again: Customer.

Define the customer first (who would use/buy this) before making a product.

</comment><comment><USER4> Solve a genuine problem of a customer (as you mentioned)

Be simple to install and use. Also Integrate easily..

</comment><comment><USER5> Use as many meaningless buzzwords as possible.</comment>


Can You Read People's Emotions? - <AUTHOR> http://marojejian.tumblr.com/post/64501763289/can-you-read-peoples-emotions <comment><USER2> It seems inappropriate to me to link to some random Tumblr rather than going straight to the NY Times article ([http://well.blogs.nytimes.com/2013/10/03/well-quiz-the- mind-...](http://well.blogs.nytimes.com/2013/10/03/well-quiz-the-mind-behind- the-eyes)) it in turn links to.

<comment><USER3> I rarely do this but I flagged the post for that very own reason. That Tumblr blog doesn't even attempt to add any value to the NYT story at all.

</comment></comment><comment><USER4> I score 33/36 on this test and very highly on others like it, yet I consider myself pretty rubbish at reading people's emotions. Still pictures are very different to real life - here, I can rely on pure technical understanding trained by years of being obsessed with art (looking for eye creases, angles of eyebrows, and imitating the expression in my head), without the distraction of people saying things in direct conflict with the range of things briefly written on their face.

I suppose it's a works-in-a-test-setting trainable sort of thing. Thanks, comics!

<comment><USER5> " I score 33/36 on this test.....I consider myself pretty rubbish at reading people's emotions."

ditto and ditto

I failed on 20, 23 and 29

It might be interesting if there was a pattern to this?

</comment></comment><comment><USER6> By the middle of the test I couldn't stop thinking that I was being played. I thought that at the end there would be a paragraph informing me that in fact most people in the pictures had a neutral expression and that if I got an answer right it was because that was the emotion most people taking the test before me judged that person to have.

There is potential for a study about prejudice there.

</comment><comment><USER7> Interesting though such tests would be better if each question is not marked as correct or not after each answer. The feedback from positives and negatives will have an impact upon the following questions.

Shan't say how low my score was but I scrolled up looked at picture and then scrolled up some more for options to find my response was not even in the selected replies, though many had related alternatives. Like the look like they are thinking "meh" which could also be bored or uniterested. But I'm clearly far from even close to average, let alone an expert on such matters and with that, what do I know. Though I do wonder if I got a few like minded people we could by process of elimination get the right answer for each from the options we did not pick. Least I do wonder.

</comment><comment><USER8> Simon Baron Cohen also did the AQ test, which is about ASD traits.

([http://www.wired.com/wired/archive/9.12/aqtest.html](http://www.wired.com/wired/archive/9.12/aqtest.html))

I score 41 on the AQ test, and 31 on the guess-the-emotion test. Some of them I knew; others I pulled the face which triggered memories; others I eliminated obviously wrong answers to get the correct answer.

</comment><comment><USER9> Why does this link to a tumblr and not direct to the NY Times?

<comment><USER10> Because some blogspammer wants the hits.

</comment></comment><comment><USER11> Hmm, the one I consistently misidentify is 'interested.'

That actually might explain a lot...

<comment><USER12> Context is everything. They're looking at me? Can't be interested, must be something else.

</comment></comment><comment><USER13> 34/36 and I was 50/50 on both of the 2 that I missed.

This is about what I expected. I'm very good at reading people in real-life situations.

I also can informally "keep score" of what battles people have won and lost in a team environment and very, very informally, without people realizing it, make small deals where people win the battles they want where the other side loses battles they don't care much about.

I don't talk about it much, but I suffered some abuse as a child and it may have been a learned behavior from being quite in tune with what is about to set someone off.

</comment><comment><USER14> Well, that was interesting. I learned some new words for emotions I didn't knew about (aghast, defiant, despondent). Some of these don't even translate to my language, I wonder how much culture affects tests like these?

</comment><comment><USER15> One thing that helps me is to imitate the expression and try to feel what _I_ feel when I'm doing it. Not always right, but sometimes I go from not having a clue to being sure.

</comment><comment><USER16> I made a bad score,22, but people tell me I am really good at reading emotions.

I never fix myself in a static moment, but I follow the movements like dancing. I also tend to match them while sensing their language.

Using just images is a very incomplete way of looking at this.

</comment><comment><USER17> 33/35\. I have social anxiety. Would not be surprised because I can read others emotions. Sometimes knowing the emotions of those around you can be very overwhelming.

</comment><comment><USER18> 32/36 after getting my score the only question I had was: "what is the probability that I can read people's emotion correctly ?"

</comment><comment><USER19> I did a lot better than I expected, given that I'm a bit of an antisocial nerd. (27/36)

</comment><comment><USER10> 31/36\. The darkest photos were the hardest to gauge. I'm a reclusive programmer that likes to hang out with people. And I have an interest in body language...

Regretful, doubtful, friendly, defiant, interested. That's quite the emotional spread.

<comment><USER20> What does it mean to be reclusive but like to hang out with people?

<comment><USER10> I enjoy being alone for most of my waking hours, although sometimes I might feel like hanging out with people - but it must be on my terms and for no more than a few hours. Then I need to go back to being alone.</comment></comment></comment>


Sun to Switch Nasdaq Ticker Symbol to JAVA - <AUTHOR> http://www.thestreet.com/s/sun-to-switch-symbol-to-java/newsanalysis/techhardware/10376053.htmlpuc=googlefi <comment><USER2> This reminds me of the last two sentences of "How Software Companies Die."

[http://www.apocalypse.org/pub/u/kjc/cool/Card.on.Software.ht...](http://www.apocalypse.org/pub/u/kjc/cool/Card.on.Software.html)

</comment><comment><USER3> Will changing the ticker to JAVA help Sun shake off it's dinosaur persona? hmmmmm

</comment><comment><USER4> That's sad. They don't even realize they're hitching their cart to a lame horse. Sun has some smart people working there...how does this come to pass?

</comment><comment><AUTHOR> Brand problem much?</comment>


Show HN: Sketch Gallery – Share how you solve problems by sketching - <AUTHOR> https://gallery.sketchboard.me Sketch Gallery shows public boards from https://sketchboard.me where you can sketch using a sketch style, rather than corporate documentation style to emphasise your idea, not how it looks. <comment><AUTHOR> Sketch Gallery shows public boards from [https://sketchboard.me](https://sketchboard.me) where you can sketch using a sketch style, rather than corporate documentation style to emphasise your idea, not how it looks.</comment>