Showing posts with label ramblings. Show all posts
Showing posts with label ramblings. Show all posts

Sunday, 8 October 2017

Everything sucks. And that's OK.

There is no perfect code, no perfect language, no perfect framework or methodology. Everything is, in some way, flawed.

This realization can be liberating -- when you accept that everything is flawed in some way, it puts aside petty arguments about the best language, editor, IDE, framework, database -- whatever some zealot is pedaling as being the ultimate solution to your problems. It also illuminates the need for all of the different options out there -- new programming languages are born sometimes on a lark, but often because the creator wanted to express themselves and their logical intent better than they could with the languages that they knew. Or perhaps they wanted to remove some of the complexity associated with common tasks (such as memory allocation and freeing or asynchronous logic). Whatever the reason, there is (usually) a valid one.

The same can be said for frameworks, database, libraries -- you name it. Yes, even the precious pearls that you've hand-crafted into existence. 

In fact, especially those.

We can be blind to the imperfections in our own creations, sometimes it's just ego in the way. Sometimes it's just a blind spot. Sometimes it's because we tie our own self-value to the things we create.

"You are not your job, you're not how much money you have in the bank. You are not the car you drive. You're not the contents of your wallet. You are not your fucking khakis."

For the few that didn't recognize the above, it was uttered by Tyler Durden from the cult classic Fight Club. There are many highlights one could pick from that movie, but this one has been on my mind recently. It refers to how people define themselves by their possessions, finding their identity in material items which are, ultimately, transient.

Much like how we're transient, ultimately unimportant in the grand scale of space and time that surrounds us. Like our possessions, we're just star stuff, on loan from the universe whilst we experience a tiny fraction of it.

I'd like to add another item to the list above:


You are not the code you have written.



This may be difficult to digest. It may stick in your throat, but some freedom comes in accepting this.

As a developer, you have to be continually learning, continually improving, just to remain marginally relevant in the vast expanse of languages, technologies, frameworks, companies and problems in the virtual sea in which our tiny domains float. If you're not learning, you're left behind the curve. Stagnation is a slow death which can be escaped by shaking up your entire world (eg forcing learning by hopping to a new company) or embraced by simply accepting it as your fate as you move into management, doomed to observe others actually living out their passions as they create new things and you report on it. From creator to observer. You may be able to balance this for a while, you may even have the satisfaction of moving the pieces on the board, but you've given up something of yourself, some part of your creator spirit. You can still learn here -- but you can also survive just fine as you are.

Or at least that's how it looks from the outside. And that's pretty-much how I've heard it described from the inside. I wouldn't know, personally. I'm too afraid to try. I like making things.

This journey of constant learning and improvement probably applies to other professions, especially those requiring some level of creativity and craftsmanship from the member. You either evolve to continue creating or your fade away into obscurity.

And if you are passionate about what you're doing, if you are continually learning, continually hungry to be better at what you do, continually looking for ways to evolve your thought processes and code, then inevitably, you have to look back on your creations of the past and feel...

Displeased.

Often I can add other emotions to the mix: embarrassed, appalled, even loathing. But at the very least, looking back on something you've created, you should be able to see how much better you'd be able to do it now. This doesn't mean that your past creations have no value -- especially if they are actually useful and in use. It just means that a natural part of continual evolution is the realization that everything you've ever done, everything you ever will do, given enough distance of time, upon reflection, sucks.

It starts when you recognize that code you wrote a decade ago sucks. It grows as you realize that code you wrote 5 years, even 2 years ago sucks. It crescendos as you realize that the code you wrote 6 months ago sucks -- indeed, even the code you wrote a fortnight ago could be done better with what you've learned in the last sprint. 

It's not a bad thing. The realization allows you to divorce your self-worth from your creations. If anything, you could glean some of your identity from the improvements you've been able to make throughout your career. Because, if you realize that your past creations, in some way or another, all suck, if you realize that this truth will come to pass for your current and future creations, then you have to also come to conclusion that realizing deficiencies in your past accomplishments highlights your own personal evolution.

If you look back over your past code and you don't feel some kind of disappointment, if you can't point out the flaws in your prior works, then I'd have to conclude that you're either stagnating or you're deluding yourself -- perhaps out of pride, perhaps because you've attached your self-worth to the creations you've made. Neither is a good place to be -- you're either becoming irrelevant or you're unteachable and you will become irrelevant.

If you can come to accept this as truth, it also means that you can accept criticism with valid reasoning as an opportunity to learn instead of an attack on your character. 

I watched a video where the speaker posits that code has two audiences: the compiler and your co-workers. The compiler doesn't care about style or readability. The compiler simply cares about syntactical correctness. I've tended to take this a little further with the mantra:


Code is for co-workers, not compilers.



I can't claim to be the original author -- but I also can't remember where I read it. In this case, it does boil down to a simple truth: if your code is difficult for someone else to extend and maintain, it may not be the sparkling gem you think it is. If a junior tasked with updating the code gets lost, calls on a senior for help and that senior can't grok your code -- it's not great. If that senior points that out, then they are doing their job as the primary audience of that code. This is not a place for conflict -- it is a place for learning. Yes, sometimes code is just complex. Sometimes language or framework features are not obvious to an outside programmer looking in. But it's unusual to find complex code which can't be made understandable. Einstein said:

“If you can't explain it to a six year old, you don't understand it yourself.” 

And I'd say this extends to your code -- if your co-workers can't extend it, learn of the (potentially complex) domain, work with the code you've made, then you're missing a fundamental reason for the code to exist: explaining the domain to others through modelling it and solving problems within it.

Working with people who haven't accepted this is difficult -- you can't point out flaws that need to be fixed or, in extreme cases, even fix them without inciting their wrath. You end up having to guerilla-code to resolve code issues or just bite your tongue as you quietly sweep up after them. Or worse -- working around the deficiencies in their code because they insist you depend on it whilst simultaneously denying you the facility to better it.

At some point, we probably all felt the pang when someone pointed out a flaw in our code. Hopefully, as we get older and wiser, this falls away. Personally, I think that divorcing your self-image from your creations, allowing yourself to be critical of the things you've made -- this is one of the marks of maturity that defines the difference between senior developer and junior developer. Not to say that a junior can't master this already -- more to say that I question the "seniority" of a senior who can't do this. It's just one of the skills you need to progress. Like typing or learning new languages.

All of this isn't to say that you can't take pride in your work or that there's no point trying to do your best. We're on this roundabout trying to learn more, to evolve, to be better. You can only get better from a place where you were worse. Once of the best sources of learning is contemplated failure. You can also feel pride in the good parts of what you've created, as long as that is tempered by a realistic, open view on the not-so-good parts. 

You may even like something you've made, for a while, at least. I'm currently in a bit of a honeymoon phase with NExpect (GitHub, Nuget): it's letting me express myself better in tests, it's providing value to handful of other people -- but this too shall pass. At some point, I'm going to look at the code and wonder what I was thinking. I'm going to see a more elegant solution, and I'm going to see the inadequacies of the code. Indeed, I've already experienced this in part -- but it's been overshadowed by the positive stuff that I've experienced, so I'm not quite at the loathing state yet.

You are not your fucking code. When it's faults become obvious, have the grace to learn instead of being offended. 

Wednesday, 4 January 2017

Gentoo adventures: Diablo 1 HD!

I recently wrote about switching to Gentoo. It's been an overall quite positive experience. The following is a story about getting Diablo 1 HD running through WINE, because:
  • Diablo 1 is one of the most iconic games ever
  • Diablo 1 (vanilla) has always had some issues running through WINE (most notably, the main menu -- though I discovered today that if you alt-tab (in Plasma shell, at least), then the window preview actually does show the menu)
  • I stumbled across someone's post on Reddit stating that it could be done (though it turned out that his advice didn't work for me, but I did eventually get there)

Just in case you didn't follow the link, this is what I'm talking about:

