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

Hi

I practically don't dare asking but

...are there any plans how to use TYPE in the future?

I checked some code with Concise and Terse, but the opcodes don't seem to show any differences, only the parser checks for known packages.

Declaring data types like "integer" might help with run time checking or code optimization...

(actually these plans were mentioned in the Panther-book from 1997...)

Cheers Rolf

PS: No flames intended...

Replies are listed 'Best First'.
Re: my TYPE EXPR ?
by ikegami (Patriarch) on Apr 20, 2010 at 19:10 UTC

    Declaring data types like "integer" might help with run time checking or code optimization...

    The check is currently just a simple bit check. To get any benefit, you would have to eliminate the check completely by moving it to compile-time.

    Let's look at $x+$y. (Looking at ops with a variable number of arguments would just complicate things.) It compiles into three ops:

    1 padsv[$x] -> 2 2 padsv[$y] -> 3 3 add -> 4

    There's nothing to affect! Right now, it would be of no benefit.

    Let's look at what it would take to benefit from it. Let's suppose some of the code in "add" was taken out and turned into ops. $x+$y would then compile into the following code:

    1 padsv[$x] -> 2 2 padsv[$y] -> 3 3 add_if_overloaded -> 11 if overloaded, 4 otherwise 4 swap_stack[0,1] -> 5 5 get_magic -> 6 6 numify -> 7 7 swap_stack[0,1] -> 8 8 get_magic -> 9 9 numify -> 10 10 add_prenumified -> 11

    If both $x and $y are known to be numbers, the optimiser could turn the above into the following:

    1 padsv[$x] -> 2 2 padsv[$y] -> 10 10 add_prenumified -> 11

    But changing Perl to produce the above would require changing just about every opcode. And then there's the optimiser additions on top of that. That's a crazy amount of work.

    What would be the result of that work?

    • Saved four bit tests under the best and rarest of circumstances.
    • Added seven ops in the normal circumstance.
    • Made the code slower even in the best of circumstances due to the overhead and cache misses of dispatching more ops.
    • On the bright side, it might facilitate the insertion of a JIT compiler. which in turn might remove the problems identified in the previous bullet???
      I should have made clearer what I meant with "run time checking or code optimization..."

      "run time checking"

      If I'm indexing with $i into an array, its clear that $i should never be a string or a ref.

      So flagging the type with  my int $i; could help checking at runtime (or compile-time) if ever something else than an integer was assigned to $i and consequently raising an error. (maybe using a "static" bit)²

      "code optimization"

      you mentioned JIT-compiler, the old Panther mentions a C-converter (most likely B::CC) to take advantage of it.

      To avoid further misunderstandings I'm thinking about little snippets, embedded for time-critical loops, but much easier and intuitive than with XS.

      The python community uses cython for this purpose facilitating to embed C-code.

      my motivation

      I'm writing a little hack emitting elisp snippets out of Perl-Code by translating the optree.

      (mainly because I hate writing lisp syntax)

      Actually I have to take care for implicit type conversions:

      --- example
      something like "abc".$i can't simply be translated to (concat "abc" i) because I get a Wrong type argument if $i is a integer.

      Sure, this can easily be solved by defining an "perl operator like" function pl-concat which does the needed type conversion. This slows down execution but normally thats not too important in emacs. But if I could give the compiler a static hint that $i is an integer, I could make pl-concat a macro which generates the appropriate code at compile time.

      Unfortunately I can't read out of the opcodes if $i was explicitly declared as of TYPE integer¹, I have to realize workarounds (e.g naming conventions like $i_INT) to transport this information.

      future ???

      I could read out of the old panther that this kind of usage was intended and it seems natural. Furthermore the docs read like the old usage of fields is deprecated now.

      So what are the plans/use cases for TYPE?

      Or is it completely deprecated now?

      Cheers Rolf

      UPDATES:

      ¹) Example:

      perl -MO=Concise -e '{package int}; my int $y' 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 2 -e:1) v:{ ->3 5 <2> leaveloop vK/2 ->6 3 <{> enterloop(next->5 last->5 redo->4) v ->4 4 <0> stub v ->5 6 <;> nextstate(main 2 -e:1) v:{ ->7 7 <0> padsv[$y:2,3] vM/LVINTRO ->8
      line 7 doesn't change if write my $y instead.

      ²) Of course this could be achieved using tie, but much slower and with more verbose code.

        I should have made clearer what I meant with "run time checking or code optimization..."

        I only commented on the "or code optimisation" aspect.

        you mentioned JIT-compiler, the old Panther mentions a C-converter

        There's an active project to JIT-compile Perl. The library uses some kind of byte code, not C.

        To avoid further misunderstandings I'm thinking about little snippets, embedded for time-critical loops

        I don't see how this matters.

        something like "abc".$i can't simply be translated to (concat "abc" i)

        Sure it can. That's exactly what Perl does. You just didn't define concat properly if you want Perl semantics. It should be doing stringify(get_magic()) on its args.

        But you're not trying to get Perl semantics according to what you said before, so I don't see why this is a problem. This entire problem only exists if you try to reimplement Perl semantics rather than just adopting its syntax.

        elisp using Perl syntax:

        "abc".stringify($i)

        elisp generated:

        concat( "abc" stringify(i) )

        But if I could give the compiler a static hint that $i is an integer, I could make pl-concat a macro which generates the appropriate code at compile time.

        That's exactly what my post discusses. I used addition since you said my Integer, but the same applies to concat.

        1 padsv[$x] -> 2 2 padsv[$y] -> 3 3 concat_if_overloaded -> 11 if overloaded, 4 otherwise 4 swap_stack[0,1] -> 5 5 get_magic -> 6 6 stringify -> 7 7 swap_stack[0,1] -> 8 8 get_magic -> 9 9 stringify -> 10 10 concat_prestringified -> 11

        Unfortunately I can't read out of the opcodes if $i was explicitly declared as of TYPE integer

        Remember that I recommended a parser, not an opcode visitor.

        Note: I don't know any version of Lisp.

        Update: Moved a paragraph.

        To avoid further misunderstandings I'm thinking about little snippets, embedded for time-critical loops, but much easier and intuitive than with XS.

        The python community uses cython for this purpose facilitating to embed C-code.

        And if you want something easier than XS, you can use the Inline family of modules (featuring Inline::C) that will build the XS glue code for you.