Software/Device Development and Design

I recently ran into an issue I'd like to talk about in case anyone else has hit the same problem.

On my main PC, I run Manjaro Linux (an offshoot of Arch Linux). Recently, when I tried to to perform a system update, I started getting errors preventing me from updating. The problem was a conflict relating to package "ffmpeg2.8", which was in turn required by "4kvideodownloader". Now, you may or may not be familiar with 4kvideodownloader, but the details of it aren't especially important (aside from the fact that it's freaking awesome and I highly recommend it). What is important here is that I like 4kvideodownloader, and there are reasons I don't want to give it up.

This left me with a dilemma. The 4kvideodownloader tool (via its "ffmpeg2.8" dependency) were blocking me from updating my machine. The obvious choices were to either stop making any updates to my machine forever, or uninstall both "ffmpeg2.8" and "4kvideodownloader". I hated both options.

So I took a gamble. I uninstalled both "ffmpeg2.8" and "4kvideodownloader", hoping I would then be able to update my Manjaro/Arch-ish system and then...somehow...be able to get "4kvideodownloader" installed and working again.

Which brings me to the whole point of this post:

The gamble paid off! Once I uninstalled "ffmpeg2.8" and "4kvideodownloader" via yaourt (turns out, both are AUR packages), I had no trouble updating my system. And then, best of all, I had no trouble re-installing "4kvideodownloader" (along with its dependency, "ffmpeg2.8") afterwards.

Summary (ie, that's ordinary English for "TL;DR", for any of you hipster, fashion, Portlandia-as-everyday-life nerds out there.) :

You don't have to give up 4kvideodownloader, or wait for a AUR update to 4kvideodownloader, to update your Arch Linux-based system. Just uninstall them so you can update your system, and then you should have no trouble re-installing both. It worked for me...

In the D community, we have a strong belief in D's potential as a suitable and favorable alternative to C and C++ for areas commonly served by C/C++. This isn't surprising, since that's exactly how D was originally designed and envisioned.

To help facilitate that, D has always been designed to easily interface and directly link with C code. More recently, major improvements have also been made in interfacing D with C++. Naturally, one major benefit of this is to provide D with access to the wide array of existing C/C++ libraries. But the other key idea here is to help encourage D uptake. How? By making it easier for existing C/C++ projects to include D portions without the entire project needing to be ported.

This C/C++ interoperability is a fantastic feature for D to offer, and is essential in encouraging and facilitating migration to D. Building off this, we have Deimos, to offer D projects ready-made bindings to C/C++ libraries. Other projects in code.dlang.org may offer to auto-generate D bindings or wrap existing Deimos bindings with D-centric benefits and simplifications. All of this, we hope, will make D appealing enough and entice C/C++ users to try out D in their projects - and potentially, commit more fully down the road.

But we're overlooking a key part of the picture. We're looking at something backwards:

Our whole approach to giving D inroads into the C/C++ world relies on convincing C/C++ users to actually try out writing D. Even before they do that, they must actively decide to go learn some D. We've had some success, but as many of us have learned, this can be a significant uphill battle. The status quo is strong with programmers (and understandably so).

Take our existing focus, offering C/C++ libraries to D projects: What if we flipped that around and started using D's C/C++ interoperability to offer D libraries to C/C++ projects?

Think about it: If a D library came with its own C/C++ bindings, then it may as well be a C/C++ library as far as most C/C++ users are concerned. Then just slap into a C-world-compatible makefile into the library, which auto-detects a D compiler and, if none, does an automatic project-local download/install of DMD/LDC/GDC (this could all be offered to D libraries via a single D tool up on code.dlang.org), or even just include precompiled library binaries, and done: on any platform D supports, C/C++ users can use your D library just as if it were another C/C++ library.

That gives D inroads into C/C++ projects without requiring any C/C++ user to ever have to touch one line of D. Then, later, when coders wonder how the library they use works so efficiently and reliably, and is developed so productively - they can glance into the lib, see how simple it really is compared to a C/C++ equivalent, and see how much easier still it would be to use the library from D. Nice, D has just marketed itself.

tl;dr (In my day we called that a "summary"): I propose free C/C++ bindings with every D library! The D community should strive to offer them as a standard matter of course. Tools should be created to help D library authors offer their own C/C++ bindings. This will take us much farther into the C/C++ domain than merely offering C/C++ libraries to D users will.

Hell, I'm amazed they even choose to swipe it in the first place: The biggest visual abomination to hit computing devices since Windows 2, attached to the biggest operating system blunder since...well, since the last Microsoft operating system blunder, Vista, and some Google genius decides, "Yes, this is a great thing for us to imitate."

As if stealing Metro wasn't insane enough, they just had omit the one good thing Metro actually does have going for it: Actual...fucking...words right below all the nonsensical hieroglyphs. (Even Chinese/Japanese logographic writing occasionally has such a thing as "Ruby/Furigana". And those are for long-established symbols, not some vague squiggly metaphor pulled out of a random cubicle-dwelling technohipster's ass one afternoon.)

