some guy on the Internet

the network engineer fears the backhoe, and the systems engineer fears the network engineer

When Philosophy Majors Write Perl

| Comments

In the interest of doing something other than yelling at clouds, it occurred to me that rather than just sniping at other people’s Perl, I might step up and demonstrate an alternate path. So, here goes; reference code is at my convenience fork of Math::Derivative.

The original:

1
2
3
4
5
6
7
8
9
10
11
12
sub Derivative1 {
    my ($x,$y)=@_;
    my @y2;
    my $n=$#{$x};
    $y2[0]=($y->[1]-$y->[0])/($x->[1]-$x->[0]);
    $y2[$n]=($y->[$n]-$y->[$n-1])/($x->[$n]-$x->[$n-1]);
    my $i;
    for($i=1; $i<$n; $i++) {
        $y2[$i]=($y->[$i+1]-$y->[$i-1])/($x->[$i+1]-$x->[$i-1]);
    }
    return @y2;
}

My substitute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
sub Derivative1 {
    my( $x_vector, $y_vector ) = @_;
    my( @derivatives );

    my $p1 = _getNextPoint( $x_vector, $y_vector );
    my $p2 = _getNextPoint( $x_vector, $y_vector );

    push( @derivatives, _slope( $p1, $p2 ) );

    while ( my $p3 = _getNextPoint( $x_vector, $y_vector ) ) {
        push( @derivatives, _slope( $p1, $p3 ) );

        $p1 = $p2;
        $p2 = $p3;
    }

    push( @derivatives, _slope( $p1, $p2 ) );

    return @derivatives;
}

sub _getNextPoint {
    my( $x_vector, $y_vector ) = @_;
    my $point;

    my $x = shift( @{$x_vector} );
    my $y = shift( @{$y_vector} );

    if ( defined( $x ) && defined( $y ) ) {
        $point->{x} = $x;
        $point->{y} = $y;
    }

    return $point;
}

sub _slope {
    my( $first, $second ) = @_;

    my $dx = ( $second->{x} - $first->{x} );
    my $dy = ( $second->{y} - $first->{y} );

    my $slope = 0;
    if ( defined( $dx ) && defined( $dy ) && ( $dx > 0 ) ) {
        $slope = ( $dy / $dx );
    }

    return $slope;
}

Yikes. I can’t help but notice that my version ended up being on the order of four times as long; however, about one-third of that increase is whitespace. To my eyes, the use of whitespace, indentation, and grouping characters helps break down the program into manageable, coherent chunks. And to the best of my knowledge, I didn’t cheat and use any syntax that wasn’t available at the time the original was written.

It didn’t help that there were no tests included with the individual module; I made one simple test, which the original code and my code both pass (prove -l t from the top-level directory to run the test). There’s still plenty of room for additional testing, never mind the fact that neither version has any reasonable amount of input validation, error handling etc.

So, there’s my assertion that Perl doesn’t have to look like gobbledegook.

When Mathematicians Write Perl

| Comments

As a followup (of sorts) to my last post, I give you the following:

1
2
3
4
5
6
7
8
9
10
11
12
sub Derivative1 {
    my ($x,$y)=@_;
    my @y2;
    my $n=$#{$x};
    $y2[0]=($y->[1]-$y->[0])/($x->[1]-$x->[0]);
    $y2[$n]=($y->[$n]-$y->[$n-1])/($x->[$n]-$x->[$n-1]);
    my $i;
    for($i=1; $i<$n; $i++) {
  $y2[$i]=($y->[$i+1]-$y->[$i-1])/($x->[$i+1]-$x->[$i-1]);
    }
    return @y2;
}

That code is correct, right? I sure hope so, because man do I not want to grovel over that and figure out what the hell it is doing.

This glorious manifestation of the human intellect comes from Math::Derivative, a Perl module which, well, does what it says on the tin: it provides functions that compute first and second derivatives of matrices of points. The excerpt above is the first derivative function; the second derivative function is just like that, except more so.

To start out I should mention that it consistently provides plausible results (I’m using it in code that tries to detect sudden changes in rate of change of numeric metrics over time, i.e. “call for help if the database starts bloating up”), but the style, oh, where to start?

  • Um, whitespace? Ever? Between lines? Between characters? It’s like reading someone’s JavaScript after it’s been through JSMin or some such. Especially since Perl is tolerant of inserting newlines for clarity, there’s no excuse.
  • The variable names. Yes, I know, it’s basically translating from the formula, but the combination of the one-character names with the one-character (or multi-character) sigils – seriously, $n=$#{$x}, I never want to see you again – is a recipe for headache. Oh, and also you have to play detective to figure out what kind of data each variable represents? Was it immediately obvious to you that the $x and $y that get passed into the subroutine are references to arrays of scalar values? Yeah, it’s clear in retrospect, but the principle of least astonishment is not just for user interfaces.
  • The mishmash of operators. Considering the previous two points, the similarity between the - operator (in this case numerical subtraction) and the -> operator (dereference) and the > operator (numerical greater-than) makes the code look eerily like a QR code or a random-dot stereogram.

And so forth. There’s no good reason why this code has to be so obscure; sure, it’s written in an older idiom, but even then it was terrible. One thing at least the author can be proud of: the version of this module on CPAN is 0.01, written in 1995.

Apparently mathematicians get it right the first time. :)

An Entirely Needless Obstruction

| Comments

