Mightn't it be simpler to create an adverb, say "doInDir", perhaps in its
own locale, which handles the switching rather than pushing the limits of
the design of "each"?

On Thu, May 6, 2021 at 3:43 PM Raul Miller <[email protected]> wrote:

> 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
>


-- 

Devon McCormick, CFA

Quantitative Consultant
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to