in reply to RFC: Inline::Blocks or inline as a keyword?
You seem to have missed Damians latest(?) stroke of genius resulting in Keyword::Declare and PPR.
holli
You can lead your users to water, but alas, you cannot drown them.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: RFC: Inline::Blocks or inline as a keyword?
by shmem (Chancellor) on Jul 30, 2018 at 15:14 UTC | |
Source filtering? No! Quick, throw away your C pre-processor! and along with that, all that autoconf and automake rubble. I have explained in the op why in this case source filtering makes sense, and I see no point against that if it is done sensibly. If I don't do it sensibly, please point out why. You seem to have missed Damians latest(?) stroke of genius resulting in Keyword::Declare and PPR. I missed them only slightly. I am aware of those beasts, but I didn't delve much into them because I currently haven't any use for them. Please don't compare me to Damian, that's unfair to both of us.
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] |
by holli (Abbot) on Jul 30, 2018 at 15:30 UTC | |
holli You can lead your users to water, but alas, you cannot drown them. | [reply] [d/l] |
by shmem (Chancellor) on Jul 30, 2018 at 22:35 UTC | |
Source filtering? No! Since - in what way is Keyword::Declare not a source filter? From the description of that module (emphasis mine): At compile time, when the parser subsequently encounters source code such as:then the keyword's $count parameter would be assigned the value "10" and its $code parameter would be assigned the value "{\n$cmd = readline;\nlast if valid_cmd($cmd);\n}". Then the "body" of the keyword definition would be executed and its return value would be used as the replacement source code: Skimming that module, I get the impression that it is definitely a source filtering module. It is not a general purpose macro module. It is not a module for inlining subroutine bodies at the calling places as do blocks. It implements a "domain-specific language" (this might be the wrong term, beat me to death for it please) to extend Perl with arbitrary keywords. Right? That's all ok, and I admire Damian's genius. But the purpose of this meditation was not about "the right way to implement" inlining, but rather asking (see title) - should we have an inline keyword, or have a module for that. The attached module is a POC, a thinly veiled attempt to get approval and XP, and something which just does what it claims to do, nothing else. Had there been written instead A more robust way to implement your module is Keyword::Declare, since (arguments here) no misunderstanding would have arisen. Instead in the follow-up I read I wanted to express that the Keyword::Declare module is the tool you need to implement your module without source filters or rolling your own perl parsing regexes. which induces violence phantasies in me and, at the same time, drops me into utter resignation. Gosh, what a shitty job did I do. No wonder, cuz there will always be someone brighter than me, and they can annihilate my efforts with just one fell stroke of genius. Then there is the the tool you need to implement your module which, as so often, means "do as I say, but I won't tell you how." And it sounds so pythonesque. There's one way. Leaving away the "source filters" part, since that was discussed above. I'm so fed up with, and consider harmful, such advises as Q: How can I match IPv4 addresses reliably? I use /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ without at least saying "if you want to know what else you have to check, read the source" or at least saying that 377 isn't a valid dotted quad component and why. So, somebody please (if it is worth the effort) implement this module in a more robust fashion using Keyword::Declare. Lastly, to address the rolling your own perl parsing regexes - yeah, that's the right way to go, don't roll your own, blame somebody else. In one of my first posts here I answered to don't re-invent the wheel with "I don't want to reinvent the wheel, I just want a wheel with no car around just in case I want to build a nifty chopper". No more choppers, I'm tired of it all. Bye.
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] [select] |
by tobyink (Canon) on Jul 31, 2018 at 07:49 UTC | |
by RonW (Parson) on Aug 01, 2018 at 00:01 UTC | |
Despite such vehement discouragement, there's nothing (IMHO) intrinsically wrong with source filtering. It's just requires being very careful when using it. Also, it can make a program it using harder to debug. Anyway, I can suggest how you might use Keyword::Declare to accomplish your inlining module. Though with a modified syntax. Although Keyword::Declare will let you redefine sub (and other keywords), it won't do what you want. Instead, I suggest adding another keyword, maybe inlinable to mark a subroutine as suitable for inlining. Your handler for inlinable would save the body of the sub for later use by inline, then return the sub definition without the inlinable keyword. For inline sub definitions, save the body, then instead of returning the sub definition, use the name to define a new keyword. When perl later encounters the name of the sub, it will be treated as a plug-able keyword. then your handler can inline the routine. Caveat: Keywords defined by Keyword::Declare are only recognized at the beginning of a statement. If you want to inline in the middle of a statement, you have to enclose the "call" in a do { } block. There might be a plus side to this caveat. Since you know the inlining will always take place at the start of a statement, you might not have to inline it as a do { } block, but as a plain block. This is because if your inlined code isn't "returning" a value, you shouldn't need the do { } block. But if it does "return" a value and you want that value, the "call" will already be inside a do { } block (as long as it is the last (or only) statement in the do { } block). Summary: A Keyword::Declare based module may be easier to fully implement, but a source filter version probably will result in a cleaner syntax. The Keyword::API might be able to install keywords that work in the middle of expressions, but is not as easy to use as Keyword::Declare. Disclaimer: I have not tested any of this. YMMV. Edited to correct grammer errors. | [reply] [d/l] [select] |
by Eily (Monsignor) on Aug 01, 2018 at 15:58 UTC | |
Seriously, why should source filtering be bad for perl, but good for C?In both cases the compiler might report an error where the mistake was inserted, rather than where it actually is. Also in perl, source filters screw up the line numbering (insert two lines in the code, and the line numbers for every compilation message, or warn or die afterwards will be off by two). A call to warn on the last line of your test will indicate an issue on line 35 of a 26 lines file... The #line directive can solve most of those issues though, so if you turn into Mistakes in the parameter list (eg increase(£thing)) will be marked as coming from line 3 (the line of the call), and mistakes from the function definition (eg ++£foo) will be reported as coming from inside the function definition. local @_ makes it possible to access $_[0] and other values inside @_, while making line numbering easier (if ($foo) = @_ is replaced by ($foo) = $thing, the LHS comes from the function body but the RHS from the call, so where do you report an erreor?), but it probably slows things down... And since $foo = shift; uses @_ inside a function, but @ARGV elsewhere, it might introduce some interresting bugs. Also note that the C preprocessor will only expand macros in code, not in comments nor in strings. Try this in your example: and you'll get some confusing errors. It's pretty easy to correct that one, but things might get difficult with strings and pod. | [reply] [d/l] [select] |
by shmem (Chancellor) on Aug 01, 2018 at 23:51 UTC | |
In both cases the compiler might report an error where the mistake was inserted, rather than where it actually is. Well, after the file is filtered and text inserted via inline directive expansion, the erroneous code is duplicated and defacto is actually also at the new location. That's how inlining works. Anybody using a source filtering module should know what they are doing. The confusing line numbers issue can be mitigated by running -MO::Deparse,-l on the faulty file, and the line numbers reported by the compiler will match those of the output. This is precisely why I included the debug switch into the module configuration, which causes the output of the code after mangling. But yes, there are much more CAVEATS than those currently mentioned in that section. Thanks for your input!
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] |