OK, see this? This is why people say uncharitable things about Perl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (@cmd)
{
    next unless grep /^\Q$cmd\E$/, split(" ", $_->[1]);
    $cmd_data = $_;
    push @{$cmd_data->[3]}, ["filter", undef, undef, \&parse_filter] if $_->[1] =~ /\bdescribe/;
    for (@{$cmd_data->[3]})
    {
  for (split(" ", $_->[0]))
  {
      (my $key = $_) =~ s/-/_/g;
      $keyword{$key} = undef;
  }
    }
    last;
}

It doesn’t matter whose code this is. Suffice it to say that it

  • is a crucial part of a publically-available, fairly popular program,
  • was last edited in 2011,
  • is standing in the way of my getting something accomplished today.

Where to even start? What’s with the magical anonymous array-indexed data structures? The positional parameters (gotta pass those undefs or everything is busted)? The assignment of named variables to $_ (yay!) and then going on to dereference $_ instead of the named variables?

I’m not sure I’m willing to give this a pass as being baby Perl; this is just a design that has been stretched comically (tragically?) far beyond its original limits. This makes me cranky and sad.

Time to figure out what the hell is going on here so that I can patch this code. Fantastic.

SETEC ASTRONOMY

| Comments

This morning I learned about Secret via Tom Limoncelli’s Twitter. I’m not at all sure how I feel about this service.

As I understand it, the motivation behind this service is that people self-censor too aggressively when posting online, and so Secret offers a platform with many of the benefits of other social network platforms, but with pervasive anonymity. I understand the concern that people are keeping their real thoughts to themselves due to fear of the real-world consequences of their expressing controversial views; however, I tend to think that more often than not this is a good thing.

GitHub Behaves Better

| Comments

I am pleased to report that after a lot of people yelled at them over the course of this past week, GitHub tried again to present the findings of their internal investigation (context), and did a much better job of it.

I particularly appreciate their willingness to look at themselves with a critical, rather than a defensive, eye. I am not unfamiliar with how it feels to have the massively distributed ire of the Internet focused on you and your organization, and I salute GitHub’s leadership for resisting the urge to tack on a parting “and that’s why you were wrong to be so mean to us” or some such.

This doesn’t mean that everything’s OK. I’m still sad about this sequence of events, both about the original incident and then the first blog post (to say nothing of Preston-Werner’s personal blog post, yikes), and I suspect it will take more time and more scrutiny before I feel comfortable being the GitHub fanboy I used to be, if ever again.

More Clay

| Comments

And the hits keep on coming. ┬ノ─┬ノ︵( ⸰ ˘ ⸰ )

Dear people and organizations in technology who I like and respect: please behave better wrt diversity and inclusion.

-steve

P.S. On the other hand, a tip of the hat to Luke Kanies and James Turnbull for reaffirming my faith in the DevOps community. Keep it up, gents.

Legs of Clay

| Comments

I came home a couple of hours ago, returning from a full day: the first two-thirds of my workday involved troubleshooting an application performance issue with my teammates, and the last third involved handing out RunKeeper swag at the Boston Marathon. I had been thinking I would write something all #BostonStrong-flavored about the experience of seeing all these people come out to spectate in defiance of last year’s madness.

But instead I made myself some dinner, and while I was cooking I read Tom Preston-Werner’s blog post about leaving GitHub (for context, a good place to start is this TechCrunch story (trigger warning: hostile work environment)).

A Real-Life Sysadmin Job Interview Question

| Comments

Yesterday one of my colleagues flags me down and points to his terminal. “Hang on a second,” he says as I walk over, “let me become root. OK, watch this: see, there’s plenty of free space on the root partition…”

At this point my heart leaps up with a sudden, fierce joy. Could it be? Really?

“But look, when I try to touch a file…”

1
2
3
4
5
6
7
# df -h
OK, see this?  This is why people say uncharitable things about Perl:Filesystem            Size  Used Avail Use% Mounted on
/dev/xvde             7.9G  5.3G  2.3G  71% /
tmpfs                 828M     0  828M   0% /dev/shm
# cd /
# touch foo
touch: cannot touch 'foo': No space left on device

At this point I cannot keep the grin off my face. “Try df -ih”, I say.

1
2
3
4
# df -ih
Filesystem           Inodes IUsed IFree IUse% Mounted on
/dev/xvde              512K  512K     0  100% /
tmpfs                  207K     1  207K    1% /dev/shm

Dun-dun-DUNNNNNNNNNNNNNN!

For the Heartbleed Doubters

| Comments

I promise that this is not going to become the All Heartbleed All The Time blog, but in my defence, this is kind of a big deal.

A vendor called CloudFlare decided to perform a practical test of the exploitability of Heartbleed by setting up a vulnerable site and challenging people to steal the private key. I think these two quotes encapsulate the story perfectly:

Here’s the good news: after extensive testing on our software stack, we have been unable to successfully use Heartbleed on a vulnerable server to retrieve any private key data.

followed by:

It turns out we were wrong. While it takes effort, it is possible to extract private SSL keys. The challenge was solved by Software Engineer Fedor Indutny and Ilkka Mattila at NCSC-FL roughly 9 hours after the challenge was first published.

Now consider a tool that my buddy Ventz put together for bulk scanning of network segments to detect Heartbleed-vulnerable webservers. There’s no reason to believe that he was the first person to think of building something like this.

The two lessons I see here are the following:

  1. Remember that there’s a difference between “I can’t do it” and “It’s impossible” :) Smart people tend to forget this, to their and others’ detriment.

  2. There is no more security through obscurity. If your service is accessible from the public Internet, you should assume that you are being scanned on a regular basis.

-steve