<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - xeus</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/tag-xeus.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2025-10-16T15:04:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>GNU Octave Meets JupyterLite: Compute Anywhere, Anytime!</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2025/gnu-octave-meets-jupyterlite-compute-anywhere-anytime/" rel="alternate"/><published>2025-10-16T15:04:00+00:00</published><updated>2025-10-16T15:04:00+00:00</updated><author><name>Isabel Paredes</name></author><id>tag:jasongrout.github.io,2025-10-16:/medium-archive/pelican/posts/2025/gnu-octave-meets-jupyterlite-compute-anywhere-anytime/</id><summary type="html">&lt;p&gt;We are thrilled to announce the newest member of our JupyterLite kernel ecosystem: Xeus-Octave. Xeus-Octave allows you to run GNU Octave…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/gnu-octave-meets-jupyterlite-compute-anywhere-anytime/images/001-1__Ha5vHmLH66mSH3WFg1fxg.jpg" alt="Octave-lite logo" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;We are thrilled to announce the newest member of our JupyterLite kernel ecosystem: &lt;strong&gt;Xeus-Octave&lt;/strong&gt;. Xeus-Octave allows you to run GNU Octave code directly on your browser. GNU Octave is a free and open-source Scientific Programming Language that can be used to run Matlab scripts. In this article, we present the challenges encountered when targeting WebAssembly, the current state of the Xeus-Octave kernel, and the future plans for expanding the GNU Octave ecosystem.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Earlier this year, we introduced the JupyterLite kernel for R, &lt;a href="/posts/2025/r-in-the-browser-announcing-our-webassembly/"&gt;&lt;strong&gt;Xeus-R-Lite&lt;/strong&gt;&lt;/a&gt;. Much like R, cross-compiling GNU Octave to WebAssembly required the same custom toolchain to enable the compilation of Fortran code, combining LLVM Flang and Emscripten.&lt;/p&gt;
&lt;p&gt;Similar to many other mathematically oriented language packages, GNU Octave requires a BLAS/LAPACK implementation. Fortunately, OpenBLAS and the Netlib implementations of BLAS/LAPACK had already been added to the emscripten-forge WebAssembly distribution. Initially, OpenBLAS was the preferred implementation, but for the successful compilation of Octave, Netlib LAPACK was selected as it presented fewer hurdles during the build process.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="cross-compilation-of-gnu-octave"&gt;Cross-Compilation of GNU Octave&lt;/h2&gt;
&lt;p&gt;One of the complications of cross-compiling Octave to WebAssembly, which had not been encountered with the R source code, was the extensive use of Fortran common symbols blocks in the internal libraries of Octave such as odepack.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;liboctave&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;external&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;odepack&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;slsode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-----------------------------------------------------------------------&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;following&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Common&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;contains&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;which&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subroutine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whose&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;must&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;preserved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;routine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;own&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;which&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;communicated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subroutines&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SLS001&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;declared&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subroutines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SLSODE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SINTDY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SSTODE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SPREPJ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SSOLSY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Groups&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;replaced&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arrays&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Common&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;declarations&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;routines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;those&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-----------------------------------------------------------------------&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;COMMON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;SLS001&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CONIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CRATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ELCO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;HOLD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RMAX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TESCO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;CCMAX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EL0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HMIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HMXI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HU&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UROUND&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;INIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MXSTEP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MXHNIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NHNIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NSLAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NYH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;IALTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IPUP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LMAX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MEO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NQNYH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NSLP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;ICF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IERPJ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IERSL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JCUR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JSTART&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;KFLAG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;LYH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LEWT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LACOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LSAVF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LWM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LIWM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;METH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MITER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;MAXORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MAXCOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MSBP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MXNCF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NFE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NJE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NQU&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initially, it was not possible to cross-compile these common blocks to WebAssembly because the latest version of LLVM (v20 at the time of testing) did not support common symbol linkage.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Source: llvm/lib/MC/MCWasmStreamer.cpp&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MCWasmStreamer::emitCommonSymbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MCSymbol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint64_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="n"&gt;Align&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ByteAlignment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;llvm_unreachable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Common symbols are not yet implemented for Wasm&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As a temporary solution, LLVM was patched with the help of &lt;a href="https://github.com/serge-sans-paille"&gt;Serge Guelton&lt;/a&gt; to simulate common symbols as weak symbols.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;void MCWasmStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
&lt;span class="w"&gt; &lt;/span&gt;                                     Align ByteAlignment) {
&lt;span class="gd"&gt;-  llvm_unreachable(&amp;quot;Common symbols are not yet implemented for Wasm&amp;quot;);&lt;/span&gt;
&lt;span class="gi"&gt;+  auto *Symbol = cast&amp;lt;mcsymbolwasm&amp;gt;(S);&lt;/span&gt;
&lt;span class="gi"&gt;+  getAssembler().registerSymbol(*Symbol);&lt;/span&gt;
&lt;span class="gi"&gt;+  Symbol-&amp;gt;setWeak(true);&lt;/span&gt;
&lt;span class="gi"&gt;+  Symbol-&amp;gt;setExternal(true);&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A proper solution to enable support of common symbols is currently in progress and will likely be included in the next release of LLVM v22 (see &lt;a href="https://github.com/llvm/llvm-project/pull/151478"&gt;llvm-project/pull/151478&lt;/a&gt;). For curious readers, the patched version of LLVM can be found &lt;a href="https://github.com/IsabelParedes/llvm-project/releases/download/v20.1.7_emscripten-wasm32/llvm_emscripten-wasm32-20.1.7-h2e33cc4_5.tar.bz2"&gt;here&lt;/a&gt; (linux only).&lt;/p&gt;
&lt;p&gt;In addition to the patches for LLVM, GNU Octave required a few minor modifications to target WebAssembly; mainly this entailed disabling the GUI functionalities and consolidating the Fortran function signatures and calling conventions. A full list of patches can be found in the &lt;a href="https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/octave/patches"&gt;recipe directory&lt;/a&gt; on emscripten-forge.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="xeus-octave"&gt;Xeus-Octave&lt;/h2&gt;
&lt;p&gt;Once GNU Octave had been successfully packaged for WebAssembly, bringing &lt;a href="https://github.com/jupyter-xeus/xeus-octave"&gt;Xeus-Octave&lt;/a&gt; to JupyterLite was a simple matter of adding a recipe to &lt;a href="https://github.com/emscripten-forge/recipes/"&gt;emscripten-forge&lt;/a&gt;!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A JupyterLite notebook demonstrating plots with Xeus-Octave" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/gnu-octave-meets-jupyterlite-compute-anywhere-anytime/images/002-1_lKsfXJGc7_tM1ONU5Ej0Ng.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;&lt;a href="https://jupyter-xeus.github.io/xeus-octave/lab/?path=xeus-octave-wasm.ipynb"&gt;&lt;strong&gt;Try Xeus-Octave in JupyterLite!&lt;/strong&gt;&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;h2 id="future-work"&gt;Future Work&lt;/h2&gt;
&lt;p&gt;For our next steps, the team is planning on expanding the Octave ecosystem by adding Octave packages to both conda-forge and emscripten-forge. The packaging work will require defining a process where Octave packages can be installed in predetermined conda environments, perhaps with some minor modifications to the existing pkg utility.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Isabel Paredes&lt;/strong&gt;, who led the charge on bringing GNU Octave to emscripten-forge, is a senior scientific software developer at QuantStack. Prior to working on this project, she focused on porting the R programming language and the Robot Operating System (ROS) framework to WebAssembly.&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This project synthesizes work from many open-source contributors.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/emscripten-forge/recipes/"&gt;&lt;strong&gt;Emscripten-forge&lt;/strong&gt;&lt;/a&gt;, the distribution of conda packages for WebAssembly, was created by Thorsten Beier, who continues to lead the project. Many recipes were contributed by Isabel Paredes, Anutosh Bhat, Martin Renou, Ian Thomas, Wolf Vollprecht, and Johan Mabille.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jupyterlite.readthedocs.io/en/stable/?badge=latest"&gt;&lt;strong&gt;JupyterLite&lt;/strong&gt;&lt;/a&gt;, the Jupyter distribution that runs entirely in the web browser, was created by Jeremy Tuloup.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus"&gt;&lt;strong&gt;Xeus&lt;/strong&gt;&lt;/a&gt;, the C++ library implementing the Jupyter kernel protocol, enabling a custom communication layer, and is foundational to kernels like xeus-r, xeus-python, running in JupyterLite, was created by Johan Mabille and is maintained by a broader team including Martin Renou, Sylvain Corlay, and Thorsten Beier, who worked on the first integration with JupyterLite.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-octave"&gt;&lt;strong&gt;Xeus-Octave&lt;/strong&gt;&lt;/a&gt;, the Xeus-based Jupyter kernel for GNU Octave, was created by Giulio Girardi and Antoine Prouvost.&lt;/li&gt;
&lt;/ul&gt;
</content><category term="JupyterLite"/><category term="kernels"/><category term="WebAssembly"/><category term="xeus"/></entry><entry><title>R in the Browser: Announcing Our WebAssembly Distribution</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/" rel="alternate"/><published>2025-02-28T08:31:00+00:00</published><updated>2025-04-25T07:39:00+00:00</updated><author><name>Isabel Paredes</name></author><id>tag:jasongrout.github.io,2025-02-28:/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/</id><summary type="html">&lt;p&gt;R is now available in emscripten-forge, enabling the Xeus-R kernel in JupyterLite&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/001-1_y4YmV8C0L1CkE1Q5JRJLkg.webp" alt="Banner with gradient background and R-lite logo" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;In the past few months, &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; has received funding from the &lt;a href="https://www.gatesfoundation.org/"&gt;&lt;strong&gt;Bill &amp;amp; Melinda Gates Foundation&lt;/strong&gt;&lt;/a&gt; through a grant to &lt;a href="https://coursekata.org/"&gt;CourseKata&lt;/a&gt; to develop support for the R programming language in &lt;a href="https://jupyterlite.readthedocs.io/en/stable/"&gt;JupyterLite&lt;/a&gt; and the &lt;a href="https://emscripten-forge.org/"&gt;Emscripten-forge&lt;/a&gt; distribution for WebAssembly.&lt;/p&gt;
&lt;p&gt;Today, we are thrilled to announce the availability of the R programming language in the Emscripten-Forge distribution for WebAssembly, which enables R workflows in JupyterLite through the Xeus-R Jupyter kernel.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Screenshot of JupyterLite with an R Jupyter notebook in use" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/002-0_9D50aOr7jhxFnjzo.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;JupyterLite with an R Jupyter notebook in use&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To experience R in JupyterLite, simply click on the link below:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://isabelparedes.github.io/xeus-r-demo/lab/?path=demo.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/003-0_qOr5KTmon-fiZ37l.webp" alt="Button to access JupyterLite" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this article, we present the details of our efforts to enable R workflows in JupyterLite. We cover the challenges encountered in packaging R and its dependencies for this platform, the solutions we implemented, and the process of handling R mamba packages on the frontend.&lt;/p&gt;
&lt;h2 id="why-webassembly-scaling-scientific-computing-workflows-in-jupyter-to-millions-of-users"&gt;&lt;strong&gt;Why WebAssembly? Scaling scientific computing workflows in Jupyter to millions of users&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The main challenge in scaling Jupyter deployments lies in providing a live computing environment on the server side for each user session.&lt;/p&gt;
&lt;p&gt;While Kubernetes-based JupyterHub deployments have been successfully implemented at a university scale (such as the UC Berkeley Data 8 class, or the JupyterHub deployment of Université Paris Saclay), they demand substantial computing resources and a skilled DevOps team to achieve and maintain this level of scalability.&lt;/p&gt;
&lt;p&gt;In contrast, &lt;a href="https://jupyterlite.readthedocs.io/"&gt;&lt;strong&gt;JupyterLite&lt;/strong&gt;&lt;/a&gt; represents a fundamentally different paradigm. As a browser-based distribution of Jupyter, it runs language kernels directly in the browser, enabling significantly greater scalability and ease of deployment. Notable JupyterLite-based applications include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A JupyterLite console integrated into &lt;a href="http://numpy.org"&gt;&lt;strong&gt;NumPy&lt;/strong&gt;&lt;/a&gt;’s front page, providing immediate access to NumPy functionality without requiring installation.&lt;/li&gt;
&lt;li&gt;A similar console application on &lt;a href="https://live.sympy.org/"&gt;&lt;strong&gt;SymPy&lt;/strong&gt;&lt;/a&gt;’s project page, fully hosted statically.&lt;/li&gt;
&lt;li&gt;The official &lt;a href="https://jupyter.org/try"&gt;&lt;strong&gt;Jupyter&lt;/strong&gt;&lt;/a&gt; website¹.&lt;/li&gt;
&lt;li&gt;The examples in &lt;a href="https://scikit-learn.org/stable/lite/lab/index.html"&gt;&lt;strong&gt;Scikit-Learn&lt;/strong&gt;&lt;/a&gt;’s documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These examples illustrate how WebAssembly can be transformative by providing ready-to-use computing environments for scientific workflows, in documentation, blog posts, and scientific communications. The WebAssembly environments are made available to the hundreds of thousands of monthly visitors of these websites without requiring any computing resources on the backend.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://NumPy.org"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/004-0_-531naCHla3pK14Q.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://live.sympy.org/"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/005-0_vk6bu54D0C7y4k9b.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://jupyter.org/try"&gt;&lt;img alt="JupyterLite deployments displayed on the NumPy, SymPy, and Jupyter websites" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/006-0_SKvqpunHcz3i2mBG.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;JupyterLite deployments displayed on the NumPy, SymPy, and Jupyter websites&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;[1] Even though it powers the deployment of Jupyter on the main Jupyter website, JupyterLite is not an officially sanctioned Jupyter project.&lt;/p&gt;
&lt;h2 id="beyond-python-enabling-r-in-the-browser-and-more"&gt;&lt;strong&gt;Beyond Python, enabling R in the browser, and more&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;While the initial focus of the JupyterLite team has been on the Python programming language, the JupyterLite infrastructure was designed to be language-agnostic from the outset. The same principle applies to the package management stack we have been contributing to over the past few years, namely, &lt;a href="https://github.com/mamba-org/mamba"&gt;mamba&lt;/a&gt; and &lt;a href="https://conda-forge.org/"&gt;conda-forge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When we began targeting the WebAssembly platform, we chose to build our efforts on the mamba and conda-forge ecosystem. This decision allowed us to provide customizable environments for WebAssembly and expand beyond Python. This enabled applications such as the &lt;a href="https://github.com/jupyterlite/terminal"&gt;&lt;strong&gt;JupyterLite terminal&lt;/strong&gt;&lt;/a&gt;, created by Ian Thomas, which comprises a bash-like shell written in TypeScript called &lt;a href="https://github.com/jupyterlite/cockle"&gt;Cockle&lt;/a&gt;, and WebAssembly builds of native shell commands such as cat, grep, ls, and vim. You can read the &lt;a href="/posts/2024/jupyterlite-terminal/"&gt;&lt;strong&gt;earlier&lt;/strong&gt; &lt;strong&gt;announcement&lt;/strong&gt;&lt;/a&gt; introducing the JupyterLite terminal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Today, we are excited to reveal the availability of R in emscripten-forge, enabling Jupyter kernels such as Xeus-R to be used in JupyterLite.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With the addition of R, emscripten-forge now provides a unified packaging solution for Python, R, and terminal applications for WebAssembly. This covers the scopes of &lt;a href="https://pyodide.org/"&gt;&lt;strong&gt;Pyodide&lt;/strong&gt;&lt;/a&gt; (a Python distribution for WebAssembly), &lt;a href="https://docs.r-wasm.org/"&gt;&lt;strong&gt;WebR&lt;/strong&gt;&lt;/a&gt; (an R distribution for WebAssembly), and &lt;a href="https://sandbox.bio/"&gt;&lt;strong&gt;Sandbox.bio&lt;/strong&gt;&lt;/a&gt; (a shell emulator with WebAssembly commands).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="building-r-for-emscripten-forge"&gt;&lt;strong&gt;Building R for Emscripten-forge&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Emscripten-forge is a GitHub organization containing recipes to build &lt;strong&gt;conda packages&lt;/strong&gt; for the emscripten-wasm32 platform; it is also the first distribution of conda packages targeting this platform. It is built upon a modernized stack, leveraging &lt;strong&gt;rattler-build&lt;/strong&gt; (the successor to the conda-build package builder) and &lt;strong&gt;mamba&lt;/strong&gt;. The emscripten-forge project, which was created and is still led by Thorsten Beier, is now a team effort covering a broad range of packages.&lt;/p&gt;
&lt;p&gt;In order to build R with emscripten-forge, we first required a toolchain capable of converting Fortran and C/C++ code into WebAssembly. Since R relies on BLAS and LAPACK (which are written in Fortran) and many essential R packages wrap native libraries that use Fortran, this conversion capability was crucial.&lt;/p&gt;
&lt;h2 id="fortran"&gt;&lt;strong&gt;Fortran&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;By default, the emscripten-forge toolchain can cross-compile any C/C++ packages into WebAssembly; however, the first challenge in building the R stack was expanding the toolchain to also compile Fortran code. The two compilers that we considered for this task are LFortran and Flang.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lfortran.org/"&gt;&lt;strong&gt;LFortran&lt;/strong&gt;&lt;/a&gt; is a compiler built on top of LLVM and designed from the ground up as a cross-compiler. Despite its potential, LFortran is still in its early stages compared to Flang and does not yet fully support all Fortran features.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flang.llvm.org/"&gt;&lt;strong&gt;LLVM Flang&lt;/strong&gt;&lt;/a&gt; is the Fortran compiler of the LLVM project. Unfortunately, it does not support cross-compilation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Working with Serge Guelton and Kerim Birgi, we initially experimented with the LFortran compiler and contributed to addressing issues encountered when building Netlib &lt;a href="https://github.com/Reference-LAPACK/lapack"&gt;LAPACK&lt;/a&gt;. The BLAS implementation from this package served as a valuable testing ground since BLAS is one of the core dependencies for R.&lt;/p&gt;
&lt;p&gt;After careful consideration, we found that Flang, with its ability to compile a wider variety of Fortran projects, brought us closer to building the Fortran components of R to WebAssembly. George Stagg, the main developer of the WebR project, has written a detailed &lt;a href="https://gws.phd/posts/fortran_wasm/"&gt;article&lt;/a&gt; on using Flang to produce WebAssembly, which was adapted to the (then) latest version of LLVM (&lt;a href="https://github.com/r-wasm/llvm-project/blob/wasm/llvm/CMakeLists.txt"&gt;v18&lt;/a&gt;). Inspired by George Stagg’s endeavors, Serge posted upstream contributions to the Flang project (&lt;a href="https://github.com/llvm/llvm-project/pull/99465"&gt;#99465&lt;/a&gt;, &lt;a href="https://github.com/llvm/llvm-project/pull/99822"&gt;#99822&lt;/a&gt;, &lt;a href="https://github.com/llvm/llvm-project/pull/101242"&gt;#101242&lt;/a&gt;, &lt;a href="https://github.com/llvm/llvm-project/pull/105589"&gt;#105589&lt;/a&gt;), resolving issues with 32-bit platforms that were impacting our effort to support WebAssembly. All of these changes will be included in LLVM/Flang 20.0.&lt;/p&gt;
&lt;p&gt;The remaining patches which cannot be merged upstream at this point involve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(1) enabling code generation that targets WebAssembly (&lt;a href="https://github.com/llvm/llvm-project/commit/198c0e1e23a52abb3e274ee44223551247f2c38f"&gt;198c0e1&lt;/a&gt;),&lt;/li&gt;
&lt;li&gt;(2) encoding target-specific size definitions for various data types given that the host and target platforms have different architectures (&lt;a href="https://github.com/llvm/llvm-project/commit/1da66cda3652da369f5d1be871c27368a12b55e9"&gt;1da66cd&lt;/a&gt;), and&lt;/li&gt;
&lt;li&gt;(3) disabling support for 128-bit floating-point types (&lt;a href="https://github.com/llvm/llvm-project/commit/f20c7c05db0ed9afb50c0092dad7bc991d933481"&gt;f20c7c0&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A version of (2) that could be contributed upstream is in the works, which would be one step closer to making WebAssembly an official target for Flang. Additionally, (3) will no longer be needed starting with Flang v20.&lt;/p&gt;
&lt;p&gt;These patches were integrated by Axel Obermeier into the Flang build recipe for the conda-forge distribution, making the modified build accessible to everyone. It can be installed on Linux with mamba or micromamba by executing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;micromamba&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;conda-forge/label/emscripten::flang&lt;span class="w"&gt; &lt;/span&gt;libllvm19&lt;span class="w"&gt; &lt;/span&gt;--no-channel-priority
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The final ingredient for our toolchain involved creating a compatible Fortran runtime library. Since Flang implements its runtime library in C/C++, compiling this library with Emscripten proved to be straightforward. We added a &lt;a href="https://github.com/emscripten-forge/recipes/blob/9b08a19a531bb5e03c7d5147367f6de2acb57e40/recipes/recipes_emscripten/libflang/recipe.yaml"&gt;recipe for libflang&lt;/a&gt; to emscripten-forge, which packages the runtime library and includes all the aforementioned patches.&lt;/p&gt;
&lt;p&gt;In the following example, we invoke Flang on a simple Fortran script, and execute the resulting JavaScript and WebAssembly with NodeJS.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;ls
hello.f90&lt;span class="w"&gt;  &lt;/span&gt;libFortranRuntime.a
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;hello.f90
File:&lt;span class="w"&gt; &lt;/span&gt;hello.f90
program&lt;span class="w"&gt; &lt;/span&gt;hello
&lt;span class="w"&gt; &lt;/span&gt;print&lt;span class="w"&gt; &lt;/span&gt;*,&lt;span class="w"&gt; &lt;/span&gt;“Hello,&lt;span class="w"&gt; &lt;/span&gt;Fortran!”
end&lt;span class="w"&gt; &lt;/span&gt;program&lt;span class="w"&gt; &lt;/span&gt;hello
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/emsdk/emsdk_env.sh
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;flang-new&lt;span class="w"&gt; &lt;/span&gt;--target&lt;span class="o"&gt;=&lt;/span&gt;wasm32-unknown-emscripten&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;hello.f90&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;hello.o
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;emcc&lt;span class="w"&gt; &lt;/span&gt;hello.o&lt;span class="w"&gt; &lt;/span&gt;libFortranRuntime.a&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;hello.js
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;ls
hello.f90&lt;span class="w"&gt;  &lt;/span&gt;hello.js&lt;span class="w"&gt;  &lt;/span&gt;hello.o&lt;span class="w"&gt;  &lt;/span&gt;hello.wasm&lt;span class="w"&gt;  &lt;/span&gt;libFortranRuntime.a
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;node&lt;span class="w"&gt; &lt;/span&gt;hello.js
Hello,&lt;span class="w"&gt; &lt;/span&gt;Fortran!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With a working Fortran-to-WebAssembly toolchain, we managed to compile BLAS and LAPACK (See the &lt;a href="https://github.com/emscripten-forge/recipes/blob/main/recipes/recipes_emscripten/lapack/recipe.yaml"&gt;LAPACK recipe&lt;/a&gt;). But before we could get started with building R, we needed to tackle the remaining R dependencies.&lt;/p&gt;
&lt;h2 id="walking-up-the-stack"&gt;&lt;strong&gt;Walking up the stack&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In R (v4.4), there are a handful of dependencies that are required to provide basic functionality; these are: libiconv, zlib, bzip2, xz, pcre2, and libcurl. Thanks to the packaging efforts led by Thorsten Beier and Wolf Vollprecht, these dependencies are available on emscripten-forge with the exception of libcurl. Because of its socket-based networking architecture and reliance on system-level resource access, libcurl faces fundamental incompatibilities with WebAssembly’s sandboxed environment constraints. Therefore, libcurl had to be disabled in the R source code. As a consequence, downstream R packages which depend on libcurl cannot be ported to WebAssembly until a suitable libcurl replacement is available.&lt;/p&gt;
&lt;p&gt;Apart from the core dependencies, R also requires a BLAS implementation. Although external BLAS libraries can be used with R, the R code base contains linear algebra routines from Netlib BLAS and a subset of LAPACK where both libraries are written in C and Fortran. To simplify configuration, we opted for these internal implementations instead of using external BLAS and LAPACK libraries.&lt;/p&gt;
&lt;p&gt;Furthermore, several key optional dependencies were cross-compiled to WebAssembly to enhance R’s graphical capabilities; these include libpng, libtiff, cairo, and pango, along with their respective subdependencies. One particularly challenging aspect of packaging these libraries was the cross-compilation of glib, which both cairo and pango depend on. Compiling glib was only possible thanks to the efforts of &lt;a href="https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887"&gt;Kleis Auke Wolthuizen&lt;/a&gt; whose patches made glib compatible with Emscripten, and Johan Mabille who disabled multi-threading.&lt;/p&gt;
&lt;p&gt;The R dependencies are summarized in the following table:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A table summarizing the R dependencies." src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/r-in-the-browser-announcing-our-webassembly/images/007-1_9VQSZHRow-lBASg0wxfklg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Table of R dependencies&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="cross-compilation-of-r"&gt;&lt;strong&gt;Cross-compilation of R&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Although R typically configures and builds seamlessly on most unix platforms, cross-compiling is not straightforward because R uses a bootstrap approach; first it creates a minimal version of R which is then used to run several R scripts to complete the build process. Bootstrapping is a challenge because the built binaries for the target platform (WebAssembly) are not executable (at least not directly) from the host platform. Therefore, the r-base package necessitates two build phases. First, we compile R for the host platform (Linux) with GCC and Flang; this generates the R and Rscript executables needed for the second phase. And then, we cross-compile to WebAssembly with Emscripten and Flang.&lt;/p&gt;
&lt;p&gt;One of the major challenges of this setup was generating the R Data Base (.rdb) and R Data Index (.rdx) files for the internal packages of r-base (base, compiler, grDevices, graphics, grid, methods, parallel, splines, stats, stats4, tools, and utils). To accomplish this, it was necessary to dynamically load some of the internal shared libraries (tools, grDevices, graphics, utils, stats, and methods) which provide essential functionality to generate the data and index files. However, the R executables we created during the first phase of the build are incompatible with the WebAssembly shared libraries. In order to work around this, we temporarily replaced the WebAssembly libraries of the internal packages with the linux shared libraries we built during the first phase (See &lt;a href="https://github.com/emscripten-forge/recipes/blob/9b08a19a531bb5e03c7d5147367f6de2acb57e40/recipes/recipes_emscripten/r-base/cross_libraries.sh"&gt;cross_libraries.sh&lt;/a&gt;). This makeshift solution is also used to cross-compile all other R packages; the setup is carried out by the activation script of the cross-r-base package (See &lt;a href="https://github.com/conda-forge/r-base-feedstock/blob/54c15117f86693d54d69aacdd2fb76f622e31e5a/recipe/activate-cross-r-base.sh#L18"&gt;activate-cross-r-base.sh&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Additionally, the R source code required a few modifications to enable cross-compilation to WebAssembly.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Emscripten platform was added to select the correct configuration for the platform.&lt;/li&gt;
&lt;li&gt;The dependency on libcurl was removed (as mentioned in the previous section) and as a consequence, the internet package which relies on libcurl was disabled.&lt;/li&gt;
&lt;li&gt;System calls which are not compatible with our WebAssembly environment were disabled.&lt;/li&gt;
&lt;li&gt;Cairo replaced Xlib as the default bitmap type to enable graphics.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The complete list of patches applied to R is available here: &lt;a href="https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/r-base/patches"&gt;r-base patches&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="the-r-package-ecosystem"&gt;&lt;strong&gt;The R package ecosystem&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Building R itself was just the beginning. The next challenge was to provide a wide array of R packages to create a robust development environment. Fortunately, many packages are written in pure R and are available as “noarch” packages on conda-forge, making them directly compatible with emscripten-forge environments. However, for the R packages that require compilation, a package recipe needs to be created and added to emscripten-forge. Thanks to the help of Anutosh Bhat, the following packages have been compiled and are available to use.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;r-askpass     r-digest    r-haven      r-magrittr  r-purrr    r-tidyr
r-base64enc   r-dplyr     r-hexbin     r-mass      r-rcpp     r-tzdb
r-bit         r-ellipsis  r-htmltools  r-matrix    r-readr    r-utf8
r-bit64       r-fansi     r-isoband    r-mgcv      r-rlang    r-vctrs
r-cachem      r-farver    r-jsonlite   r-mime      r-sp       r-vroom
r-cli         r-fastmap   r-later      r-nlme      r-stringi  r-xfun
r-colorspace  r-ggrepel   r-lattice    r-plyr      r-sys      r-yaml
r-data.table  r-glue      r-lazyeval   r-promises  r-tibble
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Most of the time, cross-compiling an R package is very simple because the bulk of the work is handled by r-base. Building a package typically boils down to a single line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;CMD&lt;span class="w"&gt; &lt;/span&gt;INSTALL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$R_ARGS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Occasionally, minor patches are applied to the package source code to enable the WebAssembly target platform or to simplify cross-compilation. Some R packages, such as r-nlme, contain Fortran code; for such packages, the custom flang compiler needs to be installed before the package can be cross-compiled. Should any package be needed for your use case, feel free to contribute them to emscripten-forge!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="xeus-r"&gt;&lt;strong&gt;Xeus-R&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Once a sufficient set of packages is available for the platform, the next step is to provide a development environment for end users. Our chosen tool for this purpose is Jupyter.&lt;/p&gt;
&lt;p&gt;The most popular Jupyter kernel for R is &lt;a href="https://github.com/IRkernel/IRkernel"&gt;IRkernel&lt;/a&gt;, which has been developed over several years. It includes complete ZeroMQ bindings for the R language and comprehensive coverage of the Jupyter protocol. However, since IRkernel is tied to ZeroMQ, we opted to work with the &lt;a href="https://github.com/jupyter-xeus/xeus-r"&gt;Xeus-R&lt;/a&gt; project instead, which was &lt;a href="/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/"&gt;announced last year.&lt;/a&gt; Xeus-R was developed by Romain François in collaboration with our team and with JupyterLite in mind. It is built upon the Xeus library, which provides a native implementation of the Jupyter protocol and is adapted to work with the JupyterLite frontend.&lt;/p&gt;
&lt;p&gt;Fortunately, the components of IRkernel responsible for the rich representation of R objects and rich display in Jupyter frontends were split into two separate R packages: &lt;strong&gt;IRdisplay&lt;/strong&gt; and &lt;strong&gt;repr&lt;/strong&gt;. These packages can be reused in Xeus-R. As a result, Xeus-R and IRkernel offer the same rich display functionality, ensuring that Jupyter notebooks created with one kernel will work with the other. However, Xeus-R provides a different implementation of the communication layer through &lt;a href="https://github.com/jupyterlite/xeus"&gt;jupyterlite-xeus&lt;/a&gt;, which enables integration with the JupyterLite stack. This integration was previously implemented for Xeus-Python and Xeus-Lua.&lt;/p&gt;
&lt;p&gt;One key aspect of this integration is the populating of the in-memory file system used by JupyterLite kernels with the required runtime dependencies, particularly shared libraries. This process is done upon bootstrapping the kernel. For this purpose, Anastiasiia Sliusar and Martin Renou developed &lt;a href="https://github.com/emscripten-forge/mambajs"&gt;mambajs&lt;/a&gt;, which, in combination with jupyterlite-xeus, processes conda packages in the frontend and installs them in the kernel filesystem at startup. In WebAssembly, shared libraries need to be handled with special care in order to function as expected. Drawing inspiration from the Python community, we adapted the pioneering work of Pyodide to properly load shared libraries into the filesystem.&lt;/p&gt;
&lt;h2 id="how-to-make-a-deployment-with-custom-packages"&gt;&lt;strong&gt;How to make a deployment with custom packages&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The GitHub repository &lt;a href="https://github.com/jupyterlite/xeus-lite-demo"&gt;https://github.com/jupyterlite/xeus-lite-demo&lt;/a&gt; is a template for creating a JupyterLite deployment on GitHub pages that includes the packages specified in a conda environment.&lt;/p&gt;
&lt;p&gt;The process is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new repository from the GitHub template.&lt;/li&gt;
&lt;li&gt;Enable the deployment on GitHub pages from a GitHub action, as shown in the README.&lt;/li&gt;
&lt;li&gt;Edit the environment file to include the desired packages.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For example, to deploy an R kernel with coursekata installed, the environment.yml file would contain the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;xeus-r&lt;/span&gt;
&lt;span class="nt"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;https://repo.mamba.pm/emscripten-forge&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;conda-forge&lt;/span&gt;
&lt;span class="nt"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;xeus-r&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;r-coursekata&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The deployment linked at the beginning of this article was created with this template.&lt;/p&gt;
&lt;h2 id="how-to-contribute"&gt;&lt;strong&gt;How to contribute&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Contributors are always welcome! New R packages can be requested by opening an issue on emscripten-forge, or added directly by opening a pull request with the desired package recipe. For instructions on how to contribute, please visit &lt;a href="https://emscripten-forge.org/"&gt;https://emscripten-forge.org/&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="what-is-in-the-works"&gt;&lt;strong&gt;What is in the works&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Currently, we are developing the infrastructure to dynamically install emscripten-forge and conda-forge noarch packages in JupyterLite kernel environments. This will apply to all Xeus kernels that make use of these packages, such as Xeus-Python, Xeus-R, and Xeus-Lua. In the case of R, this may be directly bound to install.packages.&lt;/p&gt;
&lt;p&gt;Additionally, we are working on more advanced features for the R kernel, including support for Jupyter interactive widgets and the split of the pure R parts of xeus-r into a separate package, which would facilitate a possible convergence with IRkernel.&lt;/p&gt;
&lt;p&gt;Finally, other language kernels based on the same package management stack are also in the works. Stay tuned for future announcements!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="about-the-author"&gt;&lt;strong&gt;About the Author&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Isabel Paredes&lt;/strong&gt;, who led the charge on bringing R to emscripten-forge, is a senior scientific software developer at QuantStack. Prior to working on this project, she focused on porting the Robot Operating System (ROS) framework to WebAssembly.&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;&lt;strong&gt;Acknowledgments&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This effort brought together several endeavors from many open-source developers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JupyterLite&lt;/strong&gt;, the Jupyter distribution that runs entirely in the web browser, was created by Jeremy Tuloup.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xeus&lt;/strong&gt;, the C++ library implementing the Jupyter kernel protocol, enabling a custom communication layer, and is foundational to kernels like xeus-r, xeus-python, running in JupyterLite, was created by Johan Mabille and is maintained by a broader team including Martin Renou, Sylvain Corlay, and Thorsten Beier, who worked on the first integration with JupyterLite.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Emscripten-forge&lt;/strong&gt;, the distribution of conda packages for WebAssembly, was created by Thorsten Beier, who continues to lead the project. Many recipes were contributed by Isabel Paredes (for the R ecosystem), but also Kerim Birgi, Anutosh Bhat, Martin Renou, Wolf Vollprecht, and Johan Mabille.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xeus-R&lt;/strong&gt;, the Xeus-based Jupyter kernel for R, was created by Romain François.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IRDisplay&lt;/strong&gt; and &lt;strong&gt;repr&lt;/strong&gt; are pure R packages providing rich display and rich mime type rendering of many core R types, which are used in xeus-r. These two packages stem from the IRkernel project, a Jupyter kernel for R written in R, which was started by Thomas Kluyver, and has been maintained over the years by Philipp Angerer and Jan Katins.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MambaJS&lt;/strong&gt;, the library enabling the processing of conda packages in the frontend, was developed by Anastasiia Sliusar and Martin Renou.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conda-forge&lt;/strong&gt;, the main distribution of conda packages, includes a large number of “noarch” recipes, including for R packages, and is developed by a broad community of contributors worldwide.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebR&lt;/strong&gt;, an R distribution for WebAssembly, was created by George Stagg. Although not directly used in this project, it documented numerous patches and changes to the Flang compiler that were adapted for this effort.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="funding"&gt;&lt;strong&gt;Funding&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The work by &lt;strong&gt;Isabel Paredes&lt;/strong&gt; and other &lt;strong&gt;QuantStack&lt;/strong&gt; team members on bringing R and Xeus-R to Emscripten-Forge was supported by the &lt;a href="https://www.gatesfoundation.org/"&gt;&lt;strong&gt;Bill &amp;amp; Melinda Gates Foundation&lt;/strong&gt;&lt;/a&gt; through a grant to &lt;strong&gt;CourseKata&lt;/strong&gt;. CourseKata is a nonprofit project dedicated to improving statistics and data science education through interactive, research-backed curricula that integrate professional tools like R and Jupyter notebooks. This grant was part of CourseKata’s broader mission to scale its innovative curriculum, equipping students with the skills and confidence to engage with statistics, data science, and coding in meaningful ways.&lt;/p&gt;
</content><category term="JupyterLite"/><category term="kernels"/><category term="WebAssembly"/><category term="xeus"/></entry><entry><title>Meet Xeus-R: a future-proof Jupyter kernel for R</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/" rel="alternate"/><published>2024-01-22T17:20:00+00:00</published><updated>2024-01-22T17:20:00+00:00</updated><author><name>Romain François</name></author><id>tag:jasongrout.github.io,2024-01-22:/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/</id><summary type="html">&lt;p&gt;The Jupyter ecosystem provides a versatile and user-friendly platform for data analysis and scientific computing, it has democratised…&lt;/p&gt;
</summary><content type="html">&lt;figure&gt;
&lt;img alt="Screenshot of a Jupyter notebook with two cells displayed alongside a contextual help panel. The first cell shows the execution of an R command display(head(mtcars, 3)). The output is a nicely formatted table display with 3 rows. The second cell contains is a call to the ggplot function from the ggplot2 package. The output is a scatter plot of the variables hwy and displ, coloured by the class factor. The cursor shows auto completion for ggplot. On the right, contextual help for ggplot." src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/001-1_cFmKZKFycjvG1v_Xub4snQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;JupyterLab session with a notebook powered by the Xeus-R kernel for R&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;em&gt;Jupyter&lt;/em&gt; ecosystem provides a versatile and user-friendly platform for data analysis and scientific computing, it has democratised access to powerful tools for researchers, scientists, educators, and data professionals.&lt;/p&gt;
&lt;p&gt;The name &lt;em&gt;Jupyter&lt;/em&gt;, a blend of &lt;em&gt;Julia&lt;/em&gt;, &lt;em&gt;Python&lt;/em&gt;, and &lt;em&gt;R&lt;/em&gt; has always hinted at its relevance in multiple scientific programming languages and has since conquered new horizons thanks to its flexible and extensible design.&lt;/p&gt;
&lt;p&gt;Underneath the interactive surface of &lt;em&gt;Jupyter&lt;/em&gt; lie the &lt;em&gt;Jupyter&lt;/em&gt; kernels, a set of language specific engines orchestrating the dynamic execution and exploration of code. Kernels implement the &lt;em&gt;Jupyter&lt;/em&gt; protocol, a shared specification of the communication process between notebooks and kernels, defining how messages, commands and outputs are exchanged and processed.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Xeus&lt;/em&gt; framework is a central piece of the puzzle, offering a reference to facilitate &lt;em&gt;Jupyter&lt;/em&gt; kernel implementations. The speed, extensibility, and alignment with the official protocol make &lt;em&gt;Xeus&lt;/em&gt; a perfect technology to implement new kernels.&lt;/p&gt;
&lt;h2 id="xeus-r"&gt;Xeus-R&lt;/h2&gt;
&lt;p&gt;Today, we, &lt;em&gt;a collaborative team led by Romain François and supported by QuantStack&lt;/em&gt;, are thrilled to announce the initial release of &lt;em&gt;Xeus-R&lt;/em&gt;, a future-proof &lt;em&gt;Jupyter&lt;/em&gt; kernel for R. &lt;em&gt;Xeus-R&lt;/em&gt; builds upon the components of &lt;em&gt;Xeus&lt;/em&gt; to facilitate the use of &lt;em&gt;R&lt;/em&gt; in &lt;em&gt;Jupyter&lt;/em&gt; notebooks and already supports typical capabilities: &lt;em&gt;R&lt;/em&gt; code execution, inspection, completion, and contextual help.&lt;/p&gt;
&lt;p&gt;The recent advancements in support for &lt;em&gt;WebAssembly&lt;/em&gt; in the &lt;em&gt;R&lt;/em&gt; world led by the &lt;em&gt;WebR&lt;/em&gt; project, the flexible design of Xeus, and the rise of &lt;em&gt;JupyterLite&lt;/em&gt; all contribute to our strong belief that &lt;em&gt;Xeus-R&lt;/em&gt; has the potential to deliver &lt;em&gt;Jupyter&lt;/em&gt; in-browser experience for data scientists using &lt;em&gt;R&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Xeus-R&lt;/em&gt; is currently at the stage of a proof of concept, but we wanted to communicate about it early to broadcast our excitement about its potential, share some of our thoughts, and initiate a conversation.&lt;/p&gt;
&lt;h2 id="relationship-with-irkernel"&gt;Relationship with IRkernel&lt;/h2&gt;
&lt;p&gt;While the &lt;em&gt;IRkernel&lt;/em&gt; project paved the way and is the current reference implementation of a &lt;em&gt;Jupyter&lt;/em&gt; kernel for R, it does not take advantage of the &lt;em&gt;Xeus&lt;/em&gt; infrastructure and includes a complete implementation of the &lt;em&gt;Jupyter&lt;/em&gt; protocol, down to the composition of all of the &lt;em&gt;JSON&lt;/em&gt; messages and most importantly how they are transported through &lt;em&gt;ZeroMQ&lt;/em&gt; sockets.&lt;/p&gt;
&lt;p&gt;In contrast, &lt;em&gt;Xeus-R&lt;/em&gt; fully embraces and leverages the capabilities of &lt;em&gt;Xeus&lt;/em&gt;, while borrowing some higher level concepts from &lt;em&gt;IRkernel&lt;/em&gt; and reusing features from its dependent packages &lt;em&gt;IRdisplay&lt;/em&gt; and &lt;em&gt;repr&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We believe this path will benefit future development as it gives us the freedom to work on innovations that are specific to the needs of &lt;em&gt;R&lt;/em&gt; users, and let &lt;em&gt;Xeus&lt;/em&gt; absorb evolutions of the &lt;em&gt;Jupyter&lt;/em&gt; protocol.&lt;/p&gt;
&lt;h2 id="key-features"&gt;Key features&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Xeus-R&lt;/em&gt; implements the basic building blocks of what you would expect from a &lt;em&gt;Jupyter&lt;/em&gt; kernel. The results of a code cell, i.e. the value of its last expression are displayed in the output, taking advantage of &lt;em&gt;ANSI&lt;/em&gt; escape codes for colours as were made popular by the &lt;em&gt;crayon&lt;/em&gt; and later &lt;em&gt;cli&lt;/em&gt; &lt;em&gt;R&lt;/em&gt; packages.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/002-1_XznRckf13HpNy_S7h7-_iA.webp" alt="Screenshot of a Jupyter notebook with 3 cells visible. The first cell [2] contains a line of R code that uses cat and glue to print “hello world” with “world” coloured in green thanks the col_green function from the cli package. The second cell [3] shows the command head(mtcars) which outputs a plain text version of the first 6 rows of the mtcars data frame. The third cell [9] contains R code that loads the tibble package and then prints mtcars as a tibble, therefore benefitting from formatting." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Traditional and &lt;em&gt;ggplot2&lt;/em&gt;-powered graphics are captured and displayed as images. The aspect ratio of plots can be controlled by setting the &lt;em&gt;repr.plot.height&lt;/em&gt; and &lt;em&gt;repr.plot.width&lt;/em&gt; options either globally, or locally via the &lt;em&gt;cell_options()&lt;/em&gt; function.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/003-1_oi1bSbjYZg_I_H104v-75g.webp" alt="A Jupyter notebook cell [13] with R code and its output. The code sets options locally with the cell_options() function and then creates a box plot with the following code: boxplot(decrease ~ treatment, data = OrchardSprays, col = “bisque”, log = “y”). The output is a a graphic with 8 boxplots, representing the treatment factor and its levels A to H on the x axis, and the variable decrease on the y axis, with a logarithmic scale." loading="lazy" data-body-image=""&gt;&lt;br&gt;
&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/004-1_7bZITs9PxXYWwqgDWEniJg.webp" alt="Screenshot of a Jupyter notebook cell [15] with R code and output. The code is loading the ggplot2 package and then creating a scatterplot with the following code: ggplot(mpg, aes(displ, hwy, colour = class)) + geom_point(). The resulting plot is a scatter plot with displ on the x axis and fwy on the y axis, showing different colored points representing different classes of vehicles from the class factor." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Thanks to the scaffolding in place in the &lt;em&gt;IRdisplay&lt;/em&gt; and &lt;em&gt;repr&lt;/em&gt; packages, &lt;em&gt;Xeus-R&lt;/em&gt; is also able to emit richer displays through mime bundles.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/005-1_-T33jRshu16eWh96_OVuvA.webp" alt="Screenshot of a Jupyter notebook with 2 cells with R code. The first cell [16] contains the command display(1:10). The output shows a rich representation of 1:10: the numbers 1 to 10 separated by dots. The second cell [17] also uses the display function to create a rich display of the first 6 rows of the mtcars data frame: display(head(mtcars)). The result presents the data frame as a well formatted table display with alternating shading for rows to improve readability." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;In contrast with &lt;em&gt;IRkernel&lt;/em&gt;, the rich displays need to be explicitly requested with the &lt;em&gt;display()&lt;/em&gt; function. There are cases however, such as &lt;em&gt;HTML&lt;/em&gt; widgets, where automatic rich display makes the most sense because a text/plain representation is not valuable.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/006-1_5QOitnpbBdDNpQ9ERIILpg.webp" alt="Screenshot of a Jupyter notebook cell [24] showing R code that uses packages htmltools and plotly to create an HTML widget with 2 plotly-powered histograms. The result first shows information messages about conflicts, then shows two typical plotly-powered histograms. The top histogram shows a selection, indicating that the display is about to be zoomed in a smaller value range, to show that the HTML widget can be interacted with." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Xeus-R&lt;/em&gt; also supports contextual help and includes a basic completion system, based on the internal &lt;em&gt;utils::.getTokenFromLine()&lt;/em&gt; system.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/meet-xeus-r-a-future-proof-jupyter-kernel-for-r/images/007-1_jWuiihVGV0_7utFx3Tzvng.webp" alt="Screenshot of a Jupyter notebook interface with an open R code cell and a contextual help panel side by side. On the left side, the code cell is active with the incomplete R function call “rnorm(“ being typed, and an auto-completion tooltip showing the options “n=”, “mean=”, “sd=”. The tooltip also shows a repetition of the function name “rnorm”. On the right side, the contextual help panel shows the documentation for the rnorm function." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="installation-and-getting-started"&gt;Installation and Getting Started&lt;/h2&gt;
&lt;p&gt;At the time of writing this article, &lt;em&gt;Xeus-R&lt;/em&gt; is only available and tested to work on Unix-based systems. We consciously decided to focus initial efforts on features rather than platform comprehensiveness, but we should be able to fix this soon enough.&lt;/p&gt;
&lt;p&gt;The easiest way to get up and running with &lt;em&gt;Xeus-R&lt;/em&gt; is to install it from conda-forge:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;xeus-r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Instructions to build from source are available in the github repository for &lt;em&gt;Xeus-R&lt;/em&gt;: &lt;a href="https://github.com/jupyter-xeus/xeus-r"&gt;https://github.com/jupyter-xeus/xeus-r&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="looking-ahead-jupyterlite-integration"&gt;Looking ahead: JupyterLite Integration&lt;/h2&gt;
&lt;p&gt;Another benefit of a &lt;em&gt;Xeus&lt;/em&gt;-based approach is that it has been designed in a way that supports in-browser experience to power &lt;em&gt;JupyterLite&lt;/em&gt;. Together with the recent developments around &lt;em&gt;WebR&lt;/em&gt;, we can envision &lt;em&gt;R&lt;/em&gt; becoming a first-class citizen in the &lt;em&gt;JupyterLite&lt;/em&gt; world.&lt;/p&gt;
&lt;p&gt;This is an exciting vision and will serve as our North Star ⭐️ for future developments of &lt;em&gt;Xeus-R&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Join us in welcoming &lt;em&gt;Xeus-R&lt;/em&gt;, a &lt;em&gt;Jupyter&lt;/em&gt; kernel for &lt;em&gt;R&lt;/em&gt; that leverages the robust foundation of &lt;em&gt;Xeus&lt;/em&gt; architecture. &lt;em&gt;R&lt;/em&gt; is a language of paramount importance for Data Science and Scientific Computing and it rightfully deserves its place as a first-class citizen within the &lt;em&gt;Jupyter&lt;/em&gt; ecosystem.&lt;/p&gt;
&lt;p&gt;We firmly believe that &lt;em&gt;Xeus-R&lt;/em&gt; has the potential to become a reference implementation for an &lt;em&gt;R&lt;/em&gt; kernel, well positioned to tackle the challenges of the ever-evolving landscape of in-browser Scientific Computing, a promising future led by the &lt;em&gt;JupyterLite&lt;/em&gt; and &lt;em&gt;WebR&lt;/em&gt; projects.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The work by Romain François on Xeus-R was funded by &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="author-bio"&gt;Author Bio&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.linkedin.com/in/romain-francois"&gt;Romain François&lt;/a&gt; is a prominent figure in the &lt;em&gt;R&lt;/em&gt; community, recognised for his longstanding contributions to &lt;em&gt;R&lt;/em&gt; programming and Data Analysis. With a profound passion for open-source software and commitment to advancing the capabilities of &lt;em&gt;R&lt;/em&gt;, he has earned a well-deserved reputation as a respected expert.&lt;/p&gt;
&lt;p&gt;Romain’s expertise encompasses a wide spectrum of &lt;em&gt;R&lt;/em&gt;-related fields, including package development, data manipulation, and interoperability with other programming languages. He is widely recognized for his work on packages like &lt;em&gt;dplyr&lt;/em&gt;, which has become a cornerstone for efficient data manipulation in &lt;em&gt;R&lt;/em&gt;, and for his contributions to &lt;em&gt;Rcpp&lt;/em&gt;, a library that bridges the power of &lt;em&gt;C++&lt;/em&gt; with &lt;em&gt;R&lt;/em&gt; for optimizing &lt;em&gt;R&lt;/em&gt; packages and enhancing performance.&lt;/p&gt;
</content><category term="kernels"/><category term="xeus"/></entry><entry><title>Xeus-Lite</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/" rel="alternate"/><published>2021-10-25T09:40:00+00:00</published><updated>2021-10-25T09:40:00+00:00</updated><author><name>Thorsten Beier</name></author><id>tag:jasongrout.github.io,2021-10-25:/medium-archive/pelican/posts/2021/xeus-lite/</id><summary type="html">&lt;p&gt;JupyterLite + Xeus = ❤️️&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/001-1_PUlJi6czJovO90t-Dsgt5g.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;JupyterLite is a &lt;a href="https://jupyter.org/"&gt;JupyterLab&lt;/a&gt; distribution that runs entirely in the web browser, backed by in-browser language kernels. &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; is C++ library for writing &lt;a href="https://jupyter.org/"&gt;Jupyter&lt;/a&gt; kernels. In this blogpost we show how these two can work together.&lt;/p&gt;
&lt;h2 id="jupyterlite"&gt;JupyterLite&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/002-1_dbJO26hiSR8EFygX1rnqrA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;With vanilla Jupyter, kernels are running in separate processes. The communication between the kernels and the client is achieved with &lt;a href="https://zeromq.org/"&gt;ZeroMQ&lt;/a&gt;. In contrast to this, JupyterLite runs entirely in the browser, including the language kernels. The following kernels are already implemented in the JupyterLite framework:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JavaScript Kernel&lt;/li&gt;
&lt;li&gt;P5 Kernel: Since P5 is a JavaScript library, it is easy to provide a P5 kernel running in the browser.&lt;/li&gt;
&lt;li&gt;A Python kernel based on &lt;a href="https://github.com/pyodide/pyodide"&gt;pyodide&lt;/a&gt; called pyolite: While the two JavaScript based kernels are trivial to implement as in-browser kernels, &lt;a href="https://github.com/pyodide/pyodide"&gt;pyodide&lt;/a&gt; is a Python interpreter compiled to WebAssembly via Emscripten. Not only Python itself has been compiled to WebAssembly, but also the whole Scientific Stack including packages like: Numpy, Scipy, Pandas and many more. An overview of packages can be found &lt;a href="https://github.com/pyodide/pyodide/tree/main/packages"&gt;here&lt;/a&gt;. Furthermore any pure Python package can be installed from within pyolite.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since JupyterLite runs entirely in the browser, it is &lt;a href="https://jupyterlite.github.io/demo/lab/index.html"&gt;very easy to try it out&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="xeus"&gt;Xeus&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://xeus.readthedocs.io/en/latest/?badge=latest"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/003-1_c-fyt4I1GOXnrq3tkexaGA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; is C++ library for writing &lt;a href="https://jupyter.org/"&gt;Jupyter&lt;/a&gt; kernels. It is not a kernel but a library that simplifies the process of writing kernels. &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; implements the &lt;a href="https://jupyter-client.readthedocs.io/en/stable/messaging.html"&gt;Jupyter messaging protocol&lt;/a&gt;, so that kernel authors only need to implement a handful of methods related to the actual interpreter, like executing pieces of code and auto-completing.&lt;br&gt;
With the help of Xeus, it is very easy to write Jupyter kernels . In fact, &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; has already been used for making several &lt;a href="https://jupyter.org/"&gt;l&lt;/a&gt;anguage kernels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; is a Xeus-based C++ kernel.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; is a Xeus-based Python kernel.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; is a Xeus-based Lua kernel.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-sql"&gt;xeus-sql&lt;/a&gt; / &lt;a href="https://github.com/jupyter-xeus/xeus-sqlite"&gt;xeus-sqlite&lt;/a&gt; are Xeus-based kernel for SQL / SQLite databases.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt; is a Jupyter kernel for the &lt;a href="https://robotframework.org/"&gt;Robot Framework&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/lfortran/lfortran/-/merge_requests/514"&gt;LFortran&lt;/a&gt; is a modern interactive Fortran compiler with a Xeus-based Jupyter kernel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since it is very easy to write Xeus based kernels for Jupyter, we also want to leverage Xeus for writing JupyterLite kernels. This has been the main motivation for &lt;a href="/posts/2021/xeus-2-0/"&gt;Xeus 2.0&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="xeus-architecture"&gt;Xeus Architecture&lt;/h2&gt;
&lt;p&gt;Xeus is has three extension points as depicted below&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/004-1_CTgb-wk-_TMWVhDzB-Yx7g.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;/em&gt; is the middleware component responsible for receiving and sending messages to the Jupyter client. The default server it is built upon ZeroMQ and handles the concurrency model of the application.&lt;br&gt;
As we will see later, a custom server is needed to connect Xeus with JupyterLite.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;&lt;strong&gt;Interpreter&lt;/strong&gt;&lt;/em&gt; provides the interface that kernel authors must implement.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;&lt;strong&gt;Debugger&lt;/strong&gt;&lt;/em&gt; provides the interface that can to be implemented when the kernel shall have &lt;a href="/posts/2020/a-visual-debugger-for-jupyter/"&gt;debug capabilities&lt;/a&gt;, but we do not yet support this for Xeus-JupyterLite-Kernels.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="jupyterlite-xeus-kernels"&gt;JupyterLite Xeus-Kernels&lt;/h2&gt;
&lt;p&gt;Traditionally, the Jupyter kernel and the Client to the Jupyter kernel run in separate processes as depicted below:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/005-1_jHLLHjTjNWlV0e38GjvACw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The communication between the kernels and the client (ie the Jupyter-server) are done with inter-process communication via &lt;a href="https://zeromq.org/"&gt;ZeroMQ&lt;/a&gt;. But with JupyterLite the &lt;a href="https://jupyterlite.readthedocs.io/en/latest/"&gt;kernel runs directly in the browser&lt;/a&gt;. In that case, ZeroMQ is not required anymore to communicate with the frontend. This was the motivation for &lt;a href="/posts/2021/xeus-2-0/"&gt;Xeus 2.0&lt;/a&gt;, where it is possible to build Xeus without ZeroMQ. To implement JupyterLite Kernels with Xeus, we need to implement a custom Server which handles the &lt;a href="https://emscripten.org/"&gt;Emscripten&lt;/a&gt;/&lt;a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html"&gt;Embind&lt;/a&gt;-based communication layer&lt;/p&gt;
&lt;p&gt;The overall architecture is best described with the picture below: The C++ Xeus-Kernel is compiled to WebAssembly with &lt;a href="https://emscripten.org/"&gt;Emscripten&lt;/a&gt; / &lt;a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html"&gt;Embind&lt;/a&gt;. The WebAssembly compiled code runs in a dedicated WebWorker thread. The WebWorker communicates via Message Passing with a thin layer of TypeScript which implements the &lt;a href="https://github.com/jupyterlite/jupyterlite/blob/d94d472fcdfb5ce760820a6a9cd2c6ea6fc84014/packages/kernel/src/tokens.ts#L45"&gt;IKernel&lt;/a&gt; API of JupyterLite. The communication between JupyterLite and the JupyterLite k ernel is done entirely in JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/006-1_AwkYyHKDxj0_EYitMAxZ5Q.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The C++ code needed to compile an existing xeus-kernel to WebAssembly is very minimal:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/007-1_Qdv9gVF_oO9n2nLffY35SQ.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Furthermore one needs a thin layer of TypeScript / JavaScript to implement the JupyterLite &lt;a href="https://github.com/jupyterlite/jupyterlite/blob/d94d472fcdfb5ce760820a6a9cd2c6ea6fc84014/packages/kernel/src/tokens.ts#L45"&gt;IKernel API&lt;/a&gt;. A good example of this code is given in the &lt;a href="https://github.com/jupyterlite/xeus-lua-kernel"&gt;JupyterLite Xeus-Lua repository&lt;/a&gt;. While most of the repositories code is boilerplate, one needs to provide a simple &lt;a href="https://github.com/DerThorsten/jupyterlite_xeus_lua/blob/main/Dockerfile"&gt;Dockerfile&lt;/a&gt; which compiles the Xeus-Kernel to WebAssembly.&lt;/p&gt;
&lt;h2 id="xeus-lua"&gt;Xeus-Lua&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/008-1_XjZ84G9Ftb3krekpiqBuiw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We recently released a &lt;a href="/posts/2021/from-jupyter-to-the-moon/"&gt;Xeus based Lua kernel.&lt;/a&gt; Even though its worthwhile to have Xeus-Lua kernel for vanilla Jupyter, the main purpose of Xeus-Lua was to experiment with Xeus-based JupyterLite kernels.&lt;br&gt;
We choose Lua as the first language to try out Xeus-based JupyterLite kernels since Lua is easy to compile to WebAssembly.&lt;br&gt;
A JupyterLite instance with Xeus-Lua included can be found &lt;a href="https://jupyterlite.github.io/demo/lab/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Xeus-Lua has built in support for interactive widgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/009-1_Iwg6iPSZmr5o1ZozOlJXDQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Xeus-Lua has built in support for interactive widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="xeus-wren"&gt;Xeus-Wren&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/DerThorsten/xeus-wren"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/010-1_AaO7Or9i6ZDmYR3PNGXh9Q.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wren is relatively new “&lt;a href="https://wren.io/"&gt;Classy Little scripting Language&lt;/a&gt;” created by the author of the great book &lt;a href="https://craftinginterpreters.com/"&gt;“Crafting Interpreters”&lt;/a&gt;. Wren can be described with the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://wren.io/"&gt;Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We choose Wren as a second language to experiment with Xeus + JupyterLite since it is small, simple to compile to WebAssembly and easy to embed in C++. A JupyterLite instance with Xeus-Wren included can be found &lt;a href="https://jupyterlite.github.io/demo/lab?path=xeus-wren%2Fiwren.ipynb"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Xeus-Wren has built in support for displaying data of various MIME-types" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-lite/images/011-1_b-X9cmzXfq7NIXeEwfEzow.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Xeus-Wren has built in support for displaying data of various MIME-types&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="outlook"&gt;Outlook&lt;/h2&gt;
&lt;p&gt;There are many languages which can be compiled to WebAssembly like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Julia: &lt;a href="https://github.com/Keno/julia-wasm"&gt;https://github.com/Keno/julia-wasm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Octave: &lt;a href="https://news.ycombinator.com/item?id=22926120"&gt;https://news.ycombinator.com/item?id=22926120&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C++: &lt;a href="https://github.com/binji/wasm-clang"&gt;https://github.com/binji/wasm-clang&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Python: &lt;a href="https://github.com/pyodide/pyodide"&gt;https://github.com/pyodide/pyodide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also databases as sqlite can be compiled to WebAssembly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sqlite: &lt;a href="https://github.com/sql-js/sql.js/"&gt;https://github.com/sql-js/sql.js/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Our goal is to provide Xeus-based JupyterLite kernels for these projects to make the JupyterLite ecosystem even more powerful.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;We like to thank&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/jtpio"&gt;Jeremy Tuloup&lt;/a&gt;, &lt;a href="https://twitter.com/mad_tandon"&gt;Madhur Tandon&lt;/a&gt;, &lt;a href="https://twitter.com/martinrenou"&gt;Martin Renou&lt;/a&gt;, and &lt;a href="https://github.com/bollwyvl"&gt;Nicholas Bollweg&lt;/a&gt; for their work on JupyterLite.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/johanmabille"&gt;Johan Mabille&lt;/a&gt; for Xeus and his help implementing the Xeus-Emscripten server.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/thorstenbeier"&gt;Thorsten Beier&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;, he graduated in computer science at the University of Heidelberg and worked at the &lt;a href="https://www.embl.org/"&gt;EMBL&lt;/a&gt;. As an open source developer, Thorsten worked on a variety of projects, from &lt;a href="https://github.com/DerThorsten/nifty"&gt;nifty&lt;/a&gt; and &lt;a href="https://github.com/ukoethe/vigra"&gt;vigra&lt;/a&gt; in C++ to &lt;a href="https://github.com/inferno-pytorch/inferno"&gt;inferno&lt;/a&gt;, &lt;a href="https://kipoi.org/"&gt;kipoi&lt;/a&gt; and &lt;a href="https://www.ilastik.org/"&gt;ilastik&lt;/a&gt; in Python.&lt;/p&gt;
</content><category term="kernels"/><category term="WebAssembly"/><category term="xeus"/></entry><entry><title>Xeus 2.0</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-2-0/" rel="alternate"/><published>2021-09-28T09:41:00+00:00</published><updated>2021-09-28T09:41:00+00:00</updated><author><name>Johan Mabille</name></author><id>tag:jasongrout.github.io,2021-09-28:/medium-archive/pelican/posts/2021/xeus-2-0/</id><summary type="html">&lt;p&gt;Announcing a major release of the Xeus library&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Announcing a major release of the Xeus library&lt;/p&gt;
&lt;p&gt;We have just released &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; 2. This is a major release of the library. While it includes backward-incompatible changes, they are very limited and upgrading your kernels should be relatively easy.&lt;/p&gt;
&lt;h2 id="how-to-upgrade-xeus-based-kernels"&gt;How to upgrade Xeus-based kernels&lt;/h2&gt;
&lt;p&gt;Let’s illustrate that with the code of a simple kernel before and after upgrading to Version 2. Most typically, only the kernel’s main file will have to be updated:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;25 diff --git a/example/src/main.cpp b/example/src/main.cpp
&lt;span class="w"&gt; &lt;/span&gt;26 index 29de437..eb8fdba 100644
&lt;span class="w"&gt; &lt;/span&gt;27 --- a/example/src/main.cpp
&lt;span class="w"&gt; &lt;/span&gt;28 +++ b/example/src/main.cpp
&lt;span class="w"&gt; &lt;/span&gt;29 @@ -21,12 +21,14 @@ int main(int argc, char* argv[])
&lt;span class="w"&gt; &lt;/span&gt;30      std::string file_name = (argc == 1) ? &amp;quot;connection.json&amp;quot; : argv[2];
&lt;span class="w"&gt; &lt;/span&gt;31      xeus::xconfiguration config = xeus::load_configuration(file_name);
&lt;span class="w"&gt; &lt;/span&gt;32 
&lt;span class="w"&gt; &lt;/span&gt;33 +    auto context = xeus::make_context&amp;lt;zmq::context_t&amp;gt;();
&lt;span class="w"&gt; &lt;/span&gt;34 +
&lt;span class="w"&gt; &lt;/span&gt;35      // Create interpreter instance
&lt;span class="w"&gt; &lt;/span&gt;36      using interpreter_ptr = std::unique_ptr&amp;lt;custom::custom_interpreter&amp;gt;;
&lt;span class="w"&gt; &lt;/span&gt;37      interpreter_ptr interpreter = interpreter_ptr(new custom::custom_interpreter());
&lt;span class="w"&gt; &lt;/span&gt;38 
&lt;span class="w"&gt; &lt;/span&gt;39      // Create kernel instance and start it
&lt;span class="w"&gt; &lt;/span&gt;40 -    xeus::xkernel kernel(config, xeus::get_user_name(), std::move(interpreter), xeus::make_xs    erver_zmq);
&lt;span class="w"&gt; &lt;/span&gt;41 +    xeus::xkernel kernel(config, xeus::get_user_name(), std::move(context), std::move(interpr    eter), xeus::make_xserver_zmq);
&lt;span class="w"&gt; &lt;/span&gt;42      kernel.start();
&lt;span class="w"&gt; &lt;/span&gt;43 
&lt;span class="w"&gt; &lt;/span&gt;44      return 0;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first change is that you now have to instantiate and pass an additional argument to the kernel constructor: the &lt;em&gt;context&lt;/em&gt;. Fortunately, Xeus provides a function to build such a context object, making the update straightforward. We will detail the reason for this change in the next section.&lt;/p&gt;
&lt;p&gt;The second change is that the kernel constructor now &lt;em&gt;requires&lt;/em&gt; a function to build the server while a default value was provided for it in Xeus 1.x. Again, the motivations for this change will be detailed in the next section. Finally the functions for building the servers have moved to different headers.&lt;/p&gt;
&lt;p&gt;To summarize, here is the list of the breaking changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The kernel’s constructor now requires an additional argument, the context. Xeus provides a function to easily instantiate it.&lt;/li&gt;
&lt;li&gt;The order of kernel’s constructor arguments has changed, and the function for building the server is now required.&lt;/li&gt;
&lt;li&gt;The functions for building the servers have moved to the headers where the corresponding servers are defined.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="motivation-for-these-changes"&gt;Motivation for these changes&lt;/h2&gt;
&lt;p&gt;When we created &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt;, kernels were expected to run in separate processes. The communication between the kernels and the client was achieved with the &lt;a href="https://zeromq.org/"&gt;ZeroMQ&lt;/a&gt; middleware framework, and it was natural to heavily rely on it in Xeus.&lt;/p&gt;
&lt;p&gt;Recent &lt;a href="/posts/2021/jupyterlite-jupyter-webassembly-python/"&gt;developments&lt;/a&gt; have pushed in a different direction, where the &lt;a href="https://jupyterlite.readthedocs.io/en/latest/"&gt;kernel can run directly in the browser&lt;/a&gt;. In that case, a middleware library is not required anymore to communicate with the frontend. The architecture of Xeus was not suitable for this new kind of kernels. An update was required so that it is possible to build Xeus without the dependency on ZeroMQ.&lt;/p&gt;
&lt;h2 id="about-the-developers"&gt;About the developers&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-2-0/images/001-0_tHIyMRx_JbgkU2xy.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Johan Mabille&lt;/strong&gt; is a scientific software developer at QuantStack. Johan is a co-author of Xeus, and developed the debugger extension to xeus-python.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-2-0/images/002-0_zUMSbNcno1BZSfjO.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sylvain Corlay&lt;/strong&gt; is the founder and CEO of QuantStack, and a core Jupyter developer. He co-authored Xeus and xeus-python.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/xeus-2-0/images/003-1_kGCA9WV-Gf5tiNqqy9vTMQ.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="xeus"/></entry><entry><title>From Jupyter to the Moon</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/" rel="alternate"/><published>2021-09-24T12:24:00+00:00</published><updated>2021-09-24T12:24:00+00:00</updated><author><name>Thorsten Beier</name></author><id>tag:jasongrout.github.io,2021-09-24:/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/</id><summary type="html">&lt;p&gt;A new Jupyter kernel for Lua based on Xeus&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/001-1_Or2bu8twFwywgACqLOE9AA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Jupyter architecture in a nutshell" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/002-0_jvG9j3sKufQRiuLl.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;&lt;a href="https://jupyter.org/"&gt;Jupyter&lt;/a&gt; architecture in a nutshell&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A key principle in Jupyter’s design is &lt;em&gt;&lt;strong&gt;language agnosticism&lt;/strong&gt;&lt;/em&gt;, and one of the main extension points of the Jupyter ecosystem is the &lt;em&gt;&lt;strong&gt;kernel&lt;/strong&gt;&lt;/em&gt;, the part of the architecture responsible for executing the user’s code.&lt;/p&gt;
&lt;p&gt;In the end, a Jupyter kernel is merely an executable implementing a well-defined inter-process communication protocol.&lt;/p&gt;
&lt;p&gt;A reference implementation of the kernel is ipykernel, which provides the default Python kernel, and utilities to build other language kernels. Another reference implementation of the protocol is &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="xeus"&gt;Xeus&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; is C++ library for writing &lt;a href="https://jupyter.org/"&gt;Jupyter&lt;/a&gt; kernels. It is not a kernel but a library that simplifies the process of writing kernels. &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; implements the &lt;a href="https://jupyter-client.readthedocs.io/en/stable/messaging.html"&gt;Jupyter messaging protocol&lt;/a&gt;, so that kernel authors only need to implement a handful of methods related to the actual interpreter, like executing pieces of code and auto-completing. There is a long &lt;a href="https://github.com/dbohdan/embedded-scripting-languages"&gt;list of scripting languages&lt;/a&gt; which can be embedded in C/C++. With the help of Xeus, it is very easy to write kernels for such languages. In fact, &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; has already been used for making several &lt;a href="https://jupyter.org/"&gt;l&lt;/a&gt;anguage kernels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; is a Xeus-based C++ kernel.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; is a Xeus-based Python kernel.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-sql"&gt;xeus-sql&lt;/a&gt; / &lt;a href="https://github.com/jupyter-xeus/xeus-sqlite"&gt;xeus-sqlite&lt;/a&gt; are Xeus-based kernel for SQL / SQLite databases.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt; is a Jupyter kernel for the &lt;a href="https://robotframework.org/"&gt;Robot Framework&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/lfortran/lfortran/-/merge_requests/514"&gt;LFortran&lt;/a&gt; is a modern interactive Fortran compiler with a Xeus-based Jupyter kernel.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="xwidgets"&gt;xwidgets&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://github.com/jupyter-xeus/xwidgets"&gt;xwidget&lt;/a&gt; library is a C++ implementation of the &lt;a href="https://ipywidgets.readthedocs.io/en/latest/"&gt;Jupyter Interactive Widget protocol&lt;/a&gt;. Xwidgets were initially developed for xeus-cling, the Xeus C++ kernel, but any Xeus-based kernel can reuse these components.&lt;/p&gt;
&lt;h2 id="a-xeus-based-lua-kernel"&gt;A xeus-based Lua kernel&lt;/h2&gt;
&lt;p&gt;Today, I am pleased to announce the release of &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt;, a new &lt;a href="https://jupyter.org/"&gt;Jupyter&lt;/a&gt; kernel for &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; based on &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/003-0_xQYvimlGgIZuuZC2.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="lua"&gt;Lua&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt;, which means “Moon” in Portuguese, is a lightweight embeddable scripting language written in C. While Python is one of the leading scripting languages for scientific application, &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; is the leading scripting language used in games / game engines. The &lt;a href="https://en.wikipedia.org/wiki/Category:Lua_(programming_language)-scripted_video_games"&gt;list of video games using Lua&lt;/a&gt; is long and includes triple-a games like Crisys and Farcry. Not only games rely on Lua, but &lt;a href="https://en.wikipedia.org/wiki/List_of_applications_using_Lua"&gt;also applications like Adobe Photoshop Lightroom&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="sol2"&gt;Sol2&lt;/h2&gt;
&lt;figure&gt;
&lt;img alt="With the Sol2 library, Lua can be embedded into C++ in a very elegant way." src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/004-0_qDdOEdX0PhOKNTMJ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;With the &lt;a href="https://github.com/ThePhD/sol2"&gt;Sol2&lt;/a&gt; library, Lua can be embedded into C++ in a very elegant way.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;While Lua itself can be embedded in a C++ application quite easy, it is even easier when using &lt;a href="https://github.com/ThePhD/sol2"&gt;Sol2&lt;/a&gt;. &lt;a href="https://github.com/ThePhD/sol2"&gt;Sol2&lt;/a&gt; is a C++ library that simplifies the usage of Lua from C++. Furthermore &lt;a href="https://github.com/ThePhD/sol2"&gt;Sol2&lt;/a&gt; can be used to expose C++ classes to Lua, in a similar fashion as &lt;a href="https://github.com/pybind/pybind11"&gt;pybind11&lt;/a&gt; can be used to expose C++ classes to Python.&lt;/p&gt;
&lt;h2 id="xeus-lua"&gt;Xeus-lua&lt;/h2&gt;
&lt;figure&gt;
&lt;img alt="The compulsory “Hello, World!” from xeus-lua. This blog-post would be incomplete without it." src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/005-0_Rw3rs6Cdj5FEfAQf.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The compulsory “Hello, World!” from xeus-lua. This blog-post` would be incomplete without it.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I am pleased to announce &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua,&lt;/a&gt; a new Jupyter kernel for the Lua language based on &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt;. Using &lt;a href="https://github.com/ThePhD/sol2"&gt;Sol2&lt;/a&gt; and &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt;, it was very easy to implement a feature rich kernel using modern C++. With the help of &lt;a href="https://github.com/ThePhD/sol2"&gt;Sol2&lt;/a&gt;, it was trivial to expose the xwidgets classes to Lua such that we can use the widgets within &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; notebooks.&lt;/p&gt;
&lt;h2 id="but-why-a-lua-kernel"&gt;But why a Lua kernel?&lt;/h2&gt;
&lt;p&gt;While &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; might not be the hippest language in 2021, there are multiple reasons while I choose to implement such a &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; kernel, and why such a kernel can be useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing a &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt;-based kernel is the best way to learn and familiarize oneself with the &lt;a href="https://github.com/jupyter-xeus"&gt;xeus ecosystem&lt;/a&gt;. And since Lua is so easy to build and embed, Lua and Xeus are perfect match. Implementing this kernel gave me great insights into Xeus and Jupyter itself.&lt;/li&gt;
&lt;li&gt;Learning &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; with &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; is fun! Before writing &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt;, I had zero Lua experience. While implementing xeus-lua I learned &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; from within Jupyter by playing around with xwidgets from within Lua — this was a very joyful experience.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; implementation might serve as reference for future kernel authors. In particular the &lt;a href="https://github.com/jupyter-xeus/xeus-lua/blob/main/src/xwidgets.cpp"&gt;integration of xwidgets in xeus-lua&lt;/a&gt; might be useful for future implementations.&lt;/li&gt;
&lt;li&gt;Since Lua is so easy to build, &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; can be built for WebAssembly and will be integrated in &lt;a href="https://jupyterlite.readthedocs.io/en/latest/"&gt;JupyterLite&lt;/a&gt; — &lt;strong&gt;stay tuned!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="features"&gt;Features&lt;/h2&gt;
&lt;p&gt;Obviously &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; supports the execution of code.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simple code execution" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/006-0_AzW845V1EKlvxO2j.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simple code execution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Streams are redirected to the notebooks output&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Redirection of streams" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/007-0_A-2SpNknQua_D73o.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Redirection of streams&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Errors messages are shown in the notebooks output&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Error Handling" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/008-0_yMSCAFt70y43daKm.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Error Handling&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Input streams are redirected to the notebooks input system&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="User Input" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/009-0_Pfa9ASycXFejuZKp.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;User Input&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Statements can be auto-completed with a press of tab&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Code Completion" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/010-0_dQfGwr6PtuQaSUAb.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Code Completion&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Data of different sources as Latex, JSON and html can be displayed.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Display Data" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/011-0_tHhXDPzcThHTqor5.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Display Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Interactive widgets can be added to the notebook!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Widgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/012-0_066MCiSNqv21zJOS.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We can feed the widgets with data!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Binary buffers for widgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/013-0_ArP2iU5tKYDHvvZd.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Binary buffers for widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Try It Out&lt;/p&gt;
&lt;p&gt;You can try it right now with &lt;a href="https://mybinder.org/"&gt;binder&lt;/a&gt;, without the need of installing anything on your computer, just by clicking on &lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xeus-lua/main?urlpath=/lab/tree/notebooks/game_of_life.ipynb"&gt;&lt;strong&gt;this link&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xeus-lua/main?urlpath=/lab/tree/notebooks/game_of_life.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/from-jupyter-to-the-moon/images/014-0_NiFI9An8ZGVDSYyG.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="other-lua-kernels"&gt;Other Lua kernels&lt;/h2&gt;
&lt;p&gt;There are several &lt;a href="https://www.lua.org/"&gt;Lua&lt;/a&gt; kernels available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tomstitt/lupyter"&gt;lupyter&lt;/a&gt;: A Python based implementation of a Lua Jupyter kernel. The heavy lifting is done in a C-extension.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/guysv/ilua"&gt;ILua&lt;/a&gt;: A feature rich implementation. Ilua is implemented in Python and does the communication with Lua via IPC.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pakozm/IPyLua"&gt;IPyLua&lt;/a&gt;: IPyLua is a pure Lua implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While these implementations are feature rich and work well, none of the above supports interactive widgets. Since &lt;a href="https://github.com/jupyter-xeus/xeus-lua"&gt;xeus-lua&lt;/a&gt; is based on X&lt;a href="https://github.com/jupyter-xeus/xeus"&gt;eus&lt;/a&gt;, we can reuse components from the Xeus ecosystem like &lt;a href="https://github.com/jupyter-xeus/xwidgets"&gt;xwidgets&lt;/a&gt; with minimal effort.&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;We are grateful to &lt;a href="https://twitter.com/juliettetaka?lang=en"&gt;Juliette Taka&lt;/a&gt; for the illustration.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://quantstack.net/thorsten.html"&gt;Thorsten Beier&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;, he graduated in computer science at the University of Heidelberg and worked at the &lt;a href="https://www.embl.org/"&gt;EMBL&lt;/a&gt;. As an open source developer, Thorsten worked on a variety of projects, from &lt;a href="https://github.com/DerThorsten/nifty"&gt;nifty&lt;/a&gt;, and &lt;a href="https://github.com/ukoethe/vigra"&gt;vigra&lt;/a&gt; in C++ to &lt;a href="https://github.com/inferno-pytorch/inferno"&gt;inferno&lt;/a&gt;, &lt;a href="https://kipoi.org/"&gt;kipoi&lt;/a&gt; and &lt;a href="https://www.ilastik.org/"&gt;ilastik&lt;/a&gt; in Python.&lt;/p&gt;
</content><category term="kernels"/><category term="xeus"/></entry><entry><title>Abracadabra! Bringing the magics to xeus-python</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/" rel="alternate"/><published>2021-02-18T13:30:00+00:00</published><updated>2021-02-18T14:06:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jasongrout.github.io,2021-02-18:/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/</id><summary type="html">&lt;p&gt;Last year, we set ourselves to implement a visual debugger for JupyterLab. This endeavor required major developments in the JupyterLab…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Last year, we set ourselves to implement a &lt;strong&gt;visual debugger for JupyterLab&lt;/strong&gt;. This endeavor required major developments in the JupyterLab front-end, in core-Jupyter protocols, and on the kernel side (the part of the Jupyter infrastructure responsible for executing the code).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/001-0_B0kK-zNJr0Suisyv.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For kernel-side development, we decided to start with the &lt;a href="/posts/2019/a-new-python-kernel-for-jupyter/"&gt;&lt;strong&gt;xeus-python&lt;/strong&gt; kernel&lt;/a&gt;, a lightweight implementation of a Jupyter kernel for the Python programming language. Based on &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;&lt;strong&gt;xeus&lt;/strong&gt;&lt;/a&gt;, xeus-python has a flexible concurrency model that was required to &lt;em&gt;e.g.&lt;/em&gt; add breakpoints while executing code.&lt;/p&gt;
&lt;p&gt;Unfortunately, xeus-python did not provide all ipykernel features (magics, Matplotlib support, &lt;em&gt;etc.&lt;/em&gt;). Furthermore, many notebooks depend on IPython, as they import it explicitely or make use of the IPython configuration system.&lt;/p&gt;
&lt;p&gt;Today, we are proud to announce that xeus-python supports 100% of the IPython magics! This was achieved by leveraging the core IPython package. This is getting us closer to feature parity with ipykernel.&lt;/p&gt;
&lt;h2 id="magics"&gt;Magics&lt;/h2&gt;
&lt;p&gt;xeus-python now supports all magics that IPython provides and even user-defined magics!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Support for builtin IPython magics and user-defined magics" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/002-1_PTiGVyDsazc_ziz6Bk4EnA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Support for builtin IPython magics and user-defined magics&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="matplotlib"&gt;Matplotlib&lt;/h2&gt;
&lt;p&gt;Most Matplotlib back-ends are now supported by xeus-python, allowing you to show static plots with the inline back-end or interactive plots with &lt;a href="https://github.com/matplotlib/ipympl"&gt;ipympl&lt;/a&gt; in your Notebook:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Matplotlib inline back-end and ipympl interactive back-end" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/003-1_cmnPUKlhHHwUf8PZhNQx2g.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Matplotlib inline back-end and ipympl interactive back-end&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="extending"&gt;Extending&lt;/h2&gt;
&lt;p&gt;IPython has a rich configuration system that you can tweak in order to get an enhanced Notebook experience. Xeus-python now supports any configuration you setup for IPython:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Automatically import NumPy in the IPython settings" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/004-1_bB5hiXIbVAlV3kX9KJfLfg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Automatically import NumPy in the IPython settings&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="visual-debugging"&gt;Visual Debugging&lt;/h2&gt;
&lt;p&gt;The latest JupyterLab version introduced a visual debugger in its interface. xeus-python was the first Jupyter kernel to add support for it!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Stepping into Python code in JupyterLab with the visual debugger" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/005-1_efZAtaJQqeirAZoEqbxvdw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Stepping into Python code in JupyterLab with the visual debugger&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;xeus-python is not the only Jupyter kernel that supports debugging anymore: &lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt; is a xeus-based Jupyter kernel for the &lt;a href="https://robotframework.org/"&gt;RobotFramework&lt;/a&gt; language that supports the JupyterLab visual debugger.&lt;/p&gt;
&lt;h2 id="try-it-online"&gt;Try it online&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;, you can try it out without the need of installing anything on your computer. Just follow this link:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xeus-python/stable?urlpath=/lab/tree/notebooks/xeus-python.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/006-0_2sBOFFsk_322apCe.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;
&lt;p&gt;You can install the latest xeus-python version using mamba or conda:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install xeus-python -c conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install xeus-python -c conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also compile it yourself, instructions can be found in the repository:&lt;br&gt;
&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;https://github.com/jupyter-xeus/xeus-python&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;My work on &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt; at &lt;a href="https://twitter.com/QuantStack"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; was funded by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/007-0_5XdymjYwzZe-hvy8.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt;, I am a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt;. Before joining QuantStack, I studied at the aerospace engineering school &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt; in Toulouse, France. I also worked at Logilab in Paris, France and Enthought in Cambridge, UK. As an open-source developer at QuantStack, I work on a variety of projects, from &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python/"&gt;xeus-python&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; in Python and JavaScript/TypeScript.&lt;/p&gt;
</content><category term="IPython"/><category term="kernels"/><category term="xeus"/></entry><entry><title>Xeus is now a Jupyter subproject</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2020/xeus-is-now-a-jupyter-subproject/" rel="alternate"/><published>2020-02-04T12:08:00+00:00</published><updated>2020-02-08T13:30:00+00:00</updated><author><name>Johan Mabille</name></author><id>tag:jasongrout.github.io,2020-02-04:/medium-archive/pelican/posts/2020/xeus-is-now-a-jupyter-subproject/</id><summary type="html">&lt;p&gt;The Xeus project has been incorporated as a Jupyter subproject.&lt;/p&gt;
</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It is a great pleasure to announce that the Xeus project has been incorporated as a Jupyter subproject. Xeus will now be subject to the&lt;/em&gt; &lt;a href="https://github.com/jupyter/governance/blob/master/governance.md"&gt;&lt;em&gt;Jupyter governance&lt;/em&gt;&lt;/a&gt; &lt;em&gt;and&lt;/em&gt; &lt;a href="https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md"&gt;&lt;em&gt;code of conduct&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For reference, the Jupyter Enhancement Proposal (JEP) for the Xeus incorporation is available &lt;a href="https://github.com/jupyter/enhancement-proposals/pull/44"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="what-is-xeus"&gt;What is Xeus?&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://github.com/jupyter-xeus/xeus/"&gt;Xeus&lt;/a&gt; project is a C++ implementation of the Jupyter kernel protocol. Xeus is not a kernel, but a library meant to facilitate the authoring of kernels.&lt;br&gt;
Several Jupyter kernels have been created with Xeus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;xeus-cling&lt;/a&gt;, a kernel for the C++ programming language, based on the Cling C++ interpreter. The &lt;a href="https://github.com/root-project/cling"&gt;cling&lt;/a&gt; project comes from CERN and is at the foundation of the &lt;a href="https://github.com/root-project/root.git"&gt;ROOT&lt;/a&gt; project.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="The xeus-cling Jupyter kernel for the C++ programming language." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/xeus-is-now-a-jupyter-subproject/images/001-0_SSdFFWmES-6AW8Yo.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The xeus-cling Jupyter kernel for the C++ programming language.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt;, a kernel for the Python programming language, embedding the Python interpreter.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="The xeus-python Jupyter kernel for the Python programming language" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/xeus-is-now-a-jupyter-subproject/images/002-0_Mh5cOdG7YWJxrFSw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The xeus-python Jupyter kernel for the Python programming language&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-calc"&gt;xeus-calc&lt;/a&gt;, a calculator kernel, meant as an educational example on how to make Jupyter kernels with Xeus.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Beyond these three kernels built on top of Xeus by the Xeus maintainers, third-parties have developed other Jupyter kernels with Xeus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/JuniperKernel/JuniperKernel"&gt;JuniperKernel&lt;/a&gt;, a kernel for the R programming language by Spencer Aiello.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/atomex-me/xeus-fift"&gt;xeus-fift&lt;/a&gt;, a kernel for the fift programming language by Michael Zaikin. The fift programming language was developed by Telegram to create TON blockchain contracts.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt;, a kernel for the Python programming language by Kitware which integrates into the Qt event loop of the Kitware “Slicer” project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, the xeus-python kernel includes a first implementation of the Jupyter debugger protocol used by the &lt;a href="https://github.com/jupyterlab/debugger"&gt;Jupyter debugger&lt;/a&gt; project. xeus-python enables the &lt;a href="https://microsoft.github.io/debug-adapter-protocol/"&gt;Debug Adapter Protocol&lt;/a&gt; over the Control channel through new debug request/reply and debug event messages.&lt;/p&gt;
&lt;h2 id="why-moving-xeus-under-the-jupyter-governance"&gt;Why moving Xeus under the Jupyter governance?&lt;/h2&gt;
&lt;p&gt;While Xeus started as a side project for &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; engineers, the project now has several stakeholders who depend on it. We think that moving the project to an open governance organization may be a better way to reflect this situation.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Xeus was started by the team of open-source developers at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; as a separate project, but with the full intent to incorporate it into Jupyter. The initial project development at QuantStack was funded by &lt;a href="https://twitter.com/techatbloomberg"&gt;Bloomberg&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Now, Xeus contributors work in many institutions, including &lt;a href="https://www.universite-paris-saclay.fr/"&gt;Université Paris-Saclay&lt;/a&gt; and &lt;a href="https://www.polytechnique.edu/"&gt;École Polytechnique&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/johanmabille?lang=en"&gt;Johan Mabille&lt;/a&gt; is a Scientific Software Developer at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;, specializing in high-performance computing in C++. He holds master’s degree in computer science from Centrale-Supelec.&lt;/p&gt;
&lt;p&gt;As an open source developer, Johan coauthored &lt;a href="https://quantstack.net/xtensor.html"&gt;&lt;strong&gt;xtensor&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://quantstack.net/xeus.html"&gt;&lt;strong&gt;xeus&lt;/strong&gt;&lt;/a&gt;, and &lt;a href="https://quantstack.net/xsimd.html"&gt;&lt;strong&gt;xsimd&lt;/strong&gt;&lt;/a&gt;. He also made major contributions to the JupyterLab debugger project and bqplot.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/xeus-is-now-a-jupyter-subproject/images/003-1__77MmwnTvIhdFVM8noFAIA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="C++"/><category term="xeus"/></entry><entry><title>Building a Calculator Jupyter Kernel</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/" rel="alternate"/><published>2019-07-16T08:36:00+00:00</published><updated>2019-07-16T09:14:00+00:00</updated><author><name>QuantStack</name></author><id>tag:jasongrout.github.io,2019-07-16:/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/</id><summary type="html">&lt;p&gt;A step-by-step guide for authoring language kernels with Xeus&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;strong&gt;A step-by-step guide for authoring language kernels with Xeus&lt;/strong&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="An early device for interactive computing" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/images/001-0_h6rfGRuTgOkwonN9.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;An early device for interactive computing&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In order to provide a language-agnostic scientific development environment, the &lt;strong&gt;Jupyter project&lt;/strong&gt; is built upon a &lt;a href="https://jupyter-client.readthedocs.io/en/stable/messaging.html"&gt;&lt;em&gt;well-specified protocol&lt;/em&gt;&lt;/a&gt; to communicate with the &lt;em&gt;Kernel&lt;/em&gt;, the part of the infrastructure responsible for executing the code.&lt;/p&gt;
&lt;p&gt;For a programming language to leverage the potential of the Jupyter ecosystem, such as &lt;em&gt;JupyterHub&lt;/em&gt;, &lt;em&gt;JupyterLab&lt;/em&gt;, and &lt;em&gt;interactive widgets&lt;/em&gt;, all that is needed is a &lt;em&gt;Kernel&lt;/em&gt; to be created for that language that is, an executable implementing the specified inter-process communication. Dozens of kernels have already been implemented bringing Jupyter to many programming languages.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We are completing our engineering degree and interning at QuantStack. We recently attended the&lt;/em&gt; &lt;a href="/posts/2019/jupyter-community-workshop-building-upon-the-jupyter/"&gt;&lt;em&gt;Jupyter Community Workshop&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on the kernel protocol that took place in Paris in late May. In this occasion, we set ourselves to write a new Jupyter kernel.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Today, we are proud to announce the first release of &lt;a href="https://github.com/QuantStack/xeus-calc"&gt;&lt;em&gt;&lt;strong&gt;xeus-calc&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;, a calculator kernel for Jupyter! xeus-calc is meant to serve as a &lt;em&gt;minimal,&lt;/em&gt; &lt;em&gt;self-contained&lt;/em&gt;example of Jupyter kernel. It is built upon the &lt;a href="https://github.com/QuantStack/xeus/"&gt;&lt;em&gt;&lt;strong&gt;xeus&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; project, a modern C++ implementation of the protocol. This article is a step-by-step description on how the kernel was implemented.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You may find this post especially useful if you are creating a new programming language and you want it to work in Jupyter from the start.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="xeus"&gt;Xeus&lt;/h2&gt;
&lt;p&gt;Implementing the &lt;a href="https://jupyter-client.readthedocs.io/en/stable/messaging.html"&gt;&lt;strong&gt;Jupyter kernel protocol&lt;/strong&gt;&lt;/a&gt; from scratch may be a tedious and difficult task. One needs to deal with ZMQ sockets and complex concurrency issues, rely on third-party libraries for cryptographically signing messages or parsing JSON efficiently. This is where the &lt;a href="https://github.com/QuantStack/xeus/"&gt;&lt;em&gt;&lt;strong&gt;xeus&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; project comes into play: it takes all of that burden so that developers can focus on the parts that are specific to their use case.&lt;/p&gt;
&lt;p&gt;In the end, the kernel author only needs to implement a small number of virtual functions inherited from the &lt;code&gt;xinterpreter&lt;/code&gt; class.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;xeus/xinterpreter.hpp&amp;quot;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;nlohmann/json.hpp&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;xeus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;xinterpreter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nlohmann&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;namespace custom
{
    class custom_interpreter : public xinterpreter
    {
    public:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;        custom_interpreter() = default;
        virtual ~custom_interpreter() = default;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;     private:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;nl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;execute_request_impl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;execution_counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="nx"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;silent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;store_history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="nx"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;node_type&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user_expressions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;allow_stdin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;nl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;complete_request_impl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                       &lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cursor_pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inspect_request_impl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="nb nb-Type"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cursor_pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                      &lt;/span&gt;&lt;span class="nb nb-Type"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;detail_level&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is_complete_request_impl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;nl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;kernel_info_request_impl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Typically, a kernel author will make use of the C or C++ API of the target programming language and embed the interpreter into the application.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This differs from the &lt;em&gt;wrapper kernel&lt;/em&gt; approach documented in the ipykernel package where kernel authors make use of the kernel protocol implementation of ipykernel, typically spawning a separate process for the interpreter and capturing its standard output.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Jupyter kernels based on xeus include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus-cling"&gt;&lt;em&gt;&lt;strong&gt;xeus-cling&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;: a C++ kernel built upon the cling C++ interpreter from CERN&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus-python"&gt;&lt;strong&gt;xeus-python&lt;/strong&gt;&lt;/a&gt;: a new Python kernel for Jupyter.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/JuniperKernel/JuniperKernel"&gt;&lt;em&gt;&lt;strong&gt;JuniperKernel&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;: a new R kernel for Jupyter based on xeus.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post, instead of calling into the API of an external interpreter, we implement the internal logic of the calculator in the kernel itself.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Exposing the xeus calculator to Jupyter" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/images/002-0_Q2jOwO75XQvNuqaR.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Exposing the xeus calculator to Jupyter&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="a-calculator-project"&gt;A calculator project&lt;/h3&gt;
&lt;p&gt;First, to implement your own Jupyter kernel, you should install Xeus. You can either download it with conda, or install it from sources as detailed in the &lt;a href="https://github.com/QuantStack/xeus"&gt;&lt;em&gt;&lt;strong&gt;readme&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now that the installation is out of the way, let’s focus on the implementation itself.&lt;/p&gt;
&lt;p&gt;Recall that the main class for the calculator kernel must inherit from the &lt;code&gt;xinterpreter&lt;/code&gt;class so that Xeus can correctly route the messages received from the front-end.&lt;/p&gt;
&lt;p&gt;This class defines the behavior of the kernel for each message type that is received from the front-end.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kernel_info_request_impl&lt;/code&gt;: returns the information about the kernel, such as the name, the version or even a “banner”, that is a message that is prompted to console clients upon launch. This is a good place to be creative with ASCII art.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;complete_request_impl&lt;/code&gt;: checks if the code can be completed, by that we mean semantic completion, and makes a suggestion accordingly. This way the user can receive a proposition for an adequate completion to the code he is currently writing. We did not use it during our implementation as you will see later, it is safe to return a JSON with a status value only, if you do not want to handle completion.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;is_complete_request_impl&lt;/code&gt;: whether the submitted code is complete and ready for evaluation. For example, if brackets are not all closed, there is probably more to be typed. This message is not used by the notebook front-end but is required for the console, which shows a continuation prompt for further input if it is deemed incomplete. It also checks whether the code is valid or not. Since the calculator expects single-line inputs, it is safe to return an empty JSON object. This may be refined in the future.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inspect_request_impl&lt;/code&gt;: concerns documentation. It inspects the code to show useful information to the user. We did not use it in our case and went with the default implementation (that is to return an empty JSON object).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;execute_request_impl&lt;/code&gt;: the main function. An &lt;code&gt;execute_request&lt;/code&gt; message is sent by the front-end to ask the kernel to execute the code on behalf of the user. In the case of the calculator, this means parsing the mathematical expression, evaluating it and returning the result, as described in the next section.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Implementation of the calculator&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First things first, we need to find a way to parse mathematical expressions. To do so, we turn the user input into &lt;em&gt;&lt;strong&gt;Reverse Polish Notation&lt;/strong&gt;&lt;/em&gt; (or RPN), a name full of meaning for the wisest among our readers (or at least the oldest) who used RPN calculators in high school.&lt;/p&gt;
&lt;p&gt;The RPN, also called &lt;em&gt;&lt;strong&gt;Postfix&lt;/strong&gt;&lt;/em&gt; notation, presents the mathematical expression in a specific way : the operands go first followed by the operator. The main advantage of this notation is how it implicitly displays the precedence of operators.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Reverse Polish Notation illustration" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/images/003-0_7eozUxbipal_WV0c.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Reverse Polish Notation illustration&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The main logic of the calculator is provided by two main functions dealing respectively with parsing and evaluating the user expression and a third one for handling spaces in the expression.&lt;/p&gt;
&lt;p&gt;First we have the parsing function (&lt;code&gt;parse_rpn&lt;/code&gt;) transforming the expression into this representation. For this purpose we implement the &lt;a href="https://en.wikipedia.org/wiki/Shunting-yard_algorithm"&gt;&lt;em&gt;&lt;strong&gt;Shunting-yard algorithm&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is based on the use of a stack data structure to change the order of the elements in the expression, depending on their type : operator, operand or parenthesis.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Transforming a user expression into RPN" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/images/004-0_kJeaW70rAkyeYh5l.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Transforming a user expression into RPN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now that we have the expression turned into RPN (with spaces delimiting operands and operators) we need to do the computation. For this purpose we have the function &lt;code&gt;compute_rpn&lt;/code&gt;. Its implementation is based on a loop through a stringstream (hence the need for space delimiters) which performs operations in the right order.&lt;/p&gt;
&lt;p&gt;Note that the result is not returned as an &lt;code&gt;execute_reply&lt;/code&gt; message but is sent on a broadcasting channel instead, so that other clients to the kernel can also see it. The function &lt;code&gt;execute_reply_impl&lt;/code&gt; actually returns the status of the execution only, as you may see in the code below.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;execute_request_impl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb nb-Type"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;execution_counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                           &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                           &lt;/span&gt;&lt;span class="nb nb-Type"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="n"&gt;silent&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                           &lt;/span&gt;&lt;span class="nb nb-Type"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="n"&gt;store_history&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                           &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="n"&gt;user_exprs&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                           &lt;/span&gt;&lt;span class="nb nb-Type"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="n"&gt;allow_stdin&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pub_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Result = &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;publish_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;try&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;spaced_code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;formating_expr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compute_rpn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse_rpn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spaced_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                                       &lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                                             &lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;pub_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text/plain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;publish_execution_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;execution_counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                 &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pub_data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                                 &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ok&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;payload&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;user_expressions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;runtime_error&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;nl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;publish_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;stderr&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;what&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jresult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that’s it for our calculator! It is as simple as that.&lt;/p&gt;
&lt;p&gt;Yet remember that Xeus is a library, not a kernel by itself. We still have to create an executable that gathers the interpreter and the library. This is done in a &lt;code&gt;main&lt;/code&gt; function whose implementation looks like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb nb-Type"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb nb-Type"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Load&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;connection.json&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;xeus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;xconfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;xeus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;load_configuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;                                                   &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;interpreter_ptr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unique_ptr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;xeus_calc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;interpreter_ptr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;xeus_calc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;                              &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;xeus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;xkernel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;                         &lt;/span&gt;&lt;span class="n"&gt;xeus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;get_user_name&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;                         &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;                           &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;                                                   &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First, we need to load the configuration file. To do so, we check if one was passed as an argument, otherwise, we look for the connection.json file.&lt;/p&gt;
&lt;p&gt;Then, we instantiate the interpreter that we previously set up. Finally, we can create the kernel with all that we defined beforehand. The kernel constructor accepts more parameters that allow customizing some predefined behaviors. You can find more details in the &lt;a href="https://xeus.readthedocs.io/en/latest/"&gt;&lt;em&gt;&lt;strong&gt;Xeus documentation&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;. Start the kernel and we are good to go!&lt;/p&gt;
&lt;p&gt;Now that everything is set, we can test out our homemade calculator kernel.&lt;/p&gt;
&lt;p&gt;As you can see in the demonstration below, the code displays step-by-step how the computation is done with RPN. This is done with &lt;code&gt;publish_stream&lt;/code&gt;statements, which is equivalent to &lt;code&gt;std::cout&lt;/code&gt; for the Jupyter notebook, very useful for debugging purposes.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The final result, a functional calculator!" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/building-a-calculator-jupyter-kernel/images/005-0_o8XXbdwfzxiC8Nmj.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The final result, a functional calculator!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You should now have all the information you need to implement your own Jupyter kernel. As you noticed, the Xeus library makes this task quite simple. All that you have to do is to inherit from the &lt;code&gt;xinterpreter&lt;/code&gt; virtual class and implement the functions related to the messaging protocol. Nothing more is required.&lt;/p&gt;
&lt;p&gt;This project can be found on &lt;a href="https://github.com/QuantStack/xeus-calc"&gt;&lt;em&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;. Feel free to contribute to the project if you wish to improve it, keeping in mind that xeus-calc should remain lean and simple!&lt;/p&gt;
&lt;p&gt;Note that the current implementation only supports arithmetical operators. However it can be easily extended and we may add functional support in the near future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Acknowledgments&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We would like to thank the whole &lt;a href="https://quantstack.net/the-team.html"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; team for their help throughout the process of making this blog post.&lt;/p&gt;
&lt;p&gt;We are also grateful to the organizers of the &lt;a href="/posts/2019/jupyter-community-workshop-building-upon-the-jupyter/"&gt;&lt;em&gt;&lt;strong&gt;Jupyter community workshop on kernels&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; as we actually started to endeavor during the event.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;About the authors&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vasavan Thiru&lt;/strong&gt; is completing a master’s degree at &lt;em&gt;Sorbonne Université Pierre &amp;amp; Marie Curie&lt;/em&gt; in applied mathematics for mechanics. He is currently interning as a scientific software developer at QuantStack.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thibault Lacharme&lt;/strong&gt; is finishing a master’s degree in Quantitative Finance at &lt;em&gt;Université Paris Dauphine&lt;/em&gt;. Thibault is currently on his internship as a scientific software developer at QuantStack.&lt;/p&gt;
</content><category term="C++"/><category term="kernels"/><category term="xeus"/></entry></feed>