简体   繁体   中英

different result once square root is added inside tacit

Very new to J. I love it but still far from fluent in it. I have managed to hit an issue and I don't know why it is happening. If somebody could please explain why this is occuring I could learn more about this straight-to-the-point language.

Basically I'm doing difference (-) then squared (*:) then sum (+/) then want to take the square root (%:). Now the sum square error part ( (+/@:*:@:-) ) works fine:

   1 2 3 4 5 (+/@:*:@:-) 2 2 2 2 2
15

Then I can get the square root this way (just add %: to left):

   %: 1 2 3 4 5 (+/@:*:@:-) 2 2 2 2 2
3.87298

But when I add square root to left of the atco (tacit?) part in the middle it doesn't give me the right result:

   1 2 3 4 5 (%:@:+/@:*:@:-) 2 2 2 2 2
1.57001

It instead returns 1.57001 instead of 3.87298.

My understanding is all I have done is add a 'then do square root' but obviously I am wrong. But I don't understand why.

When I dissect:

require 'debug/dissect'
dissect '1 2 3 4 5 (%:@:+/@:*:@:-) 2 2 2 2 2'

I see diff (-) and square (*:) are in their own dissect boxes. But then the last box combines sum (+/) and square root (%:) together, showing %:@:+/. Not a separate box for +/ and then %: .

As I said I am new to J and am struggling to understand why this is occuring here.

I've tried changing to &, &: and @ instead but as expected that didn't fix this issue. It doesn't appear to be due to some composition limit either since this works fine (has many more atco's combined):

   (>:@:>:@:>:@:>:@:>:@:>:@:>:@:>:@:>:) 2 2 2
11 11 11

Thank you

The issue that you are encountering is that

(%:@:+/@:*:@:-)

is being evaluated as

   1 2 3 4 5 ((%:@:+)/@:*:@:-) 2 2 2 2 2
1.57001

and not

   1 2 3 4 5 %:@:(+/@:*:@:-) 2 2 2 2 2
3.87298

because of the way that conjunctions take as much of the left operand as possible. This means that your partial result from *:@:- is being processed by %:@:+/ when you want %: to apply to the result of +/@:*:@:-

Since you are just starting your journey with J, this may be a bit advanced, but at some point you may want to read the tacit programming section of J for C programmers by Henry Rich. It has a very good explanation about how J sentences are parsed. Parenthesis are your friend when you want to change the order of execution. https://www.jsoftware.com/help/jforc/contents.htm#_Toc191734581

Edit: As @Eelvex points out in the comment below the break actually occurs at (+/) , but the result is the same because of the way that conjunctions are evaluated left to right.

You are trying to form a dyadic verb for the expression:

%: +/ *: x - y  NB. which we can write as

f g h x - y     NB. if we define:

f =: %:
g =: +/
h =: *:

f g h x - y
3.87298

One way of making this a dyadic verb is to apply @: everywhere:

x (f@:g@:h@:-) y
3.87298

x (%: @: (+/) @: *: @: -) y
3.87298

A more idiomatic way of doing it uses under (&.) which inverses a verb after applying another:

f &.: g  y             NB. expands to
(g-inverse) f g y

g &.: h (x - y)
3.87298

x ( g &.: h @: -) y 
3.87298

NB. or if you prefer monadic verbs:
(g &.: h @: -/) x,: y

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM