in reply to BEGIN block and prototyped subroutines

The begin block doesn't work because it's too late. In fact, the BEGIN block in your code does not serve any purpose (there's no code the run).

Prototypes come in action at compile time. When foo('bar') is compiled, the BEGIN block hasn't been seen. Nor has the definition of sub foo.

If you use prototypes, you must make the prototype known before the call to the sub is compiled. Otherwise, the compiler cannot know what to check/how to compile the call.