⎕USING and Dfns

General APL language issues

⎕USING and Dfns

Postby paulmansour on Mon Jul 20, 2020 2:00 pm

Consider the following function:

Code: Select all
OpenExcelFile←{
     ⍝ ⍵ ←→ File Name
     ⍝ ← ←→ .NET ZipArchive
     ⎕USING←'System.IO.Compression,System.IO.Compression.FileSystem.dll'
     ZipFile.OpenRead⊂⍵
 }


It works. But only if there is not some object (a variable, function, or namespace) named ZipFile as a sibling of OpenExcelFile. (Leaving aside what ⎕PATH might do!).

I can covert to a trad function, and localize ZipFile in the header, and then it will work properly in all cases. (The trad function in more functional than the dfn!)

Two questions:

1. Is there any way to properly do this in a dfn? That is, is there a more explicit way to say I want to use a .NET class?

2. In trad function, it would seem a requirement to localize any top-level .NET name one accesses as otherwise the function only really works by accident as is the case with the dfn. Or am I missing something?
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: ⎕USING and Dfns

Postby paulmansour on Wed Jul 22, 2020 3:48 pm

To answer my own question (#1), while it does not explicitly locate the .NET class, we can localize a non-existing variable in a dfn, achieving the same result of putting a name in the header of a trad function, by creating it and deleting it. Thus:

Code: Select all
OpenExcelFile←{
     ⍝ ⍵ ←→ File Name
     ⍝ ← ←→ .NET ZipArchive
     ZipFile←0
     _←⎕EX 'ZipFile'
     ⎕USING←'System.IO.Compression,System.IO.Compression.FileSystem.dll'
     ZipFile.OpenRead⊂⍵
 }


This also has the salutary effect of not leaving behind a reference to ZipFile in the workspace. Not sure if that is a performance hit or not.
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: ⎕USING and Dfns

Postby paulmansour on Wed Jul 22, 2020 4:23 pm

Some rough testing indicates no meaningful performance hit for localization of the .NET class.
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: ⎕USING and Dfns

Postby PGilbert on Wed Jul 22, 2020 4:35 pm

In case it might help this post is explaining my understanding of ⎕USING. I am retaining this passage from John:

The interpreter optimizes multiple assignments to ⎕USING so that assemblies are loaded all at once when a reference might need them - thus the behaviour you are seeing - the assemblies are not loaded into the appdomain until you force a reference.


I have tried the code in your first post in a )CLEAR WS (v18) and it is working for me.
User avatar
PGilbert
 
Posts: 436
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: ⎕USING and Dfns

Postby paulmansour on Wed Jul 22, 2020 7:14 pm

I have tried the code in your first post in a )CLEAR WS (v18) and it is working for me.

Yes, it works in a clear workspace. The point is that is does not work in a workspace with a variable, function, or namespace named "ZipFile". It specifically relies are there NOT being such an object.
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: ⎕USING and Dfns

Postby PGilbert on Wed Jul 22, 2020 7:53 pm

Sorry Paul, you are correct, it does not work when 'ZipFile' is defined outside of the dfn and does not seems to be the correct behavior to me also.

I have tried many things and I can't make it work the way you presented it.
User avatar
PGilbert
 
Posts: 436
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: ⎕USING and Dfns

Postby Veli-Matti on Thu Jul 23, 2020 7:47 am

Hi,
.NET is not my favourite thing, but just occurred to me that this trick might work:

      OpenExcelFile←{
ZipFile←#
⎕USING←'System.IO.Compression,System.IO.Compression.FileSystem.dll'
_←⎕EX'ZipFile'
ZipFile.OpenRead⊂⍵
}


-Veli-Matti
Veli-Matti
 
Posts: 93
Joined: Sat Nov 28, 2009 3:12 pm

Re: ⎕USING and Dfns

Postby paulmansour on Thu Jul 23, 2020 1:34 pm

Hi Veli-Matti,

That does indeed work as I showed above when I (partly) answered my own question. In a dfn, simply assigning 0 (or anything) to a name and then expunging the name effectively localizes the name. A subsequent reference to that name will produce a value error even if the name exists globally.
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: ⎕USING and Dfns

Postby StefanoLanzavecchia on Mon Aug 03, 2020 6:47 am

paulmansour wrote:To answer my own question (#1), while it does not explicitly locate the .NET class, we can localize a non-existing variable in a dfn, achieving the same result of putting a name in the header of a trad function, by creating it and deleting it. Thus:


I'd do the same. But I'd probably set ZipFile to []NS'' just to show my intention of later overriding it with another "namespace".
This said, let me warn you of something I discovered empirically: if you localise ZipFile in a trad-fn and work with multiple APL threads (&), sometimes the interpreter does not put the external names back in ZipFile when switching from thread to thread. The bug has been reported more than once but there does not seem to be a simple solution at the horizon. And I got a recommendation by JD himself to never localize directly a .NET namespace but to always encapsulate those in a traditional namespace.
In other words, I changed all my code to be:
Code: Select all
     _NET←⎕NS''
     _NET.⎕USING←,⊂''

      counter←_NET.System.DateTime.UtcNow.ToBinary.ToString ⍬


and I only localize _NET.
This works flawlessly. Notice that you can set []USING to your taste. My taste is to always use full names which makes my invocations very verbose, but you don't need to.
I don't know if the issues can be replicated in d-fns but I wouldn't be surprised if that was the case.
User avatar
StefanoLanzavecchia
 
Posts: 109
Joined: Fri Oct 03, 2008 9:37 am

Re: ⎕USING and Dfns

Postby norbertjurkiewicz84 on Mon Aug 03, 2020 2:05 pm

StefanoLanzavecchia wrote:
paulmansour wrote:To answer my own question (#1), while it does not explicitly locate the .NET class, we can localize a non-existing variable in a dfn, achieving the same result of putting a name in the header of a trad function, by creating it and deleting it. Thus:


I'd do the same. But I'd probably set ZipFile to []NS'' just to show my intention of later overriding it with another "namespace".
This said, let me warn you of something I discovered empirically: if you localise ZipFile in a trad-fn and work with multiple APL threads (&), sometimes the interpreter does not put the external names back in ZipFile when switching from thread to thread. The bug has been reported more than once but there does not seem to be a simple solution at the horizon. And I got a recommendation by JD himself to never localize directly a .NET namespace but to always encapsulate those in a traditional namespace.
In other words, I changed all my code to be:
Code: Select all
     _NET←⎕NS''
     _NET.⎕USING←,⊂''

      counter←_NET.System.DateTime.UtcNow.ToBinary.ToString ⍬


and I only localize _NET.
This works flawlessly. Notice that you can set []USING to your taste. My taste is to always use full names which makes my invocations very verbose, but you don't need to.
I don't know if the issues can be replicated in d-fns but I wouldn't be surprised if that was the case.



Very interesting. By chance I started doing this a years ago. I create a #.DotNET namespace where I initialize 99% of the .NET code at application startup.
User avatar
norbertjurkiewicz84
 
Posts: 62
Joined: Mon Nov 01, 2010 7:26 pm

Next

Return to Language

Who is online

Users browsing this forum: No registered users and 1 guest