Proc::ZMQed

Proc::ZMQed provides external evaluators (Mathematica, Python, R, Raku, etc.) via ZMQ.

Raku Proc::ZMQed

This package, "Proc::ZMQed", 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.

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

...aka Wolfram Language (WL).

The following examples 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 tre 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
Pkg.add("ZMQ")
Pkg.add("JSON")

(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 OOP the 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.)

TODO

  1. TODO Robust, comprehensive ZMQ-related failures handling.

  2. TODO More robust ZMQ patterns.

    • Like the "Lazy Pirate" mentioned above.

  3. TODO Implement "Proc::ZMQed::Java".

  4. TODO Better message processing in "Proc::ZMQed::R".

  5. TODO Verify that "Proc::ZMQed::JavaScript" is working.

    • Currently, I have problems install ZMQ in JavaScript.

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.

Proc::ZMQed v0.1.0

Proc::ZMQed provides external evaluators (Mathematica, Python, R, Raku, etc.) via ZMQ.

Authors

  • Anton Antonov

License

Artistic-2.0

Dependencies

Net::ZMQ:ver<0.8+>

Test Dependencies

Provides

  • Proc::ZMQed
  • Proc::ZMQed::Abstraction
  • Proc::ZMQed::JavaScript
  • Proc::ZMQed::Julia
  • Proc::ZMQed::Mathematica
  • Proc::ZMQed::Python
  • Proc::ZMQed::R
  • Proc::ZMQed::Raku

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.