Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Porting (old) code to something else

by Tux (Canon)
on Feb 16, 2015 at 14:41 UTC ( [id://1116877]=perlmeditation: print w/replies, xml ) Need Help??

As I am in the process of porting Text::CSV_XS to perl6, I have learned not only a lot about perl6, but also about loose ends.

We all know by now that perl6 is reasonable likely to be available in September (of this year), and depending on what you hope or expect, you might be delighted, disappointed, disillusioned or ecstatic (or anything in between: YMMV).

My goal was to be able to present a module working in perl6 that would provide the user with as much functionality possible of what Text::CSV_XS offers: flexible feature-rich safe and fast CSV parsing and generation.

For now I have to drop the "fast" requirement, but I am convinced that the speed will pick up later.

Text::CSV_XS currently offers a testsuite with 50171 tests, so my idea was that if I convert the test suite to perl6 syntax, it good very well serve a point of proof for whatever I wrote in perl6.

There's a few things that you need to know about me and my attitude towards perl6 before you are able to value what has happened (at least I see this as a valueable path, you might not care at all).

I do not like the new whitespace issues that perl6 imposes on the code. It strikes *me* as ugly and illogical. That is the main reason why I dropped interest in perl6 very early in the process. In Sofia however, I had a conversation (again) with a group of perl6 developers who now proclaimed that they could meet my needs as perl6 now has a thing called "slang", where the syntax rules can be lexically changed. Not only did they tell me it was possible, but early October 2014, Slang::Tuxic was created just for me and low and behold, I could write code in perl6 without the single big annoyance that drove me away in the first place. This is NOT a post to get you to use this slang, it is (amongst other things) merely a reason to show that perl6 is flexible enough to take away annoyences.

Given that I now can write beautiful perl (against, beauty in the eyes of the beholder), I regained enjoyment again and John and I were so stupid to take the fact that perl6 actually can be used now, to promise to pick a module in the perl5 area and port it to perl5. XS being an extra hurdle, we aimed high and decided to "do" CSV_XS.

So, I have 50000+ tests that I want to PASS (ideally) but I soon found out that with perl6 having type checking, some tests are useless, as the perl6 compiler already catches those for you. Compare that to use strict in perl5, so I can just delete all tests that pass wrong arguments to the different methods.

Converting error-dealing stuff was fun too but I think that if you try to mimic what people expect in perl5, it is not too hard to get the best of both worlds: I'm quite happy already with error-handling as it stands.

So, the real reason for this post is what I found to have no answer to, as it wasn't tested for or had tests that were bogus.

  • What should be done when parsing a single line of data is valid, but there is trailing data in the line after parsing it.?
    $csv->parse (qq{"foo",,bar,1,3.14,""\r\n"more data});
    parse is documented to parse the line and enable you to get the fields with fields. In contrast with getline, which acts on IO, it will just discard all data beyond the EOL sequence. I am uncertain if that is actually what it should do. Should it "keep" the rest for the next iteration? Should it be discarded? Should it cause a warning? Or an error?
  • What is the correct way to deal with single ESCapes (given that Escape is not the default " or otherwise equal to QUOtation). Here I mean ESCape being used on a spot where it is not required or expected without the option to accept them as literal.
    $csv->escape_char ("+"); $csv->parse ("+"); $csv->parse ("+a"); $csv->parse ("+\n");
    Leave the ESCape as is? Drop it, being special? Warn or Error?

Questions like those slowed down the conversion as a whole, as I can now take my own decisions with sane defaults (like binary => True) instead of caring about backward compatibility issues.

Anyway, feel free to check out what I have done so far on my git repo and I welcome comments (other than those on style) in the issues section. Feel free to join #csv on IRC to discuss. Hope to see you (or some of you) at the next Dutch Perl Workshop 2015 in Utecht.


Enjoy, Have FUN! H.Merijn

Replies are listed 'Best First'.
Re: Porting (old) code to something else [Perl 6 whitespace rules are not illogical!]
by smls (Friar) on Feb 18, 2015 at 17:20 UTC
    I do not like the new whitespace issues that perl6 imposes on the code. It strikes *me* as ugly and illogical.

    Don't you think you may be trying a little too hard to rigidly carry along your favorite coding style and way of doing things from one language to another, rather than adpating to the new language and the ways it does things differently from what you're used to?

    "ugly" is of course subjective, but I don't think it's fair to call the Perl 6 function-call whitespace rules "illogical". Different from what you may be used to, yes, but they do make sense within the context of the language:

    No accidental listop/function-call ambiguity

    First of all, those rules solve the function-call ambiguity that can make working with listops in Perl 5 annoying. For example, say you have a Perl 5 script that prints a short line of text like this:

    say $line;

    ...and you are tasked with amending it so that the line is indented by a certain (variable) number of spaces. Imagine you already have the required indentation width stored in the variable $n, so you might change the code to:

    say (" " x $n).$line;

    ...right? Wrong, because the parser now interprets say (" " x $n) as a function call and .$line as a concatenation on the return value of the function. At least newer versions of Perl will print a warning for specific (commonly written by accident) cases like this, but it's still annoying, and the work-arounds to make the code do what was intended involve extra clutter:

    say "".(" " x $n).$line; say( (" " x $n).$line );

    And in Perl 6 this situation would be much worse, because every subroutine can be called both using the function-call style and the listop style, so in most cases the parser couldn't print a warning when you accidentally turn a listop into a function call because it doesn't know that it was unintentional.

    So it's important to disambiguate the two in a way that doesn't lead programmers to misstate their intent by accident. Checking whether or not the very first letter after the subroutine name is a paren, works quite well in this regard in Perl 6:

    # listop style: foo; foo "bar", $baz, 42; foo (1, 2, 3), [1, 2, 3]; # one List, one Array foo { $_ * 10 }, 2, 4, 6; # one Block, three Int # function-call style: foo(); foo( "bar", $baz, 42 ); foo( (1, 2, 3), [1, 2, 3] ); # one List, one Array foo( { $_ * 10 }, 2, 4, 6 ); # one Block, three Int

    If you want a listop, you would never thoughtlessly write a paren immediately after the identifier.
    If you want a function call, you do need to remember the "no space before the paren" rule when you write it, but it is not something you would thoughtlessly change when coming back to tweak the code later on.
    So either way, you're reasonably safe.

    Language consistency/integrity

    The "no whitespace before the paren" rule actually cuts both ways: Whenever you see an identifier in 'term position' immediately followed by an opening paren, you know it's parsed as a function call.
    For example, you could define a qq subroutine and when you write qq(42) it will call that subroutine rather than invoke the qq/.../ quoting construct. Not that you would necessarily re-use the names of built-in constructs, but imagine a case where one module adds a quoting construct and another module exports a subroutine of the same name.
    It's important for the language to give programmers a way to disambiguate clearly between syntax constructs and cover all corner cases, and it's good if it can do that using a simple rule that you only need to learn once and is used across the board: in this case, "parsed as a function call if and only if the identifier is immediately followed by a left paren".

    Slangs to make everyone happy?

    I share BrowserUK's reservations about lexically scoped cosmetic slangs - if you end up with multiple different ones in the same project, you'll always have to be super careful to be aware of the exact slang you're currently in when you make changes, and it will likely just end up a mess.

    And in this particular case (Slang::Tuxic) we're talking about one that adds ambiguity to the grammar (as its README readily admits), which is imo an additional red flag.

    So yeah, if FROGGS had fun writing the slang and you have fun using it while learning Perl 6, more power to you, but I would advise against using something like this in production code.

    Better to embrace the design of the programming language you're working with and try to learn and discover the most elegant ways to do things within that design, rather than bracing yourself against it and trying to force the language into the habits you carried over from other languages.

      And in this particular case (Slang::Tuxic) we're talking about one that adds ambiguity to the grammar (as its README readily admits), which is imo an additional red flag.

      If not doing any dangerous things that cross the (thin) line, I don't see a problem (other than having others maintain the code later).

      So yeah, if FROGGS had fun writing the slang and you have fun using it while learning Perl 6, more power to you, but I would advise against using something like this in production code.

      I have full confidence that slangs are implemented safe enough to not leak into userland. IMHO perl6 is not yet ready for "production code" in the coming few months, but it is going there fast!

      <vlockquote>Better to embrace the design of the programming language you're working with and try to learn and discover the most elegant ways to do things within that design, rather than bracing yourself against it and trying to force the language into the habits you carried over from other languages.

      If I percieve this "elegance" as illogical and ugly, I won't use the language at all. at all. As said, part of programming is having FUN! And if if I amm annoyed on every line I write in whatever programming language, I will not have FUN and I will stop using that language (unless payed for by a factor many multiplies of my current sallary).

      You also use the word "habits". If you have taken the time to read my reasoning (and I do not expect you to agree), you will at least see that it meets a logic. Maybe not your logic, but it is consistent. I took a lot of time to think this over, together with my fellow students.

      You probably underrate the influence of the flexibility of how a programming language can match the train of thoughts of a programmer. Perl5 is EXCELLENT in supporting this. Perl6 matches this in programming rules and flexibility in the language, but NOT in the flexibility in style. That has put me off. So much that it tool Slang::Tuxic to bring me back.

      You say it is important for the language to give programmers a way to disambiguate clearly between syntax constructs. I disagree. It is not important for the programmer, but for the language interpreter/compiler. The programmer writes it the way he or she understands the problem. It is his/her task to write it in a way the interpreter/compiler will do what the programmer intended the code to do. IMHO it is very counterproductive to write in a way that your mind doesn't understand, just to match the language rules.

      The no whitespace before paren rule is likely to work for the majority of (fresh) programmer who learned it like that, but you will have to accept the fact that it also works opposite to other programmers (like me), who do NOT recognize it the way you see it, but only see "ugly code" and are annoyed.


      Enjoy, Have FUN! H.Merijn
      For me, this space-matters-in-some-situations thing is probably the one I dislike the most in Perl 6.

      The difference is too subtle and no other language with C-like-syntax does it. I know that I am going to bump into it, over and over.

        For me, this space-matters-in-some-situations thing is probably the one I dislike the most in Perl 6.

        Isn't it the other way around?

        Currently, space-matters-in-some-situations in Perl 5; and this is the antidote to it. No space allowed between a function name and it opening paren. Sorted.

        (Is it any different to requiring that there be no space between '=' & '~' in the regex operator?)

        It's correcting a problem (in Perl5) rather than creating a new one.

        'cept maybe for those who dogmatically believe that the close presence of a ( makes this: func (); suddenly become invisible: func( );. I can still see it.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
        In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
        I know that I am going to bump into it, over and over.

        I don't experience it that way personally. (I've started using Perl 6 for some of my private scripting needs a few months ago, which doesn't give me a huge amount of experience with it, but at least a general feeling for the language.)

        Once you internalize the rule that the paren has to immediately follow the identifier, you start looking at them differently – almost like they form a single token. And you really only need to think about it when writing a new function call, which is exactly when your brain is most likely to remind you of the syntax rules for function calls... ;)

        OTOH the Perl 5 ambiguity that I demonstrated by example in my above answer, is something that I still run into every now and then even after many years of using Perl. Because at the time when you add the parens in such a situation, you're probably not thinking about function calls, but rather about the Perl features involved in extending the expression you're editing: in the example of extending $line to (" " x $n).$line, that would be the repetition operator and string concatenation.
        It takes discipline to consciously pay attention to the fact that the expression which you're editing there is actually the first argument to a listop, and thus requires special care with parens – and if you're a human programmer, you're bound to sometimes overlook such things, resulting in a compiler warning in the best case, and an unnoticed bug in the worst.

        That's my experience, at least... Other people's brains may work differently. :)

      "production code" -- oh, good. The perl-6 nags have started their coding standard bludgeonings based on some hypothetical production-ready status.

      You do know that Larry only announced his hope to make a real announcement something this year, perhaps, maybe, right?

Re: Porting (old) code to something else
by LanX (Saint) on Feb 16, 2015 at 22:59 UTC
    Sorry I can't contribute to your questions, but I find your strategy interesting.

    ( and its a meditation, after all :)

    > So, I have 50000+ tests that I want to PASS (ideally)

    Not sure if I understood correctly but are you saying you started with porting the test code first?

    Wouldn't it be wiser to try to test your P6 code (in case of same functionality and semantic) with your P5 test suite (using a kind of bridge maybe)? Like this keeping both test-suites in sync?

    I understand that type checking doesn't make sense and that you could drop this part of the tests, but the risk of bugs in the test-suite would be reduced and you could immediately start porting.

    OTOH are test-suites easier to translate because they mostly consist of "simpler" code, which could help you having a smoother transition phase. (maybe?)

    Cheers Rolf

    PS: Je suis Charlie!

      No I/we started of by making 4 different extremely simple versions of CSV parsing core code, just to see how ell approaches would work.

      1. Chucks of interest
      2. State machine
      3. Grammar based
      4. Brute force

      The first three are still alive, and I personally only develop in the chunks version, which is - for me - the easiest to develop.

      I did not want to put people off in the initial post, but speed is about the most serious drawback at the moment. Not having CPAN can be worked around using use Inline::Perl5;. Examples of how to do that are available on the git repo, that includes working with XS modules (including DBI)! (passing IO arguments is work-in-progress)

      When I started in October 2014, my initial version was 6700 times slower than the XS version. Meanwhile is is "just" 1010 time slower. Some of that is because I learn to code more efficient in perl6, but most of that is because the perl6 core gets faster. We're not there yet. Here is a compare:

      Perl5 Text::CSV::Easy_XS 0.016 These two have no options and only parse v +alid CSV Text::CSV::Easy_PP 0.016 Text::CSV_XS 0.039 Highly optimized XS with many options Text::CSV_PP 0.514 Pure perl version Pegex::CSV 1.356 Ingy's Pegex parser Perl6 csv.pl 8.133 John's state machine csv-ip5xs 8.950 Text::CSV_XS with Inline::Perl5 csv-ip5pp 9.812 Text::CSV_PP with Inline::Perl5 csv_gram.pl 13.426 Using a grammar-based parser test.pl 38.733 My first attempt, no options test-t.pl 39.502 Almost compatible with Text::CSV_XS

      The numbers shown are the time needed in seconds to parse a valid 10000 line CSV file with 5 columns.

      Back to your question. Of course one cannot start with the test suite, but one can start with the test suite as a guide. So after building the initial core parser, feed it the tests and look what works and what does not. Then use the failing tests as a plan to alter the code to make the tests pass: implement error-handling, make all the attributes work, catch all exceptions etc etc

      Building a bridge would imho be a waste of time: that will not make you learn perl6 any faster, not will you hit problem areas that one needs to fix in the code eventually. As perl6 is type-checked and passes arguments by reference (all are objects), supporting array-refs to speed things up is counter-productive, so one needs to match the test suite to what is feasible and sane in perl6: don't slow don to match perl5 behavior. Things are changing anyway. I'm not trying to mimic the old CSV syntax, I'm trying to port its versatility and flexibility keeping the complete and safe parsing rules.


      Enjoy, Have FUN! H.Merijn
        > Building a bridge would imho be a waste of time: that will not make you learn perl6 any faster,

        Hm I think this shows our different approaches to "porting old code to something else".

        I would be rather interested to create a "cross compile" code, which can be easily maintained in both languages (possibly isolating differing parts to sub-modules)

        I understand that there is already a bridge to use the old CPAN modules, so you are rather concentrating on exploring Perl 6.

        > but speed is about the most serious drawback at the moment.

        So your goal is to write P6 code which can compete with XS code?

        Wow...

        Personally I'd be inclined to do it evolutionary step by step, having a full scale 1 to 1 port from P5 maybe slow, then using XS, then replacing XS with P6 "magic".

        But I can easily believe that this might be too boring! ;)

        Good luck and thumbs up! =)

        Cheers Rolf

        PS: Je suis Charlie!

        PS: I wouldn't care much about isolated voices here!

Re: Porting (old) code to something else
by BrowserUk (Patriarch) on Feb 16, 2015 at 15:20 UTC
    I do not like the new whitespace issues that perl6 imposes on the code.

    Sorry, could you clarify?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

      Of course I can :)

      In perl6 the opening paren (() of a function cannot be separated from the function by whitespace:

      Legal in perl5: my $foo = foo( 1 ); # A my $foo = foo(1); # B my $foo = foo (1); # C my $foo = foo ( 1 # D );

      For reasons I explain in my style guide MY preference is C. Perl6 only supports A and B.

      This is only an example. The syntax rules go deeper than that, causing the dot (.) to be special too, so that

      my $foo = $object->method (1) ->method (2) ->method (3);

      chaining as allowed in perl5 (break to a newline wherever you like), would NOT translate to

      my $foo = $object.method(1) .method(2) .method(3);

      This is bad (IMHO), see:

      $ cat t.pl use v6; class C { has Int $.x is rw = 0; method foo (Int $i) { $!x += $i; return self; } method bar (Int $i) { $!x -= $i; return self; } } C.new().foo(1).bar(2).say; $ perl6 t.pl C.new(x => -1) $ cat t.pluse v6; class C { has Int $.x is rw = 0; method foo (Int $i) { $!x += $i; return self; } method bar (Int $i) { $!x -= $i; return self; } } C.new() .foo(1) .bar(2) .say; $ perl6 t.pl ===SORRY!=== Error while compiling t.pl Two terms in a row at t.pl:11 ------> &#9167;.foo(1) expecting any of: infix stopper infix or meta-infix statement end statement modifier statement modifier loop

      This is because a leading dot (after whitespace) will see the next word as method on the current topic ($_) instead of as a method on the previvious "thing". As the previous line has no trailing semi-colon, I would prefer the default to be different. The perl6 core dev people state it is possible with a backslash:

      cat t.pl use v6; class C { has Int $.x is rw = 0; method foo (Int $i) { $!x += $i; return self; } method bar (Int $i) { $!x -= $i; return self; } } C.new()\ .foo(1)\ .bar(2)\ .say; $ perl6 t.pl C.new(x => -1)

      But do you want your code to look ugly like that? I do not!


      Enjoy, Have FUN! H.Merijn
        For reasons I explain in my style guide MY preference is C.

        Ah! Okay.

        No further rational discussion is possible (for me) here because I find your preferred style utterly abhorrent :)


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
        In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        I did think of one serious -- and hopefully non-controversial -- question regarding your use of Slang for your module.

        If at some point in the (hopefully far) future, it becomes necessary for someone else to take over your module -- someone who doesn't share your stylistic preferences -- how hard will it be for them to undo your use of Slang?

        I'm not expecting an answer; but it's something to think about.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
        In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: Porting (old) code to something else
