I want to stop C, C++ and Java people referring to their languages as 'type safe'. They're not 'type safe' - they're type constrained.
C has static types for two completely distinct reasons:
In practice it's really hard to graft dynamic types onto a statically typed language. In fact once you've implemented dynamic types you've done so much work that you might as well implement the rest of the dynamic language. And if you're going to do that you might as well just use a dynamic language in the first place. The debatable virtue of type bondage is used to mask the fact that C-like languages can't get all funky and dynamic - even if they want to.
Type bondage sounds good on paper - "if we constrain this value really tightly at compile time we'll catch all sorts of runtime problems". That certainly sounds like it'd be a good thing.
Unfortunately it mitigates against a better thing: being able to write correct code that remains correct even when asked to process kinds of things that doesn't know about.
Dynamic typing? Don't need it!
You'll sometimes read something like dynamic typing offers no advantage in a properly designed program. The implication being that dynamic typing is for sloppy thinkers who can't plan ahead. That may be true. The problem is that at the limit we're all "sloppy thinkers who can't plan ahead".
The design of C does, in fact, acknowledge the need for dynamic typing. The sort() standard function achieves type-agnosticism by allowing the programmer to pass in
Whoever implemented sort understood that you'd want to able to sort just about anything. So, fortunately, they decided to make it type-unsafe, type-dangerous, type-scary. Its interface is necessary clunky - because C doesn't do dynamic types - but at least you can use it to sort your own data types.
We're invited to believe that sort is a special case, that in general you won't be needing that kind of flexibility. The necessity of type-inflexibility is spun as the virtue of type-safety. Safety is good! How can you oppose safety? Think of the children!
The current Perl QA wiki has been attracting a lot of spam recently - and we seem to have lost contact with Tyler MacDonald who as far as I know is the only person with admin access to it.
So I've moved all the content to perl-qa.hexten.net and set it up so that only registered users may edit. It's a shame to have to restrict access in that way; certainly we'll get fewer drive-by contributions as a result. On balance it's better than the message that a spam-riddled quality (quality!) wiki sends I think.
Please update bookmarks / links accordingly.
(warning: this item may contain traces of PHP)
A classic case of yak shaving: too much work on anyway, decided to take a break by turning our local community site into a wiki. Then I thought it'd be nice to embed a Google map showing a few local landmarks. Must be possible, right? Well it probably has been done already but it seemed pretty simple (and an interesting diversion) to write a MediaWiki extension to allow maps to be embedded.
So then you need to let users add points to the map - so the map needs button that spits out a chunk of markup that can be used to add a point. So I wrote some Javascript to do that.
Of course one extension is never enough (just say no kids). I was writing a load of code that'd be useful in other extensions anyway. What about a framework for extensions? Yup, the dreaded 'f' word. Oh well.
Anyway, to cut a long story short: Wiki Widgets.
One of the things I wanted to do (you know, once it became a project rather than a displacement activity) was to make widgets that, from the user's point of view, are discoverable. It's all very well installing an extension but if users can't find out about it they won't use it. Wiki Widgets has a pretty simple take on discoverability: make a blank page and add the markup:
<widget/>
to it. When you save or preview the page you'll get a list of all the installed Wiki Widgets. For each Widget there's a link that takes you directly to a (wiki) page that explains how to use it. From there you should be able to select the widget you want. Wherever possible I plan to make the individual Widgets support additional discoverability. For example if you add an empty Google Gadget Widget like this:
<widget type="googlegadget"/>
you should get a user interface that makes it easy to add the gadget you want and set up its parameters.
Anyway, back to the day job now.
Wow. I'm just installing Plagger on a couple of boxes. One of them is my regular laptop and it already has quite a lot of CPAN installed. Even so Plagger has what look like hundreds of unsatisfied dependencies.
I'm sure it's all going to be worth it - although all I want to do is merge a handful of RSS feeds. Right now it feels slightly like overkill for that task
I wish I'd never started this FizzBuzz thing now. Anyway, FizzBuzz/Perl in 60 bytes:
print$_%3*$_%5?$_:($_%3?Bu:$_%5?Fi:FizzBu).zz,"\n"for 1..100
Can it be bettered?
As you may know Perl's test result protocol is officially known as TAP - the Test Anything Protocol. Over on the perl-qa mailing list a discussion has been raging about the future of TAP. One of the points that came up was that TAP is no longer Perl specific. That means that a Perl mailing list is no longer the best place to discuss it. So that there's a language-neutral hangout for TAP fans I've created tap-l - a mailing list dedicated to TAP.
Most of the current TAP documentation lives on the Perl QA wiki. Again, not the best place if we want to persuade people that TAP is language neutral. So there's also a new TAP specific wiki:
FizzBuzz is an extremely basic competence test for programmers. So I thought I'd write a version extremely in BASIC. Here it is in BBC Basic's embedded 6502 assembler.
What's that got to do with Perl? Well I used my 6502 emulator written in Perl to develop it on.
10 REM FizzBuzz in 6502 assembler
20 DIM code% 1000
30 OSWRCH = &FFEE
40 OSNEWL = &FFE7
50 work = &70
60 DIM FizzM 4 : $FizzM = "zziF"
70 DIM BuzzM 4 : $BuzzM = "zzuB"
80 FOR pass% = 0 TO 3 STEP 3
90 P%=code%
100 [opt pass%
110
120.FizzBuzz LDA #1
130 LDX #3
140 LDY #5
150.FB1 SEC
160 DEX
170 BNE FB2
180 JSR Fizz
190 LDX #3
200.FB2 DEY
210 BNE FB3
220 JSR Buzz
230 LDY #5
240.FB3 BCC FB4
250 JSR PrDecimal
260.FB4 PHA
270 JSR OSNEWL
280 PLA
290 CLC
300 ADC #1
310 CMP #101
320 BCC FB1
330 RTS
340
350.Fizz PHA
360 LDX #3
370.Fizz1 LDA FizzM, X
380 JSR OSWRCH
390 DEX
400 BPL Fizz1
410 CLC
420 PLA
430 RTS
440
450.Buzz PHA
460 LDY #3
470.Buzz1 LDA BuzzM, Y
480 JSR OSWRCH
490 DEY
500 BPL Buzz1
510 CLC
520 PLA
530 RTS
540
550.PrDecimal STA work
560 PHA
570 TXA
580 PHA
590 LDA #0
600 PHA
610.PrDec0 LDX #8
620 LDA #0
630.PrDec1 ASL work
640 ROL A
650 CMP #10
660 BCC PrDec2
670 SBC #10
680 INC work
690.PrDec2 DEX
700 BNE PrDec1
710 CLC
720 ADC #ASC"0"
730 PHA
740 LDX work
750 BNE PrDec0
760.PrDec3 PLA
770 BEQ PrDec4
780 JSR OSWRCH
790 JMP PrDec3
800.PrDec4 PLA
810 TAX
820 PLA
830 RTS
840 ]
850 NEXT
I've been working this week to add support YAML-based diagnostic syntax to TAP::Parser. Those changes haven't made it to CPAN yet but we'll probably make a release in the next few days. In the mean time you can find the bleeding edge version in the subversion repo.
Now TAP producers can elect to add machine readable diagnostics to test failures like this:
TAP version 13
plan 1..5
ok 1
ok 2
not ok 3
---
severity: fail
message: "Array unsorted"
data:
got:
- 1
- 3
- 2
expected:
- 1
- 2
- 3
...
ok 4
ok 5
The harness doesn't currently actually do anything with the diagnostic information but it does expose an interface that allows display plugins to be written. With the right plugin the test harness becomes responsible for displaying the detail of what went wrong. Currently that's something test scripts must do themselves, calling diag() to display a description of the problem. Because diag() outputs to STDERR the diagnostics can get out of sync with the test results.
Look out for more progress on display plugins and a practical end-to-end example of a test that emits structured diagnostics sometime next week.
From Adam Kennedy's YAML::Tiny:
if ( $string =~
/^"((?:\\.|[^"])*)"$/ ) {
my $str = $1;
$str =~ s/\\"/"/g;
$str =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$ 1}/gex;
return $str;
}
What, never?
This is a bit of a long shot. We have a test failure for TAP::Parser 0.51 on Windows:
http://www.nntp.perl.org/group/perl.cpan.testers/2007/03/msg437065.html
It's Perl 5.8.5 and to this (untutored) eye it looks as if it's not ActiveState's build. I've tried to build 5.8.5 here but can't get it to play nice with VC++ 8.0.
If anyone might happen to have 5.8.5 installed on a Windows box and could make test against both T::P 0.51 and a snapshot from the SVN and report back I'd be most grateful.
FWIW the tests all pass on Windows/5.8.8.