Seriously Google, if I wanted my phone to look like Windows Phone Unicorn-Vomit Edition, I'd get a Windows phone. At least then I could actually read all the meaningless idiotically-designed buttons.

It's no secret I'm a big fan of D, and very critical of most other languages. But there is another language I actually do like: Nemerle.

Some highlights of Nemerle

Like D, Nemerle is one of the few languages which truly "gets" metaprogramming and provides a decent implementation[1] (unlike, say, C# which only offers a half-baked generics system plus a dynamic type and simply leaves it at that). D and Nemerle's approaches to metaprogramming are entirely different and both have their pros and cons, but I like them both.

Another thing I love about Nemerle is its powerful, yet extremely accessible, algebraic types and pattern matching. This is actually one area where Nemerle is vastly ahead of D: While D does offer algebraics via its standard library, they're nowhere near as nice and clean as they are in Nemerle.

Nemerle (as does D) naturally has its downsides, though. For one, it lacks D's fantastic "ranges and algorithms" system. Also, like C#, Nemerle's reliance on CLR (ie, Mono/.NET) renders it medicore at best for low-level bare-metal work. And unlike Nemerle's designer's, I remain entirely unconvinced that merging the ideas of "statement" and "expression" leads to an cleaner, nicer language. I realize the common statement/expression separation isn't necessary and hasn't always existed, but I happen to like it, and I find it more useful than problematic. I don't like implicit returns, and as for the benefits of blurring the statement/expression line: Having lambdas, the ternary operator and an expression equivalent to switch blocks are all I've ever desired. The merging just seems unneccesary and overboard. But that said, I can certainly live with it just fine.

Overall, D is still my preferred language. But Nemerle is the only other language I can say I genuinely like.

Nemerle's one big blunder

For all its good, there is one big thing about Nemerle that's been bugging the hell out of me: The if statement requires an else clause. If you don't want else, you say "when", not "if".

That may seem minor, and the Nemerle designers do have a very deliberate reason for it: "to avoid stupid bugs with dangling-else". They provide the usual old dangling-else example that relies on combining bad indentation with omitting brackets on multi-line blocks.

I have a problem with that reasoning.

In language design, any feature or deviation from common expectation needs to pull its own weight. The benefits must outweigh the costs. Let's see:

Benefit: "Eliminate stupid dangling-else bugs": Mmmm hmmm. Ok. So....Who the fuck actually hits this issue?!? I've been coding for twenty-five years. As such, I firmly believe that stupid mistakes happen, to even the best of programmers, and that the true mark of an amateur is believing you can (or have) overcome that. I openly admit I've made, and will continue to make on a regular basis, every stupid freaking mistake in the book...except this one. I have never made this one. I have never even seen this one get made by anyone, anywhere. I admit, I really do have no doubt it does get made. Sure. Occasionally. On rare occasions. But heck, who the fuck ever omits the curly braces around a multi-line "if" body anyway (a requirement for this bug to occur in a whitespace-insensitive language)? If it does happen, who the fuck lets it pass code review, whether dangling-else bug or not?

Is the benefit of eliminating this rare bug worthwhile? Naturally, that depends on the cost:

Cost: Take one of the most basic, common, fundamental constructs in all of programming, modify it, rename it, and force every addition/removal of every "else" clause anywhere to always involve swapping between "if" and "when" on a different line of code.

So, a major disruption to one of the most fundamental constructs in order to eliminate a bug that's quite frankly more theoretical than real? No. No Nemerle, that is not a good tradeoff.

Solution

Luckily, Nemerle's biggest problem also demonstrates one if it's greatest strengths: This design flaw is easily changed, in mere user code alone, without hacking or modifying the language or compiler at all:

macro plainIf(cond, body)
syntax("if", "(", cond, ")", body)
{
}

That's it. That solves it. Those few lines bring back a normal "if". Just toss that into a "plainIf.n", compile to a DLL:

ncc -r Nemerle.Compiler.dll -t:dll plainIf.n -o plainIf.dll

Then toss that DLL into your project:

ncc -r plainIf.dll [...the rest of your args here...]

And magically, you can use "if"s with or without an else. Nice.

For convenience, I've put this code (along with Posix/Windows buildscripts and a small test program) up on GitHub, in a simple project named plainIf.

[1] Ok, I realize there is *ahem* a certain enthusiastic subset of programmers who will look at Nemerle's macros and bring up the ol' "Everything is LISP" idea. And y'know what? They may well be mostly right. But, if I want to drown in a torrent of barely-readable symbols, I'll just use brainfuck and get to the "shoot myself" stage that much quicker.