Before we begin: WINE doesn't deal well with an app which changes resolution and then dies unexpectedly. I found this out the hard way. I'd highly recommend installing (if you don't have it already) xrandr and binding a hotkey to set your native resolution. If you're using xbindkeys (yes, I like old-school... it works, reliably and I have an existing config with tweaks to allow volume changing via the buttons on the side of my mouse), you can add this to your .xbindkeysrc:


"xrandr -s 1920x1080"
    Control + Alt + Shift + F12



to be able to swap back to 1920x1080 by pressting ctrl-alt-shift-f12, in case, somewhere along the way, you end up with a strange-looking desktop.

On with it then!

First of all, you're going to need an (ahem) original Diablo 1 CD. Just so happens that I do have one of those, living on a shelf of other games, many of which I own on Steam because optical media is so last century. I'm not advocating other methods for doing this. When I got this Diablo 1 CD, it cost around R50 (~$13). Not really gonna break the bank. If you really can't get one, you could try alternative methods, if you know what I mean.

Naturally, my instructions are going to be in Gentoo dialect, but I expect that there won't be a lot different for others, except the USE flag fiddling I did -- which you won't have to do in a binary distribution and also which may not be entirely necessary, though not hurtful. Some were attempts to get around sound issues and I'll point those out.

Ok, so you have your original Diablo 1 CD, right? First we need to install that, which means we need wine. I installed with the following package.use:

app-emulation/wine dos openal s3tc staging

Note that I added dos simply in case I wanted dosbox later, s3tc because equery u wine claims it may be needed for some games, staging because I was curious what I would be missing out on from pre-release features and openal because of that aforementioned Redditer. So I don't think you actually need any of this.

Once you have WINE installed, run the autorun.exe from your original Diablo 1 CD. Setup should be quick and launch into the game -- cinematics first and then a black screen as the menu isn't properly displayed. You can alt-tab out of this and just kill it.

Now download the latest Diablo 1 HD release and unpack it where you installed Diablo 1. If you stuck with all defaults, you'll find it under ~/.wine/drive_c/Diablo. This adds a Belzebub.exe executable, which you can attempt to WINE -- but you'll get an error about OpenAL. Belzebub is shipped with an OpenAL32 dll -- the problem is that it depends on DirectSound. The false trail to follow is to use the inbuilt openal in WINE -- for me, that stopped the error, but also left me with no in-game sound (though the cinematics did have sound).

What worked better for me was to run winetricks, which I installed with the following package.use:

app-emulation/winetricks rar
 
simply because I didn't want some arbitrary download to fail simply because it came down as a rar archive. I'm pretty sure you don't need it for this process though -- winetricks was downloading the directx9 installer and pulling out dsound.dll (source at time of writing). Once again, I don't think you need my USE flags at all -- but they don't hurt. If your distro doesn't bindle Winetricks, you can always get it here: https://github.com/Winetricks/winetricks.
Run winetricks and go through:
  1. Select default wineprefix
  2. Install a Windows DLL or component
  3. Select dsound and hit the Ok button
Downloading may take a little while, depending on your pipe. Installation was quite quick. Running winecfg afterwards, looking at the Libraries tab, you should see *dsound set native. And now you should be able to run

wine Belzebub.exe

in the ~/.wine/drive_c/Diablo folder, with the original CD in your optical drive and the game should start up and work properly. You can bask in the glory of a 20-year-old game, running at a modern resolution on an OS it wasn't designed for (:

For bonus points, you can pack away that CD if you're prepared to keep an ISO on disk:
  1. mkdir ~/DIABLO1_CD
  2. dd if=/dev/sr0 of=~/diablo1.iso (substitute your optical drive for /dev/sr0 if it differs)
  3. add the following line to your /etc/fstab
    /home/{USER}/diablo1.iso /home/{USER}/DIABLO1_CD/ auto loop,users 0 0
  4. mount ~/DIABLO1_CD

You could even put that into a script in your Diablo folder:  

#!/bin/sh 
cd $(dirname $0) 
mount ~/DIABLO1_ISO 
wine Belzebub.exe
cd - 

You will probably see some odd flickering as the app starts up. Just hang in there! Mount won't barf on multiple runs -- it will just refuse to remount. Happy hunting!

Monday, 2 January 2017

Like changing religion, only harder, part 2

Gentoo is not the distribution for you if:

  • You hate reading
  • You don't want to learn new stuff
  • You're not willing to do a lot of it manually
The Handbook is an excellent resource, rich in detail. I'd actually recommend that anyone wanting to learn more about how Linux-based stuff works give an installation a go, even if just in a safe VirtualBox VM.

That's where I starrted -- a VM. I need my desktop to stay in a fully working state, so I can't afford to have it partially working or offline for days on end. And even a preliminary look at the handbook was enough to inform me that this was no trivial task.

Now, I've been a little coddled, possibly, by how good even the early Debian (curses-based) installers were (and still are). Debian subscribes to the "chicken-peck philosophy": basically, once the installer is going, you're going to be asked a lot of questions, but the default answer, which a chicken would get by just pecking on the enter key, is sane and will work for most people, Debian also attempts to install with a sane set of default packages which would be useful (or at least not get in the way) for most people.

Gentoo, on the other hand follows the "your machine, your rules" philosophy -- you're basically not guided with much at the terminal. You are going to need that handbook, unless you've done this a few times before.

After a few hours each night for a few nights, I felt like I had a handle on this and discovered that I had a hard drive I wasn't using. My only niggle was that I hadn't managed to get sound to work in the VM -- whenever I tried to play any sound, the player would just lock up. Still, I thought it was worth giving a go, whilst leaving my default boot sequence intact (and manually selecting the spare drive to boot from, when I needed to). I also found that I could do a lot just in a chroot whilst being booted into my existing Debian installation, so that helped a lot.

I'm still learning, but so far, I've gotten to the point where my default boot is the Gentoo installation, launching into a Plasma5 desktop. It's appreciably more responsive than I ever had Plasma5 before (which is why I had been quite happy to downgrade to KDE4 when I last installed Debian over Ubuntu) -- indeed it's more responsive than my Debian install in pretty-much every way. Some points that were interesting in the process:

  • The dmix ALSA plugin no longer requires magick to make it work (as it did when I first encountered it, ages ago). DMIX was, for me, this unattainable holy grail -- I never managed to muster the .asoundrc-foo to get it working. Which is why I had resigned myself to having to be bound to PulseAudio for all these years. But the good news is that I didn't have to configure a thing -- ALSA worked with software mixing out of the box, with no coaxing. WIN!
  • Installing a service doesn't mean it will be automatically started at system boot. This was a little surprising to me, but it fits in with the Gentoo philosophy -- you need to consciously decide that you want a service running at startup. It doesn't just happen. Fortunately, OpenRC is very easy to deal with, not like SystemD (at least, that's my experience)
  • Debian users will know that you pretty-much just need apt-get (install stuff and update lists of stuff you can install) and apt-cache (search for stuff to install). Gentoo has emerge for the searching and installing, but you're really going to want equery (from gentoolkit) and probably genlop.
  • Coming from a binary-based distro, USE flags are both interesting and scary. So now I have software compiled on my system with exactly the feature-set I asked for -- unlike binary packages, where I get whatever an upstream developer thought was a good feature-set. Not that that upstream developer was wrong or needed second-guessing: I never had a complaint with that. It's just an interesting paradigm shift and that Gentoo philosophy of consciously selecting stuff comes through again: I've often found that packages have practically the bare minimum of features aligned (Handbrake / ffpmeg is a good example) and I really wish I'd found equery uses a lot earlier. That handy little command not only tells you what use flags are available (which you can figure out with emerge -pv), but (mostly) what they actually mean.
  • Compiling. Eish. Be prepared to let your pc grind for an hour or so. Sometimes you can avoid this: there are binary packages for some of the more arduous bits (like LibreOffice and PaleMoon, though I chose to install those from source for funsies). Sometimes you can't (when I found that something I'd installed required that 32-bit versions of 177 other libraries be built). It's an elegant system though.
So I guess it's "So long, Debian, and thanks for all the fish". Perhaps Devuan will get a little more impetus and woo me back again. Who knows? But for now, I'm an habitually-tweaking Gentoo user.

Like changing religion, only harder, part 1.

I've used Debian or some derivative (Ubuntu, Linux Mint and even a brief stint with Corel Linux) as my primary desktop OS at home for around 16 years. Ok, I'll admit there was a brief period when I used Mandrake, before it was Mandriva and long before OpenMandriva. I also used OpenSUSE for a good few months, until RPM reminded me just how much I hate it.

Sure, I reboot to "that other OS" to game and sometimes dev (though that's mainly on a notebook now) and to observe windows updates. Gotta have a hobby. But my home pc spends upwards of 90% of its life in Linux land -- even more recently because I've been too lazy to reboot to game :/

I liked most of Debian, only choosing a derivative when I wanted more current software. I used Ubuntu long before it was the OS of the kool kids, all the way from Warty. It was all I liked about Debian with more current software but not the mad downloads required to keep up with Debian testing. I gave up on Ubuntu partly because of Unity / GNOME3 -- I had swiched to KDE, but it was never particularly fast. But something had already begun to bug me: PulseAudio.

Sound in Linux has traditionally been hard. I started before ALSA, when OSS was the way and there were a few sound daemons you could choose from, but honestly the best approach was to just get a sound card with hardware mixing -- I found a Creative AWE32 and things were good. But this PulseAudio beast was foisted on me and I never quite figured out how to shake it. I dislike it because it introduces noticable latency (even to my non-studio ears) and was always a little flaky. Last time I reloaded (from Ubuntu back to Debian plain, about a year ago), it was after finally simply having had enough of PA dying randomly. Nothing I tried would fix it for long and my desktop was laggy too -- it was just time for a clean house.

Going back to Debian was like a breath of fresh air -- things were faster, but there's still no (easy) hiding from PulseAudio. And Debian has also chosen to go the SystemD route -- another piece of software which I gave a chance, but just grew to hate more and more. Where are my logs? I have to learn journalctl commands, because they're not just in nice little text files under /var/log any more. How do I start/stop/restart a service? I have to learn systemctl commands, because /etc/init.d/(some service) (start|stop|restart) is only available for "antiquated" packages which haven't "upgraded" to systemd yet.

And don't get me started on boot (and even worse: shutdown / reboot) times. I'm running an i7 3770k with 16 gig RAM and an NVidia 660ti. Yeah, none of that is cutting edge -- but none of it is slothful either. Windows 10 on the same machine was making my precious Linux desktop feel positively sluggish.

We can't have that!

So I did what any other pedantic geek would do: downloaded ISOs and started checking out other distros in VirtualBox VMs. Primarily, I was interested in finding something that didn't use systemd, but it also had to be actively maintained, have a decently-sized community, have a lot of packages, have a good history (or be built on the shoulders of a giant with good history, like Debian). I found a nice comparison chart here: https://en.wikipedia.org/wiki/Comparison_of_Linux_distributions#Technical and set to work on evaluating in virtual environments. Ideally, I'd like to have found something Debian-based as I know the layout and tooling fairly well, but I was open to new experiences.

Most of the options I tried out didn't wow me, but a quick glance at the list linked above shows that one of the systemd-independent distributions is Gentoo.

Rewind a decade or so, and I remember having a good friend who loved Gentoo. Personally, it always felt like the OS of choice for an habitual tweaker. It just didn't seem to be worth the effort. For a while, the argument that compiling all packages locally would give a faster desktop was the primary reason I heard that I should consider it. It was also the primary reason for angst back then -- when getting a Gentoo box up and running with a desktop environment, browser, email client, office suite, etc, would take around a week. Those were the days when an Athlon 1800 was the business -- and there's no way an Athlon 1800 can compete with even a low-power current chip for compiling. Gentoo was the distro for people with nothing better to do than watch compilation output scrolling across their screens.

But I noticed that

  • OpenRC is the default init system for Gentoo (not some unsupported "you can do it, but good luck" option, like with Arch Linux, another distro I did consider because I've read a lot of good things about it),
  • Gentoo had a clear howto on setting up ALSA for sound cards which don't support hardware mixing and 
  • Gentoo is documented to the max -- there are wiki page upon wiki page of information
The last point is good -- but it's also a little scary for the same reason that over-documented code is scary: at some point, the documenting comments fall out of sync with the actual software logic and become misleading lies (and I've found some rabbit-holes in Gentoo wiki pages -- but mostly, they've been really helpful)

So Gentoo looked like a good choice.... Onwards and upwards!

Tuesday, 12 July 2016

Learn another language

A recent "Ask Slashdot" post posed the question about how often other developers switch and / or choose languages to develop in. One answer particularly caught my eye: the author proposed that there was a limit to the usefulness of learning a new language, particularly because a developer would probably stop using some or other language at some point and forget the language.

I have a different take:

Learning a new language allows you to see new ways of doing things (assuming you learn some of the ins and outs). Every language designed was made because someone couldn't do what they wanted in an existing language or the world it "lives in" (VM for interpreted languages, base library / stdlib for compiled-to-bytecode ones). Ok, so every serious language (leaving out the ones which are obviously just there because some people have a sense of humor (eg Shakespeare) and some people have a twisted sense of humor (Perl... ehm, I mean, whitespace!, yes, whitespace! And brainfuck! (: ).

The point is this: every time I've learned a new language, it's shaped how I write the languages I already know. F# changed how I write C#. C# changed how I write Javascript, and so on and so forth, turtles all the way down. In addition, it seems that the more languages I'm exposed to, the more abstractly I can think about concepts when coding -- much as I understand that learning more spoken languages trains the brain to think in a language-agnostic manner.

Sometimes learning a new language makes me appreciate the features I already know in other languages (I'm looking at you, R), sometimes learning a new language teaches you new respect for formatting and "just getting along" (Python). Sometimes a new language teaches you about constraints (Lua, particularly embedded), sometimes about being mad careful about memory (C/C++), sometimes it's about what can be cobbled together with existing pieces (ie, quick wins) -- bash / zsh / sh / batch  / PowerShell.

Sometimes learning a new language gives you insight into a technology stack which seemed mystically complex before learning it (PHP, classic ASP with VBScript/JScript; the web was all dark magick before I worked in it and classic ASP and PHP were where I cut my teeth -- not to mention, of course, Javascript for the front-end -- but the other two made me learn about HTTP and how the whole web stack works at a lower level than a lot of people can be bothered to understand these days).

Sometimes a language teaches you to think a level higher than the language itself -- Javascript, SQL, PHP -- anything with an eval() or equivalent and / or where you can inspect / reflect at runtime (Javascript, anything .NET, even, to a degree, COM-based programming. These teach you to think "meta" about what you're doing, instead of just cranking out another loop; also understanding the ins and outs of Javascript lets you subvert Typescript when it gets in the way).

Sometimes it's about understanding the lowest-level stuff (asm, IL), sometimes about dealing in sets instead of procedures (SQL, R). Sometimes it's a reminder that more words may initially seem more readable, but just become a PITA (VB6 / VB.net -- and they are well different) or that even if a language seems like it's "for dummies", you can still accomplish the same thing as more "respected" languages (VB6 / VB.net again).

Sometimes learning a language makes you learn how to listen very carefully to its proponents, eg Tcl: "everything is a list" and "everything is a command" -- when that truly sinks in, there's a white-hot moment of clarity; it takes a day or two, but when it properly sinks in...boom. After that lesson, I give a little more thought to seemingly esoteric observations about a language.

Sometimes a language teaches you about the UNIX philosophy -- doing one thing and doing it well, then chaining together with other utilities which also do one thing well (F#, shell / batch languages) -- which shaped how I wrote "more capable" languages, producing smaller, simpler units instead of monolithic ones.

Sometimes a "language" is just descriptive (document languages: HTML, XML, JSON, YAML, CSS) but sometimes they can be bent (XSLT) or bent via pre-processing (SASS/LESS). Sometimes a language teaches you to embrace the warts for all the cool stuff (Javascript) and sometimes a language tells you about how it was designed when you have seen some of the others that inspired it (Ruby) -- which is interesting in and of itself.

Sometimes a language seems more long-winded than it actually is and pleasantly surprises you (Java, particularly v7 on Android had some nifty tricks up its sleeve). Sometimes hacking something in a language gives you enough chills to not want to go back there (for me: Erlang, though I'm open to trying again) -- and even that is a positive learning experience.

Sometimes learning a language is just a lesson in history, of how things were once done and how, despite the forces against them, people can leave a mark on technology that is visible from space. I'm looking at you, Grace Hopper, and your creation: COBOL. There's a language structured around making your code look like something you'd find in a ring binder somewhere. And much of the world's financial institutions ran on that for, well, decades.

There's not one of them I'd wish to unlearn to get the time back. Indeed, I'm trying to get together the self-motivation to learn either Rust or Go, perhaps Haskell or Scala. Perhaps even Perl 6 (Larry promises that it's all better now). No particular reason other than perhaps it teaches me how to use my current tools better. Or perhaps I find another language which suits particular problems very well.

And yes, apart from whitespace and brainfuck (and, to be brutally honest, Erlang, which I hacked a little, but really, it doesn't count), which I've only read about, I've written code in all of the above. Some languages have been home for a long time -- literally tens of thousands of lines. Some I've dabbled in and moved on when I found something more suited to my immediate needs.

By "dabble", I mean only a few hundred lines or perhaps enough to understand how to port away from it (Perl, which never really managed to gain my approval, even though it's powerful stuff, but Perl seems to be a training ground for how to write line noise). But all have taught me something; all have been part of shaping my code as it dribbles out in the present, even if that lesson is how not to do it.

If you're a developer and you only know one language, you're doing yourself (and your team-mates and employer) a great disservice. Go out there and learn one of the wonderful, free languages that are available. If you don't know where to start, then pick the first one from this list that you don't already know:
  • Python
  • F#
  • Javascript (yes, there are people who don't know Javascript! Don't judge!)
Or any other language significantly different from the one you program in most -- find something that has a reasonably-sized community, many libraries (so you can actually get something done) and free tooling. There are heaps! Happy hunting (:

What's new in PeanutButter?

Retrieving the post... Please hold. If the post doesn't load properly, you can check it out here: https://github.com/fluffynuts/blog/...