Saturday, April 16, 2011

Being interchangeable part - survival guide

Lemma:
Employers much prefer that workers be fungible, rather than maximally productive

Proof:
Java Enterprise (J2EE) and UML.
The good parts: standards (Hibernate, Servlets), deployments, security, runtime environment (JVM, app servers), maven. They make it easy to program.
The bad: Bloat of the code, static typing, Eclipse (slowness!), need to reaload classes while developing, UML instead of talking to your team. This makes us inefficient and slows us down.

Static typing creates an well-selling illusion of easy finding the way in the code. Object oriented programming/J2EE methodology and static typing turns 66% of programmer's day into of text generating mini-game (with comming up with cool class name being the fun part). Having to compile and reload the code wastes another 10%. Add 4% for coffee and frustration from slowness of tools... This leaves 20% of time to programm. No wonder that it takes several months to finish simple projects.

Why companies are pushing such ineffective technologies?

Labor cost is highest position in almost any company's budget. But it still obviously pays for them for you to be ineffective. Why? Because with java you are an interchangeable part of the system (just like an object implementtion). Ability to replace you makes your wage drop and makes you easier (more obedient) and cheaper to manage (with poor management).

We all fear the change. Knowing that we are easly expendable and totally unrelevant make us care for our job and put up with unreasonable requirements, methodologies and bad management.

Effectiveness distinguishes programmers from each other, it's our value and currency. By making our main asset irrelevant, Java (J2EE) hurts our souls and sips off our energy turing us into bland Eclipse operators.

How can we earn respect?

To break free, we need to go from irrelevant to being importand and catually appreciated for not being easly replacable.

How to break free: jedi

permalink
  • Become relevant by being technicaly perfect. Know alot. Bring cool new toys to development. Learn new things afterwork. Write blog, do opensource
  • Promote new technologies. Unknown terrain is an opportunity to show off your skills.
  • Write some software for company-wide use - it makes you seem less expendable. As a bonus, try to please your coworkers with clean, easy syntax or even nice DSL
  • Become part of usual landscape, be last one that comes in mind when staff reductions are near. Do some maintenance tasks that no one likes. Take care of fields no one wants to touch.
  • When you learn something at the expense of your current employee, stay with him till it's obvious it was worth it to invest. This might help creating better environment for all of us. Do however find other job if someone takes advantage of your passion and honesty.
  • Ask for code reviews and technical appreciation of your work. Treat it as part of your salary and be proud of praises. Remember to ask for position change when new duties come along. This costs employer very little, but makes you feel much better. Also writting new position in contract makes you more valuable and relatively less expendable.
  • If you are not appreciated technicaly, but know you do good work, find siths around you
  • Consider switchin career to Ruby
  • Consider switchin career to Python
  • Consider switchin career to Scala
  • Consider working for small company where technical team members do specialise and trust is the binding
  • Consider working in fast-paced environments, that take requirements from marketing not IT, have ambitious deadlines and is properly, competently and honestly managed.

How to break free: the dark side

permalink
  • Reinvent as much wheels as possible - custom solutions instead of well renown working ones. Effectively go away from java to 'my way of thinking'.
  • Go along Java bloat. Promote extensive unit testing, insist on using CMMI and/or bloated project management methodologies (PMI, Prince2). Use UML. Complicate database schemas.
  • Help lazy managers do the bad job. They are your best advocates in hard times.
  • Loudly preach good practices but don't follow your advice. Backstab and sucker-puch anyone that naively proposes something long-term sane, but more costly than dirty, bad hacks. You will become immediate treasure for your employer.
  • If you are medicore programmer or choosen programming career for money only, promote everything that slows work down. This gives you easy way to compete agains passionates (it frustrates them to start with). You also have passions that need the money - why would they take what you deserve?
  • Try locking company in your unique knowledge or abilities. If you have none, create an illusion that you do by learning something unpopular (ex: LISP or Perl).
  • Write or introduce software that seems brilliant speedup but actually hinders development. Example: software for class reloading and classes cached so that they actually often won't reload. Have explanation for every quirky case at hand - become competent in promoting that software.
  • Use years of experience and CS degree as arguments in discussions against others. Always agree with those with higher experience. Do not let self-tought barbarians gain any points or fields.
  • Help survice stone-age standards and solutions. Cunny enterprises only work with them, because it's cheap to buy programmers to do what everyone is already doing. Helping management promotes you.
  • Help kick out of the company every naive programmer that says it loud that bad things happen. Marginalize rebeliants. Kill all jedi.

Examples and inspirations:

  • Writting your own OR/Mapping with one well-selling feature that JPA doesn't have. Make sure it changes the way standard-users think about schema.
  • Suggesting use of LISP by selling on it's famous effectiveness and than wrapping it up so that it actually slows work down.
  • Sell in Clojure language (LISP for JVM) to be used (promotes you!) and forbidd anyone (but you!) to write macros. A perfect career cheat.
  • Insisting that beacause of security reasons (try something that kicked company's butt before, like XSS) all programmers must suffer quirky, undocumented, intentionaly badly written (by you) wrapups for every function in the code. Again, become unquestionable expert at solving issues there.
  • Oppose Agile methodologies at all costs and the same time promoting Java. Agile with java requires inhuman ability to write modular, clean code with no assumptions of future use. If you'd ever like Agile, switch language :)
  • Support your boss helping to survive old methodologies by finding or making up costs of dropping it. He will love for that.
  • Promote using in-code caches instead of external ones (like memcached). Cache is a root of all evil and creates alot of hard work.
  • Quickly assasionate everyone mentioning names of: Varnish, Scala or Play Framework
  • Do promote TDD methodology. It makes you seem enterprise-team-member (again, less expendable) and slows down work for the whole team. More time for coffe, less deadlines. More opportunities to write bad, proprietary locking-in solutions.
  • Remeber, you need to seem relatively (to your colegues) less expendable. Bring some bad things to development and sell it as importand innovations.
  • If company happen to invest in you or you learn something new, immediately apply for new job and ask for bigger salary. It works, because your current company paid alot of money for your education and next company just uses that knowledge. Repeat -> profit!

Dark side is easier, but it eats your soul. Think carefuly what shade of gray are your doings...

Wednesday, April 13, 2011

Find errors in compile-time with static typing

I've just read interesting article of upcomming (wishful thinking) Java replacement: http://blog.talawah.net/2011/04/gavin-king-unviels-red-hats-top-secret.html

One of core points was:
Static Typing (find errors at compile time, not run time)

What is strong and static typing

Strong typing
is when a variable once assigned cannot be assigned objects of other type. Compiler checks it at compile-time and later runtime errors are thrown when types mismatch
Static typing
is when you declare type of variable at it's creation and it cannot change. This enables full compile-time checks. No need to check type at runtime.

Static typing is a major feature of language that makes code written in it run faster than ever possible with dynamicaly typed languages. But this comes at price of extreme difficulties with doing real-time evaluation/interpretation. Yes, staticaly typed languages typicaly use some binary (intermediate or direct) format (.class, .obj, .com) for running.

What types of errors only staticaly typed compilator can find and rule out?

  • Missassigment (assigning something awkward) of variables due to simple glitch or more serious code or documentation (API) misunderstanding.
  • Missusing a variable (for example very annoying runtime exceptions in Clojure when you use normal variable but list was expected (rest/cons and so on))

What is a common mistake is that some importand types of errors are affiliated with compilator, but not with static typing. For example compiler (linker to be exact) is able to catch a problem with using non-existand method as methods are symbols in libraries. Staticaly typed language would also enforce properly using that method (parameters).

Ruby makes a use of lack of compiler by providing method_not_found() method. It is requested if someone used a .methodThatDoesNotExist(). For one interesting application see Ruby chapter in '7 languages in 7 weeks' by Bruce Tate (already a must-have classic book).

What types of errors cannot be eliminated with static typing alone?

  • Off by one, buffer overflow, integer overflow, list out of range, invalid map key
  • SQL Injection, not coding for security
  • Bad logic, edge cases, not fulfilling the contract
  • I/O and concurrency problems
  • Lack of resources (db connections closed, out of memmory error, firewall)
  • Typical bugs like missing button or something not working in Internet Explorer.

Let's see.. Some serious and very common problems on this list. Somehow using a Map instead of List become less importand in face of SQL Injection... ain't it?

Testing to catch errors

As professionals, we test our software before our clients test it. We employ alot of cool and efficient techniques to protect our reputation:

  • Manual or automated iMacros,Selenium testing of requirements/contracts fullfillment
  • Testing while building - JUnit/Mockito
  • Code review, coding standards (variable naming), API documentation in-code, javadoc/pydoc/Clojure:doc..

These are not tied to languages, but to profesional attitude towards programming craft.

Static typing promises are lies

  1. Static typing prevents only minor set of problems of little relative importance (type error is many times less serious than 'Buy' button or PayPal integration not working.
  2. Static typing is actually much less usefull than strong typing. Scala language is strongly but not staticaly typed. Programmer doesn't have to waste time on type declaration (and comming up with a type name to begin with)
  3. Typicaly compiling takes so much time while developing software, that no runtime speedup is going to make up for it. I work with java framework that takes 90 seconds to fully rebuild (class reloading problems: IBM WAS restart required). Doing that few times an hour distracts me and my colegues so much, that after few hours we are frustrated and error prone (yes, programmer can also be error prone :).
  4. Staticaly typing to speedup runtime is premature optimization. One should code so that software works, apply test suites and if there are throughtput problems, find solutions then. Typical solutions orders of magnitude more efficient than static typing are: memcached, squid reverse proxy, load balancing that works (and another one), or fully featured accelerators like Varnish. Oh, web only solutions you say? Who cares about the rest? =D>

Summary

Happy developers with power at their hands are precious resources. Do not waste it in staticaly typed environment. Do not confuse static typing with compiler or linker. Do not confuse static typing with strong typing.

When choosing next languge for your project, start with interpreted languages considering frameworks maturity. If JVM (and J2EE deployment) is a must, take a look at Scala, Clojure, Jython or JRuby.

Thursday, April 7, 2011

Like C language and hate Java? Check Scala!

I've recently read a C praising article, that rants at Java:
http://www-cs-students.stanford.edu/~blynn/c/ch08.html

Author seems to take it personally and is more biased than a scientist should be. But he is mostly right in his java rant.

In another chapter he mentions C lang problems, that he beliefs could be walked around. And this is where he is mistaken. Most C programmers read glibc and linux code and take it as example. Since there are obscure macros there, most programmers will write the same. The result is that coding C is no longer simple and will never be. Obscure macros will make any language fall (and fail) - and this is why Clojure will vanish after few moments of glory.

Most blows at Java are blows at lack of functionality, speed and inheritent code bloat. Java also indeed does some things the worst possible way, namely multiple inheritance.

Author is forced to admit that Garbage Collector and code divided into packages are seriously importand features of Java platform. If he ever did any web deployment, he'd also notice that jars, wars and ears packaging in J2EE are unique and save a lot of hassle. No other language has working deployment out of the box (maven war - one liner that builds the world).
Ooh.. maven :) Another killer app. In fact so good, everyone want to reinvent it.

Let's go through C wishlist, having Scala in mind.

Scala is functional (mostly, pragmaticaly they allow object state and imperative loops) programming language written in Java and running on JVM. You get J2EE packages, deployment and state of the art Garbage Collection for free.

Scala has also one nice feature - it's C-style formatted language

  • Package system -> inherited from java
  • Text substitution keyword instead of #define -> luckyly Scala has no preprocessing macros, so we don't need to fix that
  • Multiple return values -> just return an inline-built object. Side note: In python you'd just unpack a tuple:
    edata, newfunc, value = fReturnTuple()
  • Anonymous functions -> lambdas all the way in Scala, go ahead
  • Multi-line literal strings -> Scala has exactly the same multi-line operator """ as python
  • Flexible array ranges (not starting from 0) -> C-only problem. Real world has enums, iterators...
  • Regular expressions -> the author should take a deeper look at regexp librariers. RE is no longer slow. A missfire.
  • Reflection -> lol, actually someone here likes java more than he admits. Sure, there is reflection in scala
  • Closures -> full support in Scala
  • Way to detect overflow -> JVM anyone?

Summary

C language is broken. Has no namespaces (all functions are visible everywhere), most code uses obscure macros. Pointers syntax is complicated to a perl-level. C is error prone. C requires deeper understanding of machine and memory (ever switched 32bit code to 64bits?) that is practical for average programmer to learn... Only bad things happen when you program in C.

Instead of fixing Java with C, and wishing C had JVM features, one should look at Scala.

Wednesday, April 6, 2011

Pragmatic programmer - what I've learned

What I learned from:

Book cover of: The Pragmatic Programmer: From Journeyman to Master, by Andrew Hunt and David Thomas

Most things in this book is way beyond what CS students learn. At the same time these things are absolutely essential to become a programmer. This is good for self-tought programmers: we have a chance ;)

  • Do care about your work quality
  • Think about you work, how and why you do things
  • Individual mastery does metter
  • Think Kaizen, little steps towards perfection

Pragmatic philosophy

  • Never say 'impossible' - find solutions. Responsibility instead of excuses.
  • Poor excuses and lies are unprofessional
  • One broken window (smelly code) dooms and destroys stronges projects
  • Small, carlesly accepted scope changes lead to huge project failure.
  • You don't have to be perfect, you just need to be good enough.

Your assets

  • The best investment is always the knowledge
  • Knowledge depreciates with time. Fast.
  • Invest regularly. Read about your craft. Learn programming languages. My advice: start with lisp.
  • Stay in touch with other programmers and exchange views, knowledghe and code
  • If you don't know or understand something that just came up, do check it. Use every excuse to learn something new.

Approach to programming

  • DRY: don't repeat yourself. My comment: be lazy and automate or generate everything
  • Copy&paste is a sign to start thinking
  • Make your code easy to reuse but don't try to predict
  • Orthogonality. Get rid of links between unrelated modules or badly defined relationships
  • Expect orthogonality in project roles. If multiple people do simmilar tasks, those tasks are never done properly. My comment: Fuzzy responsibility is always a warning sign for a professional.
  • Be ready for a change in code (this is now called Agile Programming) or architecture. This is where you need to cunningly predict and overestimate a little.
  • Develop a system so that progress is easly visible. Ask for feedback early and often. My comment: If you are forced to develop and present whole system at once (waterfall) - you know managers are incompetent. Run!
  • DSLs - invent your own vocabulary. My comment: use monads and have every method return something (preferably this/self)

Estimating and harmonograms

  • Use adequate measure - if it takes 17 days, say 3 weeks.
  • Write down your estimates and compare to what happened. Take notes.
  • Harmonogram is always changing - do not let anyone force any date on you, unless no scope changes are possible. Watch out for managers that promise "no more changes" and later the same day ask for new features. Stop delivering any estimates to them. Try not to work with such people.

Toolbox

  • Descriptive variable names, natural language as values even when sending/storing data, text files as data source -> these are good things always and everywhere.
  • Use Linux and know your shell
  • Learn to use powerful text editor. My comment: Vim or Emacs. Eclipse only wastes your time. As for me, touch typing, knowing shell and mastering text editor are crucial programmers skills
  • Master text processing in python, perl, sed or awk. My comment: definately python
  • Understand what RTFM means. Learn newsgroups culture (now sadly extinct). Try saving other people time.

Fixing bugs

  • Don't panic. My comment: Chad Fowler says that professionals never panick.
  • Start with your code, assume you are the one to blame. No, that's not JVM bug. That's your bug.
  • Proove your theories by provoking a crash. Do not assume, make it crash.

Programming techniques

  • Have contracts in your code. My comment: basically try to have preprocessor or compiler warn you about changes in outer code. Ignore orthogonality here - you can delete uneeded contracts if decoupling/reusing.
  • Throw runtime execeptions (and let them fly)
  • Use asserts, especially in production code
  • Minimalise connections/bindings between modules
  • Use metadata to change local, specific behaviour

Coding

  • Accidential coding, programming by luck, "I don't know why this works" <- don't do this
  • Understand whole project and all used concepts
  • Do refactor code. My comment: never ask for permission, instead ask for forgiveness when caught refactoring
  • Do not use manual procedures. My comment: manual (step by step with printed instructions) procedures do not work. If it cannot be automated to a script, real person will make a mistake
  • Make sure that bug once found, never again happends

Pragmatic projects

  • Test your work before end users do
  • Slightly exceed expectations every time
  • Sign your work, be proud of your mastery

This book is a corner stone and a basic requirement to be any good in programming industry.