regarding decap, you may be aware that f@:g is only equivalent to [: f g if g is fully parenthesized.
+:@:+/ 1 2 3 22 +:@:(+/) 1 2 3 12 ([: +: +/) 1 2 3 12 At is super impressive to process and decompose a verb. I have a simpler process for macros described at http://www.jsoftware.com/jwiki/PascalJasmin/Multiline%20tacit%20expressions%20with%20macros I should have provided examples of macros outside of the multiline definition context: MACcompose =: 1 : 0 NB. inserts @: between consecutive verbs. or adverb verb ;: inv ({. ;: m), 2 {:`('@:' , leaf {:)@.(((1=ncS@{. ) +. 3=ncS@{.) *. 3=ncS@{:)\ ;: m ) eval =: 1 : ' a: 1 : m' ncS=:3 :'z=.y 1 :y label_. 4!:0 <''z'' ' :: _2: NB. nameclass of string '+ / + *' MACcompose eval +/@:+@:* To be fancier, or correct, the MACcompose adverb should also check C N V (placing conjunction between N and V), and should preprocess parens to get a nameclass entity for what they contain. But there is a simple hack that has some convenience in escaping the composition, while still allowing any valid one: A =: 1 : 'u' '+&3 +:'MACcompose_multiline_ + & 3 +: NB. no @: inserted because N V is parsed. '+&3 A +:'MACcompose_multiline_ + & 3 A @:+: NB. inserting dummy adverb allows composition to trigger '+&3 A +:'MACcompose_multiline_ eval +&3@:+: NB. A is automatically stripped out in tacit conversion There is an even simpler definition of MACcompose, that requires no hack for correct composition '+&3 +: y' (13 :) [: +&3 +: This type of macro or whole line processing can be a big enhancement to J in that it allows inserting any conjunction between verb phrases. While @: is the most common and convenient, short circuits or code that signals and captures escapes (errors) to abort further processing are useful generic processes best defined as a conjunction. ----- Original Message ----- From: Jose Mario Quintana <[email protected]> To: Programming forum <[email protected]> Cc: Sent: Tuesday, May 20, 2014 7:34:40 PM Subject: [Jprogramming] 13 : within explicit definitions The moral of the story is: Beware of potential adverse performance effects due to the use of the adverb 13 : (and other adverbs and conjunctions) within explicit definitions. This is the story… I do not subscribe to the chat forum but sometimes I peruse its contents to see what I have been missing J These are a couple of excerpts from last week "google code jam" thread (http://www.jsoftware.com/pipermail/chat/2014-May/005968.html and http://www.jsoftware.com/pipermail/chat/2014-May/005971.html ): Raul wrote: " Briefly, my approach looked like this: segments=: 1,2~:/\] runs=: +/\@segments uniq=:runs {./. ] counts=: #/.~@runs result=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/13 :'<./+/|-/~ y'"1]|: counts&> y ) which performed correctly on these test cases: result 'mmaw';'maw' result 'gcj';'cj' result 'aaabbb';'ab';'aabb' result 'abc';'abc' result 'aabc';'abbc';'abcc' " Dan wrote: " PS: BTW, Raul's use of 13 : n within 'result' is the first legitimate application I've seen to persist that construct in a script (as opposed to using for on-the-fly tacit translation in throwaway contexts, ie the REPL). Here, it allows Raul to maintain the clarity of explicit code for expressing a noun phrase as a sequence of verb applications (ie a pipeline without the intrusive verb compositions), while avoiding the typical performance penalty of applying an explicit verb at low rank (which would make J constantly reinterpret the verb body, which is stored as a string). Very clever and gratifying. " I saw the product of 13 :'<./+/|-/~ y' [: <./ [: +/ [: | -/~ ┌──┬──────┬───────────────────────────┐ │[:│┌──┬─┐│┌──┬─────┬────────────────┐│ │ ││<.│/│││[:│┌─┬─┐│┌──┬─┬─────────┐││ │ │└──┴─┘││ ││+│/│││[:│|│┌─────┬─┐│││ │ │ ││ │└─┴─┘││ │ ││┌─┬─┐│~││││ │ │ ││ │ ││ │ │││-│/││ ││││ │ │ ││ │ ││ │ ││└─┴─┘│ ││││ │ │ ││ │ ││ │ │└─────┴─┘│││ │ │ ││ │ │└──┴─┴─────────┘││ │ │ │└──┴─────┴────────────────┘│ └──┴──────┴───────────────────────────┘ as another interesting testing argument for my new toy: 13 :'<./+/|-/~ y' decap <./@:(+/@:(|@:(-/~))) ┌──────┬──┬───────────────────────────┐ │┌──┬─┐│@:│┌─────┬──┬────────────────┐│ ││<.│/││ ││┌─┬─┐│@:│┌─┬──┬─────────┐││ │└──┴─┘│ │││+│/││ ││|│@:│┌─────┬─┐│││ │ │ ││└─┴─┘│ ││ │ ││┌─┬─┐│~││││ │ │ ││ │ ││ │ │││-│/││ ││││ │ │ ││ │ ││ │ ││└─┴─┘│ ││││ │ │ ││ │ ││ │ │└─────┴─┘│││ │ │ ││ │ │└─┴──┴─────────┘││ │ │ │└─────┴──┴────────────────┘│ └──────┴──┴───────────────────────────┘ and (<./+/|-/~) for my, not so new, toy At: [: <./+/|-/~ At <./@:(+/)@:|@:(-/~) ┌────────────────────────┬──┬─────────┐ │┌─────────────────┬──┬─┐│@:│┌─────┬─┐│ ││┌──────┬──┬─────┐│@:│|││ ││┌─┬─┐│~││ │││┌──┬─┐│@:│┌─┬─┐││ │ ││ │││-│/││ ││ ││││<.│/││ ││+│/│││ │ ││ ││└─┴─┘│ ││ │││└──┴─┘│ │└─┴─┘││ │ ││ │└─────┴─┘│ ││└──────┴──┴─────┘│ │ ││ │ │ │└─────────────────┴──┴─┘│ │ │ └────────────────────────┴──┴─────────┘ I noticed that the first and second forms are right-associative whereas the last form is left-associative. Unsurprisingly, I tried to compare them: result=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/13 :'<./+/|-/~ y'"1]|: counts&> y ) result 'mmaw';'maw' 1 result 'gcj';'cj' Felga Won result 'aaabbb';'ab';'aabb' 4 result 'abc';'abc' 0 result 'aabc';'abbc';'abcc' 3 result0=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/(13 :'<./+/|-/~ y'decap)"1]|: counts&> y ) result0 'mmaw';'maw' 1 result0 'gcj';'cj' Felga Won result0 'aaabbb';'ab';'aabb' 4 result0 'abc';'abc' 0 result0 'aabc';'abbc';'abcc' 3 result1=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/([: <./+/|-/~ At)"1]|: counts&> y ) result1 'mmaw';'maw' 1 result1 'gcj';'cj' Felga Won result1 'aaabbb';'ab';'aabb' 4 result1 'abc';'abc' 0 result1 'aabc';'abbc';'abcc' 3 st=. (] , <@:(1&({::) * 2&({::)))@:(] ; 7!:2@:] ; 6!:2) 100 st&> ('result''aaabbb'';''ab'';''aabb''') ; ('result0''aaabbb'';''ab'';''aabb''') ; ('result1''aaabbb'';''ab'';''aabb''') ┌───────────────────────────┬─────┬───────────┬────────┐ │result'aaabbb';'ab';'aabb' │6656 │2.37412e_5 │0.158021│ ├───────────────────────────┼─────┼───────────┼────────┤ │result0'aaabbb';'ab';'aabb'│13056│0.000142205│1.85663 │ ├───────────────────────────┼─────┼───────────┼────────┤ │result1'aaabbb';'ab';'aabb'│19968│0.00039568 │7.90095 │ └───────────────────────────┴─────┴───────────┴────────┘ 100 st&> ('result''aabc'';''aabc'';''aabc''') ; ('result0''aabc'';''aabc'';''aabc''') ; ('result1''aabc'';''aabc'';''aabc''') ┌───────────────────────────┬─────┬───────────┬────────┐ │result'aabc';'aabc';'aabc' │6656 │2.34002e_5 │0.155751│ ├───────────────────────────┼─────┼───────────┼────────┤ │result0'aabc';'aabc';'aabc'│13056│0.000146231│1.90919 │ ├───────────────────────────┼─────┼───────────┼────────┤ │result1'aabc';'aabc';'aabc'│19968│0.000403057│8.04824 │ └───────────────────────────┴─────┴───────────┴────────┘ What? Wait a second! Substituting instead the forms produced by the adverbs directly, one gets: result=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/ ([: <./ [: +/ [: | -/~)"1 ] |: counts&> y ) result 'abc';'abc' 0 result 'aabc';'abbc';'abcc' 3 result0=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/(<./@:(+/@:(|@:(-/~))))"1]|: counts&> y ) result0 'abc';'abc' 0 result0 'aabc';'abbc';'abcc' 3 result1=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/(<./@:(+/)@:|@:(-/~))"1]|: counts&> y ) result1 'abc';'abc' 0 result1 'aabc';'abbc';'abcc' 3 100 st&> ('result''aaabbb'';''ab'';''aabb''') ; ('result0''aaabbb'';''ab'';''aabb''') ; ('result1''aaabbb'';''ab'';''aabb''') ┌───────────────────────────┬────┬──────────┬────────┐ │result'aaabbb';'ab';'aabb' │6400│2.13111e_5│0.136391│ ├───────────────────────────┼────┼──────────┼────────┤ │result0'aaabbb';'ab';'aabb'│6656│2.08343e_5│0.138673│ ├───────────────────────────┼────┼──────────┼────────┤ │result1'aaabbb';'ab';'aabb'│6784│1.97517e_5│0.133996│ └───────────────────────────┴────┴──────────┴────────┘ 100 st&> ('result''aabc'';''aabc'';''aabc''') ; ('result0''aabc'';''aabc'';''aabc''') ; ('result1''aabc'';''aabc'';''aabc''') ┌───────────────────────────┬────┬──────────┬────────┐ │result'aabc';'aabc';'aabc' │6400│2.31552e_5│0.148193│ ├───────────────────────────┼────┼──────────┼────────┤ │result0'aabc';'aabc';'aabc'│6656│2.17514e_5│0.144777│ ├───────────────────────────┼────┼──────────┼────────┤ │result1'aabc';'aabc';'aabc'│6784│2.11754e_5│0.143654│ └───────────────────────────┴────┴──────────┴────────┘ That makes sense, the performance of the forms is now comparable and each one of them outperforms its counterpart when the verb is produced indirectly. For completeness, this is how the left-associative capped fork form performs: result2=:3 :0 if. 1<#~.uniq&.> y do. 'Felga Won' return. end. +/([: ([: ([: <./ +/) |) -/~)"1]|: counts&> y ) result2 'abc';'abc' 0 result2 'aabc';'abbc';'abcc' 3 100 st ('result2''aaabbb'';''ab'';''aabb''') ┌───────────────────────────┬────┬──────────┬────────┐ │result2'aaabbb';'ab';'aabb'│6784│2.97104e_5│0.201555│ └───────────────────────────┴────┴──────────┴────────┘ 100 st ('result2''aabc'';''aabc'';''aabc''') ┌───────────────────────────┬────┬─────────┬────────┐ │result2'aabc';'aabc';'aabc'│6784│3.0111e_5│0.204273│ └───────────────────────────┴────┴─────────┴────────┘ ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
