711 karma · joined February 3, 2012
The experience of working on Firebase at Google is vastly different from Parse at Facebook, and it shows in Google’s continued commitment to building and expanding Firebase, integrating it with its Cloud Platform products, and otherwise pouring huge amounts of effort into making Firebase great for developers. Open sourcing our SDKs gives us even more ways to engage with the developer community and allows us to be more transparent with the progress we’re making.
This announcement is just a first step down the path toward more transparency with our SDKs, but we hope to foster community and build trust in the tools we’re developing, and welcome your contributions!
I don't like the notion of applying the "first-world problem" dismissal to things that aren't trivialities. It's one thing to laugh about how you have to get up from the couch to get a remote. It's another thing entirely to talk about major changes to one's career, wiping away years of their work, or the loss of something they care deeply about as a "first-world problem".
Sure, getting acquired might be a "good problem to have", but it doesn't make its toll any less real.
We're encouraging developers to use this alongside social login (or as a replacement for building their own email/password-based login). Developers can avoid having to build and design large amounts of UX around login, registration, email/phone verification, password resets, etc. by adopting Hoomi, while still giving their users an alternative to social login.
We plan to add a number of compelling features for both users and developers. These will increase the value of a Hoomi account as well as the benefit of adding Hoomi login to your applications.
As for "Anonymous" login, that's Facebook's term for the service they promised (and we don't use it in our own description of the product for exactly the reasons you mentioned). We act as brokers between apps and users for their data, which includes an identifier that can be used for login. When an app chooses not to ask for personal data, we let the user know that we won't be sharing any of their information with the application.
As far as Persona goes, one of the major differences is the primacy of mobile as a medium for login. And while Persona focuses on using email addresses as identifiers, we go one step further than that, isolating users/apps into their own ID spaces that aren't tied to any particular existing identifier. As a result, a user can change their email address with us without disrupting their service or updating their applications (https://developer.mozilla.org/en-US/Persona/The_implementor_...), and users don't have to divulge this information if it's not necessary, as with apps that just use login for personalization.
We're rapidly building and adding features to Hoomi, and you can expect to see the benefits to users and develoeprs grow as we flesh out users' ability to create profiles for themselves that they can give their apps access to.
Since we're not a social network, we can avoid a lot of the risk and confusion about how to use the product without accidentally sharing too much information, and really focus on building a first-class identity product.
We're happy to answer questions if you have them. There's more to come, soon!
Since we're not a social network, we can avoid a lot of the risk and confusion about how to use the product without accidentally sharing too much information, and really focus on building a first-class identity product. We're happy to answer questions if you have them. There's more to come, soon!
Regardless, thanks for your feedback, and rest assured that more SDKs are coming in very short order. We're not just testing the waters with the Android SDK -- the SDKs for a variety of platforms are nearly complete and will be available soon.
Since we're not a social network, we can avoid a lot of the risk and confusion about how to use the product without accidentally sharing too much information, and really focus on building a first-class identity product.
We're happy to answer questions if you have them. There's more to come, soon!
A sonogram like the one in this app will confirm that the effect is physical and not just an illusion: https://play.google.com/store/apps/details?id=com.ntrack.tun...
Lest anyone think that barbershop is just for old folks: https://www.youtube.com/watch?v=XWmFfFx24zs (Vocal Spectrum, 2004 international collegiate quartet champions and 2006 international quartet champions)
Or just for Americans: https://www.youtube.com/watch?v=rFWhnOP_UVk (Ringmasters, 2012 international quartet champions, from Sweden) https://www.youtube.com/watch?v=T6HM-oLG_cI (Musical Island Boys, 2014 international quartet champions, from New Zealand)
Or always serious: https://www.youtube.com/watch?v=ihdtI0E_mmQ (Storm Front, 2010 International Quartet Champions and comedy quartet)
Or just for men: https://www.youtube.com/watch?v=tWqtFxW4kiE (LoveNotes, 2014 Sweet Adelines International Quartet Champions)
Or just for adults: https://www.youtube.com/watch?v=sREQu_AaUso (The Osmond Brothers... yup ;))
The principle is actually the same -- she is modifying her singing apparatus to emphasize different upper partials that are already in her voice. Barbershoppers do this as well, though less explicitly (we do vowel matching, which helps emphasize upper partials to produce greater ring).
Here's a video from a perennial favorite quartet (the Gas House Gang): https://www.youtube.com/watch?v=pvYT_yWiLqU The top/tenor note is often the same note as the primary overtone produced by the other 3 parts (adding further emphasis to the overtone), but this effect is what gives barbershop the quality of sounding like more than 4 voices, and produces the "ring" in the sound.
Listen for when the director sings the overtone note alone, then listen to the chorus as they produce it.
As this article points out, it's mathematically impossible to perfectly tune some of these intervals, but depending on the relationships between the notes being sung, you can tune to one singer or the other. It takes a lot of practice and a good ear, but the resulting effect is pretty darned cool.
Consistency of access in Java is also really problematic for the same reason. Which pair of getter/setter methods represents a reified property? This is often done by naming convention, that's usually, but not always consistent (getFoo/setFoo is common, but there's also isFoo/setFoo, isFoo/setIsFoo, foo()/foo(value), etc.). Worse (and this is something both Android's flavor of Java SDK and Objective-C have fallen prey to), not all properties are written symmetrically (e.g. getText() and the various setText() methods on an EditText in Android, although there are some where all of the setters are subclasses of the only getter -- even worse).
In my experience, pull requests just aren't the right tool for the job at the moment. That's not to say they don't have their place, but there are definitely superior tools out there.
Recently, I had to go through a full code review back on GH pull requests, and it felt like pulling teeth in comparison. They're fine for interacting with contributors to an open source project, but compared to working with a tool like Phabricator that's built for a code reviewer's workflow (and for teams of engineers working together on a project), they just don't hold a candle, in my opinion.
Here's where you're 100% correct: a subclass should not change the specified behavior of its superclass. To do so would be a violation of the contract established by its superclass's API.
This does not, however, apply to all use of subclassing. Rather, a superclass's API can be specified in such a way that subclasses may change behavior without breaking the contract. Dog and Animal fit this mold -- the Animal API may specify that Speak() will "cause the animal to speak", intentionally leaving this behavior up to subclassers. This is core to how subtyping-based polymorphism works -- the superclass underconstrains its API in order to allow subclasses to later tighten those constraints while still providing valid implementations of the superclass's contract.
Good API design requires that interface behaviors are properly constrained. Overconstrain them, and you box yourself (and consumers of the API) out of useful abstractions. Underconstrain them and it becomes impossible to work with the APIs because consumers of the API can't count on subclasses to have the proper behavior.
It's very, very easy to accidentally underconstrain an API, as you aptly pointed out. UIView does this with its subviews array. By exposing this mutable list, it broadcasts to its consumers a huge set of APIs that make promises they can't keep. If more thought had been put into how UIViews should be subclassed, they might have further constrained it so that (for example) a UIView is responsible for maintaining and keeping internally consistent its set of subviews. This is a promise that subclasses can keep (probably by not publicly exposing subviews at all, since making it public is likely to, again, result in underconstrained APIs and more API promises it can't keep), and assumptions that are useful for consumers of the API (e.g. "I don't have to worry about managing subviews that aren't explicitly called out in the contract" or "a layout container can't accidentally mess up its contents' subviews").
FWIW, XAML's UI framework does draw these types of distinctions, making _most_ of its subtyping sane (take a look at UIElement, FrameworkElement, Control, ContentControl, and Panel). Every now and then you can find examples where the abstractions are leaky due to under/overconstraining the APIs (e.g. the subtle differences between UserControl and ContentControl... UserControl looks like you could use it instead of ContentControl in most cases because the Content property is publicly settable and probably shouldn't be -- an API decision that every UserControl subclass has to live with and usually chooses to ignore).
Anyway, my point is this: subclassing is _not_, at its core, contradictory. But API designers _must_ design classes to be subclassed. In order to properly answer the "is X a Y?" question, subclassers must also be able to assert that X's implementation meets all of the constraints of Y's API.