The problem is rather deep and I think has been in the system for a long
time, and I'm not actually sure it's an error.
Hold fast to the rule: when a locative name is executed, the current
locale is changed ONLY for the duration of the execution.
Now the sentence:
name_x_ inv
does not execute name_x_. It looks up name_x_ and gets a value, but the
only thing executed here is inv, which is in base. You should not
expect the lookup of name to occur in x.
The real surprise comes if you try to execute inv in x so that the
lookup will occur in the right locale. You would write:
name_x_ inv_x_
but IT STILL FAILS (i.e. value error because the components of name were
not looked up in x)!! Why?
inv is defined as ^:_1. When you execute
(value of name_x_)^:_1
in locale x, IT DOESN'T TAKE THE INVERSE. Instead it produces an
anonymous verb ((value of name_x_)^:_1) and puts that on the execution
stack. That anonymous verb might get assigned to a name or put into a
compound, or it might be executed. The inverse will be taken when the
verb is executed. When it is executed, you know one thing for sure:
it's not a locative any more. It will be executed in whatever the
current locale is, which might be anywhere.
To change JE to take the inverse earlier is not as easy as it looks,
because u^:_1 0 1 is legal.
I think you'd better define your inverses explicitly.
Henry Rich
On 3/24/2021 5:49 PM, Jan-Pieter Jacobs wrote:
Hi all,
In view of the dict add-on I wrote about recently (see [1]) I don't
understand why the inverses won't work for verbs in the class/locale below.
I would expect that if a verb having an inverse (e.g. {&vals@(keys&i.) )
containing more defined verbs (all in the same locale) works, its inverse
would also work.
This turns out to be wrong, so I wonder whether this is intended, or a bug,
and if intended, what use the present behaviour has:
NB. Test class
coclass 'cl'
create =: 3 : 0
'keys vals' =: y
gi =: keys&i. NB. Get indices
fv =: {&vals
0 0$0
)
get =: fv@gi NB. works but NOT inverse
cgi =: a.&i. NB. constant keys, defined class wide
cfv =: {&(i.256) NB. constant values
cget =: cfv@cgi NB. constant get, works but NOT inverse
aio =: {&(i.256)@(a.&i.)NB. all in one works ALSO inverse
fcget =: cfv@cgi f. NB. Also works both ways
lat =: 2 : 'u. @ v.' NB. localized @
aget =: cfv lat cgi NB. works, but NOT inverse.
d =: codestroy
cocurrent 'base'
o =: 'cl'conew~ 'abcd';i.4
get__o 'ac' NB. fine
get__o inv 1 3 NB. not ok.
cget__o 'ac'
cget__o inv 97 99 NB. not ok
fcget__o 'ac'
fcget__o inv 97 99 NB. works
aio__o 'ac'
aio__o inv 97 99 NB. works
aget__o 'ac'
aget__o inv 97 99 NB. not ok.
The fcget and aio do not need lookups and just work as intended, The others
work in one way, but not the inverse. It does not seem to be a problem
between the class locale and the object locale, because then cget would
work while get wouldn't.
Using, out of curiosity a "localized" version of at , using u./v. does not
resolve the problem either.
Fixing all verbs solves the issue but in my usecase, the problem is
occasionally, keys and vals are updated, which would require all verbs
using them to account for this, and it would feel messy to me, for
something I expected to just work. Or perhaps, I've gotten too used to J
being 100% logical...
What do you think? (this is in J903 beta-f on Linux 64 AVX).
Thanks,
Jan-Pieter
[1]: http://jsoftware.com/pipermail/programming/2021-March/057881.html
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
--
This email has been checked for viruses by AVG.
https://www.avg.com
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm