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

Reply via email to