Home > database >  Why does Perl have a notion of an undefined function?
Why does Perl have a notion of an undefined function?

Time:01-27

Perl has a notion of an undefined function. A function that's declared but not defined.

sub foo;
foo(); # Undefined subroutine error
bar(); # Undefined subroutine error

This function foo exists now in the symbol table and it can be used to resolve a method call. But why does this "feature" even exist? In C, it's because functions are type-checked and sometimes you want to have a call before you define (such as to resolve a circular dependency). But Perl has no such feature and all function symbols are resolved in runtime not compile time.

  • If it's for prototypes, then why should an undefined function exist if it does not have a prototype?

  • If it's not for prototypes, why does it exist at all?

  • And why is that undefined subroutines are used in method resolution? Why not ignore them entirely -- you can't call them and they're internal implementation details as far as I can see (at best)? That is why if function isn't defined can't we continue method resolution as if it did not exist (it seems like it would be less confusing).

CodePudding user response:

It is about prototypes, and the declaration (or not) of a function does have an effect at compile time. Consider

  1.  print foo   42;
    

    In isolation, this is equivalent to print('foo' 42);foo is a "bareword". If you have strict 'subs' enabled, it will instead give you a compilation error saying that barewords are forbidden.

  2.  sub foo;
     print foo   42;
    

    This is equivalent to print(foo(42)); the compiler knows that foo is a sub and it has no prototype, so it consumes everything after it in "list op" fashion, and what follows it is the term 42.

  3.  sub foo();
     print foo   42;
    

    This is equivalent to print(foo() 42); the compiler knows that foo has a prototype and that it takes no arguments, so none will be looked for, and foo and 42 will be the operands of the operator.

  4.  sub foo($);
     print foo   42;
    

    Like case 2 this is equivalent to print(foo(42)). I think there's probably a test I could have used to distinguish them.

Point being, whether a sub is known or not does have effects at compile-time, and Perl gives you the option to declare that fact before you define the body of the sub, rarely needed as it may be.

CodePudding user response:

It's the same as with other types, I'd say; just the artifact of how it is parsed.

my $hr = { a => 1 };   # $hr name introduced at compile time, assigned or not 

So the same goes with

sub name { ... };      # "name" "declared" at compile time

So saying just sub name; seems to be the same to saying my $hr; and then having a symbol which has no definition attached to it.

I don't know how the parser works but I'd guess that it has to take sub name first and add the definition later, so by happenstance we can then also say just sub name; and have that name.

CodePudding user response:

I can think of these reasons:

  • Allows placing the definition of a sub after a call to it if they have a prototype or attributes.

    Notable specifics:

    • Allows mutually recursive subs to exist if they have a prototype or attributes.
  • Allows AUTOLOADed and similar subs to be declared.

    Notable specifics:

    • Allows ones to check if AUTOLOADed subs exist.
    • Allows AUTOLOADed and similar subs to be exported.
  • Can be used as an abstract method.

  •  Tags:  
  • Related