%include format.fmt \chapter{AGs with Side Effects} \label{chapt.side-effect} %let thesis = True %let fullVersion = True %include wgt10-visit.lhs %if False TODO^2 In the introduction, side effect is only allowed in the creation of higher-order children. This is nicer as it retains the purely functional relations between attributes. I.e. the attributes are still purely functional although the structure of the tree is not. This may be considered cheating, as there is essentially no distinction between rules and trees in a higher-order AG - however the underlying implementation remains purely functional anyway so it's actually just a matter of how to model things. Node the strategy parameter. -> Since we cannot limit side effect for rules in such an impure target language anyway, we allow side effect also in rules in contrast to only children as we mentioned in the introduction. TODO!!! Add section to relate side effectful AGs to type inference. Mention that we can simulate in the AG side effect using additional attributes. However, rules are plain Haskell functions. When these functions want to make use of side effect (i.e. using the inference monad and really not want to access it read-only but also want to add to it) then side effect is needed. (Or, manually threading of attributes, which is not so nice... as is visible in the UHC implementation) Better idea: simply add a chained substitution to each visit, and use a remap feature as in the iterative-chapter to link in a child. Then use an order-aware copy rule! Also: simple side effect could be an IORef to a substitution. Or, differently: auto-threaded attributes. like a super-duper threaded attribute. Research question is still: how to constrain this to particular visits? ------ visit'Expr'Top'1 e = do visit'Expr'1 e modify (\s -> s + 1) visit'Expr'2 e visit'Expr'3 e attr Expr inh x : String thr subst begin infer end infer begin analyze end analyze sem ExprTop | Top complicated: e.subst = e.subst + 1 order end infer < rule complicated order rule complicated < begin subst ------ MORE TODO! Add the idea of rewrite rules based on visits. Since rewrite rules can change nodes, this is visible in the semantics. visit sequences are essential, because lazyness cannot be used. Lazyness requires the attributes to be defined in terms of the final transformation. Since transformations want to match on attributes this causes a cycle. Visits can help here by putting a hard barrier between them. tree-pat => conditions | tree-constr Rewrite rules are applied exhaustively to all nodes in the tree. tree patterns can match on nonterminal, production, and visit. Also, we may want to have a notion of a "nearest" match. and nested match. %endif