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?
Fixes tacit verb u (i.e. gives it a fixed value without name dependencies)
by replacing each name in u with the fixed value of the name.
Similarly, m f. replaces each name in the entity denoted by character array m with the fixed value of the name. See below for an example.
So even if names refer to other names, the fixed form contains nothing but J primitives.
The name Fix is inherited from the APL language, where an analogous system function {quad}FX ("Fix") turns a function definition (expressed as a character matrix) into an APL function.
sum=: +/ count=: # by=: % mean=: sum by count mean sum by count mean f. +/ % #
If x is a literal noun containing the name of an entity (rather than a verb as in the example above), the result is similar, with all names encountered in the definition of the item named by x replaced by their fixed values. The result in this case has the same part of speech as the value named by x
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 introduce explicit definitions to limit the scope of a recursion ($:):
r=: $:@<^:* r@>: f. $:@<^:* (1 : 0)@>: u y : x u y )
See here for an explanation of why this adverb has the effect of limiting the scope of $: within its verb operand.
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.