Ido has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks. For years my mind was pure with just Perl (and a very little java, pascal..).
I could'nt live with that sin anymore(and the course is required for my degree), and finally learned C.
I know most people go the other way around.
But that way arises many questions about the analogies. I'll start with just a few:
  1. Variables in C can live on the stack, or in the heap. How's that in Perl? There's the symbol table, and the scratchpad, but is there a good analogy? Lexicals seem very different to me from anything there's in C, am I wrong? How are they implemented?
  2. C++ has "references" for aliasing a variable. Perl sends arguments as aliases anyway, and has typeglobs for creating an alias to a variable on the symbol table: Is there any way, in Perl, to create an alias to a lexical?
Thanks,
Ido

Replies are listed 'Best First'.
Re: Finally, C
by Zaxo (Archbishop) on Dec 16, 2005 at 15:53 UTC

    There are a lot of parallels, and similar syntax, but the Real Important Stuff is very different. Memory management, for three or more.

    Perl lexicals are like C auto variables, which are generally at the top of the stack.

    C++ references are like Perl aliases. They have value semantics, but are pointers under the skin. Perl references are like C/C++ pointers.

    After Compline,
    Zaxo

      Perl lexicals are like C auto variables, which are generally at the top of the stack.

      That is somewhat true and somewhat misleading.

      Perl lexicals don't go on the stack. They can't because of the key difference between Perl lexicals and C lexicals: The lifetime of C lexicals matches their scope while Perl lexicals can live forever.

      That is, a C lexical is destroyed unconditionally when its scope is exitted. Perl lexicals are initialized (often creating a new instance) when their scope is entered and have one reference to them removed when the scope is exitted. The variable instance will only be destroyed if that was the only remaining reference to it.

      So having a sub return a pointer/reference to one of its lexical variables in C/C++ is "a bug" (as it storing a pointer/reference into something that will live past the call into the sub). Having a Perl sub (or 'do' block, etc.) return a reference to one of its lexicals is just fine (as is storing references to any variables anywhere -- though making circular references causes other, less severe, problems).

      - tye        

Re: Finally, C
by xdg (Monsignor) on Dec 16, 2005 at 15:55 UTC
    Is there any way, in Perl, to create an alias to a lexical?

    Data::Alias and/or Lexical::Alias, depending on what version of Perl you're using.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Finally, C
by Perl Mouse (Chaplain) on Dec 16, 2005 at 15:56 UTC
    Is there any way, in Perl, to create an alias to a lexical?
    Yes, but it requires a trick:
    my $foo = "foo"; for my $bar ($foo) {$bar = "bar"} print $foo; __END__ bar
    And there's the @_ trick you already mentioned. There are also a couple of constructs that allow you to alias a variable to $_.
    Lexicals seem very different to me from anything there's in C, am I wrong?
    Maybe, depending on what you are asking. If you mean that variables are implemented different than in C, yes, you are right. If you are referring to what differs a (Perl) lexical variable from a (Perl) package variable, and want to know how this differs from the C equivalent, then there's no real answer. In C, all variables are lexical - there's no such thing as name spaces in C.
    Perl --((8:>*
      This also demonstrates that the for variable is an alias, and not a copy:
      my $foo = "foo"; for my $bar ($foo) { print "foo: $foo, ", \$foo, "\n"; print "bar: $bar, ", \$bar, "\n"; $bar = "bar"; print "foo: $foo, ", \$foo, "\n"; print "bar: $bar, ", \$bar, "\n"; } print "foo: $foo, ", \$foo, "\n"; __OUTPUT__ foo: foo, SCALAR(0x18245f0) bar: foo, SCALAR(0x18245f0) foo: bar, SCALAR(0x18245f0) bar: bar, SCALAR(0x18245f0) foo: bar, SCALAR(0x18245f0) __END__

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

Re: Finally, C
by ikegami (Patriarch) on Dec 16, 2005 at 16:49 UTC
    Lexicals seem very different to me from anything there's in C, am I wrong?

    A lexicals usually behaves like a stack variable. However, that breaks down when closures are used (e.g. do { my $lex; sub { return \$lex; } }), or when the address of the lexical is copied outside of the lexical's scope (e.g. my @a; { my $lex; push(@a, \$lex); } and do { my $lex; \$lex }).

    A lexical always behaves like a ref-counted pointer (stack variable) to dynamically allocated memory (heap variable). In other words,
    my $scalar;
    is something like
    ref_ptr<scalar_t> scalar = new scalar_t();

    Is there any way, in Perl, to create an alias to a lexical?

    Yes:
    our $sym; local *sym = \$lexical;

    However, I think you meant to ask if there was a way to alias a lexical to something else. I think
    for my $lexical ($var)
    is the only way provided by the language, but there might be other ways interally. If so, there might be an XS module that does this.