Hmm... I see so many issues to touch on here.

First off, I am going to suggest a naming convention change. Instead
of 'cd' (which has a default definition in J of 15!:0), I am going to
suggest cwd if we are actually changing the working directory.

Second, though, it's important to realize that &. was never designed
to handle changes to the environment. We can make it happen by pulling
some stunts, but we need to be aware of the mechanisms and likely
failure modes.

Third, there's a naming conflict between the subject matter of this
thread and the text of your description.  A 'locale' is similar to a
'directory' but the mechanisms are different (1!:44 to change the
working directory, 18!:4 to switch the current locale).

Fourth, there's another way of thinking about this. When invoking
external programs, there's the PATH environmental variable (which has
an OS specific structure with ; as the delimiter on windows and : as
the delimiter unix derived operating systems (osx, linux, ...). I am
not certain how environmental variables are managed in windows, but in
unix-likes it's a convention involving memory in what would be the J
process. So ... since J currently doesn't supply a mechanism to
manipulate its own environmental variables to manipulate them in J you
would currently have to spin up a host program that does the work and
dynamically links in J. Easy, right? ... well... for some people it's
possible... The locale analog is quite a bit simpler in J: use the
18!:2 dyad. But... I only mention this in passing as another
alternative to circle back to later.

Fifth, the &. mechanism does not come with a 'stack' which is to say
that u&.v does not support local variables which are shared between v
and v's inverse. This can matter if u itself uses v or its inverse.
This means, in this context, that we need to think about where we
store the information to be used by v's inverse. And, we need to
decide what we're going to do about the inevitable failure modes.

-----

In computing contexts, a "failure mode" is usually an annoyance
(though when lives are at stake a failure mode can become a life
threatening issue). And an annoyance means that sooner or later we'll
encounter pressure to do something different -- which leads to a
different failure mode if we can't address the problem completely. If
we do our jobs well enough, the annoyances won't become too awful...

Here, since we don't have a stack, and since locales are themselves
stack-like structures (because of the way names are resolved in
locales), we're pushing the boundaries of the notation. So here's our
alternatives:

(1) Use 18!:5 to get the current locale. Stash the name of the current
locale in the z locale and have the obverse of our verb pull the name
from the z locale. (Failure mode -- nested locale switches trash the
restoration of the outer locale switch). Let's call our v here cwl for
'change working locale'. This also runs into a problem for u&.cwl --
how do we identify the locale for cwl and what value are we passing to
u.

(1a) let's say our z name for the locale to restore to is WL_z_ and we
want to make sure that no one nests references to it. We can erase
that name when we consume it and throw an error if we would be setting
it when it already exists. This ensures that no one uses nested
references to our mechanism. Now the failure mode is people expecting
to be able to use this mechanism frequently.

(1b) let's make a stack! We can make WL_z_ be a list of locales and
cwl can add to the list and cwlinv can remove from the list Now the
failure mode is the use of cwl without a matching cwlinv. This will
tend to show up when there's an error in u and we are trying to debug
its implementation.

Ok... so... all of these ideas are bad. And, it turns out that J
already has a mechanism for handling this situation.

Instead of using &. to deal with the locale name issue, we can use an
explicit verb. Since locales are all about dealing with explicit
names, this should be a natural approach.

example=: {{
  oldlocale=. coname''
  cocurrent x
  r=. U y
  cocurrent oldlocale
  r
}}

Here, x is the name of the temporary locale, and y is our argument to
U. If we wanted U to be dynamic, so that example was an adverb instead
of a verb, we would use u instead of U.

(If we are changing the working directory, we would do basically the
same thing, except with 1!:43 in place of coname and 1!:44 in place of
cocurrent.)

If my approach here seems a little roundabout -- well, so are locales.
From my perspective the biggest advantage of locales is that they let
different programmers build components which will be used together in
the same J session, without having to worry too much about trashing
names used by each other. This results in a little extra work at the
boundaries, but the boundaries need to be stable anyways, so it's good
to require a bit of extra work there -- that creates a bit of
'administrative inertia' (and maybe approximates the effort needed to
document the interfaces).

I hope this made sense,

-- 
Raul

On Thu, May 6, 2021 at 9:51 AM David Lambert <[email protected]> wrote:
>
> Use case:  u&.cd invokes u in some directory, then cd^:_1 restores the
> working directory.  cd is a method in another locale that stores the
> current directory before the change.  coinsert doesn't provide the desired
> encapsulation.  What, please, is the solution?
>
>    coclass'co'
>    a=:3 :'FIELD=: y'
>    b=:3 :'FIELD'
>    f=: a :. b f.
>
>    coclass'base'
>    o=:conew'co'
>
>    ([: echo 'invoked u'"_)&.f__o 98732459
> invoked u
> |noun result was required
> |       FIELD
>
>    b__o''
> 98732459
>
>    coinsert'co'
>
>    ([: echo 'invoked u'"_)&.f < 245
> invoked u
> +---+
> |245|
> +---+
>
>    FIELD=: 'and stream'
>
>    ([: echo 'invoked u'"_)&.f < 245
> invoked u
> +---+
> |245|
> +---+
>
>    FIELD
> +---+
> |245|
> +---+
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to