Why Building Apps the Wrong Way Can Be the Right Way
medium.com
medium.com
Experience teaches us where to start, where to think ahead a little, and how to structure code such that it can be refactored in the future.
Writing code the "right way" means 1) getting something working 2)taking what you've learned and refactoring and/or.
If you care about maintaining a chunk of code for 6 months, or a year, you'll quickly learn to refactor. If you are prototyping, right likely isn't a priority to begin with.
1) Make it work (at all)
2) Make it work right
3) (If necessary) make it work fast
1) Make it seem to work
2) Ship it
3) Profit ?
Them of course means customers.
It amazes me that people still think that strong typing isn't useful.
I've heard people argue that its not always a net benefit, but I've never heard anyone argue that it doesn't have benefits.
Then they add kludges to make life bearable (see also: Generics), that will then add complexity. And are sometimes horribly implemented (see: Java's type erasure), or C++ compiler authors struggling with its template system (and users struggling to this day).
Or sometimes they don't even add the kludges, making life tedious (see: Go, and endless discussions about adding generics to it)
The other category of hacks is what's usually called "Reflection", or "Introspection". Any time a language designer feels necessary to add such a name for the ability to lookup things, then you know you are in a world of pain. The contortions required to by some languages to implement Ruby's 'respond_to?' method can get ridiculous. So much so, that the usual workaround is to add 'interfaces', which are a type(that does nothing useful), and so you can check the type. Or pass it around to something that will expect that over-arching type.
Sometimes you just don't care about a thing's type. And, many times, the types that you should care about are not the ones that are actually specified. If I'm doing something important, I don't want the compiler to check if the type is integer, I want it to check if the type is, say, Miles, as opposed to Kilometers. That's what's important, or my costly space probe will literally crash.
A language should make it easy to do so, otherwise people won't bother. Or probes will crash. Even though the program compiled. And the UML diagrams are spotless, with the factories all building the object types they were supposed to.
Hey, remember this guy? He used to be pretty famous, you know.
https://sites.google.com/site/steveyegge2/is-weak-typing-str...
http://steve-yegge.blogspot.com/2008/05/dynamic-languages-st...
var obj = MyObject()
...
obj.foo()
So you could change the obj instantiation to a different type and as long as the new type has foo() too then you're good to go.Also you can have your typed properties stored in a map, which you could also add other values to dynamically at runtime.
from https://kotlinlang.org/docs/reference/delegated-properties.h...
class MutableUser(val map: MutableMap<String, Any?>) {
var name: String by map
var age: Int by map
}
I haven't used Scala but its (Duck)Structual Typing seems like it would get closer again to a dynamic typing feel with static types. Java is pretty verbose and limited in ways, and many devs having backgrounds in EJBs and Struts doesn't help. It would be interesting to see the same side-by-side project comparison in those links with a team using Scala well. Anyway thats all coming from my bias of having done 12 years of Java and 1 year of full Javascript with Angular.(miss you stevey please resume writing)
Ttatic-typed stuff requires more decision-making effort from the user as they write code. (In exchange for lowering the effort to read/analyze it later.) Naive decisions can impact how other people use your code, requiring them to "fix it up". (Fortunately, refactoring tools can help.)
Another downside is when the type system the language provides only partially addresses your vision. Then it gets a little tricky to decide how to optimize your baby-to-bathwater ratio.
In php you can do strict typing at the function call boundary, which is where it really matters, but you need the discipline to do it consistently. I like scala's approach of inferring types as much as possible and only stopping you when you're trying to do something semantically impossible. Scala often feels like a weakly typed system while coding, which is why it's so fun. For that matter, functional style java 8 feels the same way some of the time.
I think the ideal system is strongly typed but maximally inferred to minimize verbosity and maximize coding productivity. Scala is too weird to be that language though.
If you're used to dynamic imperative languages, you have to learn a lot of new concepts, ways of thinking and new kinds of errors messages. Also, it's hard for ecosystems for strongly typed languages to compete because of current popularity.
As far as the real world goes, all you get is -Wunused.
Because 'show' is probably all done for side effects. And then, maybe, Haskell would have caught that, due to the wrong type signature. If called from an otherwise pure function.
Most other "strong typed" languages wouldn't catch that. But that's hardly something type systems solve on their own.
By the way, I am 100% sure that Java wouldn't have caught that, because this IS Java.
You can build that sort of library in any language.
To compare with toString, it's more like if you didn't do obj.show(), obj.toString() would return the empty string?
Toast toast = Toast.makeText(context, text, duration); toast.show();