Yeah, I'll be trying out Go for Android. Give me an excuse to learn Go. Still don't like the idea of going without generics and exceptions, but maybe it'll surprise me. I figure we're all just biding our time until Rust is ready.
Yeah, I'll be trying out Go for Android. Give me an excuse to learn Go. Still don't like the idea of going without generics and exceptions, but maybe it'll surprise me. I figure we're all just biding our time until Rust is ready.
https://github.com/rust-lang/rust/wiki/Doc-building-for-andr...
More recently:
https://mail.mozilla.org/pipermail/rust-dev/2014-June/010323...
While I did jokingly say "Serious UI Toolkit", there's more than a few awesome applications on Android that have very, very simple UI widget requirements. Particularly games, which according to the article, they're focusing on.
Who is "he"? The poster michael was replying to said s/he was waiting for Rust to be viable.
That's a ridiculous assertion.
It isn't integrated, and as they note as one of the gaps, doesn't currently support CGO (meaning you can't compile C code or libraries in with your Go executable), but it has worked quite well for some time.
I'm pretty sure that was contributed by Samsung.
val, err := error_prone()
if err != nil {
return nil, err
}
let val = try!(error_prone());
Personally, I find that error handling isn't that bad in go. I think it's at least no worse than exceptions. Exceptions make it too easy, for me at least, to just mindlessly propagate the error. Sometimes that's the right thing to do, but in go it's a lot less repulsive to handle the error since to propagate the error you would need handling code anyway.Rust strikes a nice balance. You have to explicitly handle every error, but if you go with the by far most common handling code, you get some nice sugar that makes it mostly painless.
Part of the problem with Java exceptions is too many people feel obliged to catch exceptions, when they should be propagated.
Ideally, the only catches would be in the top-level loops (request / response dispatch for server, event loop for GUI, arguments for command-line).
Wrapping exceptions as they bubble up is only helpful if the wrapped exception adds context that aids in diagnosing the issue. Otherwise it's just boilerplate that obfuscates and gives a certain type of developer warm fuzzies. "Exposing implementation" is a non-counterargument - the component failed because its implementation preconditions were violated, you need to address those implementation preconditions to fix the problem!
You don't need to import dependencies unless you intend to catch the specific originally thrown exceptions, and that's not normally what happens in the top loop; it normally logs, dumps or transmits the exception message and possibly its stack trace. These operations are normally only rely on the base exception type, so there's no need to catch a more specific exception.
Problem languages for this approach, though, are C++ (where the culture makes a single base class for exceptions awkward) and Java (where throws clauses, a deeply misguided feature, may force dependency imports unless you specify 'throws Exception' - or my preference, wrap in RuntimeException).
PS: I should add the other fundamental problem with the Java throws clause is that it uses static types to analyze dynamic data flow in a language with polymorphism, which makes it a usability disaster. When the code being invoked is indirectly accessed via polymorphic references, exception flow checking falls apart. There's a reason Google Guava's Function and Predicate interfaces don't throw. But that's enough of my bugbears.
The "finally" clause is underused in most Java programs and the "catch" clause is overused.
I don't think this is necessarily true; assuming an XML parsing library that throws exceptions on malformed XML, you are more likely to have simply supplied generally invalid XML than to have hit an implementation-specific exception type.
So, the exception is only implementation-specific in the sense that it was created by an implementation of the class of software you wanted.
But really, in my mind the issue of not wrapping exceptions means all of your client code is now tied to the transitive library, which means the implementation can't be changed without breaking API compat.
The top-level application is usually a composition of libraries.
So in practice, I'm sanguine about apparently transitive dependencies. I prefer when exceptions from one library's plugged-in dependency flow through unmolested, as I see the libraries as mostly a flat dependency of the larger application. If you pull in dependencies transitively without paying much attention to them, you're sowing seeds for trouble with versioning, security scope, risk of stale projects if they're open source, etc.
I think of this as a corollary of Spolsky's law of Leaky Abstractions. Passing through exceptions means not trying to fool anyone into thinking they can work with the high-level abstraction without understanding anything about what's going on underneath.
Ideally the standard library provides base classes that act as core categories for different kinds of exceptions - IO, programmer error, data format error, etc. - so that general code can be written after a fashion when necessary. But I think you're fooling yourself if you think that such general code can be written the majority of the time, much less all the time. What's underneath always leaks through, one way or another, and if you try to ignore the thing that's underneath, you'll end up with brittle inefficient code.
Where high-level wrapping exceptions are justified is where there is an obvious chokepoint in the design - where the interface between several layers is very narrow. But this typically is at the junction between a service and a client - e.g. a web front end and back end, or async job queuing service, etc. - something where there is a service loop and probably service-specific logging of original exceptions, anyway.
Except this is not what happens in reality, very few people see an internal exception type and go investigate the details.
Sure it's shitty practice, but it seems orthogonal to whether the internal exception types are exposed.
I'm not saying people should just ignore what is underneath, I just think that as a library developer, you significantly constrain what you can do without breaking API compat by exposing internal exceptions.
You could take a hard line stance and say that it should be a breaking change and people should go and re-evaluate the library after the change, etc, and then rewrite their code to deal with new exceptions. But in reality it just means that library will no longer get updated, and will effectively become stale for no good reason.
I think Dart or another JVM language are the only hope for getting away from Java on Android. Dart is maybe a longshot at this point though.
That's a feature to me. Respect my Cache-Control headers!
Looking back I wouldn't mind developing on Android again but I wouldn't want to necessarily do anything with Java by itself.
The level of hackery even drips down to their own documentation and code examples. There is a line in an old example for a TabPager I believe that said "It relies on a trick." How is this acceptable API writing and role-modeling from Google?
Kotlin seems approachable and modern. Also compiles down to JS.
Case in point: To make a list on Android, you need to jump through hoops, assign stuff to a "Tag" property (a field intended for hacks and workarounds), typecast your ass of, or if you don't do all that your list will perform absolutely shitty. So, the easy flow is a crappy, slow, buggy list. The "best practice" (which is not the easy flow, because hey, why would we make good stuff easy) is a "View Holder Pattern" [0] that involves using intended-for-hacks framework features.
On top of that, to my feeling there's also a big difference in quality between the enterprisey Java ecosystem and the Android ecosystem. Android-o-world is full of not-entirely-good advice and bad examples. Jumping into Android reminded me of past PHP experience: lots of well-meaning, but ultimately not-very-experienced people set the tone. Enterprisey Java might have AbstractFactoryFactoryProviders, but at least they have no buggy/wrong/hacky/insane code with 300 stackoverflow upvotes.
[0] https://developer.android.com/training/improving-layouts/smo...
You don't have to do that. For a list with homogenous items you can use a regular ol' ListAdapter, implement getView sensibly (i.e. re-use views, which is very little work) and it will perform just fine. We tried this with a list of 2,000 items (each item had two TextViews and an ImageView) and it was completely fluid on a Samsung Galaxy Ace.
> Android-o-world is full of not-entirely-good advice and bad examples. Jumping into Android reminded me of past PHP experience
I could not agree with this more. I'd say somewhere around 2/3 of StackOverflow Android answers are downright wrong.
Everyone else just uses CursorAdapter which is easy to use and ties in nicely with things like Loaders and ContentProviders.
That's why there are all these crutches like Joda, Guava etc.
Anything GUI or system-related you have to do in Java. You won't be able to use Go to run other apps, enable wifi, receive GPS locations, communicate over bluetooth, etc. etc.
Qt is worth a look, but it's still not quite ready.
The hole point is getting advantages. Lucky us that it's hard; others won't keep pace!