# Proc::ZMQed

This blog post proclaims and describes the package, “Proc::ZMQed”, which provides external evaluators (Julia, Mathematica, Python, R, etc.) via ZeroMQ (ZMQ).

Functionality-wise, a closely related Raku package is “Text::CodeProcessing”, [AAp1]. For example, Raku can be used in Mathematica notebooks with [AAp1] and [AAp2]; see [AA1] for more details. With this package, “Proc::ZMQed”, we can use Mathematica in Raku sessions.

See the presentation “Using Wolfram Engine in Raku sessions” for a concrete application of the package:

## Installation

From GitHub:

```zef install https://github.com/antononcube/Raku-Proc-ZMQed.git

```

From Zef ecosystem:

```zef install Proc::ZMQed

```

## Usage example: symbolic computation with Mathematica

Mathematica is also known as Wolfram Language (WL).

The following example shows:

• Establishing connection to Wolfram Engine (which is free for developers.)
• Sending a formula for symbolic algebraic expansion.
• Getting the symbolic result and evaluating it as a Raku expression.
```use Proc::ZMQed;

# Make object
my Proc::ZMQed::Mathematica \$wlProc .= new(url => 'tcp://127.0.0.1', port => '5550');

# Start the process (i.e. Wolfram Engine)
\$wlProc.start-proc;

my \$cmd = 'Expand[(x+y)^4]';
my \$wlRes = \$wlProc.evaluate(\$cmd);
say "Sent : \$cmd";
say "Got  :\n \$wlRes";

# Send computation to Wolfram Engine
# and get the result in Fortran form.
say '-' x 120;
\$cmd = 'FortranForm[Expand[(\$x+\$y)^4]]';
\$wlRes = \$wlProc.evaluate(\$cmd);
say "Sent : \$cmd";
say "Got  : \$wlRes";

# Replace symbolic variables with concrete values
my \$x = 5;
my \$y = 3;

use MONKEY-SEE-NO-EVAL;
say 'EVAL(\$wlRes) : ', EVAL(\$wlRes);

# Terminate process
\$wlProc.terminate;

```
```# Sent : Expand[(x+y)^4]
# Got  :
#   4      3        2  2        3    4
# x  + 4 x  y + 6 x  y  + 4 x y  + y
# ------------------------------------------------------------------------------------------------------------------------
# Sent : FortranForm[Expand[(\$x+\$y)^4]]
# Got  : \$x**4 + 4*\$x**3*\$y + 6*\$x**2*\$y**2 + 4*\$x*\$y**3 + \$y**4
# EVAL(\$wlRes) : 4096

```

Remark: Mathematica can have variables that start with `\$`, which is handy if we want to treat WE results as Raku expressions.

Here is a corresponding flowchart:

## Setup

In this section we outline setup for different programming languages as “servers.”

Generally, there are two main elements to figure out:

• What is the concrete Command Line Interface (CLI) name to use?
• And related code option. E.g. `julia -e` or `wolframscript -code`.
• Is ZMQ installed on the server system?

The CLI names can be specified with the option `cli-name`. The code options can be specified with `code-option`.

### Julia

In order to setup ZMQ computations with Julia start Julia and execute the commands:

```using Pkg

```

(Also, see the instructions at “Configure Julia for ExternalEvaluate”.)

By default “Proc::ZMQed::Julia” uses the CLI name `julia`. Here is an alternative setup:

```my Proc::ZMQed::Julia \$juliaProc .= new(url => 'tcp://127.0.0.1',
port => '5560',
cli-name => '/Applications/Julia-1.8.app/Contents/Resources/julia/bin/julia');

```

### Mathematica

Install Wolfram Engine (WE). (As it was mentioned above, WE is free for developers. WE has ZMQ functionalities “out of the box.”)

Make sure `wolframscript` is installed. (This is the CLI name used with “Proc::ZMQed::Mathematica”.)

### Python

Install the ZMQ library “PyZMQ”. For example, with:

```python -m pip install --user pyzmq

```

By default “Proc::ZMQed::Python” uses the CLI name `python`. Here we connect to a Python virtual environment (made and used with miniforge):

```my Proc::ZMQed::Python \$pythonProc .= new(url => 'tcp://127.0.0.1',
port => '5554',
cli-name => \$*HOME ~ '/miniforge3/envs/SciPyCentric/bin/python');

```

## Implementation details

The package architecture is Object-Oriented Programming (OOP) based and it is a combination of the OOP design patterns Builder, Template Method, and Strategy.

The package has a general role “Proc::ZMQed::Abstraction” that plays Abstract class in Template method. The concrete programming language of the classes provide concrete operations for:

• ZMQ-server side code
• Processing of setup code lines

Here is the corresponding UML diagram:

```use UML::Translators;
to-uml-spec(<Proc::ZMQed::Abstraction Proc::ZMQed::Julia Proc::ZMQed::Mathematica Proc::ZMQed::Python Proc::ZMQed::R Proc::ZMQed::Raku>, format=>'mermaid');
```

(Originally, “Proc::ZMQed::Abstraction” was named “Proc::ZMQish”, but the former seems a better fit for the role.)

The ZMQ connections are simple REP/REQ. It is envisioned that more complicated ZMQ patterns can be implemented in subclasses. I have to say though, that my attempts to implement “Lazy Pirate” were very unsuccessful because of the half-implemented (or missing) polling functionalities in [ASp1]. (See the comments here.)

## References

### Articles

[AA1] Anton Antonov, “Connecting Mathematica and Raku”, (2021), RakuForPrediction at WordPress.

### Packages

[AAp1] Anton Antonov Text::CodeProcessing Raku package, (2021-2022), GitHub/antononcube.

[AAp2] Anton Antonov, RakuMode Mathematica package, (2020-2021), ConversationalAgents at GitHub/antononcube.

[ASp1] Arne Skjærholt, Net::ZMQ, (2017), GitHub/arnsholt.

### Videos

[AAv1] Anton Antonov, “Using Wolfram Engine in Raku sessions”, (2022), Anton Antonov’s channel at YouTube.