I built a small helper to log verb execution. I'll write up a wiki post on
it once my wiki password gets reset
I am not sure if it will help others, but it was fun to build.
Let's start by comparing to the built-in trace:
require'trace'
trace '(+/ % #) (5 10 15)'
--------------- 8 Paren ------
(
5 10 15
)
5 10 15
--------------- 3 Adverb -----
+
/
+/
--------------- 5 Trident ----
+/
%
#
+/ % #
--------------- 8 Paren ------
(
+/ % #
)
+/ % #
--------------- 0 Monad ------
+/ % #
5 10 15
10
==============================
10
I can see my fork is working correctly but I found the output very
confusing when I started with J and still don't quite follow it all the
time. I would have thought that the last operation was dyadic too...
The output of my logging function looks like this:
> Log [ (('+/'lf '%'lf '#'lf) (5 10 15) )[ (Log=:'')
# MONAD (y=5 10 15)
+/ MONAD (y=5 10 15)
% DYAD (y=<'# MONAD (y=5 10 15)' x=<'+/ MONAD (y=5 10 15)')
It doesn't execute the operations and it can still be confusing, but I
think it might be easier to start with
Executing from right to left, we see that first J evaluates # on our list,
then +/ on the same list, and then executes % dyadically on the results of
both
Let's run the same operation without parentheses:
+/ % # 5 10 15
0.333333
> Log [ ('+/'lf '%'lf '#'lf (5 10 15) )[ (Log=:'')
# MONAD (y=5 10 15)
% MONAD (y=<'# MONAD (y=5 10 15)')
+/ MONAD (y=<'% MONAD (y=<''# MONAD (y=5 10 15)'')')
I think this somewhat clearly shows that each operation is a monad and
what's happening is:
+/ (% (# y))
0.333333
vs our intended operation
This could be used to help Jon Hough's problem from yesterday:
http://jsoftware.com/pipermail/programming/2014-April/036989.html
Again, the trace output (not shown) trace '3&+ @: (2&-) 5' is confusing...
The first function was defined as
func1 =. 3&+ @: (2&-)
We can log it with:
> Log [ ( (('3&+'lf)@:('2&-'lf)) 5 )[ (Log=:'')
2&- MONAD (y=5)
3&+ MONAD (y=<'2&- MONAD (y=5)')
And so it's the same as doing 3&+ (2&- 5), which is 0
The hook version:
func2 =. (3&+) (2&-)
> Log [ ( (('3&+'lf)('2&-'lf)) 5 )[ (Log=:'')
2&- MONAD (y=5)
3&+ DYAD (y=<'2&- MONAD (y=5)' x=5)
Which might help show that it's doing: 5 (3&+) (2&- 5), which is 12
It can also fun to play with rank
arr=:(5 2 $ i.10)
+/"0 arr
0 1
2 3
4 5
6 7
8 9
> Log [ ( '+/'lf"0 arr )[ (Log=:'')
+/ MONAD (y=0)
+/ MONAD (y=1)
+/ MONAD (y=2)
+/ MONAD (y=3)
+/ MONAD (y=4)
+/ MONAD (y=5)
+/ MONAD (y=6)
+/ MONAD (y=7)
+/ MONAD (y=8)
+/ MONAD (y=9)
+/"1 arr
1 5 9 13 17
> Log [ ( '+/'lf"1 arr )[ (Log=:'')
+/ MONAD (y=0 1)
+/ MONAD (y=2 3)
+/ MONAD (y=4 5)
+/ MONAD (y=6 7)
+/ MONAD (y=8 9)
+/"2 arr
20 25
> Log [ ( '+/'lf"2 (5 2 $ i.10) )[ (Log=:'')
+/ MONAD (y=
0 1
2 3
4 5
6 7
8 9
)))
Here is the logging code:
NB. for logging function
template_log_ =: 0 : 0
Log=:Log,<('F MONAD (y=',(":y),')')
Last=: {: Log
5!:5 <'Last'
:
Log=:Log,<('F DYAD (y=',(":y),' x=',(":x),')')
Last=: {: Log
5!:5 <'Last'
)
NB. replaces value in template
lr_log_=:template_log_ rplc 'F';]
NB. adverb to return logging verb
lf=: 1 : '3 : (lr_log_ u)'
Happy to hear any feedback to make it easier to use or better output and
whether it could be helpful for new folks
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm