I get what you're saying, and you certainly have a valid point about flashy GUIs not necessarily being effective GUIs.
However, speaking as someone who does a lot of UI work, there is also the other side of the coin, which is that CLIs and plain text log files are often neither the most efficient nor the most accurate way to configure or discover the things you care about.
In their favour, plain text formats are amenable to scripting and analysis using general text manipulation tools, and of course they have longevity. But they are also unstructured, they offer little interactive, real-time support, and ultimately they are limited to what you can express in sequences of characters (which is just about anything, but only if you're willing to write enough).
Even in highly technical environments, a good visualisation can present information in a form that is prioritised and draws attention to the most important features or anomalous results, or that gives a realistic overview of the current situation far quicker than scanning text output would. If you start to make those visual representations interactive, you can potentially also make complicated configuration work or progressive explorations of the data quicker and less error-prone.
For example, take a classic list ordering GUI with up/down buttons. Works fine without javascript. Add javascript to make it also do drag&drop. It works better with javascript, but still works just fine without.
Web interfaces can gracefully degrade down to a very low level.
Yes they can, but not for free.
This sort of idea makes us geeks feel warm and fuzzy inside, but the reality is that you're talking about implementing two completely different versions of that UI feature. Doing so takes time and money, and you’d be spending that time and money purely to support a use case that probably represents a negligible number of users (people who want to run these UIs but have JS disabled).
Of course portability and compatibility are important for user interfaces, but this is a cost/benefit question. There is a line beyond which the results do not justify the effort, and any resources you’re spending past that line aren’t being spent on implementing other features or improving the usability elsewhere in your UI.
Code monkeys never ask Rack monkeys what issues they face on the real field.
That’s not entirely fair. As a guy making UIs, I love hearing from the front-line what the users actually want, what they like and what they would like to see improved.
However, most development roles aren’t naturally customer-facing, and the focus for most people between the customers and the developers is usually on features (and commercial matters like pricing, of course), so this is the information that will naturally flow through an organisation and drive development.
Likewise, from the user’s side, often the people who are in contact with suppliers and making buying decisions aren’t the people who are personally going to get that 4am wake-up call to actually use these products. If there are things that matter and they aren’t obvious in the way that a tick in a feature column or a discount on a price are obvious, someone has to tell the guys doing the buying/negotiations so they can pass it on.
Basically, picking up more general usability issues like the ones bertok mentioned above either takes an exceptionally enlightened and well-structured organisation where this kind of information routinely gets passed on as well, or it takes guys at both ends of the chain who form side channels to get the little details through, and this goes on both the supplier and the customer side.
Thank you for the insightful post. I create user interfaces professionally, I share many of your frustrations with the generally poor standards in the industry, and I find it reassuring that at least some people who use the kind of tools I build do actually value good usability!
The one big thing I would add to your points is that whatever kind of user interface you’re building — CLI, GUI, API, whatever — it’s always going to be limited by how well thought-out the underlying configuration model is. If you have a system that requires 745 interacting settings to be correct before it works, and the guy who changes those settings is doing it at 4am after his pager woke him up, you’re unlikely to see a happy ending no matter how polished the presentation of those 745 settings might be in any UI. It never ceases to amaze me how many UIs don’t get their fundamentals down first, and just think it’ll be OK as long as the UI is pretty, compatible with Brand X, compatible with Scripting Tool Y, compatible with Management Protocol Z, or some other useful but second-tier benefit.
Please do share any other rants, general frustrations, examples of things that were really useful, or other similar comments you have. These kinds of threads are gold for those of us who work in the industry.
What about Mercurial? [...] I'm considering switching from Subversion to something else for my team at work, but the Git UI is awful. I've heard Mercurial is better, including its GUI integration (e.g. Tortoise).
In UI terms, there are respectable GUIs available for both Mercurial and Git these days. I’d say the biggest difference is in the CLI interaction, because the usability of Git is poor even in its native habitat on Linux, and on Windows you're basically stuck with Git Bash, which is a rather glitchy emulation of a Linux shell that IMHO is very irritating to use. Hg is much simpler and less cluttered.
In terms of functionality and the underlying models for how the system works, I’d say there are a few major differences between the Git and Mercurial workflows that you're likely to come across almost immediately. Some are “real” differences. Others look like differences when you first learn the tools, but they’re only consequences of how each tool works by default and you can work the other way if you prefer.
The first is that Git by default does a two-stage commit: you identify the changes you want to commit from your working copy using git add, and then you actually commit them to your local repository with git commit. In Mercurial, the default is commit everything with a single command. However, this is one of those illusory differences, because both systems have alternative commands/options that let you work the other way if you prefer.
The second is that Git and Mercurial (in)famously have different mechanisms for using branches, and here there really are meaningful differences in the underlying model for how things are stored and what you can do. Personally, I intensely dislike Git’s approach where you “forget” which branches things originally happened on or even what those branches were called, because I find the information it discards valuable. However, you’ll have no trouble finding a Git fan to tell you I’m just being silly and obviously the branches-as-moving-tags approach taken by Git is better for other reasons. In this case, there are tools built into Hg these days that basically work the same way as Git’s branches if that suits you, but I’ve yet to find any satisfactory way of getting Git to support history tracking including branches the way Hg does.
Finally, on the subject of rewriting history, in Hg changes are basically permanent once committed, while in Git history is mutable by design using the rebase commands. Again, which is better for you will depend on your own workflow and personal preferences. In theory Git’s view is more flexible, but it’s also one of those issues where it’s a rite of passage to write a blog post about how not to screw up all your colleagues’ repos by rebasing something that was already pushed out to others, so use with care. Hg’s version is less amenable to certain workflows, but it’s also safer.
Finally, I just wanted to mention that whatever anyone tells you about how it’s obviously user error, both Git and Hg have had actual, verifiable, reproducible data loss bugs, even in the past few months. I haven’t checked very recently whether any of the ones I knew about are still unfixed, but definitely make sure you’ve got the latest versions of everything. (And if you’re using Hg, be really careful about cloning a repo on a network server directly and in particular whether you’re getting a truly independent clone or just an improperly-linked version of the original that will corrupt both over time. And if you’re using Git with an external diff tool like Araxis Merge, beware that using a git difftool --dir-diff has been doing funny things when you quit the diff tool and may overwrite any changes you made in your working directory while the tool was open.)
I respectfully disagree. I’ve worked on heavily numerical code in both C++ and Java. Writing horrors like (a.Multiply(a).Add(b.Multiply(b))) instead of a*a+b*b gets old after about the first five minutes. Also, I’m still waiting to meet the programmer who will make those * operators do division just to trick me, yet who writes Multiply to do multiplication as we’d all expect.
I find that file you cite very readable. It's well formatted, it's clear what the code is supposed to do etc., comments where necessary. Why do you think it's sarcasm?
Well, for one thing, it’s just code in a file. There is no obvious indication of how this code fits into the wider design of the program, because C doesn’t have much of a module/namespace system. (There are some comments right at the end that seem to be about build order dependencies, but it’s not clear to me what they are trying to achieve. I assume there is some sort of project standard that requires them.)
Next, consider the first function, xor_blocks. It appears to take about 20 lines of code just to call one of four other functions based on how many entries are in an array that was passed in. A significant proportion of the code is only there because the input arrived as a void** and a count rather than a typed array. The rest is repeating essentially the same pattern of code almost verbatim four times. It’s not clear whether the four do_N functions are completely different algorithms or just the same algorithm using defaults if there aren’t enough inputs provided. In the former case, you could express the entire function in about five or six lines in numerous other mainstream languages, most of which would just be a look-up table identifying the required functions. In the latter case, the entire 20+ line function would probably be redundant in many languages. And I see no reason another language that can express this kind of logic without the overheads shouldn’t generate code behind the scenes that is still 100% as efficient as the example.
A little further down, we start defining macros like BENCH_SIZE. When these are later used elsewhere, you can’t tell whether you’re working with a constant or a function call with side effects. (This is a big objection I have to complaints that C++ overloaded operators could do almost anything, coming from people who then argue that we should use C instead because everything is explicit.)
That brings us to the second big function, do_xor_speed, in which we again encounter our ambiguous struct containing function pointers and void* parameters. This time, we also use a magic number, rely on (presumably) a global variable and implicit side effects for the main loop control logic, apparently try very hard not to let that loop be optimised in some unspecified way, and cause various implicit side effects on some other (I assume) global variable.
The final major function, calibrate_xor_blocks, has similar issues, and further complicates things by interweaving local macro definitions that mean some of the code isn’t executed, or is executed but is immediately overridden anyway, as well as apparently obfuscating a simple function call behind another macro with a name that looks like a regular function itself.
Now, I do realise that a lot of this is how a lot of industrial C gets written in practice. I also realise that there are few realistic choices for a low-level, systems programming language today, and none that I know of has much better readability than C. But that doesn’t negate the criticism that the C code has fairly horrible readability/maintainability properties compared to what could be achieved in a more expressive language.
C is and will always will be more efficient with hardware than C++ (for equally skilled programmers).
Why would you say that?
There’s always been a great deal of emphasis in C++ on not paying any performance penalty for features you’re not using. Using the roughly common subset of the languages should yield similar results either way.
As far as the extra features in C++, I don’t see any reason to assume that (for example) a virtual function dispatch via a vtable in C++ should be less efficient than the old “look up a pointer in a jump table” techniques in C that serve a similar purpose. If anything, it should be the other way around, as the C++ compiler has a little more semantic information that it could potentially use to optimise the generated code for each target hardware platform.
True, but those few people who use C++ correctly seem to have learned their lessons with C.
That may be, at least in part, because many of the less than ideal aspects of C++ come from its C heritage.
I don’t understand some of the arguments made against C++ by certain “elder statesmen” of the OSS world. It seems they don’t like some of the extra functionality available in C++, seeing it as overcomplicated or too readily able to hide behaviour. In itself, that’s a reasonable concern. But then they use C, and reinvent the same wheels using crude text substitution macros that could be doing or interacting with anything.
On another forum discussion a few days ago, I saw someone argue that the Linux kernel is very readable, citing this C file as an example. I’m still not sure whether their comment was meant to be sarcasm.
And it makes sense, why would someone not want to join a site where all your friends are?
I prefer to spend time together with my friends and family in real life. Some of them I see often, and we don't always talk about big news. For those I see less often, I enjoy catching up with when we can, and that gives us interesting things to talk about if we're going to be spending a few days together.
I am well known among my social group as a Facebook skeptic and privacy advocate, but I just don't see how meaningful relationships can be maintained with a couple of impersonal "sentences" of text speak, the occasional cat photo, and dutifully typing "Happy birthday!" each time a little box pops up telling me to. If that makes me a recluse, what should we call someone whose primary social interactions come in 140 character sound-bites and who doesn't spend much social time with others away from their PC?
From personal experience, the version of Java on Macs seems to have lagged significantly behind the version widely available on other platforms from Sun/Oracle. It's not clear to me yet exactly what this announcement/reaction refers to, but if it means clients who use Macs wind up downloading/installing up-to-date Java runtimes like everyone on other platforms, and have the latest version as a result, that sounds like a good thing.
For what it’s worth, I can see a very strong case for type-safe rendering and systematic parsing of this kind of structured data. However, to my knowledge, no mainstream statically-typed language is expressive enough out-of-the-box to represent the structure of a typical JSON/XML/whatever schema in a concise, readable, maintainable form to support these goals.
Many popular statically-typed languages support all the basic arithmetic and logical operations for numeric and boolean data. Their standard libraries often include a bewildering array of additional mathematical functions as well. However, the basic text operations of rendering and parsing strings just don’t seem to get the same sort of support in most cases, perhaps because they are so much broader in scope. Likewise, manipulating structured data is often a weak point: today’s mainstream statically-typed languages tend to lack both the general flexibility you get with dynamic typing and the expressiveness and polymorphic tricks you get with algebraic data types and pattern matching in various functional programming languages.
string formatting/regexes are about the same in java as they are in python.
I’m not sure I’d go quite that far. There are several subtle advantages in Python (and one or two not so subtle ones) that IMHO make working with formatted text significantly easier overall.
For example, Java’s basic string formatting tool, String.format, and its regex patterns rely on numerical indices to identify specific placeholders and capture groups. In Python, you can use meaningful names in each case.
Another small but often useful win for Python is having raw strings, which cut down dramatically on backslash pollution when you’re writing regex patterns.
Finally, in perhaps the fairest example of the wider statically vs. dynamically typed language comparison, we have Java’s infamous verbosity against Python’s famous readability. Simple things like matching a regex with capture groups can require several lines of code and explicit creation of several objects in Java. In Python, you rarely need more than a single call to a function in re to get the same job done.
If static languages are better, why is the bulk of web development done with dynamic languages?
I don’t know how much of that is reality and how much is popular perception. In any case, here are some general trends in mainstream statically-typed languages and mainstream dynamically-typed languages today that might contribute to the popularity of the latter for web development:
The dynamic languages do not require the extra compilation steps in a build process. This probably speeds up prototyping. A lot of the web development in dynamic languages is probably done by small businesses or start-ups, and that sort of culture places a lot of emphasis on rapid prototyping.
The dynamic languages tend to have much easier basic text processing. Basics like string formatting and regular expression parsing are a horrendous chore in languages like C++, Java and C#, relative to the trivial one-liners widely available in “scripting” languages.
The dynamic languages also tend to have built-in support for structured data like nested hashes and arrays, where again you need to jump through hoops in typical mainstream static languages today. That kind of structured data is widely useful for defining easy interchange formats between browser-side code and server-side code. For example, on a current project, we have standardised JSON data that is accessed using several different programming languages in different contexts. In JavaScript or Python, it’s a breeze. In Java, it’s a chore.
Integrations of popular dynamic languages with popular web servers are widely available and easy to set up. Setting up a Java-based web application is the sort of thing people write whole books about, dropping the names of half a dozen different technologies along the way.
Likewise, integrations of popular dynamic languages with popular database systems are widely available and easy to use.
A lot of web development projects are, rightly or wrongly, not treated as critical software systems where bugs are unacceptable. Encountering an error at run-time and dumping the visitor to some sort of error page is often considered an acceptable response, and people seem to expect and tolerate this behaviour without quite the same level of loathing they reserve for “Your application has crashed” dialogs or blue screens of death.
Perhaps most important of all, most web development software is small. More formal systems with static typing and well-specified interfaces probably have a better cost/benefit ratio on larger systems where it is harder for developers to see the big picture and more difficult to co-ordinate people working on different parts of a system without such tools.
I think these are more reflections of the languages in current use and their surrounding cultures, rather than inherent traits of static vs. dynamic typing, but if we’re talking about the state of the industry today, there doesn’t seem to be any practical distinction.
Whether to do The Big Rewrite always boils down to one very simple question: do the expected gains outweigh the expected losses?
Usually, the argument against doing a rewrite boils down to two key points:
it takes time and resources just to get back to what you already had, which confers no immediate business benefit; and
you risk losing the bug fixes and special cases that have accumulated during the real world use of the original implementation.
Those are certainly valid concerns, and IME it is often true that their impact is underestimated. However, what the doomsayers tend to ignore is all the potential benefits from writing a second version of something from scratch but with the experience gained from doing it once already:
you can design based on the knowledge accumulated during the real world use of the original implementation, giving code that might be easier to maintain in future and/or allowing you to add new functionality that was not realistic before;
you can refine your requirements based on that same experience, cutting out things that haven’t helped in practice and cleanly integrating requirements that weren’t anticipated the first time around, leaving you with a code base that is fitter for its purpose;
while you lose all the old bug fixes and special case handlers, you also get to clear out all the old hacks and bolt-on workarounds that are maintenance hazards and a high risk of causing future bugs; and
the best tool for the job the first time around might not be the best tool for the job any more, and a rewrite lets you revisit that decision and take advantage of any relevant advances in development tools, programming techniques, industry knowledge, etc.
I’m sure some rewrites really are just because a developer wants to write something new instead of working with what is already there, and those are almost always a bad idea IMHO. On the other hand, it can be annoying if someone comes in assuming that this is the only possible motivation for a rewrite, without considering whether there is another justification for the decision.
In that case, would you mind explaining something that is confusing me, please? It sounds like you started the rewrite in early 2005, planned to release in mid 2006, and actually had a finished product in early 2007, which isn't on schedule but is hardly unheard of for a software project. However, you then seem to jump to saying the new version wasn't available across your entire international market until 2010. What happened in between?
Well of course they will have to follow through, because you have a political system that, despite its flaws, gives representation to third parties so everyone's political views can be represented.
Not very well yet: our voting system is still transparently biased towards the larger parties, and the compromise reached by the Liberal Democrats and Conservatives in the coalition doesn't go all the way to offering the public a referendum on PR in the Commons (though they do seem to be proposing it for the elected Lords).
But I do take your point: it seems likely that the presence of the Liberal Democrats in the coalition is pushing the civil liberties agenda higher up the government priority list. I think that is partly because it is a big Lib Dem policy area anyway, but also partly because it is something where both parties in the coalition can readily agree on most issues and say they were doing what their voters asked for. Any coalition wants to show early success to reduce the scepticism in the ranks, and since the Tories and Lib Dems have well known differences in economic policy so the top issue of today can't really help both of them at the same time, this is probably the next best area to look for that success story.
I find it ironic that the US should decide to introduce this measure under a new government when the old one was notorious for abuse of authority.
Meanwhile, here in the UK, we just handed electoral annihilation to the administration that introduced a similar guilt-by-suspicion DNA system here, not long after the European level courts ruled that keeping innocent people's DNA on the database indefinitely was illegal anyway.
One of the first proposals brought up by our new coalition government, indeed one of the points where both parties agreed on almost everything despite their general political differences, was a "Freedom Bill". That will basically be a mass repeal of all the draconian, intrusive, guilt-assuming laws that the previous lot brought in under a climate of fear that they perpetuated more effectively from the corridors of power than any terrorist group ever could. Introducing safeguards so that innocents' DNA is removed from the database in a timely fashion will be an acid test of that bill: they've talked the talk, now will they really follow through?
Hi, I’m a real typography geek. (Chorus: “Hi, typography geek!”)
*Real* typography geeks say Knuth got everything wrong.
Sure we do. We know Knuth was crazy to talk about paragraph-based hyphenation and justification, and it is madness that the Knuth-Plass algorithm remains the gold standard in H&J today and something that only TeX itself, InDesign, and a few high-end specialist packages can match even now. We hate all those fiddly thin spaces that you have to type manually, too; we’d much rather just have our adjacent quotation marks and superscripts clashing.
Speaking of superscripts, we know Knuth’s font design skills were appalling as well. Anyone could design a system of fonts that was still clearly legible when used to typeset mathematics with sub-subscripts at 4/5pt on the one hand, yet provided extensible brackets surrounding multi-line expressions without looking overly large on the other. We know this from the vast number of font families available from the world’s leading type foundries today that do the job, and the way mathematical journals have given up on TeX because modern fonts provide a much wider range of mathematical symbols that are still clearly distinguishable from any Latin or Greek glyphs that may appear nearby.
Maybe TeX was just behind the times, though. After all, in an era when TeX could only typeset a variety of proportional fonts with intelligent hyphentation, ligatures and correct punctuation, at a useful range of sizes, in a way that could survive photocopying a research paper and still be legible, the world’s serious typographers were probably already using word processors that could render a fixed size, monospaced font on their dot matrix printer with underlining!
TeX’s handling of fonts is archaic by modern standards, of course, though updates like XeTeX do a much better job when it comes to things like OpenType and Unicode. However, in fairness, Knuth developed TeX many years ago, at a time before these modern standards were a glint in their metaphorical parents’ eyes. I think it’s rather unfair to criticise on this basis, and much of what he did has set the standard for three decades.
Getting back on topic, if the person or people behind the tool we’re discussing can do half the job for musical notation that Knuth did for mathematics, it will be a very fine achievement indeed. As with mathematics, it is relatively easy to scribble musical symbols in a way that is technically correct, but rendering music in a way that remains clear and effective even when read at speed in large volumes is quite a different thing. Nitpicking about some of the typography in an early demo seems a little unfair, given the already high standard of the overall rendering.
Sorry, I wasn't clear: I was referring to big companies in the business software world, such as Microsoft and Adobe. Certainly the games world has been suffering a rash of silly DRM-related failures recently, but alas, that sort of software is not a common sight on my work machines.:-)
I'm with you on much of that, but just wanted to pick up on this point:
The failing DRM would IMHO fall under the "broken, please refund" category, as the software/game absolutely doesn't work as advertised in that case.
It's not the original purchase cost I'm so worried about in the case of dubious copy protection mechanisms, as I suspect you would have ways to get that back anyway if, say, the software wouldn't activate. What interests me in light of this case is the consequences if installing business software on a work machine rendered the PC unusable because the accompanying malware corrupted Windows, damaged the data in the boot sector, etc.
I'm particularly aware of this because not so long ago I switched to freelance work, which means that working time very much is money to me now. The thing that makes me wary of so much modern business software isn't the cost of buying it, which is a business expense I would incur anyway, it's the unknown losses due to downtime if all this activation and DRM technology somehow takes out an essential PC that I need to work on a contract.
My perception from reading various reports on the Web is that most of the time, the big companies do get it right, but if you're the unlucky one whose system is a bit unusual or whose product key some pirate clones, then there's a good chance you'll be hung out to dry. I would feel much better about investing in high-end software if I knew that I would have grounds for compensation if my business was interrupted because the attached malware went wrong under such circumstances.
Imagine if a car or a washing machine came with an agreement like that
I had a hybrid version: an automated car wash at a petrol station did serious damage to my car after it collided with it.
The immediate reaction from the staff on site was to deny everything, point at some weasel words on a sign full of disclaimers, and claim that my car wasn't suitable for their machine (even though they could see it when they sold me the token to put in the machine, and it had been through the same machine without incident on several previous occasions).
However, when it reached their central "customer care" people at head office, they immediately arranged to pay out a substantial sum of money to cover the cost of repairs on a reasonable basis (asked me to provide two quotes from reputable local repair shops).
I later discovered that there had previously been at least one similar case that had gone to court, where the car wash operators pretty much got torn a new one. I imagine the "customer care" people were aware of this, or at least their legal team was.
So much for "good enough" software
On the contrary, it seems this ruling says precisely that software must be good enough. Unless there's something in the actual ruling that is completely missing from TFA, this doesn't require all sold software to be perfect or bug-free, just that it be fit for purpose and of merchantable quality.
That probably means that the more you pay for software and the more the advertising promises, the better the quality and functionality would need to be. A cute graphics demo that cost £1 on an app store for your mobile phone would not be expected to do the same things and with the same reliability as medical device control software you sold to a hospital at £100,000 per unit.
A contract of sale of goods is a contract by which the seller transfers or agrees to transfer the property in goods to the buyer for a money consideration, called the price.
I doubt £0 would constitute "consideration" in this context.
As far as I can see, the most significant consequences of this ruling are that:
software can be covered by consumer protection legislation;
those selling software cannot escape responsibility for the related obligations just by putting small print in a contract of adhesion; and
liability can exceed the original cost of the software where the damages are greater.
This is particularly interesting because if EULAs do have any legal standing at all here, then they are probably a contract of adhesion based on technicalities about copyright.
I imagine some lawyers are running around looking nervous at quite a few big software companies this morning. All those DRM systems, for example, just became a bit of a liability: if I install a game and it simply doesn't work, then all those arguments about not returning opened products for a refund just became untenable. (Take note, Ubisoft and games shops.) And if you play silly wotsits on someone's computer to try to install your software's copy protection system and you get it wrong and damage their system, $DEITY help you, because it looks like the courts aren't going to. (Take note Sony, Adobe, et al.)
Of course, we'd have to see the complete context before reading too much into this case, because it sounds like the sale was made following significant contact between the parties and specific claims by the sellers, which might or might not still be the case with typical off-the-shelf or preinstalled software.
Don't CAD systems represent everything in very large integers?
Not necessarily: the libraries I used to work on used floating point values for the APIs. Typically, there would also be explicit resolution/tolerance values provided, which would be chosen according to the scale of the model.
Well, OK, I’m moving the goalposts. But discussing something that strictly speaking no-one can do isn’t particularly interesting, while there is an interesting underlying issue of whether it is cost-effective to write relatively high quality software, or whether we are doomed by economics to the predominantly mediocre mass market software we use today.
True security is done in logs.
I get what you're saying, and you certainly have a valid point about flashy GUIs not necessarily being effective GUIs.
However, speaking as someone who does a lot of UI work, there is also the other side of the coin, which is that CLIs and plain text log files are often neither the most efficient nor the most accurate way to configure or discover the things you care about.
In their favour, plain text formats are amenable to scripting and analysis using general text manipulation tools, and of course they have longevity. But they are also unstructured, they offer little interactive, real-time support, and ultimately they are limited to what you can express in sequences of characters (which is just about anything, but only if you're willing to write enough).
Even in highly technical environments, a good visualisation can present information in a form that is prioritised and draws attention to the most important features or anomalous results, or that gives a realistic overview of the current situation far quicker than scanning text output would. If you start to make those visual representations interactive, you can potentially also make complicated configuration work or progressive explorations of the data quicker and less error-prone.
For example, take a classic list ordering GUI with up/down buttons. Works fine without javascript. Add javascript to make it also do drag&drop. It works better with javascript, but still works just fine without.
Web interfaces can gracefully degrade down to a very low level.
Yes they can, but not for free.
This sort of idea makes us geeks feel warm and fuzzy inside, but the reality is that you're talking about implementing two completely different versions of that UI feature. Doing so takes time and money, and you’d be spending that time and money purely to support a use case that probably represents a negligible number of users (people who want to run these UIs but have JS disabled).
Of course portability and compatibility are important for user interfaces, but this is a cost/benefit question. There is a line beyond which the results do not justify the effort, and any resources you’re spending past that line aren’t being spent on implementing other features or improving the usability elsewhere in your UI.
Code monkeys never ask Rack monkeys what issues they face on the real field.
That’s not entirely fair. As a guy making UIs, I love hearing from the front-line what the users actually want, what they like and what they would like to see improved.
However, most development roles aren’t naturally customer-facing, and the focus for most people between the customers and the developers is usually on features (and commercial matters like pricing, of course), so this is the information that will naturally flow through an organisation and drive development.
Likewise, from the user’s side, often the people who are in contact with suppliers and making buying decisions aren’t the people who are personally going to get that 4am wake-up call to actually use these products. If there are things that matter and they aren’t obvious in the way that a tick in a feature column or a discount on a price are obvious, someone has to tell the guys doing the buying/negotiations so they can pass it on.
Basically, picking up more general usability issues like the ones bertok mentioned above either takes an exceptionally enlightened and well-structured organisation where this kind of information routinely gets passed on as well, or it takes guys at both ends of the chain who form side channels to get the little details through, and this goes on both the supplier and the customer side.
Thank you for the insightful post. I create user interfaces professionally, I share many of your frustrations with the generally poor standards in the industry, and I find it reassuring that at least some people who use the kind of tools I build do actually value good usability!
The one big thing I would add to your points is that whatever kind of user interface you’re building — CLI, GUI, API, whatever — it’s always going to be limited by how well thought-out the underlying configuration model is. If you have a system that requires 745 interacting settings to be correct before it works, and the guy who changes those settings is doing it at 4am after his pager woke him up, you’re unlikely to see a happy ending no matter how polished the presentation of those 745 settings might be in any UI. It never ceases to amaze me how many UIs don’t get their fundamentals down first, and just think it’ll be OK as long as the UI is pretty, compatible with Brand X, compatible with Scripting Tool Y, compatible with Management Protocol Z, or some other useful but second-tier benefit.
Please do share any other rants, general frustrations, examples of things that were really useful, or other similar comments you have. These kinds of threads are gold for those of us who work in the industry.
What about Mercurial? [...] I'm considering switching from Subversion to something else for my team at work, but the Git UI is awful. I've heard Mercurial is better, including its GUI integration (e.g. Tortoise).
In UI terms, there are respectable GUIs available for both Mercurial and Git these days. I’d say the biggest difference is in the CLI interaction, because the usability of Git is poor even in its native habitat on Linux, and on Windows you're basically stuck with Git Bash, which is a rather glitchy emulation of a Linux shell that IMHO is very irritating to use. Hg is much simpler and less cluttered.
In terms of functionality and the underlying models for how the system works, I’d say there are a few major differences between the Git and Mercurial workflows that you're likely to come across almost immediately. Some are “real” differences. Others look like differences when you first learn the tools, but they’re only consequences of how each tool works by default and you can work the other way if you prefer.
The first is that Git by default does a two-stage commit: you identify the changes you want to commit from your working copy using git add, and then you actually commit them to your local repository with git commit. In Mercurial, the default is commit everything with a single command. However, this is one of those illusory differences, because both systems have alternative commands/options that let you work the other way if you prefer.
The second is that Git and Mercurial (in)famously have different mechanisms for using branches, and here there really are meaningful differences in the underlying model for how things are stored and what you can do. Personally, I intensely dislike Git’s approach where you “forget” which branches things originally happened on or even what those branches were called, because I find the information it discards valuable. However, you’ll have no trouble finding a Git fan to tell you I’m just being silly and obviously the branches-as-moving-tags approach taken by Git is better for other reasons. In this case, there are tools built into Hg these days that basically work the same way as Git’s branches if that suits you, but I’ve yet to find any satisfactory way of getting Git to support history tracking including branches the way Hg does.
Finally, on the subject of rewriting history, in Hg changes are basically permanent once committed, while in Git history is mutable by design using the rebase commands. Again, which is better for you will depend on your own workflow and personal preferences. In theory Git’s view is more flexible, but it’s also one of those issues where it’s a rite of passage to write a blog post about how not to screw up all your colleagues’ repos by rebasing something that was already pushed out to others, so use with care. Hg’s version is less amenable to certain workflows, but it’s also safer.
Finally, I just wanted to mention that whatever anyone tells you about how it’s obviously user error, both Git and Hg have had actual, verifiable, reproducible data loss bugs, even in the past few months. I haven’t checked very recently whether any of the ones I knew about are still unfixed, but definitely make sure you’ve got the latest versions of everything. (And if you’re using Hg, be really careful about cloning a repo on a network server directly and in particular whether you’re getting a truly independent clone or just an improperly-linked version of the original that will corrupt both over time. And if you’re using Git with an external diff tool like Araxis Merge, beware that using a git difftool --dir-diff has been doing funny things when you quit the diff tool and may overwrite any changes you made in your working directory while the tool was open.)
I respectfully disagree. I’ve worked on heavily numerical code in both C++ and Java. Writing horrors like (a.Multiply(a).Add(b.Multiply(b))) instead of a*a+b*b gets old after about the first five minutes. Also, I’m still waiting to meet the programmer who will make those * operators do division just to trick me, yet who writes Multiply to do multiplication as we’d all expect.
I find that file you cite very readable. It's well formatted, it's clear what the code is supposed to do etc., comments where necessary. Why do you think it's sarcasm?
Well, for one thing, it’s just code in a file. There is no obvious indication of how this code fits into the wider design of the program, because C doesn’t have much of a module/namespace system. (There are some comments right at the end that seem to be about build order dependencies, but it’s not clear to me what they are trying to achieve. I assume there is some sort of project standard that requires them.)
Next, consider the first function, xor_blocks. It appears to take about 20 lines of code just to call one of four other functions based on how many entries are in an array that was passed in. A significant proportion of the code is only there because the input arrived as a void** and a count rather than a typed array. The rest is repeating essentially the same pattern of code almost verbatim four times. It’s not clear whether the four do_N functions are completely different algorithms or just the same algorithm using defaults if there aren’t enough inputs provided. In the former case, you could express the entire function in about five or six lines in numerous other mainstream languages, most of which would just be a look-up table identifying the required functions. In the latter case, the entire 20+ line function would probably be redundant in many languages. And I see no reason another language that can express this kind of logic without the overheads shouldn’t generate code behind the scenes that is still 100% as efficient as the example.
A little further down, we start defining macros like BENCH_SIZE. When these are later used elsewhere, you can’t tell whether you’re working with a constant or a function call with side effects. (This is a big objection I have to complaints that C++ overloaded operators could do almost anything, coming from people who then argue that we should use C instead because everything is explicit.)
That brings us to the second big function, do_xor_speed, in which we again encounter our ambiguous struct containing function pointers and void* parameters. This time, we also use a magic number, rely on (presumably) a global variable and implicit side effects for the main loop control logic, apparently try very hard not to let that loop be optimised in some unspecified way, and cause various implicit side effects on some other (I assume) global variable.
The final major function, calibrate_xor_blocks, has similar issues, and further complicates things by interweaving local macro definitions that mean some of the code isn’t executed, or is executed but is immediately overridden anyway, as well as apparently obfuscating a simple function call behind another macro with a name that looks like a regular function itself.
Now, I do realise that a lot of this is how a lot of industrial C gets written in practice. I also realise that there are few realistic choices for a low-level, systems programming language today, and none that I know of has much better readability than C. But that doesn’t negate the criticism that the C code has fairly horrible readability/maintainability properties compared to what could be achieved in a more expressive language.
C is and will always will be more efficient with hardware than C++ (for equally skilled programmers).
Why would you say that?
There’s always been a great deal of emphasis in C++ on not paying any performance penalty for features you’re not using. Using the roughly common subset of the languages should yield similar results either way.
As far as the extra features in C++, I don’t see any reason to assume that (for example) a virtual function dispatch via a vtable in C++ should be less efficient than the old “look up a pointer in a jump table” techniques in C that serve a similar purpose. If anything, it should be the other way around, as the C++ compiler has a little more semantic information that it could potentially use to optimise the generated code for each target hardware platform.
True, but those few people who use C++ correctly seem to have learned their lessons with C.
That may be, at least in part, because many of the less than ideal aspects of C++ come from its C heritage.
I don’t understand some of the arguments made against C++ by certain “elder statesmen” of the OSS world. It seems they don’t like some of the extra functionality available in C++, seeing it as overcomplicated or too readily able to hide behaviour. In itself, that’s a reasonable concern. But then they use C, and reinvent the same wheels using crude text substitution macros that could be doing or interacting with anything.
On another forum discussion a few days ago, I saw someone argue that the Linux kernel is very readable, citing this C file as an example. I’m still not sure whether their comment was meant to be sarcasm.
And it makes sense, why would someone not want to join a site where all your friends are?
I prefer to spend time together with my friends and family in real life. Some of them I see often, and we don't always talk about big news. For those I see less often, I enjoy catching up with when we can, and that gives us interesting things to talk about if we're going to be spending a few days together.
I am well known among my social group as a Facebook skeptic and privacy advocate, but I just don't see how meaningful relationships can be maintained with a couple of impersonal "sentences" of text speak, the occasional cat photo, and dutifully typing "Happy birthday!" each time a little box pops up telling me to. If that makes me a recluse, what should we call someone whose primary social interactions come in 140 character sound-bites and who doesn't spend much social time with others away from their PC?
From personal experience, the version of Java on Macs seems to have lagged significantly behind the version widely available on other platforms from Sun/Oracle. It's not clear to me yet exactly what this announcement/reaction refers to, but if it means clients who use Macs wind up downloading/installing up-to-date Java runtimes like everyone on other platforms, and have the latest version as a result, that sounds like a good thing.
For what it’s worth, I can see a very strong case for type-safe rendering and systematic parsing of this kind of structured data. However, to my knowledge, no mainstream statically-typed language is expressive enough out-of-the-box to represent the structure of a typical JSON/XML/whatever schema in a concise, readable, maintainable form to support these goals.
Many popular statically-typed languages support all the basic arithmetic and logical operations for numeric and boolean data. Their standard libraries often include a bewildering array of additional mathematical functions as well. However, the basic text operations of rendering and parsing strings just don’t seem to get the same sort of support in most cases, perhaps because they are so much broader in scope. Likewise, manipulating structured data is often a weak point: today’s mainstream statically-typed languages tend to lack both the general flexibility you get with dynamic typing and the expressiveness and polymorphic tricks you get with algebraic data types and pattern matching in various functional programming languages.
string formatting/regexes are about the same in java as they are in python.
I’m not sure I’d go quite that far. There are several subtle advantages in Python (and one or two not so subtle ones) that IMHO make working with formatted text significantly easier overall.
For example, Java’s basic string formatting tool, String.format, and its regex patterns rely on numerical indices to identify specific placeholders and capture groups. In Python, you can use meaningful names in each case.
Another small but often useful win for Python is having raw strings, which cut down dramatically on backslash pollution when you’re writing regex patterns.
Finally, in perhaps the fairest example of the wider statically vs. dynamically typed language comparison, we have Java’s infamous verbosity against Python’s famous readability. Simple things like matching a regex with capture groups can require several lines of code and explicit creation of several objects in Java. In Python, you rarely need more than a single call to a function in re to get the same job done.
If static languages are better, why is the bulk of web development done with dynamic languages?
I don’t know how much of that is reality and how much is popular perception. In any case, here are some general trends in mainstream statically-typed languages and mainstream dynamically-typed languages today that might contribute to the popularity of the latter for web development:
I think these are more reflections of the languages in current use and their surrounding cultures, rather than inherent traits of static vs. dynamic typing, but if we’re talking about the state of the industry today, there doesn’t seem to be any practical distinction.
Whether to do The Big Rewrite always boils down to one very simple question: do the expected gains outweigh the expected losses?
Usually, the argument against doing a rewrite boils down to two key points:
Those are certainly valid concerns, and IME it is often true that their impact is underestimated. However, what the doomsayers tend to ignore is all the potential benefits from writing a second version of something from scratch but with the experience gained from doing it once already:
I’m sure some rewrites really are just because a developer wants to write something new instead of working with what is already there, and those are almost always a bad idea IMHO. On the other hand, it can be annoying if someone comes in assuming that this is the only possible motivation for a rewrite, without considering whether there is another justification for the decision.
I'm the author of the blog post.
In that case, would you mind explaining something that is confusing me, please? It sounds like you started the rewrite in early 2005, planned to release in mid 2006, and actually had a finished product in early 2007, which isn't on schedule but is hardly unheard of for a software project. However, you then seem to jump to saying the new version wasn't available across your entire international market until 2010. What happened in between?
Well of course they will have to follow through, because you have a political system that, despite its flaws, gives representation to third parties so everyone's political views can be represented.
Not very well yet: our voting system is still transparently biased towards the larger parties, and the compromise reached by the Liberal Democrats and Conservatives in the coalition doesn't go all the way to offering the public a referendum on PR in the Commons (though they do seem to be proposing it for the elected Lords).
But I do take your point: it seems likely that the presence of the Liberal Democrats in the coalition is pushing the civil liberties agenda higher up the government priority list. I think that is partly because it is a big Lib Dem policy area anyway, but also partly because it is something where both parties in the coalition can readily agree on most issues and say they were doing what their voters asked for. Any coalition wants to show early success to reduce the scepticism in the ranks, and since the Tories and Lib Dems have well known differences in economic policy so the top issue of today can't really help both of them at the same time, this is probably the next best area to look for that success story.
I find it ironic that the US should decide to introduce this measure under a new government when the old one was notorious for abuse of authority.
Meanwhile, here in the UK, we just handed electoral annihilation to the administration that introduced a similar guilt-by-suspicion DNA system here, not long after the European level courts ruled that keeping innocent people's DNA on the database indefinitely was illegal anyway.
One of the first proposals brought up by our new coalition government, indeed one of the points where both parties agreed on almost everything despite their general political differences, was a "Freedom Bill". That will basically be a mass repeal of all the draconian, intrusive, guilt-assuming laws that the previous lot brought in under a climate of fear that they perpetuated more effectively from the corridors of power than any terrorist group ever could. Introducing safeguards so that innocents' DNA is removed from the database in a timely fashion will be an acid test of that bill: they've talked the talk, now will they really follow through?
Hi, I’m a real typography geek. (Chorus: “Hi, typography geek!”)
*Real* typography geeks say Knuth got everything wrong.
Sure we do. We know Knuth was crazy to talk about paragraph-based hyphenation and justification, and it is madness that the Knuth-Plass algorithm remains the gold standard in H&J today and something that only TeX itself, InDesign, and a few high-end specialist packages can match even now. We hate all those fiddly thin spaces that you have to type manually, too; we’d much rather just have our adjacent quotation marks and superscripts clashing.
Speaking of superscripts, we know Knuth’s font design skills were appalling as well. Anyone could design a system of fonts that was still clearly legible when used to typeset mathematics with sub-subscripts at 4/5pt on the one hand, yet provided extensible brackets surrounding multi-line expressions without looking overly large on the other. We know this from the vast number of font families available from the world’s leading type foundries today that do the job, and the way mathematical journals have given up on TeX because modern fonts provide a much wider range of mathematical symbols that are still clearly distinguishable from any Latin or Greek glyphs that may appear nearby.
Maybe TeX was just behind the times, though. After all, in an era when TeX could only typeset a variety of proportional fonts with intelligent hyphentation, ligatures and correct punctuation, at a useful range of sizes, in a way that could survive photocopying a research paper and still be legible, the world’s serious typographers were probably already using word processors that could render a fixed size, monospaced font on their dot matrix printer with underlining!
TeX’s handling of fonts is archaic by modern standards, of course, though updates like XeTeX do a much better job when it comes to things like OpenType and Unicode. However, in fairness, Knuth developed TeX many years ago, at a time before these modern standards were a glint in their metaphorical parents’ eyes. I think it’s rather unfair to criticise on this basis, and much of what he did has set the standard for three decades.
Getting back on topic, if the person or people behind the tool we’re discussing can do half the job for musical notation that Knuth did for mathematics, it will be a very fine achievement indeed. As with mathematics, it is relatively easy to scribble musical symbols in a way that is technically correct, but rendering music in a way that remains clear and effective even when read at speed in large volumes is quite a different thing. Nitpicking about some of the typography in an early demo seems a little unfair, given the already high standard of the overall rendering.
Sorry, I wasn't clear: I was referring to big companies in the business software world, such as Microsoft and Adobe. Certainly the games world has been suffering a rash of silly DRM-related failures recently, but alas, that sort of software is not a common sight on my work machines. :-)
I'm with you on much of that, but just wanted to pick up on this point:
The failing DRM would IMHO fall under the "broken, please refund" category, as the software/game absolutely doesn't work as advertised in that case.
It's not the original purchase cost I'm so worried about in the case of dubious copy protection mechanisms, as I suspect you would have ways to get that back anyway if, say, the software wouldn't activate. What interests me in light of this case is the consequences if installing business software on a work machine rendered the PC unusable because the accompanying malware corrupted Windows, damaged the data in the boot sector, etc.
I'm particularly aware of this because not so long ago I switched to freelance work, which means that working time very much is money to me now. The thing that makes me wary of so much modern business software isn't the cost of buying it, which is a business expense I would incur anyway, it's the unknown losses due to downtime if all this activation and DRM technology somehow takes out an essential PC that I need to work on a contract.
My perception from reading various reports on the Web is that most of the time, the big companies do get it right, but if you're the unlucky one whose system is a bit unusual or whose product key some pirate clones, then there's a good chance you'll be hung out to dry. I would feel much better about investing in high-end software if I knew that I would have grounds for compensation if my business was interrupted because the attached malware went wrong under such circumstances.
Imagine if a car or a washing machine came with an agreement like that
I had a hybrid version: an automated car wash at a petrol station did serious damage to my car after it collided with it.
The immediate reaction from the staff on site was to deny everything, point at some weasel words on a sign full of disclaimers, and claim that my car wasn't suitable for their machine (even though they could see it when they sold me the token to put in the machine, and it had been through the same machine without incident on several previous occasions).
However, when it reached their central "customer care" people at head office, they immediately arranged to pay out a substantial sum of money to cover the cost of repairs on a reasonable basis (asked me to provide two quotes from reputable local repair shops).
I later discovered that there had previously been at least one similar case that had gone to court, where the car wash operators pretty much got torn a new one. I imagine the "customer care" people were aware of this, or at least their legal team was.
So much for "good enough" software
On the contrary, it seems this ruling says precisely that software must be good enough. Unless there's something in the actual ruling that is completely missing from TFA, this doesn't require all sold software to be perfect or bug-free, just that it be fit for purpose and of merchantable quality.
That probably means that the more you pay for software and the more the advertising promises, the better the quality and functionality would need to be. A cute graphics demo that cost £1 on an app store for your mobile phone would not be expected to do the same things and with the same reliability as medical device control software you sold to a hospital at £100,000 per unit.
Interestingly, the sale of goods act would cover open source software - even if the price was zero.
I am not a lawyer, but I fail to see why. From the Sale of Goods Act 1979, 2(1):
A contract of sale of goods is a contract by which the seller transfers or agrees to transfer the property in goods to the buyer for a money consideration, called the price.
I doubt £0 would constitute "consideration" in this context.
As far as I can see, the most significant consequences of this ruling are that:
This is particularly interesting because if EULAs do have any legal standing at all here, then they are probably a contract of adhesion based on technicalities about copyright.
I imagine some lawyers are running around looking nervous at quite a few big software companies this morning. All those DRM systems, for example, just became a bit of a liability: if I install a game and it simply doesn't work, then all those arguments about not returning opened products for a refund just became untenable. (Take note, Ubisoft and games shops.) And if you play silly wotsits on someone's computer to try to install your software's copy protection system and you get it wrong and damage their system, $DEITY help you, because it looks like the courts aren't going to. (Take note Sony, Adobe, et al.)
Of course, we'd have to see the complete context before reading too much into this case, because it sounds like the sale was made following significant contact between the parties and specific claims by the sellers, which might or might not still be the case with typical off-the-shelf or preinstalled software.
Don't CAD systems represent everything in very large integers?
Not necessarily: the libraries I used to work on used floating point values for the APIs. Typically, there would also be explicit resolution/tolerance values provided, which would be chosen according to the scale of the model.
Well, OK, I’m moving the goalposts. But discussing something that strictly speaking no-one can do isn’t particularly interesting, while there is an interesting underlying issue of whether it is cost-effective to write relatively high quality software, or whether we are doomed by economics to the predominantly mediocre mass market software we use today.