by Anonymous Monk on Feb 17, 2015 at 00:25 UTC
    I have no idea about CSV but I hope you'll keep posting once in a while about your experiences with P6, especially concerning "can be used now".

      I’ve been messing around with it lately. Not production or even pre-production ready for the risk averse but certainly fun and something I would put into a small personal project at this point; I even had a candidate but it wasn’t small enough and the lack of a comprehensive 6PAN shot it down. The huge drawback for me before was speed. It’s not super fast now but it does some things faster than 5 and the things it doesn’t aren’t factors of ten slower anymore.

      https://github.com/tadzik/rakudobrew + panda (instructions on same page) make it easy to play with now. All critiques and disappointing timelines aside, it’s fun and I do think now is the time to consider early ecosystem work as Tux has; all ++s to you and your extremely helpful code. I encourage everyone to do it on github. The more open and easy, the faster things can be done.

      For the gainsayers: doing new things, even things that fail, can be edifying. I repeat something I’ve said before. Most of my chops were not acquired on the clock but at home on long nights and weekends.

      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Porting (old) code to something else
by Laurent_R (Canon) on Feb 20, 2015 at 00:15 UTC
    Thank you very much, tux for your very interesting post.

    I don't agree with your coding recommendation, but that is a secondary question, I agree with pretty much everything else you said about Perl 6.

    Je suis Charlie.
