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

Reply via email to