Tuesday, July 5, 2011

Static hard typing is useless is method signatures

Consider following interface method signatures:
AlfaRomeoTargetProduct getByPK(java.lang.Integer languageVersionId, java.lang.Integer alfaRomeoId);

SigmaOmegaTargetProduct getByPK(java.lang.Integer sigmaOmegaId, java.lang.Integer languageVersionId);

And several other such getByPK methods. These were generated by O/R Mapping software. They are parts of the same application and are used together.

I've just spend at least half an hour looking for reasons for code below to explode:

...
case SIGMA_OMEGA_TEASER_OBJECT_TYPE:
productId = sigmaOmegaTargetProductDAO.getByPK(myObjectId, lvId, true).getProductId();
break;

case ALFA_ROMEO_OBJECT_TYPE:
productId = alfaRomeoTargetProductDAO.getByPK(myObjectId, lvId).getProductId();
break;
...

Until I checked the actual O/R Mapping code for getByPK.

For quirky reasons order of method attributes is shifted between various objects - sometimes languageVersionId is first, sometimes last.

Guess what? It should have been:

productId = alfaRomeoTargetProductDAO.getByPK(lvId, myObjectId).getProductId();

Static hard typing haven't prevented this error. I could be writting this code in dynamic language and save a lot of time.

It get's worse..

Let's suppose method signatures are fixed and myObjectId is always first and there is one more attribute lvId.

With language like python or ruby we could just ommit the switch/case structure and write:

dao = getDaoByName('alfaRomeoTargetProduct')
productId = dao.getByPK(myObjectId, lvId).getProductId()

We can't in java. Unless all of these O/R Mapping objects were using the same interface. Which is unsupported in O/R Mapping we use. So sad..

Moral: Static hard typing is useless. Even if no errors/inconsequences are present, static hard typing is counterproductive.

Monday, May 30, 2011

Want TextMate for Linux? Use kate!

Let's go through TextMate features with Kate in mind:

Ability to Search and Replace in a Project

That Eclipse-like goodie is actually better left to really powerful bash > find | sed && awk scripts. Otherwise you hit a wall rather sooner than later.

Auto-Indent for Common Actions Like Pasting Text

That of course is simply wrong thing to do. Usually one needs to guess what editor did and fix it manually. But kate has it of course if you insist.

Auto-Pairing of Brackets and Other Characters

Kate has it. Emacs has it. Vim has it. Basic prerequisite for any programming text tool.

Clipboard History

That would be cool. Oh wait, KDE has that..

Column Selections and Column Typing

Impressive but totally useless.

Completion of Words from Current Document

Kate has it.

CSS-like Selectors to Pinpoint the Scope of Actions and Settings

What? You know local scope for programming language you didn't know existed? How?

Declarative Language Grammars for Graceful Mixing and Hacking

Kate has it and even more. It has API for scripting: http://docs.kde.org/stable/en/kdesdk/kate/plugins.html

Dynamic Outline for Working With Multiple Files

Kate is also very good with multiple files.

Expand Trigger Words to Code Blocks With Tab-able Placeholders

You should avoid programming language that needs this feature often. You'd be better off. Actually doing that breaks DRY principle - you should add a method/macro to your code instead of repeating it.

File Tabs when Working With Projects

Tabify Kate pluging

Foldable Code Blocks

Classic. Kate has it.

Function Pop-up for Quick Overview and Navigation

This is actually better than in Kate. I miss it.

Plug-able Through Your Favorite Scripting Language

As said above, Kate is scriptable both from KDE and via Kate plugins.

Recordable Macros With No Programming Required

As iMacros prooves it, this is wrong path. Macros needs programming to be useful. Otherwise they just break DRY principle as above.

Regular Expression Search and Replace (grep)

I'd bet my money Kate has world-class support for regexp (positional, grouping) here. I've changed original text:
    * Ability to Search and Replace in a Project
    * Auto-Indent for Common Actions Like Pasting Text
    * Auto-Pairing of Brackets and Other Characters
to HTML H4 headers:
<h4>Ability to Search and Replace in a Project</h4>
<h4>Auto-Indent for Common Actions Like Pasting Text</h4>
<h4>Auto-Pairing of Brackets and Other Characters</h4>
By replace
    \* (.*)
with
<h4>\1</h4>

Run Shell Commands from Within a Document

Sure, type them without readline, without Ctrl+R history? Useless.

Support for Darcs, Perforce, SVK, and Subversion

Cool names. What do they do? Oh, you mean syntax highlihting? Kate has it. As for subversion: Integrating code revision control systems into text editor takes from you the power of text console. If you don't like console, you should work on it.

Support for More Than 50 Languages

Only 50?

Switch Between Files in Projects With a Minimum of Key Strokes

Kate beats strokes with one stroke (Alt+arrow).

Themable Syntax Highlight Colors

Kate has it.

Visual Bookmarks to Jump Between Places in a File

That is killer feature of Kate. It actually made me think TextMate is somewhat based on Kate.

Works As External Editor for (s)ftp Programs

With kate -u switch (use existing kate instance) you get to work on any project incredibly fast.

Works Together With Xcode and Can Build Xcode Projects

Cool, but I like both make and maven for a build system.

Wednesday, May 4, 2011

Encoding video with subtitles for playing on Xbox 360

mencoder HSE_0720.avi \
    -sub HSE_0720.srt -subfont-text-scale 3 -utf8 \
    -o HSE_out.avi \
    -of lavf -lavfopts format=asf -ovc lavc -lavcopts vcodec=wmv2 \
    -oac lavc -lavcopts acodec=wmav2 

It encodes any video playable with mplayer so that it is playable on Xbox (via uShare or Media Center).

Subtitles are rendered into video stream, so output .avi is standalone.

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.