Re: Porting (old) code to something else
by bduggan (Pilgrim) on Feb 19, 2015 at 15:23 UTC
    Hi Tux, I had a similar issue with mandatory perl6 whitespace, but it was regarding mandatory whitespace and operators (maybe related?) :
    $ perl6 > if 1 < 2 { say 'hi' } hi > if 1<2 { say 'hi' } ===SORRY!=== Error while compiling <unknown file> Whitespace required before < operator at <unknown file>:2 ------> <BOL>&#9167;<EOL> expecting any of: postfix >
    Could a "slang" resolve this?

      Yes, a slang could solve that, but not Slang::Tuxic, which is about whitespace for functions and methods.

      You however show that perl6 takes away a lot of artistic freedom. I completely disagree with smls that the programmer will be happy with the decisions taken. The compiler will be happy, but us poor programmers that deviate slightly from that paved road will not be. All those small annoyances will have to be weighed against the goods that perl6 brings in order too keep the programmers using perl6.

      Do NOT underestimate the FUN factor. I have said that a few times before, but FUN! is way more important than functionality.

      I know both smls and BrowserUK will disapprove with using whatever slang, but without slang, there will be some amongst us that would never use the language because of the missing freedom.


      Enjoy, Have FUN! H.Merijn
        I know both smls and BrowserUK will disapprove with using whatever slang, but without slang, there will be some amongst us that would never use the language because of the missing freedom.

        The funny thing is, I think I'm almost (but only almost) as wedded to my preferred style as you are to yours. As far a Perl6 is concerned, I'm either 'lucky' (or I've arrived at my chosen style by dint of experience and going with what works), because from what I've seen, Perl6 requires spaces pretty much everywhere I would put them anyway; and prohibits them where I wouldn't put them.

        Indeed, a big part of why I've steered clear of offering patches to perl5 itself, is because I find the prevailing 'style' of the sources -- especially when combined with the hotch potch of mixed styles of later additions and amendments -- almost completely unintelligible. On those occasions when I go source diving to try resolve or understand some problem, I end up reformatting whole tranches of sources to 'correct' for the whole "let's randomly skip a level of indent or two just in case there is someone out there who is still using an AMD-3a with its 64 character line width; and other such idiocies; I'm constantly annoyed by macros that have to be called as procedures instead of functions (instead of this: MYTYPE *p = (MYTYPE*)malloc( 1024 ); you have to use:

        MYTYPE *p; ... ... ... Newxc( p, 1024, MYTYPE, (MYTYPE*));

        Which is just asinine.

        But I am in the position of being mostly retired. I only take work I'm interested in; only by referral, and turn down more than I take.

        But if I were you, I'd be very wary of becoming so wedded to your stylistic preferences that you're unprepared to compromise them.

        Were you to come to me as a prospective employee, laying down the law that you couldn't possibly use the language I've chosen for my project, because it compromises your stylistic freedoms; and I don't think it would be a very long conversation.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
        In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
      Could a "slang" resolve this?

      For some meanings of "resolve", I guess it could.
      Though again there's a reason for why things are the way they are:

      Allowing infix < without preceding space would conflict with the postcircumfix < > construct which is used in Perl 6 for indexing/slicing associative data structures (like hashes) with string keys.
      As in %stuff<key> but not limited to explicit hash variables, i.e. it can follow arbitrary expressions:

      $ perl6 > ('xx'..'zz').classify(*.substr(1))<z> xz yz zz > {aa => 11, bb => 22, cc => 33, dd => 44}<cc> 33 > %(<aa bb cc dd> Z=> (11, 22 ... *))<cc> 33 > sub foo { return {bar => 42} } > foo<bar> 42

      I believe in the general case, the compiler simply replaces ...<key> with ...{'key'}, causing the { } postcircumfix operator to be dispatched on the return-value object of the preceding expression at run-time (or die with a run-time error if the operator is not defined for that object's type).

      The problem with code like 1<2 is that (as far as I understand it) as soon as the parser sees the opening angle bracket sticking to the right of an expression, it assumes it found an instance of the < > postcircumfix and tries to parse the following text accordingly.
      If the actual text there does not match that expectation, the parser aborts with a syntax error. In this case, the error handling code is smart enough to look at the surroundings and figure out that you probably meant to use the < infix operator (numeric comparison) there, so it prints that instead of a generic a "syntax error".

      Now in theory the parser could be written so it would try both possibilities (postcircumfix < > and infix <) when it sees an angle bracket after an expression like that, and continue parsing both variants until one of them hits a syntax error down the road and can be eliminated.
      But I'm pretty sure that would violate the design principle of keeping the Perl 6 grammar as deterministic and "self-clocking" as possible, which seems to be very important to Larry Wall (and for which authors of slangs/macros or of Perl 6 syntax highlighters / IDEs etc. will probably be grateful).

      So if you want your slang to only change the meaning of those simple cases (< between two number literals) which the compiler's error handling code can already detect anyway, that would probably be reasonably safe, but if you also want expressions like $number<5 to be interpreted as numeric comparisons, that would likely lead to all kinds of parsing difficulties.

A reply falls below the community's threshold of quality. You may see it by logging in.
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1116877]
Approved by atcroft
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-03-28 16:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found