Vocabulary/fdot
>> << Down to: Dyad Back to: Vocabulary Thru to: Dictionary
u f. m f. Fix Adverb
Rank -- depends on the rank of u -- WHY IS THIS IMPORTANT?
Gives tacit verb u an equivalent value without name dependencies.
The word fix means 'nail down', not 'repair'.
u f. is the value of u with each name replaced by name f. .
So even if names refer to other names, the fixed form contains nothing but J primitives.
(u f.) is equivalent to (u f: 'all').
sum=: +/ count=: # by=: % mean=: sum by count mean sum by count mean f. +/ % #
Common uses
1. To reduce the number of public names used in a verb definition.
Consider the following lines in a script:
'`sum count by log' =: +/ ` # ` % ` ^. NB. Same verbs as above, assigned quickly mean =: sum by count gmean =: mean&.:log NB. Geometric mean gmean mean&.:log mean sum by count
Suppose that gmean is the only definition you really need to be public. Unfortunately, the other names must also be public, polluting the common namespace, because gmean refers to them.
You can fix this:
'`sum count by log' =. +/ ` # ` % ` ^. NB. Use private assignment for temporary names mean =. sum by count gmean =: mean&.:log f. NB. f. makes temporary names go away. Assign gmean publicly gmean NB. All the names are gone (+/ % #)&.:^.
Because these lines are in a script, the names assigned privately (using =.) disappear after the script has loaded, leaving only the name gmean publicly assigned.
2. To pass a private verb into a modifier.
a =: adverb define u y ) vb =: verb define pv =. *: NB. private verb pv a y NB. pass pv into a, execute (pv a) on y ) vb 5 |value error: pv
The problem is that pv is defined in the private namespace of vb and is not visible to a. The solution is to replace the name pv by its value using (f.)
u y vb =: verb define pv =. *: NB. private verb pv f. a y NB. create the name-free verb value for pv, pass THAT to a ) vb 5 25
3. To create special code combinations unrecognised by J because some J code was assigned to a name
ts =: 6!:2 , 7!:2@] NB. Verb to find the time and space used by a sentence a =: 1000 1000 ?@$ 0 NB. create 1 million random values ts 'plus/@enfile a' NB. the worst of times 0.322007 8.39059e6 ts 'plus/@enfile f. a' NB. the best of times 0.00179939 4736
4. To execute a verb in another locale without changing the current locale
This is part of J's standard Object-Oriented Programming (OOP) support
coclass 'parent' NB. Create object. y is the name to give the object create =: verb define objname =: y ) coclass 'child' NB. child class coinsert 'parent' NB. Create object. y is the name to give the object create =: verb define create_parent_ y ) coclass 'base' NB. Back to main session NB. Create two objects obj1 =: 'object one' conew 'child' obj2 =: 'object two' conew 'child' NB. Verify obj names are what we set objname__obj1 NB. Unexpected result... object two objname__obj2 object two
The error is subtle, in the line
create_parent_ y
Executing a locative changes the implied locale before executing the verb. So create_parent_ was run in the locale: parent for both objects.
The solution is even more subtle. It uses f. to call create_parent_
coclass 'child' NB. Create object. y is the name to give the object create =: verb define create_parent_ f. y ) coclass 'base' NB. Back to main session obj1 =: 'object one' conew 'child' obj2 =: 'object two' conew 'child' objname__obj1 NB. Better object one objname__obj2 object two create_parent_ f. NB. 'create_parent_ f.' is not a locative 3 : 'objname=:y'
The key point is that create_parent_ f. is not a locative. The locative has been replaced by the value of the name, and executing that value does not change the implied locale, so objname is created in the instance locale.
More Information
1. u f. does not replace names inside the body of an explicit definition.
We can redo the mean example using mostly explicit definitions
sum =: verb define +/ y ) by =: % count =: verb define # y ) mean =: sum by count gmean =: verb define mean &.:^. y ) gmean f. 3 : 'mean&.:^.y'
The name mean in the body of the explicit definition was not altered.
mean sum by count mean f. 3 : '+/y' % 3 : '#y'
Fixing mean replaces names by their definitions, but it doesn't go inside the body of an explicit definition.
2. A modifier can be fixed by passing the character array of its name as the m operand to m f.:
Until=. {{u^:(-.@:v)^:_}} NB. conjunction; apply u until condition v is true
adv =. Until (1&>:) NB. adverb created by supplying one operand to Until
adv
Until(1&>:)
adv f. NB. a modifier train; not what we want
adv f.
'adv' f. NB. adv cannot be passed as operand to (f.), but 'adv' can
2 : 'u^:(-.@:v)^:_'(1&>:)
adv=: 'adv' f. NB. adv is now fixed
Because it is a modifier, adv cannot itself be passed as an operand to f.; the phrase adv f. creates a modifier train which applies adv to its operand, and then fixes the verb derived by the execution of adv.
If we're exporting adv from the current script, this does not help us, since adv depends on the private name Until, and so will fail with a value error when applied to a verb outside of the current script. But the character array 'adv' can be passed as an operand, yielding the fixed adverb.
3. u f. scans u for special code combinations after replacing names.
Details
1. If a name is referenced recursively, it will remain after fixing
a =: b b =: a + c c =: % a f. a + %
2. The interpreter may find it necessary to use $:: to limit the scope of a recursion ($:):
r=: $:@<^:* r@>: f. $:@<^:*$::@>: u y : x u y )
3. When the names x y u v m n are used during execution of the body of an explicit definition, they are replaced by their value (even if their value is not a noun), because their meaning changes depending on which private namespace is in use. This replacement does not fix the name (as in u f. ) but merely replaces it with its value, which may be another name.
u f: n m f: n Fix (partial) Conjunction
Rank -- depends on the rank of u -- WHY IS THIS IMPORTANT?
(u f: n) is like (u f.), but n is a string specifying what subset of the names in u are to be replaced. Words in n mean:
- single - only the name of the u argument itself is replaced. If single is not given, the value of each name encountered is also scanned for replacement, recursively.
- private — private names are replaced.
- public — public non-locative names are replaced.
- all — all public names, including locatives, are replaced.
private, public, and all are mutually exclusive; if none is given the default is private. u f. is equivalent to u f: 'all'.