Theme:
v
APL+Win 13.2 ⎕CSE Tutorial (1)

This page contains various examples showing how to use the new APL+Win Interface to .Net 4.5 using the new ⎕CSE System Function

Example 1: The basics

The first thing that needs to be done is to initialize the ⎕CSE using its Init method:

      c←'c'⎕cse'Init' 'System'

The word 'System' is the name of a Microsoft .Net Framework DLL that we will want to use with ⎕CSE

Let's build a simple script that creates 2 string variables, one returning the current local time and the other one returning the current UTC time. The script has to be an APL character matrix containing C# code:

      script1←⊃'using System;' 'DateTime local = DateTime.Now;' 'DateTime utc = local.ToUniversalTime();' 'string localTime = local.ToString("r");' 'string utcTime = utc.ToString("r");'

      script1
using System;
DateTime local = DateTime.Now;
DateTime utc = local.ToUniversalTime();
string localTime = local.ToString("r");
string utcTime = utc.ToString("r");

You can execute the script by using the Exec method:

      'c'⎕cse'Exec' script1
0

The Exec method result is 0 if the script execution succeeded: it is ¯1 otherwise.

We can now query the values of the 2 .Net string variables, using the GetValue method:

      'c'⎕cse'GetValue' 'localTime'
Tue, 10 Sep 2013 13:31:52 GMT
      'c'⎕cse'GetValue' 'utcTime'
Tue, 10 Sep 2013 11:31:52 GMT

Question: If not using .Net, how would you have programmatically got the correct current Universal Time with just APL+Win?

In general the .Net Framework easily solves quantities of problems that would be difficult if not impossible to solve with just APL+Win

Example 2: What if you make an error in your C# script?

Let's change our C# script so that it contains an error. For example; let's have one of the statements not end with a semi-colon:

      script1←⊃'using System;' 'DateTime local = DateTime.Now;' 'DateTime utc = local.ToUniversalTime();' 'string localTime = local.ToString("r");' 'string utcTime = utc.ToString("r");'

      script1
using System;
DateTime local = DateTime.Now;
DateTime utc = local.ToUniversalTime();
string localTime = local.ToString("r")
string utcTime = utc.ToString("r");

Now let's try to run the script:

      'c'⎕cse'Exec' script1
¯1

The ¯1 result indicates that there has been an error and that the script could not be executed.

Use the GetLastError method to learn about the error:

      'c'⎕cse'GetLastError'
(4,39): error CS1002: ; expected

Note that we get an explicit error message: ; expected and that we get the line number (4) and column number (39) where the problem occurred in the script.

To fix the problem, we just need to edit the script variable, add the missing semi-colon, save the change and execute the script again:

      'c'⎕cse'Exec' script1
0

This time it runs fine.

Example 3: The ⎕CSE left argument

As you have seen in the above example, we have been using 'c' as the ⎕CSE left argument because we had first created an instance of the CSE called 'c':

      c←'c'⎕cse'Init' 'System'

But we could also have used just c (i.e. the result of the above instruction) as the left argument:

      c ⎕cse'Exec' script1      ⍝ instead of:  'c' ⎕cse'Exec' script1
0

Even better than that, we could have used the new ⎕CSELF System Variable to allow us to omit the left argument:

      ⎕cself←'c'⎕cse'Init' 'System'
      ⎕cse'Exec' script1      ⍝ instead of:  'c' ⎕cse'Exec' script1   or:  c ⎕cse'Exec' script1
0

Example 4: One statement scripts

If your script contains only one statement, you can make it a 1 row matrix and still use the Exec method or make it a string vector and use the ExecStmt method:

      ⎕cself←'c'⎕cse'Init' 'System'
      ⎕cse'Exec'(⊃,⊂'string s = "Hello World!";')
0
      ⎕cse'GetValue' 's'
Hello World!
      ⎕cse'ExecStmt' 'string s = "Hi World!";'
0
      ⎕cse'GetValue' 's'
Hi World!

Example 5: Creating a handy utility function

To make it easier to use ⎕CSE, let's create and use the following Cs APL function(which assumes ⎕CSELF has been properly set):

    ∇ R←vars Cs script;rc;I
[1]   ⍝∇ R←vars Cs script -- Executes C# "script" and optionally returns variables "vars" values
[2]   ⍝∇ script: a C# script (char string or char matrix)
[3]   ⍝∇ vars: (optional) one or more C# variable names
[4]   ⍝∇ R: either 0 0⍴'' or a nested vector containing the variable values
[5]
[6]   :if 1=⍴⍴script
[7]       rc←⎕cse'ExecStmt'script
[8]   :else
[9]       rc←⎕cse'Exec'script
[10]  :endif
[11]  :if rc≡¯1
[12]      ⎕error ⎕cse'GetLastError'
[13]  :endif
[14]  :if 2=⎕nc'vars'
[15]      :if 1=≡vars ⋄ vars←,⊂vars ⋄ :endif
[16]      R←⎕cse¨(⊂⊂'GetValue'),¨⊂¨vars
[17]  :endif
    ∇

Using this function we can now do:

      Cs  ⊃(⎕split script1)~¨';'
(1,13): error CS1002: ; expected
      Cs  ⊃(⎕split script1)~¨';'
      ^

      Cs script1
      
      'utcTime'Cs script1
 Tue, 10 Sep 2013 12:33:01 GMT

      ⊃'localTime' 'utcTime'Cs script1
Tue, 10 Sep 2013 14:33:20 GMT
Tue, 10 Sep 2013 12:33:20 GMT

Example 6: Creating a C# class with a method and using the method

It is easy to create a C# script that defines a class with one or more methods, and easy to use these methods from APL+Win. Here is an example:

      script2
using System;
public class MyDateTime
{
    public string GetUtcTime()
    {
        DateTime now = DateTime.Now;
        DateTime utc = now.ToUniversalTime();
        string result = utc.ToString("r");
        return result;
    }
}

      ⎕cse'Exec'script2
0

One must understand that C# does not work like APL: the above script just defines a C# class called MyDateTime, containing one method called GetUtcTime, but it does not execute anything and does not run the method. So executing script2 with the Exec method only defines our MyDateTime class and lets .Net know about it. It is just a definition. To be able to run the method, we need to create an instance of our MyDateTime custom class and then we need to call the method on that instance:

      ⎕cse'ExecStmt' 'MyDateTime mdt = new MyDateTime();'
0
      
      ⎕cse'GetValue' 'mdt.GetUtcTime();'
Tue, 10 Sep 2013 12:50:36 GMT

The first instruction creates an instance of the MyDateTime C# class called mdt and then, the second instruction calls the GetUtcTime method on this instance. Since we want to retrieve the result of calling this method in APL, we use GetValue.

Note that we could use the C# .Net chained dot notation to simplify our method:

      script3
using System;
public class MyDateTime
{
    public string GetUtcTime()
    {
        return DateTime.Now.ToUniversalTime().ToString("r");
    }
}

      ⎕cse'Exec'script3
0
      ⎕cse'ExecStmt' 'MyDateTime mdt = new MyDateTime();'
0
      ⎕cse'GetValue' 'mdt.GetUtcTime();'
Tue, 10 Sep 2013 13:21:35 GMT

 

CSE Tutorial (2)...
CSE Tutorial (3)...
CSE Tutorial (4)...
CSE Tutorial (5)...