Monday, September 7, 2009

Things I wish were different in Padre

I've been using Padre as my primary editor for the last several days and I have to say that it's awesome. I've thoroughly enjoyed using it. However, there are some small things that tend to annoy so I thought I'd at least write them down so that, if nothing else, I'll have a list of potential things to hack into Padre if the mood takes me. And I'm making the list public in this way so that maybe even the LazyWeb will do the work for me :-)

In no particular order ...
  • The find dialog box appears right in the middle of the window and I always have to move it out of the way to see the text underneath. I think something like Firefox's find-at-the-bottom status bar would work well instead.

  • The mechanism for changing what language Padre thinks the document is written in is a little bit too cumbersome. There are times when I'm looking at some random perl file, but Padre doesn't figure out that it's Perl. So I have to go View -> View Document As -> and then select the appropriate language. I'd like something a little more Textmate-ish where I can click on the text in the status bar that indicates the language of the document and be able to select from the list there.

  • I wish there were a keystroke for deleting an entire line. There may actually be one, but I don't know what it is and I can't seem to find it.

  • The documentation could use a little work. :-) In searching for keystrokes that might delete a line, I stumbled across Control-D which apparently duplicates the current line. Later I was looking through the help and came across this:
    (TODO What is Ctrl-D ?, duplicate the current line?)

  • I can't seem to copy from the DocBrowser

  • DocBrowser Search doesn't seem to do anything useful as everything I search for ends in "no results found for ..."

  • Not really a Padre problem, but the vi plugin doesn't seem to support many editing keystrokes that I use all the time. I've been using Padre with the vi plugin turned off because of this, but I really wish one of two things would come to pass:
    1. the vi plugin supported more of the keystrokes I tend to use in vi or
    2. Padre provides some keystrokes of its own to do the things that I tend to want to do (like delete an entire line).
    Using Padre for the past week or so has made me realize that I'm not so tied to vi as I often think I am and that I could be happy with #2

  • There have been times when I'm clicking through a directory structure and the ".." entry at the top disappears. I'm not sure exactly when it happens, but it seems to happen whenever I click into a Catalyst project directory. I have to change the listing mode view to "navigate" to get it back and be able to navigate to the parent dir.

  • I really wish that padre would background itself when run from the command line. And that padre . would start the directory browser in the current directory.



Okay ... enough of that. These are just the little things that I've run across; nothing major. But it's the little things that affect your quality of life. Right now Padre is awesome but could use a few small QoL adjustments to make me happier.

CPAN.pm weirdness

The other day something strange happened. I tried azawawi's one-liner for upgrading Padre on my linux desktop. What happened was that the latest Padre (0.45) was downloaded and installed, but then so was version 0.40. I didn't realize that this had happened immediately, but once the upgrade was finished, I wanted to see something different, so I fired up Padre and went to Help -> About. I was shocked to see "Padre 0.40". So then I typed padre --version on the command line and again, it told me "Perl Application Development and Refactoring Environment 0.40". Still disbelieving, I asked on #padre how to tell the version of Padre installed and they, of course, said padre --version.

It was at this point that I realized I still had the window history available in the window I had typed the command originally. I scrolled back through the CPAN.pm output and there it was, plain as day; first in the original upgrade list was Padre 0.45 to upgrade Padre itself and then Padre 0.40 to upgrade Padre::Wx::Menu::Experimental (whatever that is). Weird. So, I ran the one-liner again while paying close attention to the output this time. This time it installed Padre 0.45 as expected ... and then installed Padre 0.44 because of Padre::Plugin::Perl5.

I don't know what was going on, but perhaps it was an old version of CPAN.pm because when I ran the same one-liner on my laptop, it worked flawlessly (I'll have to check the desktop tomorrow as it's at work and I'm not :). I have had weirdness before on my desktop since it was where I first installed Padre almost a year ago, so maybe that factored in somehow too. Anyway, in the end I just installed Padre 0.45 specifically and only and that worked just fine.

Monday, August 24, 2009

A Random Walk

Today I wandered around Perl6 stuff just a little bit. Here's some things that I ran into:

use.perl


First stop, masak's journal entry at use.perl. He's building a persistence layer for Web.pm that mimic's Ruby's ActiveRecord in a very simple way. Quite cool.

Drawing Blanks



Recently Rakudo Perl was changed so that make install could work. Actually, it was changed so that, in order to run the perl6 binary anywhere other than the build directory, you must run make install. Anyway, someone updated the page describing how to get Rakudo to include the make install instructions. Only they actually typed $make install where all of the other command-line-like lines have a space after the dollar sign and before the command. For some reason that little inconsistency was bugging me, so I thought, "I've got a login and edit rights, I'll just go change it!" The only problem is that when I tried to login, it took me to a blank page. Then, I was poking around on rakudo.org and there were several prominent pages that all ended up blank on my browser. Bummer. I left a note to alester with a bot on IRC in hopes that he'd know what to do.

Turtles all the way down



On a lark, I tried to install Rakudo on cygwin. However, the only Windows box I have handy is actually a VirtualBox instance. So, I tried installing Rakudo on a unix environment running on a virtual Windows environment running on a unix OS. In the process I realized just how much of Parrot's build process is dependant on Perl. It got a long way before it complained about not being able to find a compiler.

Unfortunately, it didn't work. After installing parrot, it died tried to execute parrot_install/bin/parrot_config. In fact, it seemed to die executing any of the parrot binaries from within the parrot_install/bin directory. In fact, it seemed that the only time executing one of the parrot binaries worked was when they were run from the parrot build directory.

The End



And here's where it ended because I was too tired to do anything else.

Monday, August 10, 2009

Perl 6 databases

Earlier today (or perhaps yesterday by the time I get around to publishing this) Tim Bunce showed up on #perl6 and asked who wanted a commit bit to his java2perl6 project that converts Java files into Perl6. I wanted one. I've long been interested in something like DBI on Parrot, but DBI on Perl 6 is the next best thing. So, I checked out a copy of java2perl6 and started poking around.

Wait ... what?!? What does Java have to do with DBI or Perl 6? A while back, Tim Bunce posted that the JDBC made a good model for the driver interface for DBI 2, so we might as well just use it. So, that's what's happening. We're starting with the java code for JDBC and writing software to automatically convert these java files to Perl 6. And then eventually, something like DBI wil be built on top of it all. But java2perl6 is the start.

Anyway, the java2perl6 README says
See the POD in java2perl6 (in the bin directory of the distribution) for information on how to use this module.
Great. I know how to do this, I'll just type perldoc bin/java2perl6and see what it takes to get started. Never mind that I only have passing familiarity with Java, I'll figure that out later. I know Perl 6 fairly well.

Oops! Perldoc had some problems:

POD ERRORS
Hey! The above document had some coding errors, which are explained below:
Around line 104:
’=end pod EOS’ is invalid. (Stack: =begin pod)

As it turns out, java2perl6 generates some POD as part of its output.
This POD is in a here-document which apparently confuses perldoc
since the directives that are part of the output are at the start of
lines. Aha! My first contribution to the java2perl6 project: making
java2perl6 accessible via perldoc.

Okay ... now what?

The documentation in java2perl6 gives me a good overview of the command line arguments, what the program is supposed to do, and some nice examples. So, after installing the dependencies, I do the usual perl Makefile.PL && make && make test dance and everything looks okay. All tests successful. Now to attempt a conversion or two.

There's a directory called testjavas which looks to contain some java code I can try this out on, so I do:

perl -Mblib blib/script/java2perl6 -j '-classpath testjavas' ClassTest

Since I haven't installed java2perl6, I invoke it from within the build directory and pass the testjavas directory as an argument to javap. The name of the file that I'm converting to Perl 6 is ClassTest.java. The result of running the above command is that I now have a ClassTest.pm file with some Perl 6 code in it that hopefully mimics the class definition specified in ClassTest.java.

Looking at ClassTest.pm, it seems that java2perl6 doesn't generate the various data members defined in the .java file. That seems like something I could try to implement. But, as usual, I have far too little time to continue pursuing this and I'm feeling sleepy, so perhaps updating the generator is tomorrow night's task.

On a lark, I reran the above command with the --check option to see what happened and it failed specatularly because it couldn't execute a perl6 binary in my path. That seems like something that's under-documented. Also, it would probably be nice to specify a particular location for the perl6 binary rather than relying on the
path.

There seems to be a goodly amount of low-hanging fruit for participation for when I'm not so sleepy. Awesome. For now, I'm off to bed.

Tuesday, July 28, 2009

Perl 6 Documentation

There's copious amounts of documentation for Perl 6 in the form of the Synopses but sometimes it just doesn't explain things in a way that mere mortals can understand. In order to help these mortals I've created a github project for other, hopefully more approachable Perl 6 documents. This repository can be found at http://github.com/perlpilot/perl6-docs

I figure there will be 3 kinds of documents that will be useful to have:
  • Introductions
  • Tutorials
  • Quick References
Check out the README for what goes in these documents.

I've seeded the repository with the beginnings of a Perl 6 Regex quick ref and an article I wrote a while back as an introduction to Perl 6 Regex.

I haven't actually thought too much about other people contributing to the repository yet. I mainly started this because I've always got ideas kicking around for things to write about but I rarely start something. This repository gives me a place to at least start writing (I have no excuses now!). But if someone wants a commit bit, just email me at duff@pobox.com.

Also, earlier today on #perl6 we talked about various book efforts relating to Perl 6. I don't know if books on Perl 6 should also go here, but I'm certainly not opposed to it if someone wants to contribute :-)

Saturday, July 25, 2009

Small, shiny focus.

Recently, I was reading Chad Fowler's excellent book, "The Passionate Programmer" and I'd gotten to Part III: Executing. Chapter 23, "Be Where You're At" struck a chord with me. The hypothetical person in that chapter was always looking for the next thing that will advance their career instead of paying attention their job, so they tended to do mediocre work. I'm not quite like that guy, but I have noticed that my procrastination manifests itself as an inability to focus on whatever it is that I should be working on because there's always another, more interesting problem to solve. In short, I'm easily distracted by small shiny objects :)

Then I was reading PerlMonks where kiz asked a question about Perl's auto-incrementing of strings. moritz replied with a brief
exposition
of how it works in Perl 6.

That post reminded me of one of the small contributions I made to Perl 6. I wrote some code to implement the Perl 6 semantics of string increment for Rakudo. That code has long since been replaced but the important thing was that at some point in the past, I was able to identify a small problem space in a language that I enjoy and did something about it. I was able to push through to a solution without being distracted by small shiny objects. (Although, I imagine that it was the shiny, distracting object for some other task that I should have been working on)

Thinking of that past contribution ignited some small desire to do that again despite the distractions in my life. Ergo, I intend on finding small perl-related things to focus on for as long as possible and then a little longer if necessary until I get to a stopping point and then I'll blog about it. Hopefully, as I exercise those neurons dealing with focus, they'll get stronger and the distractions will impinge upon my brain less.

Thursday, July 16, 2009

Euler #52

I was looking at the problems in Project Euler for things to do in Perl 6 and a few of them piqued my interest. The following is a minor adventure in implementing the solution to problem #52.

The problem is to find an integer such that twice the integer contains the same digits (obviously, in a different order) as three times the integer and the same digits as four times the integer and so on up to six times the integer. Here's the naive approach:

use v6;

my $n = 1;
loop {
my $s = (2*$n).comb.sort;
last if
$s eq (3*$n).comb.sort &&
$s eq (4*$n).comb.sort &&
$s eq (5*$n).comb.sort &&
$s eq (6*$n).comb.sort;
$n++;
}

say $n;

Some interesting things to note if you're not familiar with Perl 6:
  • there's a loop-forever construct
  • method call syntax uses a dot
  • everything is an object that you can call methods upon
See the official Perl 6 documentation for more information.

In order to check that the numbers have the same digits I needed to come up with some way to make a "signature" for each number such that numbers with the same digits have the same signature. I chose to do this by treating the numbers as a string of characters (a natural shift in thinking for Perl people), chopping up the string into a list of characters and sorting this list. For example, applying this process to the numbers "26321" and "62321" would both yield "12236", thus they have the same signature and the same digits.

To split the number into individual characters, you'd think that you would use the split subroutine and in Perl 5, you probably would. But Perl 6 has a shiny new routine called comb that acts as a counterpoint to split. In previous Perls, if you knew what you wanted to throw away from a string you would use split and if you knew what you wanted to keep, you'd use a regular expression capture (my @keep = $string =~ /\d/g). In Perl 6, split is the same, but comb is the routine of choice when you know the parts you want to keep. Given a regex, comb returns all parts of the string that match the regex. The default is to match single characters.

Like many things in Perl 6, there are both subroutine and object method forms. In the above code I use the method form of both .comb and .sort. (2*$n) gives me an integer that I then apply the .comb method to in order to turn the integer into a list of characters which I then apply the .sort method. Thus yielding an ordered list of the digits that comprise the integer in question.

But wait a second ... how can this work? If the result of using the .comb method is a list of characters and the .sort method sorts that list of characters, how can I use a string equality check on two lists? The answer is: Perl 6 magic! Because the lists are used as operands to the eq operator (a string operator), they get evaluated in string context. So, a number such as 26321 turns into the list ( '1', '2', '2', '3', '6') by .comb.sort which gets turns into "1 2 2 3 6" when evaluated as a string.

Neat, huh?

After I had coded this solution, it occurred to me that this approach could be improved. I think it was right around the time I got tired of waiting for an answer and hit Control-C to abort the run.

At some point 6*$n will be big enough that it will have more digits than 2*$n, thus making the probability that they have the same signature drop to 0. We can optimize a little by only examining those numbers where 2*$n and 6*$n have the same number of digits. How do I know how many digits they have? I could have just checked the length of each number, but I chose to use the logarithm function because I'm bent in a mathy sort of way.

The logarithm base 10 tells you how many digits are in a number. However, Perl 6's log function uses 2.718281828 (e) as its base, so I had to write a little routine that converts from base e to base 10.

Here's the improved code:

use v6;

sub log10($n) { return log($n) / log(10) }

my $mag = 1; # current power of 10
my $n = $mag; # number to start searching from
loop {
my $s = (2*$n).comb.sort;
last if
$s eq (3*$n).comb.sort &&
$s eq (4*$n).comb.sort &&
$s eq (5*$n).comb.sort &&
$s eq (6*$n).comb.sort;
$n++;
if log10(6*$n).int > log10(2*$n).int {
$mag *= 10;
$n = $mag;
}
}
say $n;

I call the .int method on the return value of my log10 routine to get the integer portion of the logarithm. If the logarithm of 6*$n is greater than the logarithm of 2*$n, then I need to skip to the next power of 10. The variable $mag keeps track of the current power of ten that I am examining.

For the curious, here's the optimized code that checks the length of each number:

use v6;

my $mag = 1; # current power of 10
my $n = $mag; # number to start searching from
loop {
my $s = (2*$n).comb.sort;
last if
$s eq (3*$n).comb.sort &&
$s eq (4*$n).comb.sort &&
$s eq (5*$n).comb.sort &&
$s eq (6*$n).comb.sort;
$n++;
if (6*$n).chars > (2*$n).chars {
$mag *= 10;
$n = $mag;
}
}
say $n;


Yes, it's simpler because I didn't need the log10 routine. But I did tell you I was bent. In Perl 6 the word "length" is outlawed because it isn't specific enough. It doesn't tell you what units you're getting. To ask, "what's the length of a string" you need to specify if you want the length in characters or bytes or graphemes or codepoints or whatever. To that end, there's now a .chars method that gives you the number of characters in a string.

Anyway ... that's a quick look at implementing problem #52 in Project Euler