Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Trees and Language::AttributeGrammar

by nothingmuch (Priest)
on Mar 06, 2006 at 17:56 UTC ( #534724=note: print w/ replies, xml ) Need Help??


in reply to Trees and Language::AttributeGrammar

First of all, the fix is this:

Cons: $/.len = { $/; $<head>.len + $<tail>.len }
As you can see mentioning $/, the attribute's invocant fixes this.

You're probably asking yourself why...

use Data::Dumper; $Data::Dumper::Deparse = 1; warn Dumper($grammar->{engine}{cases}{Cons});
Comparing the two versions shows us something interesting:
$_AG_ATTR->get($_AG_SELF)->get('len')->set(sub { $_AG_SELF; $_AG_N1->get('len', 'grammar line 4') + $_AG_N2->get('len', 'gramm +ar line 4'); }
versus
$_AG_ATTR->get($_AG_SELF)->get('len')->set(sub { $_AG_N1->get('len', 'grammar line 4') + $_AG_N2->get('len', 'gramm +ar line 4'); }
So, what is the void thingy doing in there, you are probably wondering? Aha!
'visit' => [ sub { ... # snipped my($_AG_SELF, $_AG_ATTR) = @_; ... # snipped $_AG_ATTR->get($_AG_SELF)->get('len')->set(sub { $_AG_SELF;
Basically, $_AG_SELF causes the value to remain non-garbage collected (since it's captured in the closure it's reference count stays up). Since luqui is using a lazy evaluation strategy to produce results, and this probably means that somewhere inside $_AG_ATTR or whatever there's a table of objects to their attr values, the moment that $_AG_SELF dies (and it will die, because you are creating Cons thingies on the fly inside 'children') it can no longer be referenced in a thunk, because it's StrVal cannot be reproduced. Anyway, long story short, the evaluation scheme is somehow landing on an edge case with two children in the Cons/Nil thing, and thus it's causing the value to be recalculated over and over and over and over again. I think.

The more elegant fix is to cache your linked list, something like

sub children{ return @{ $_[0]{_ll_cache} ||= [ list( @{ $_[0]->{_list} } ) ] }; }
so that the values don't go away. Remember to invalidate _ll_cache whenever new children are added.

Ciao!

-nuffin
zz zZ Z Z #!perl


Comment on Re: Trees and Language::AttributeGrammar
Select or Download Code
Replies are listed 'Best First'.
Re^2: Trees and Language::AttributeGrammar
by rg0now (Chaplain) on Mar 06, 2006 at 21:01 UTC
    Thanks for the nice response. Let's say I understand it...:-)

    Something however tells me that both of your solutions take away something very important from the elegance of the code: in my opinion the efficiency lies in that we let the Cons stuff just emerge and go away on the fly.

    My qustion is: do you have any better idea to represent trees and attribute grammars to manipulate them than mine? Once I adopted this "functional" approach I really do not want to go back to the "imperative" world...

      Haskell?

      Seriously though, post a bug on rt.cpan.org - luqui should know about this and fix it somehow...

      luqui also said he will add support for attributes over aggregate types (e.g. @<children>.foo) eventually, if he can find a nice way.

      -nuffin
      zz zZ Z Z #!perl
        The bug has finally been fixed in version 0.08. There is also syntax for aggregate types, though it is awkward: my @child_foos = `@<children>`.foo; Luke

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://534724]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (12)
As of 2015-07-30 18:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls