"+.x" and similar unusual-looking methods

I was recently reminded of the existence of these unusual-looking methods:

[1,2] +.x [3,4,5];
[1,2] +.t [3,4,5];
[1,2] +.f [3,4,5];
[1,2] +.s [3,4,5];
[1,2] +.1 [3,4,5];
[1,2] +.-1 [3,4,5];

and am aware the + can be replaced with a different mathematical symbol (- * / %). I’m also aware they can be called with the perform method:

[1,2].perform('+', [3,4,5], \x);

but seemingly not with “normal” SC code, unless I’m messing something up:

[1,2].+([3,4,5], \x);

I originally saw these in sctweets a long time ago. I can partially infer what these operations do through trial and error, but I’m mostly clueless and wondering — do these methods have proper names, are they part of a category, are they documented, and if so, where? etc. etc.

Eli

1 Like

You can find some of them in the Docs under “Adverbs for Binary Operators”
https://doc.sccode.org/Reference/Adverbs.html
I really like the +.x in Patterns

1 Like

Thanks, very helpful. That’s the help file I needed. However, it explains the alphabetic adverbs, but doesn’t explain the numeric ones. What do these mean?

[1,2] +.1 [3,4,5];
[1,2] +.-1 [3,4,5];

Also, how would one apply this syntax to binary operators that do not have a symbolic representation, such as ‘gcd’?

[3,4].perform(\gcd, [5,8,12], \x); //works
[3,4] gcd.x [5,8,12]; //syntax error

Eli

I found the doc for the numerical adverb: http://doc.sccode.org/Guides/J-concepts-in-SC.html#Operator%20depth

Methods can be named with any string of bytes, from 'postln' to '++++' to 'Foo bar' to '何'. Even an empty symbol is a valid method name and can theoretically be called with perform (3.addUniqueMethod(\, { "foo" }); 3.perform(\) returns "foo").

But the a.b(c) or b(a, c) method call syntax can only be used if the method name b is a valid identifier, i.e. is alphanumeric (including the underscore character) and begins with a lowercase letter. This explains why [1,2].+([3,4,5], \x) is invalid — '+' is a legal name for an underlying method but not an identifier used to invoke it.

The binary operator syntax a b c is valid if b consists of one or more characters from the set !@%&*-+=|<>?/, does not start with /* or //, and is not the string =. (I think there are other ad hoc restrictions in the lexer that nobody ever worked out, but you get the idea.) This explains why [3,4] gcd.x [5,8,12]; is syntactically invalid, because gcd isn’t a valid binary operator name.

If you want to use a method with a valid identifier name as a binary operator, there is a somewhat obscure syntax called the “key binary operator”:

3 gcd: 4 // equivalent to 3.perform('gcd', 4)

Apparently you can use this syntax with adverbs

[3,4] gcd:.x [5,8,12];

although this is so weird-looking that I would prefer to use perform here.

1 Like

Thanks Nathan, for the post and for tracking down that J document. This answers the rest of my questions.