I've been doing a bunch of NQP and PIR coding, where Pmichaud++ has been trying to support some kind of POD syntax. With the release of the S26 draft, he has tightened the parsing to follow more of the rules laid out in the spec, and after a few months, I've noticed that the trend (for not-quite-pod) is definitely getting worse. POD 6 isn't very nice. It certainly isn't an improvement on POD 5.

To be clear, by "not an improvement on POD5" what I mean is "I have abandoned POD6 in favor of block comments."

I don't have a rewritten S26 to offer - sorry - but I do have some thoughts on why.

There are a couple of things about POD5 that I didn't like. The biggest one, by far, was extra newlines. That got better over time, either because I changed my writing style or because the parser got smarter - I never tried to figure out which. The other big thing was no tables, which is definitely fixed (-ish) in POD6.

That said, POD5 was a lightweight, easily understood format. It was easy to figure out that there was text mixed with the code, and the delimiters were cute little = signs with some semantics attached to them, rather than just /* ... */.

But /* ... */ would work - as it does for Javadoc and Doxygen.

With S26, there are definitely some things I am happy to see. Tables. Tables! Paragraph blocks. Attributes and out-of-band stuff. But there's an awful lot of bad, too.

First, POD is not HTML. I absolutely hate =end tags. I can understand the need for a general purpose multi-line comment, but as things currently stand =begin/=end happens too much. Worse, for the kind of short-but-multiple-paragraph comments that get attached to function and methods, the extra-newlines tax gets pretty high.

In general, I think I'd like some way for POD to be in "sticky mode" -- that is, like POD5, it should either stay in POD, or stay in a particular block type, until told otherwise. This might be a block attribute -- that is, something I can configure separately:

   =config default :like<para>
   =config para :sticky

Second, POD is not XML, and it definitely isn't DOCBOOK. Why do I need magic reserved words like TOC and APPENDIX? I'm not writing a book, I'm writing code. And if I was writing a book, I wouldn't be dumb enough to write it in POD. If @Larry wants to prove something by writing books in POD, let them type =begin or =for or =whatever in front of their chapter markers -- leave my namespace alone.

Third, I think that S26 is trying to approach a couple of pretty important new(-ish) concepts in software -- inline documentation, and annotations -- from a POD standpoint. I'm willing to listen, but I'm not entirely convinced that it's possible, or that it's a good idea.

There was a flurry of discussion right after Damian posted his S26 draft about short syntax for documenting syntax elements. The focus seemed to be on making it something that POD could grab.

I'm not sure I accept that focus, especially since P6-language seems to have some kind of bias against admitting anybody ever did any syntax right after 1979. Docblocks have been around for a long time, but nobody even considered literal-string-after-{ or """ as being valid ways to indicate them. Far better to write #={ despite how ridiculous that is to type, than to consider using """ (or better yet ''' which isn't shifted).

Overall, my impression of S26 is that it's not Perly enough. The idea of paragraph blocks (=for...) is pretty clearly a compromise between single-line and multi-paragraph, and it's a step in the right direction. But I think there needs to be a better consideration of the needs of the people writing the POD, expressed maybe as explicitly reserved bits with known behaviors. (For example, some set of contexts where POD5-style "parse until I tell you to stop" allows omission of =end markers, and lets =foo stand for =begin foo.)

Also, =for just doesn't scan in a lot of places. Maybe a better way would be to depend on the text, or to add an =.

   =for para
   blah blah blah
=config para :mode<paragraph>
   blah blah blah

   =para      <-- no text means para mode?
   blah blah blah

   ==para   <-- == means para mode?
   blah blah blah

One thing I have noticed in NQP is that usually I write a function signature, and it's right. That is, I can write the signature and it corresponds with how the caller will use it. In that case, I want my inline docs to be quick, too:

   method unsort()
   --- Unsorts (randomizes) the array.

   method sort(:&order?)
   ''' Sorts the array.

=param &order? A function that takes two arguments (items in the array) and returns a number less than, equal to, or greater than zero, depending if the first argument should be considered less than, equal to, or greater than the second
   argument in the desired ordering.
   { ... }

The nice thing about this arrangement is that I get to leave the declaration in place at the top -- unlike the Java/C.* tools, where the signature is frequently too far down to see while reading the docs.

But sometimes, the gyrations I have to code in NQP *don't* match what I'm trying to express. For example, if I want at least one but possibly many parameters:

   sub at_least_one($first, *...@rest) {...}

In that case, I want to respecify the signature, too:

   sub at_least_one($first, *...@args)
   =signature (*...@args)

Does something that requires at least one parameter. It doesn't matter what
   you pass in, as long as there's at least one.

   =param *...@args   One or more arguments, of whatever type.

Note that you have to provide at least one argument (shown as C<$first>, above)
   or you'll get an exception.

   =throws NotEnoughArguments if you don't provide at least one arg.
   { @args.unshift($first); ...}

And if I'm going to be doing =stuff between a signature and a block, I shouldn't need to say ''' or anything else. DWIM!

There's a similar argument to be made for annotations. If I'm writing P6unit in P6, it's probably possible to annotate in code with syntax or attributes:

   testcase CheckSomething {

       method confirm_behavior() is test {...}

       test confirm_behavior() {...}


but for general-purpose annotations a POD variant is probably desirable:

   sub xxx() {...}

In theory, this is accessible via the magic POD data structure, but this kind of thing is common enough (in the annotation-processing community) that it's probably worth while to support verifying that a certain tag type has whatever kinds of objects following after it. (Big surprise, nobody wants to put the annotations after the code...)

Putting my simon hat on, annotation processing from POD is definitely not core. But making sure that POD is annotation-friendly is. Currently, that means some kind of structured syntax, and enough of a tie to the parsing context that symbol and type names can be resolved. I think the parsing tie is in the spec, but I'm not sure about support for any kind of structure.


Reply via email to