<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - C++</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/tag-cpp.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2025-06-19T15:29:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>C++ in Jupyter — Interpreting C++ in the Web</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/" rel="alternate"/><published>2025-06-19T15:29:00+00:00</published><updated>2025-06-19T15:29:00+00:00</updated><author><name>Anutosh Bhat</name></author><id>tag:jasongrout.github.io,2025-06-19:/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/</id><summary type="html">&lt;p&gt;A Jupyter kernel for C++ running in the Web browser&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Scientists and engineers utilize programming languages not only to build software systems but also to drive interactive exploratory workflows. They leverage developer tools to explore and reason through problems effectively. This process involves executing code, examining visualizations, loading data, and running additional code. Rapid iteration is particularly crucial during the exploratory phase of any technical project.&lt;/p&gt;
&lt;p&gt;For this reason, the most popular tools for exploratory work tend to be interpreted languages, such as Python or R. The “Read-Eval-Print-Loop” (REPL) places the user at the center of these iterative workflows. While compiled languages such as C++ are essential for performance-sensitive applications, engineers accustomed to interactive tools often struggle in such environments.&lt;/p&gt;
&lt;p&gt;At CERN, the C++ programming language has been pivotal to their data analysis platform for particle physics, notably in the ROOT framework. ROOT is underpinned by the Cling C++ interpreter, which is built on the Clang and LLVM stack. The Cling interpreter, co-created by Vassil Vassilev and Axel Naumann in the 2010s, effectively turned C++ into an agile scientific scripting language!&lt;/p&gt;
&lt;p&gt;These interactive workflows are where the Jupyter stack shines compared to traditional IDEs. Indeed, the Jupyter project was designed with exploratory computing in mind. Crucially, it was built from the ground up to be language-agnostic, accommodating multiple programming languages seamlessly. In 2017, the Xeus-Cling Jupyter kernel &lt;a href="/posts/2017/interactive-workflows-for-c-with-jupyter/"&gt;was announced&lt;/a&gt;. Developed by Sylvain Corlay, Johan Mabille and Loic Gouarin, it integrated Cling in the Jupyter ecosystem, taking advantage of the rich features of Jupyter, such as rich mime type display and interactive widgets.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="An example C++ Jupyter notebook powered by the original Xeus-Cling kernel" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/001-0_WCAlh5DEa7IT27u3.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;An example C++ Jupyter notebook powered by the original Xeus-Cling kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Packaging the Cling project proved challenging as it required patching the code base of Clang, and was not released as frequently as the LLVM stack, causing difficulties with rolling software distributions like conda-forge.&lt;/p&gt;
&lt;p&gt;In an effort led by Cling co-creator Vassil Vassilev, the &lt;a href="https://clang.llvm.org/docs/ClangRepl.html"&gt;Clang-Repl&lt;/a&gt; project was born, which consists in building the foundations for interactive C++ in the core of Clang. Clang-Repl has been undergoing active development for a few years now and a Jupyter kernel for Clang-Repl, &lt;a href="https://github.com/compiler-research/xeus-cpp"&gt;Xeus-Cpp&lt;/a&gt;, has also been developed, providing a similar set of features to Xeus-Cling.&lt;/p&gt;
&lt;p&gt;Building the new C++ kernel upon Xeus was crucial as it enabled the porting of the C++ kernel to the Web browser with JupyterLite.&lt;/p&gt;
&lt;h2 id="scaling-jupyter-with-jupyterlite"&gt;Scaling Jupyter with JupyterLite&lt;/h2&gt;
&lt;p&gt;The standard approach for Jupyter-based computing relies on providing each user with computing resources in the backend. Serving a few thousand end users necessitates substantial resources and complex deployment strategies.&lt;/p&gt;
&lt;p&gt;The JupyterLite project shifts this paradigm by running code directly in the user’s Web browser, by relying on a WebAssembly build of the kernel and required libraries. This eliminates the linear relationship between the number of users and the required resources.&lt;/p&gt;
&lt;p&gt;For instance, the NumPy.org website features a JupyterLite code console on its main page, offering a computational environment to thousands of monthly visitors without incurring any cloud costs. Similarly, the Capytale deployment of Jupyter, used in French high schools, operates on the same model. It accounts for over half a million registered users and hosts more than 200,000 user sessions weekly.&lt;/p&gt;
&lt;p&gt;In order to provide a broad range of packages and libraries for this new platform, the &lt;a href="https://jupyterlite.readthedocs.io/en/stable/"&gt;JupyterLite&lt;/a&gt; team at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; developed the &lt;a href="https://emscripten-forge.org/"&gt;Emscripten-forge&lt;/a&gt; distribution, utilizing the conda package manager for creating WebAssembly environments. Emscripten-forge comprises the main packages of the Python scientific computing ecosystem, as well as the R programming language, and several command-line applications powering the JupyterLite terminal.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Today, we are proud to announce that Xeus-Cpp and LLVM are available in emscripten-forge, effectively enabling interpreted C++ in the browser.&lt;/em&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The new C++ Jupyter kernel in action in JupyterLite." src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/002-0_XLTuIN3E7_64kPcO.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The new C++ Jupyter kernel in action in JupyterLite.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Feel free to try it out in your browser by clicking the link below!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://compiler-research.org/xeus-cpp-wasm/lab/index.html"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/003-1_gNg6NzVjE9nwIF9PSdt-jA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We now dive into the details on the internals of the WebAssembly build of Xeus-Cpp, and the key features of the project.&lt;/p&gt;
&lt;h2 id="walking-up-the-stack"&gt;Walking up the stack&lt;/h2&gt;
&lt;h3 id="emulated-just-in-time-compilation-and-webassembly"&gt;Emulated Just-in-Time Compilation and WebAssembly&lt;/h3&gt;
&lt;p&gt;A fundamental challenge inherent to the WebAssembly is that it operates in a &lt;strong&gt;sandboxed Harvard architecture&lt;/strong&gt;: code and data reside in completely distinct memory spaces. This makes conventional &lt;strong&gt;JIT compilation&lt;/strong&gt; unfeasible in the browser, as it prohibits dynamic modification of executable memory.&lt;/p&gt;
&lt;p&gt;The WebAssembly backend for Clang-Repl was introduced during the LLVM 17 development cycle, with the introduction of a WASM-specific &lt;strong&gt;IncrementalExecutor&lt;/strong&gt;, sidestepping the standard LLVM JIT approach used on native platforms. This new &lt;strong&gt;WasmIncrementalExecutor&lt;/strong&gt; class handled the WebAssembly-specific execution model as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The LLVM IR from the REPL’s Partial Translation Unit (PTU) is compiled into an object file.&lt;/li&gt;
&lt;li&gt;This object file is passed to wasm-ld with flags to generate a standalone WebAssembly module.&lt;/li&gt;
&lt;li&gt;The resulting .wasm module acts as a dynamically linked side module, designed to be loaded on top of a persistent main module at runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These side modules, while similar to shared libraries, are treated as auxiliary WASM modules that are dynamically attached to the main application using Emscripten’s dlopen mechanism. They share memory with the main module and can resolve symbols defined in previous executions. As a result, each REPL input produces a corresponding .wasm module that is compiled, linked, and loaded at runtime, incrementally extending the current execution environment.&lt;/p&gt;
&lt;p&gt;Following the initial version in LLVM 17, the support for WebAssembly was incrementally consolidated by a series of pull requests addressing various issues and corner cases with respect to symbol duplication, memory corruption, and dynamic linking failures. We believe the version available today in LLVM 20 is a solid foundation to build upon.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/llvm/llvm-project/pull/86402"&gt;PR #86402 — Initial WebAssembly support for clang-repl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/llvm/llvm-project/pull/113446"&gt;PR #113446 — Fix undefined lld::wasm::link symbol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/llvm/llvm-project/pull/116735"&gt;PR #116735 — Improve flags responsible for generating shared wasm binaries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/llvm/llvm-project/pull/117978"&gt;PR #117978 — Fix generation of wasm binaries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/llvm/llvm-project/pull/118107"&gt;PR #118107 — Remove redundant shared flag while running clang-repl in browser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a deeper understanding of the constraints of the WebAssembly platform for JIT compilation, refer to the GSOC report: &lt;a href="https://compiler-research.org/assets/presentations/Anubhab_Ghosh_wasm_clangrepl.pdf"&gt;Anubhab Ghosh — WASM Clang-Repl&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="porting-xeus-cpp-to-emscripten-forge"&gt;Porting Xeus-Cpp to Emscripten-forge&lt;/h3&gt;
&lt;p&gt;In addition to challenges with emulating JIT compilation in WebAssembly, packaging Xeus-Cpp for emscripten-forge presented another challenge: managing shared objects within the initial WebAssembly executable, which are typically built statically for other xeus kernels. This issue was addressed in the following PRS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyterlite/xeus/pull/145"&gt;PR #145 — Handle .data file for kernels that require preloading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyterlite/xeus/pull/146"&gt;PR #146 - Kernel shared libs handling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a result of this work, required side modules are now specified as metadata in the Jupyter kernelspec &lt;a href="https://github.com/compiler-research/xeus-cpp/blob/main/share/jupyter/kernels/xcpp23/wasm_kernel.json.in#L12"&gt;kernel.json&lt;/a&gt; file, enabling JupyterLite to automatically detect and utilize them.&lt;/p&gt;
&lt;h2 id="features"&gt;Features&lt;/h2&gt;
&lt;h3 id="inline-documentation"&gt;Inline documentation&lt;/h3&gt;
&lt;p&gt;To fully integrate C++ as a first-class citizen within the Jupyter ecosystem, supporting inline documentation is crucial. Similar to the Python kernel, utilizing the ? magic command should allow users to inspect the following type, perform a lookup in the available documentation, and display the relevant information.&lt;/p&gt;
&lt;p&gt;The C++ kernel comes equipped with a lookup file for the standard library, making it possible to execute queries like &lt;strong&gt;?std::vector&lt;/strong&gt; seamlessly.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Inline help feature in the C++ JupyterLite kernel" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/004-0_j7LvIkaUDbSD0urz.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Inline help feature in the C++ JupyterLite kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This can be enabled for third-party libraries. Check out the &lt;a href="https://xeus-cpp.readthedocs.io/en/latest/inline_help.html"&gt;documentation&lt;/a&gt; to enable inline help for your package.&lt;/p&gt;
&lt;p&gt;This feature, inherited from the Xeus-Cling project, was initially created by &lt;strong&gt;Loic Gouarin&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="rich-display"&gt;Rich display&lt;/h3&gt;
&lt;p&gt;One of the core benefits of integrating C++ into the Jupyter ecosystem is the ability to leverage Jupyter’s rich MIME display system. Rather than limiting output to plain text, Xeus-Cpp allows you to render rich content like &lt;strong&gt;images, HTML tables, LaTeX&lt;/strong&gt;, or even &lt;strong&gt;custom visualizations&lt;/strong&gt;, all directly from C++.&lt;/p&gt;
&lt;p&gt;This is made possible by the function xcpp::display, which sends a &lt;em&gt;MIME bundle&lt;/em&gt; to the frontend. Each bundle can include multiple representations of the same object, such as &lt;strong&gt;text/plain&lt;/strong&gt;, &lt;strong&gt;image/png&lt;/strong&gt;, or even custom mime types.&lt;/p&gt;
&lt;p&gt;This is illustrated in the following example:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Rich mime type rendering feature of the Xeus-Cpp kernel" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/005-0_icsXc3d2vC5OTF1K.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Rich mime type rendering feature of the Xeus-Cpp kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A custom renderer for any given type can be defined by defining the &lt;strong&gt;mime_bundle_repr&lt;/strong&gt; function in the corresponding namespace, which is then picked up by Xeus-Cpp’s display system through Argument-Dependent Lookup (ADL). A large collection of mime types are supported by the JupyterLab frontend, which can also be extended with plugins to support custom mime types.&lt;/p&gt;
&lt;h3 id="advanced-graphics"&gt;Advanced Graphics&lt;/h3&gt;
&lt;p&gt;Another compelling example leveraging the rich rendering capabilities, is to combine it with frameworks such as SDL for rich graphic content. Emscripten has built-in support for SDL (enabled with the &lt;strong&gt;-s USE_SDL=2&lt;/strong&gt; compilation flag), which allows us to leverage its power in C++ notebooks.&lt;/p&gt;
&lt;p&gt;To illustrate this, we ported &lt;strong&gt;Kevin Beason’s legendary&lt;/strong&gt; &lt;a href="https://www.kevinbeason.com/smallpt/"&gt;&lt;strong&gt;smallpt&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;global illumination renderer&lt;/strong&gt; (a path tracer in 99 lines of C++) into a C++ notebook. The scene is rendered using SDL onto an in-memory canvas, and the resulting image is captured and displayed with &lt;strong&gt;xcpp::display&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This setup showcases the seamless integration of SDL and the Jupyter display system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use SDL for &lt;strong&gt;real-time or offscreen rendering&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Then pipe the result through xcpp::display(…) as a PNG or pixel buffer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://github.com/compiler-research/xeus-cpp/pull/299"&gt;PR #299&lt;/a&gt; added an example notebook supporting smallpt with SDL-based rendering. Feel free to access the notebook through our &lt;a href="https://compiler-research.org/xeus-cpp/lab/index.html"&gt;lite link&lt;/a&gt; . Since the number of samples per pixel (spp) directly correlates with how long the process runs (approximately 2 minutes in our case), we’ve included debug logs to keep users informed during rendering, so they aren’t left wondering about the progress.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Smallpt tiny raytracer in action in JupyterLite" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/006-0_OrN0HWXlcMjemfj6.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Smallpt tiny raytracer in action in JupyterLite&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This approach paves the way for interactive C++ graphics demos, ray tracing notebooks, and even the prototyping of browser-based video games from within WebAssembly C++ notebooks.&lt;/p&gt;
&lt;h3 id="loading-third-party-libraries"&gt;Loading Third-Party Libraries&lt;/h3&gt;
&lt;p&gt;For a user’s perspective, a key difference between a Jupyter kernel for a compiled language like C++ and e.g. Python concerns how third-party libraries can be utilized. In Python, one merely needs to import the relevant installed packages, while in the case of C++, the relevant compiled libraries must be loaded in addition to including the corresponding headers.&lt;/p&gt;
&lt;p&gt;Thankfully, Clang-Repl provides the &lt;strong&gt;LoadDynamicLibrary&lt;/strong&gt; to dynamically load shared objects, which was adapted to the WebAssembly based in &lt;a href="https://github.com/llvm/llvm-project/pull/133037"&gt;LLVM PR #133037&lt;/a&gt;. Instead of relying directly on raw dlopen calls, this function ensures that memory layout, symbol resolution, and constructor invocation are handled correctly — even in a WebAssembly environment.&lt;/p&gt;
&lt;p&gt;Building on top of this, the CppInterOp project made these features available via a high-level C++ API.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Showcasing the dynamic loading of shared objects with CppInterOp" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/007-0_O4xsKujuUwCvMVSq.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Showcasing the dynamic loading of shared objects with CppInterOp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Library authors interested in facilitating the use of their package with the Jupyter kernel can include the calls to CppInterop’s &lt;strong&gt;LoadLibrary&lt;/strong&gt; can simply be included in user-facing headers.&lt;/p&gt;
&lt;p&gt;This has been done for example, in the Symengine library.&lt;/p&gt;
&lt;h3 id="symbolic-computing-with-symengine"&gt;Symbolic Computing with Symengine&lt;/h3&gt;
&lt;p&gt;A compelling example of the Jupyter rich display system’s advanced capabilities with Xeus-Cpp is the &lt;a href="https://github.com/symengine/symengine"&gt;&lt;strong&gt;SymEngine&lt;/strong&gt;&lt;/a&gt; package, a powerful C++ library for symbolic computing.&lt;/p&gt;
&lt;p&gt;Originally designed as a backend for symbolic Python libraries like SymPy, SymEngine offers native support for expression trees, calculus and Latex/MathJax rendering of mathematical expressions. We have integrated SymEngine into the emscripten-forge distribution, making it readily available for use. Once installed, it works seamlessly with Xeus-Cpp, requiring no additional setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SymEngine expressions can be rendered via xcpp::display()&lt;/strong&gt;, which produces LaTeX-formatted expressions and delegates their rendering to &lt;strong&gt;MathJax&lt;/strong&gt; in the frontend.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Rich mime type rendering used with Symengine" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/008-0_7E9I9OxKKGqDK_Og.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Rich mime type rendering used with Symengine&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="array-based-computing"&gt;Array-based Computing&lt;/h3&gt;
&lt;p&gt;Jupyter notebooks are particularly popular among data scientists, students, and practitioners of scientific computing. &lt;strong&gt;Array-based computing&lt;/strong&gt; is at the center of the practice, be it in Python with NumPy, in R, GNU Octave, or Julia.&lt;/p&gt;
&lt;p&gt;A framework for array-based computing is C++ is &lt;strong&gt;Xtensor&lt;/strong&gt;. Xtensor’s syntax closely mirrors that of NumPy, supporting features like array broadcasting, lazy evaluation, and element-wise operations with an idiomatic C++ API. Using Xtensor in combination with the C++ Jupyter kernel provides a similar user experience to that of NumPy with the Python Jupyter kernel.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="JupyterLite used in combination with Xtensor, utilizing rich display for tables." src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/009-0_jbBM7zjHznUTxDmp.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;JupyterLite used in combination with Xtensor, utilizing rich display for tables.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Built on top of Xtensor, &lt;strong&gt;Xtensor-BLAS&lt;/strong&gt; brings the &lt;strong&gt;high-level syntax of Xtensor&lt;/strong&gt; with the &lt;strong&gt;performance of OpenBLAS&lt;/strong&gt;. It provides convenient, NumPy-style access to BLAS and LAPACK routines making operations like matrix inversion or system solving easy to express and execute.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="JupyterLite used in combination with Xtensor-BLAS" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/010-0_Y0RXrB1PrRoP7fQ3.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;JupyterLite used in combination with Xtensor-BLAS&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To use these libraries inside a JupyterLite notebook, all you need is to include Xtensor-BLAS in your environment (available via emscripten-forge). Under the hood, Xtensor-BLAS dynamically loads &lt;strong&gt;libopenblas&lt;/strong&gt;, which is bundled automatically as a dependency.&lt;/p&gt;
&lt;h3 id="simd-acceleration"&gt;SIMD Acceleration&lt;/h3&gt;
&lt;p&gt;We can take a step further with &lt;strong&gt;SIMD (Single Instruction, Multiple Data)&lt;/strong&gt; acceleration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using raw WebAssembly intrinsics :&lt;/strong&gt; WebAssembly includes 128-bit SIMD instructions, which are provided in Clang’s &lt;strong&gt;&amp;lt;wasm_simd128.h&amp;gt;&lt;/strong&gt; header. They can be used to perform vectorized operations directly.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Xeus-Cpp kernel showcasing the use of SIMD instructions" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/011-0_PyE8StfrE9f5s7g8.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Xeus-Cpp kernel showcasing the use of SIMD instructions&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Using Xsimd :&lt;/strong&gt; Here’s an improved version of your text with better flow, clarity, and conciseness.&lt;/p&gt;
&lt;p&gt;Rewriting specialized vectorized routines for WebAssembly can be cumbersome. This is where frameworks like &lt;a href="https://github.com/xtensor-stack/xsimd"&gt;&lt;strong&gt;Xsimd&lt;/strong&gt;&lt;/a&gt; come in. It provides a high-level SIMD API in C++ that abstracts platform-specific SIMD instructions. With Xsimd, you can efficiently operate on batches of numbers using familiar arithmetic operators or mathematical functions, while benefiting from optimized performance under the hood.&lt;/p&gt;
&lt;p&gt;Xsimd powers SIMD acceleration in Xtensor and is also used in many other projects, including Apache Arrow, Firefox, Velox, Pythran, and Krita. Here’s how the same example would look when when using Xsimd instead of raw intrinsics:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Xeus-Cpp kernel showcasing the Xsimd library" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/012-0_cmTseJsCeHr02SRp.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Xeus-Cpp kernel showcasing the Xsimd library&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="magic-commands"&gt;Magic Commands&lt;/h3&gt;
&lt;p&gt;In addition to interpreting standard C++ code, Xeus-Cpp also supports &lt;strong&gt;magic commands&lt;/strong&gt;, special notebook commands prefixed with % or %% that allow for extended functionality not defined by the C++ language itself.&lt;/p&gt;
&lt;p&gt;These magics let you interact with the runtime environment, manage files, or perform meta-operations, all from within a code cell. The following magics are available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;%file :&lt;/strong&gt; The %file magic enables file creation and editing directly from a code cell. You can append to an existing file using the &lt;strong&gt;-a&lt;/strong&gt; flag&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Using the %file magics in Xeus-Cpp-lite" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/013-0_-sOa-yVDMKuTdJ6R.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the %file magics in Xeus-Cpp-lite&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;%timeit :&lt;/strong&gt; A %timeit magic has also been prototyped via &lt;a href="https://github.com/compiler-research/xeus-cpp/pull/289"&gt;PR #289&lt;/a&gt; by &lt;a href="https://github.com/kr-2003"&gt;@kr-2003&lt;/a&gt;, enabling performance measurement for expressions in the notebook.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, due to the lack of &lt;strong&gt;last value printing support&lt;/strong&gt; in Clang-Repl, this feature currently relies on a workaround and hasn’t yet been merged. Once upstream support is in place, %timeit will be integrated cleanly and available out of the box.&lt;/p&gt;
&lt;p&gt;Here’s a preview of the %timeit magic in action:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using the %timeit magics in Xeus-Cpp-lite" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/014-1_TxNBjy8ovN1LbrQ1UYejAQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the %timeit magics in Xeus-Cpp-lite&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Magic commands open the door to a more expressive and interactive notebook experience for C++. While support is currently limited to a few core magics, this is just the beginning — with more capabilities and enhancements expected in the near future.&lt;/p&gt;
&lt;h3 id="interactive-widgets"&gt;Interactive Widgets&lt;/h3&gt;
&lt;p&gt;Beyond rich mime type rendering and inline documentation, the Jupyter widgets system allows users to create interactive components in the Jupyter notebook, leveraging by-directional communication with the kernel for more interactivity.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/jupyter-xeus/xwidgets"&gt;&lt;strong&gt;xwidgets&lt;/strong&gt;&lt;/a&gt; package is a C++ implementation of the Jupyter widget protocol, comprising an implementation of all the core Jupyter widgets, and which underlies other interactive visualization libraries like &lt;a href="https://github.com/jupyter-xeus/xleaflet"&gt;&lt;strong&gt;xleaflet&lt;/strong&gt;&lt;/a&gt; or &lt;a href="https://github.com/jupyter-xeus/xcanvas"&gt;&lt;strong&gt;xcanvas&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are a couple examples demonstrating interactive widgets through xwidgets &amp;amp; xcanvas with Xeus-Cpp-lite.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Displaying a slider using xwidgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/015-1_uJRTSmvJ8OgZbDLliI5BkQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Displaying a slider using xwidgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Displaying a canvas through xcanvas" src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/c-in-jupyter-interpreting-c-in-the-web/images/016-1_w-SeiUeAmHPcMeIY84tb0w.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Displaying a canvas through xcanvas&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you inspect the codebase of xwidgets or xcanvas, you will notice that it contains very little code. All that is required on the C++ end is a declaration of the attributes that should be synchronized with the frontend, and serialization methods for complex data types.&lt;/p&gt;
&lt;p&gt;Most of the programmatic logic for Jupyter interactive widgets lies in the frontend implementation. The consequence for the C++ Jupyter kernel is that with seemingly little implementation effort, we could enable an entire ecosystem of widget libraries, covering a large range of use cases. Interactive widgets for 2-D plotting (&lt;strong&gt;bqplot&lt;/strong&gt;, &lt;strong&gt;plotly&lt;/strong&gt;) and 3-D plotting (&lt;strong&gt;ipyvolume&lt;/strong&gt;), GIS (&lt;strong&gt;ipyleaflet&lt;/strong&gt;), efficient rendering of meshes (&lt;strong&gt;ipygany&lt;/strong&gt;), graph visualization (&lt;strong&gt;ipycytoscape&lt;/strong&gt;), and many more could be almost automatically connected to the C++ world.&lt;/p&gt;
&lt;h2 id="how-to-deploy-jupyterlite-with-xeus-cpp"&gt;How to deploy JupyterLite with Xeus-Cpp&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 C++ kernel with Symengine &amp;amp; Xtensor-blas 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-cpp&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.prefix.dev/emscripten-forge-dev&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-cpp&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;symengine&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;xtensor-blas&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="future-work"&gt;Future work&lt;/h2&gt;
&lt;p&gt;The journey of interactive C++ in Jupyter, both natively and in the browser, is still evolving. While Xeus-Cpp already offer powerful foundations, several exciting developments are underway that will further expand their capabilities across platforms&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debugger Support:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Currently, only a few Jupyter kernels like Xeus-Python offer full integration with the Jupyter Debug Protocol to enable the Jupyterlab debugger. We’re working to bring that experience to C++ as well.&lt;/p&gt;
&lt;p&gt;This summer, thanks to &lt;a href="https://summerofcode.withgoogle.com/programs/2025/projects/uEB2as1n"&gt;Google Summer of Code 2025&lt;/a&gt;, &lt;strong&gt;Abhinav Kumar&lt;/strong&gt; will be implementing native debugging support in Xeus-Cpp.The approach is based on using &lt;strong&gt;LLDB&lt;/strong&gt; and its &lt;strong&gt;Debug Adapter Protocol (lldb-dap)&lt;/strong&gt;. Modeled after Xeus-Python, it leverages LLDB’s Clang and JIT debugging capabilities to enable &lt;strong&gt;breakpoints&lt;/strong&gt;, &lt;strong&gt;variable inspection&lt;/strong&gt;, and &lt;strong&gt;step-through execution&lt;/strong&gt; directly within the JupyterLab debugger interface.&lt;/p&gt;
&lt;p&gt;We already have a proof-of-concept demonstrating that debugging C++ in Jupyter is possible. You can track this effort here&lt;a href="https://github.com/compiler-research/xeus-cpp/issues/282"&gt;: xeus-cpp issue #28&lt;/a&gt;2.&lt;/p&gt;
&lt;p&gt;In the longer term, we aim to explore extending debugging to the browser through Xeus-Cpp.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cuda Support in Xeus-Cpp:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CUDA support in Clang-Repl was broken by the time LLVM 20 was released, but that changed with this upstream patch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLVM PR: &lt;a href="https://github.com/llvm/llvm-project/pull/136404"&gt;#136404 — Enable CUDA support in clang-rep&lt;/a&gt;l&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We’re now preparing to bring CUDA support directly to Xeus-Cpp, enabling GPU programming from a Jupyter notebook. Early planning is underway:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub issue: &lt;a href="https://github.com/compiler-research/xeus-cpp/issues/300"&gt;#300 — CUDA REPL support in xeus-cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Last Value Printing:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;cling&lt;/strong&gt;, a widely appreciated feature is &lt;em&gt;last value printing&lt;/em&gt;, simply writing a variable at the end of a cell automatically displays its value, without needing any manual printing. This behavior naturally carried over to &lt;strong&gt;xeus-cling&lt;/strong&gt;, making interactive exploration even smoother.&lt;/p&gt;
&lt;p&gt;This feature stands almost done in Clang-Repl:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLVM PR: &lt;a href="https://github.com/llvm/llvm-project/pull/84769"&gt;#84769 — Last Value Printing in clang-repl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once merged, this will be integrated into Xeus-Cpp, enabling seamless REPL experience for C++ users.&lt;/p&gt;
&lt;h2 id="how-to-contribute"&gt;How to contribute?&lt;/h2&gt;
&lt;p&gt;Whether you’re a developer, package maintainer, educator, or simply curious about C++ in the browser, &lt;strong&gt;contributions are always welcome&lt;/strong&gt;!&lt;/p&gt;
&lt;h3 id="packaging-for-the-browser"&gt;Packaging for the Browser&lt;/h3&gt;
&lt;p&gt;Many of the capabilities in xeus-cpp-lite rely on packages built for the WebAssembly platform via &lt;strong&gt;emscripten-forge&lt;/strong&gt;. If you’re interested in porting a library or creating a new recipe, please visit &lt;a href="https://emscripten-forge.org/"&gt;emscripten-forge.org&lt;/a&gt; for detailed guidelines and examples.&lt;/p&gt;
&lt;p&gt;PRs and discussions are welcome at &lt;a href="https://github.com/emscripten-forge"&gt;github.com/emscripten-forge&lt;/a&gt;, especially if you’re looking to bring more numerical, graphical, or scientific libraries into the browser.&lt;/p&gt;
&lt;h3 id="improving-xeus-cpp-cppinterop-and-clang-repl"&gt;Improving Xeus-Cpp, CppInterOp and Clang-Repl&lt;/h3&gt;
&lt;p&gt;We welcome contributions to the broader &lt;strong&gt;xeus&lt;/strong&gt; project, which is part of the &lt;a href="https://jupyter.org/"&gt;Project Jupyter&lt;/a&gt; ecosystem. Xeus-Cpp in particular is actively seeking contributors, whether to improve kernel behavior, expand feature support, or explore new magic commands and UI integrations.&lt;/p&gt;
&lt;p&gt;On the LLVM side, the &lt;strong&gt;Clang-Repl&lt;/strong&gt; component is still under active development and can greatly benefit from community contributions, particularly around WebAssembly backend improvements and incremental execution features.&lt;/p&gt;
&lt;h3 id="areas-of-need-opportunities-for-collaboration"&gt;Areas of Need &amp;amp; Opportunities for Collaboration&lt;/h3&gt;
&lt;p&gt;In addition to code contributions, we are seeking funding opportunities to advance the project. We’ve identified several areas where focused effort could significantly enhance the ecosystem, and we warmly welcome collaborators or potential funding partners interested in helping us move these efforts forward, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integration testing&lt;/strong&gt;: LLVM currently lacks tests for Clang-Repl + WebAssembly. Establishing a reliable test harness in this area is both challenging and critical.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interactive plotting&lt;/strong&gt;: A robust plotting library or plugin for Xeus-Cpp would make the kernel far more expressive for teaching, data exploration, and scientific computing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plugin system for magics&lt;/strong&gt;: Further decoupling kernel extensions would simplify development and allow community-driven growth. A concrete description of this project is framed on &lt;a href="https://hepsoftwarefoundation.org/gsoc/2025/proposal_XeusCpp-Plugins.html"&gt;CERN’s website&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you or your organization shares the vision of making modern C++ more accessible, especially in-browser, we’d love to hear from you.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/anutosh491"&gt;&lt;strong&gt;Anutosh Bhat&lt;/strong&gt;&lt;/a&gt; is a scientific software engineer at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;. His contributions range from the core of LLVM and Xeus, to their packaging for the Emscripten-forge software distribution. In the course of this endeavor, Anutosh was granted commit rights to the LLVM project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/vgvassilev"&gt;&lt;strong&gt;Vassil Vassilev&lt;/strong&gt;&lt;/a&gt; is a Research Software Consultant with Princeton at &lt;a href="https://home.cern/"&gt;CERN&lt;/a&gt;. As the co-creator of Cling and the lead developer of the Clang-Repl and CppInterOp projects, he has spearheaded the development of interpreted C++ for over a decade.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The work by &lt;strong&gt;Vassil Vassilev&lt;/strong&gt; on this project is done in the context of the &lt;a href="https://compiler-research.org/"&gt;Compiler Research&lt;/a&gt; group, funded by the National Science Foundation grant OAC-2311471.&lt;/p&gt;
&lt;p&gt;The work by &lt;strong&gt;Anutosh Bhat&lt;/strong&gt; on this project is funded by &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;, as part of a broader initiative to enable the data science ecosystem within the Web browser.&lt;/p&gt;
&lt;p&gt;Work on prototyping the WebAssembly infrastructure for Clang-Repl was done by &lt;strong&gt;Anubhab Ghosh&lt;/strong&gt;, supported through &lt;a href="https://summerofcode.withgoogle.com/archive/2023/projects/X0cFgJkY"&gt;Google Summer of Code 2023&lt;/a&gt; via the LLVM mentoring organization.&lt;/p&gt;
&lt;p&gt;A significant portion of the Xeus-Cpp codebase was inherited from the Xeus-Cling project and adapted for the Clang-Repl interpreter. This includes work by &lt;strong&gt;Sylvain Corlay&lt;/strong&gt;, &lt;strong&gt;Johan Mabille&lt;/strong&gt;, &lt;strong&gt;Loic Gouarin&lt;/strong&gt;, and &lt;strong&gt;Martin Renou&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;strong&gt;Thorsten Beier&lt;/strong&gt;, the creator and lead developer of the emscripten-forge software distribution, for his support in packaging LLVM and Xeus-Cpp.&lt;/p&gt;
&lt;p&gt;We extend our gratitude to &lt;strong&gt;Martin Renou&lt;/strong&gt; and &lt;strong&gt;Anastasiia Sliusar&lt;/strong&gt; for devising the processing of conda packages in the frontend, which underlies the support of third-party libraries in WebAssembly environments used by Xeus-Cpp and xeus-r. We are grateful to &lt;strong&gt;Johan Mabille&lt;/strong&gt; for creating xeus and for his code reviews within the xeus stack. We also thank &lt;strong&gt;Jeremy Tuloup&lt;/strong&gt; for creating JupyterLite.&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;strong&gt;Matthew Barton, Tharun Anandh &amp;amp; Abhinav Kumar&lt;/strong&gt; for their numerous and significant contributions to the Xeus-Cpp project.&lt;/p&gt;
&lt;p&gt;Finally, we are immensely grateful to the authors and maintainers of Emscripten and LLVM for building such remarkable technologies and for their engagement and support during our numerous interactions on GitHub.&lt;/p&gt;
</content><category term="C++"/><category term="WebAssembly"/></entry><entry><title>A Curiously Recurring Widget Library</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/" rel="alternate"/><published>2021-01-27T14:22:00+00:00</published><updated>2021-01-27T21:41:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jasongrout.github.io,2021-01-27:/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/</id><summary type="html">&lt;p&gt;Diving into the implementation of xwidgets&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;Diving into the implementation of xwidgets&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Interactive widgets allow Jupyter users to create user interfaces inline in their notebooks, and to turn them into standalone applications with tools such as &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Language backends for Jupyter interactive widgets exist in Python (with &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt;), and C++ (with &lt;a href="https://github.com/jupyter-xeus/xwidgets"&gt;xwidgets&lt;/a&gt;, and the &lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;xeus-cling&lt;/a&gt; C++ Jupyter kernel), reusing the same frontend implementation of the widgets in JavaScript.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simple interactive widgets at play in JupyterLab with the xeus-cling C++ kernel" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/images/001-1_b_2s5wfIzrqGapkhBytHSg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simple interactive widgets at play in JupyterLab with the xeus-cling C++ kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this article, we dive into some of the C++ techniques used in the implementation of the xwidgets library, including&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;discussions on &lt;strong&gt;value semantics&lt;/strong&gt; and &lt;strong&gt;RAII&lt;/strong&gt; (&lt;em&gt;Resource Acquisition Is Initialization&lt;/em&gt;),&lt;/li&gt;
&lt;li&gt;an original application of &lt;strong&gt;CRTP&lt;/strong&gt; (&lt;em&gt;Curiously Recurring Template Pattern&lt;/em&gt;),&lt;/li&gt;
&lt;li&gt;an original implementation of the &lt;strong&gt;observer&lt;/strong&gt; pattern, xproperty,&lt;/li&gt;
&lt;li&gt;a plea for allowing the &lt;strong&gt;overloading of the dot operator&lt;/strong&gt; in C++, to enable better proxy types.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;For readers interested in knowing more about&lt;/em&gt; &lt;em&gt;&lt;strong&gt;interpreted C++&lt;/strong&gt;&lt;/em&gt;&lt;em&gt;, we recommend the following posts:&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/posts/2017/interactive-workflows-for-c-with-jupyter/"&gt;Interactive workflows for C++ with Jupyter&lt;/a&gt; &lt;em&gt;(Jupyter blog), by Sylvain Corlay, Loic Gouarin, Johan Mabille, and Wolf Vollprecht.&lt;br&gt;
-&lt;/em&gt; &lt;a href="https://blog.llvm.org/posts/2020-12-21-interactive-cpp-for-data-science/"&gt;Interactive C++ for Data Science&lt;/a&gt; &lt;em&gt;(LLVM blog), by Vassil Vassilev, David Lange, Simeon Ehrig, and Sylvain Corlay&lt;br&gt;
-&lt;/em&gt; &lt;a href="/posts/2018/interpreted-c-for-gis-with-jupyter/"&gt;Interpreted C++ for GIS with Jupyter&lt;/a&gt; &lt;em&gt;(Jupyter blog), by Martin Renou&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="using-the-raii-pattern-for-a-widget-library"&gt;Using the RAII pattern for a widget library&lt;/h2&gt;
&lt;p&gt;Jupyter widgets are special objects that trigger the creation of a counterpart JavaScript model object in the Jupyter frontend upon creation. The state of the object in the backend is synchronized with the state of the JavaScript frontend object. Views of that widget model are instantiated upon display.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The MVC (Model View Controller) architecture of Jupyter widgets, and synchronization with the backend" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/images/002-1_ThTvsqji0l85Pr__5hs9bQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The MVC (Model View Controller) architecture of Jupyter widgets, and synchronization with the backend&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This MVC (Model-View-Controller) architecture for Jupyter interactive widgets allowed us to reuse all of the frontend implementation, by simply providing an alternative backend in C++, implementing the same messaging protocol.&lt;/p&gt;
&lt;p&gt;In order to tie the lifetime of the kernel and frontend objects, we decided to use the &lt;a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization"&gt;RAII (Resource Acquisition Is Initialization)&lt;/a&gt; pattern. RAII is a common programming idiom that consists of tying the lifetime of an object with the holding of a resource. Most typically, the resource is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;acquired&lt;/strong&gt;&lt;/em&gt; in the &lt;em&gt;&lt;strong&gt;constructor&lt;/strong&gt;&lt;/em&gt; of the object,&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;released&lt;/strong&gt;&lt;/em&gt; in the &lt;em&gt;&lt;strong&gt;destructor&lt;/strong&gt;&lt;/em&gt; of the object.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The RAII pattern is not common in garbage-collected languages because unlike in C++, the time when objects are destroyed is not deterministic. The Python programming language mitigates that issue by introducing&lt;/em&gt; &lt;a href="https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"&gt;&lt;em&gt;context managers&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, often used to&lt;/em&gt; e.g. &lt;em&gt;open and close files.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A consequence of relying on object lifetime for resource management in C++ is to adopt the “&lt;em&gt;&lt;strong&gt;value semantics&lt;/strong&gt;&lt;/em&gt;” for widget instances, instead of “&lt;em&gt;&lt;strong&gt;reference semantics&lt;/strong&gt;&lt;/em&gt;” which is more typical for widget frameworks like Qt.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note: value semantics vs reference semantics&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you are not familiar with the concepts of&lt;/em&gt; &lt;strong&gt;value&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;reference&lt;/strong&gt; &lt;strong&gt;semantics&lt;/strong&gt; &lt;em&gt;in C++, I recommend reading the&lt;/em&gt; &lt;a href="https://isocpp.org/wiki/faq/value-vs-ref-semantics"&gt;&lt;em&gt;&lt;strong&gt;excellent FAQ&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; &lt;em&gt;of isocpp.org.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To summarize:&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;- with&lt;/em&gt; &lt;em&gt;&lt;strong&gt;value semantics&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;objects hold actual values, and copying an object copies their attributes. With value semantics, one should provide implementations of&lt;/em&gt; &lt;em&gt;&lt;strong&gt;copy, and move constructors&lt;/strong&gt;&lt;/em&gt;*, as well as* &lt;em&gt;&lt;strong&gt;copy and move assignment operators&lt;/strong&gt;&lt;/em&gt;*. Besides, values should not have virtual methods.*&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;- with&lt;/em&gt; &lt;em&gt;&lt;strong&gt;reference semantics&lt;/strong&gt;&lt;/em&gt;*, objects are manipulated through references (or pointers) and never by value. Reference semantics is typically used for polymorphic programming with* &lt;em&gt;&lt;strong&gt;virtual methods&lt;/strong&gt;&lt;/em&gt;*. With reference semantics, it is recommended to delete copy and move constructors, as well as copy and move assignment operators to avoid accidental copies when passing objects to functions taking arguments by values, causing object slicing. (They can also be made private). Explicit cloning of a reference semantics object is generally allowed via a call to a* &lt;em&gt;&lt;strong&gt;clone&lt;/strong&gt;&lt;/em&gt; &lt;em&gt;virtual method.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In a C++ codebase, the existence of public copy or move constructors alongside virtual methods in the same class is generally a sign of a bad design.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The use of value semantics for xwidgets provides clear lifetime management for associated resources. Careful use of the move semantics provides fine-grained control.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Illustration of the move semantics for xwidgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/images/003-1_i1D4_PqaKhej-XRSKkoyBw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Illustration of the move semantics for xwidgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another advantage of using value semantics in xwidgets is that C++ &lt;strong&gt;beginners&lt;/strong&gt; who are typical users of the Jupyter notebook (often used by instructors) can easily manipulate “widgets as values” without having to deal with manual memory allocation etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With value semantics, addressing the lifetime of objects becomes the responsibility of the framework author, in a carefull implementation of (copy and move) constructors, destructors, and (copy and move) assignment operators.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="static-polymorphism-and-the-crtp-pattern"&gt;Static polymorphism and the CRTP pattern&lt;/h2&gt;
&lt;p&gt;While the use of value semantics provides fine-grained control over the lifetime of widgets, it prevents the use of virtual methods in their implementation. Code reuse is achieved with static polymorphism techniques and specifically the CRTP pattern.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern"&gt;Curiously Recurring Template Pattern (CRTP)&lt;/a&gt; is the practice of making a class &lt;code&gt;X&lt;/code&gt; derive from a class template instantiation using &lt;code&gt;X&lt;/code&gt; itself as a template argument.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;X&lt;/span&gt; : &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="nb"&gt;base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;X&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;CRTP is commonly used by matrix or tensor algebra libraries making use of expression templates (such as&lt;/em&gt; &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;&lt;em&gt;xtensor&lt;/em&gt;&lt;/a&gt;, &lt;a href="http://eigen.tuxfamily.org/index.php?title=Main_Page"&gt;&lt;em&gt;eigen&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, or&lt;/em&gt; &lt;a href="https://github.com/blitzpp/blitz"&gt;&lt;em&gt;blitz&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) to prevent the overhead of virtual function dispatch for operations likely to be performed in a loop, such as element access.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Placing common code in a CRTP base allows code reuse without the overhead of virtual dispatch. However, the template base class is specialized for each final type increasing the resulting &lt;strong&gt;binary size&lt;/strong&gt;. This can be mitigated by factoring as much of the code in a base class that would not be templated by the derived type.&lt;/p&gt;
&lt;h2 id="crtp-in-xwidgets-closing-the-recursion"&gt;CRTP in xwidgets — closing the recursion&lt;/h2&gt;
&lt;p&gt;In order to allow for code reuse without virtual inheritance, xwidgets’ class hierarchy is entirely based on CRTP. Our naming scheme is that CRTP bases, which should not be instantiated directly are prefixed with the letter &lt;code&gt;x&lt;/code&gt; and final concrete widget types are not.&lt;/p&gt;
&lt;p&gt;Upon construction of &lt;em&gt;e.g.&lt;/em&gt; the &lt;strong&gt;&lt;code&gt;button&lt;/code&gt;&lt;/strong&gt; widget, constructors of base types are called in the order of inheritance, which is why we need to establish the connection with the frontend in the constructor of the most derived type, after all attributes have been initialized, and send a message to the frontend with all the values.&lt;/p&gt;
&lt;p&gt;The pattern for creating the most derived type being always the same, we defined the &lt;strong&gt;&lt;code&gt;xmaterialize&lt;/code&gt;&lt;/strong&gt; template class closing the CRTP hierarchy with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;using button = xmaterialize&amp;lt;xbutton&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;strong&gt;&lt;code&gt;xmaterialize&lt;/code&gt;&lt;/strong&gt; template class is defined as &lt;strong&gt;final&lt;/strong&gt;, to prevent further inheritance. The constructors and assignment operators forward to those of the CRTP bases and implement the RAII pattern.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;final&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="nx"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;...&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;self_type&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="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base_type&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="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;self_type&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;...&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="nx"&gt;base_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;//  RAII: create the frontend model.&lt;/span&gt;
&lt;span class="w"&gt;    &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;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&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;class&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;inline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xmaterialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;P&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::~&lt;/span&gt;&lt;span class="n"&gt;xmaterialize&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="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;moved_from&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;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// RAII: delete the frontend model.&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="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;/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;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The full implementation of &lt;strong&gt;&lt;code&gt;xmaterialize&lt;/code&gt;&lt;/strong&gt; (as of xwidgets 0.25) is available &lt;a href="https://raw.githubusercontent.com/jupyter-xeus/xwidgets/0.25.0/include/xwidgets/xmaterialize.hpp"&gt;here&lt;/a&gt;. Beyond the logic described in this section, it also includes the handling of the move semantics and the method chaining API which is the subject of a later section.&lt;/p&gt;
&lt;h2 id="precompilation-and-binary-size-optimization"&gt;&lt;strong&gt;Precompilation and binary size optimization&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Even though xwidgets is fully based on template types, we decided to precompile all final widget types for faster interactive use with the xeus-cling kernel. This is achieved with&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an &lt;strong&gt;&lt;code&gt;extern&lt;/code&gt;&lt;/strong&gt; declaration in the header (here in &lt;code&gt;xbutton.hpp&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;extern template class xmaterialize&amp;lt;xbutton&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;and in the source file (here in &lt;code&gt;xbutton.cpp&lt;/code&gt;), an instruction for the precompilation&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;template class XWIDGETS_API xmaterialize&amp;lt;xbutton&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Doing this for all widget types of the library initially resulted in a large compiled binary size. Using the &lt;strong&gt;&lt;code&gt;button&lt;/code&gt;&lt;/strong&gt; widget as an example, we see that base types are templated by the final type in the class hierarchy &lt;strong&gt;&lt;code&gt;button -&amp;gt; xbutton&amp;lt;button&amp;gt; -&amp;gt; xwidgets&amp;lt;button&amp;gt; -&amp;gt; xobject&amp;lt;button&amp;gt;&lt;/code&gt;&lt;/strong&gt;, and therefore, their binary representation is duplicated for each final type.&lt;/p&gt;
&lt;p&gt;A strategy for reducing the binary size has been to factor out as much of the logic of &lt;strong&gt;&lt;code&gt;xobject&amp;lt;D&amp;gt;&lt;/code&gt;&lt;/strong&gt; in a non-template base &lt;strong&gt;&lt;code&gt;xcommon&lt;/code&gt;&lt;/strong&gt; improving compilation speed and preventing binary code duplication.&lt;/p&gt;
&lt;h2 id="xproperty-an-implementation-of-the-observer-pattern"&gt;Xproperty: an implementation of the observer pattern&lt;/h2&gt;
&lt;p&gt;In order to update the frontend upon changes of widget properties, xwidgets relies on an implementation of the observer pattern called &lt;a href="https://github.com/jupyter-xeus/xproperty"&gt;&lt;strong&gt;&lt;code&gt;xproperty&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;. xproperty is to xwidgets what &lt;a href="https://github.com/ipython/traitlets"&gt;traitlets&lt;/a&gt; are to ipywidgets.&lt;/p&gt;
&lt;p&gt;In order to trigger observers and validators in the owner object upon assignment of new values, xproperty relies on the overload of the assignment operator &lt;strong&gt;&lt;code&gt;=&lt;/code&gt;&lt;/strong&gt;.&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;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;inline&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;xproperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reference&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Before assigning the new value, invoke validators&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// which may also mutate the value.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;m_value&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;owner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;invoke_validators&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_name&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="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&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="c1"&gt;// Call class-level observer.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;m_value&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="c1"&gt;// Call registered observers for that attribute&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;invoke_observers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m_name&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="c1"&gt;// Return the new value &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;m_value&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;h2 id="method-chaining-for-widget-initialization"&gt;Method chaining for widget initialization&lt;/h2&gt;
&lt;p&gt;Jupyter interactive widgets have many attributes that may be specified at construction time.&lt;/p&gt;
&lt;p&gt;In the Python implementation, this is handled with keyword arguments, but the C++ programming language does not support keyword arguments. There exist various approaches to enable this feature with advanced metaprogramming techniques. In the case of xwidgets, this need is limited to the initialization of xproperty attributes, which allowed us to adopt a more scoped approach: a method chaining API for property initialization:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;slider&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="no"&gt;slider&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;double&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="no"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;.min&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="no"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;.max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="no"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;.description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Another slider&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="na"&gt;.finalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;this was enabled by overriding the function call operator () on xproperties to pass an intial value (only when the said property is an rvalue). A static &lt;strong&gt;&lt;code&gt;initialize&lt;/code&gt;&lt;/strong&gt; method is used instead of the default constructor to prevent the initialization of the JavaScript counterpart while all attributes may not have been set yet. The frontend counterpart is only acquired with the &lt;strong&gt;&lt;code&gt;finalize()&lt;/code&gt;&lt;/strong&gt; call.&lt;/p&gt;
&lt;h2 id="building-upon-xwidgets"&gt;Building upon xwidgets&lt;/h2&gt;
&lt;p&gt;Jupyter interactive widgets are not limited to the controls available in the core package. In fact, there is a rich ecosystem of widget libraries built upon the core framework: &lt;a href="https://github.com/maartenbreddels/ipyvolume"&gt;ipyvolume&lt;/a&gt; (3-D plotting), &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; (maps visualization), &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; (2-D plotting), &lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt; (3-D mesh visualization), &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt; (generic drawing), &lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt; (streaming video and audio), and many many more.&lt;/p&gt;
&lt;p&gt;For the C++ programming language, we have already provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xleaflet"&gt;xleaflet&lt;/a&gt; (the C++ equivalent to ipyleaflet, reusing the same frontend),&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xwebrtc"&gt;xwebrtc&lt;/a&gt; (the C++ equivalent to ipywebrtc, reusing the same frontend).&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Screencast of xleaflet in JupyterLab, loading and visualizing a GeoJSON dataset in a C++ notebook." src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/images/004-1_IULQ8LZDnLFMmB1nsbNF0Q.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Screencast of xleaflet in JupyterLab, loading and visualizing a GeoJSON dataset in a C++ notebook.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Potentially, C++ backend to all Jupyter interactive widget packages could be provided, creating a huge opportunity for interactive data visualization in C++.&lt;/p&gt;
&lt;h2 id="c-should-allow-overloading-the-dot-operator"&gt;&lt;strong&gt;C++ should allow overloading the dot operator&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;xwidgets&lt;/strong&gt; and &lt;strong&gt;xproperty&lt;/strong&gt; makes heavy use of value semantics, and proxy objects.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At the moment, to access an attribute or method of a value held in an xproperty object, we must first call the function call operator () to access the undelying object first, which is cumbersome.&lt;/li&gt;
&lt;li&gt;This is also an issue in other places in the xwidgets stack, when making use of &lt;em&gt;e.g.&lt;/em&gt; reference proxies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Being able to automatically map all methods of the underlying type to be accessible in the xproperty would be incredibly powerful, and remove the need for explicitly accessing the underlying.&lt;/p&gt;
&lt;p&gt;Interestingly, the C++ standard does have the equivalent operator overload when it comes to pointer semantics, with the arrow operator &lt;strong&gt;&lt;code&gt;-&amp;gt;&lt;/code&gt;&lt;/strong&gt;. If overloading the dot operator . was allowed, this could enable this kind of usecase:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;struct V
{
    void f();
};

struct X
{
    V&amp;amp; operator.() { return m_value; }
    V m_value;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;in which case, &lt;strong&gt;&lt;code&gt;X::f&lt;/code&gt;&lt;/strong&gt; would call &lt;strong&gt;&lt;code&gt;V::f&lt;/code&gt;&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;Allowing the overloading of the dot operator . would also enable usecases such as &lt;strong&gt;smart references&lt;/strong&gt; (similar to smart pointers, but with value semantics) and fully-fledged &lt;strong&gt;reference proxies&lt;/strong&gt; (such as the return type of &lt;code&gt;operator[]&lt;/code&gt; for &lt;code&gt;std::vector&amp;lt;bool&amp;gt;&lt;/code&gt;).&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 xwidgets 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/xwidgets/stable?filepath=notebooks/xwidgets.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/a-curiously-recurring-widget-library/images/005-0_TQpdhVZSAnE-XOrm.jpg" alt="&amp;quot;Launch binder&amp;quot; badge" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt; is the founder and CEO of &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;, an open-source software development studio comprising maintainers of key projects of the scientific computing ecosystem.&lt;/p&gt;
&lt;p&gt;As an open-source developer, Sylvain is very active in the Jupyter project, contributing to the &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; stack, Jupyter interactive widgets, &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà dashboards&lt;/a&gt;. He is a member of the Jupyter steering committee and was the vice chair of &lt;a href="https://jupytercon.com/"&gt;JupyterCon 2020&lt;/a&gt;. Sylvain also contributes to the &lt;a href="https://conda-forge.org/"&gt;conda-forge&lt;/a&gt; project and he is the co-creator of the &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;Xtensor&lt;/a&gt; C++ tensor algebra library.&lt;/p&gt;
</content><category term="C++"/><category term="widgets"/></entry><entry><title>A C++ API for Vega-Lite</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/" rel="alternate"/><published>2020-12-02T15:27:00+00:00</published><updated>2020-12-03T14:23:00+00:00</updated><author><name>Madhur Tandon</name></author><id>tag:jasongrout.github.io,2020-12-02:/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/</id><summary type="html">&lt;p&gt;In this post, we present the first public release of XVega, a C++ library for producing vega-lite charts.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;In this post, we present the first public release of XVega, a C++ library for producing Vega-Lite charts.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Data science workflows differ from traditional software development in that engineers make use of available tools to &lt;em&gt;explore&lt;/em&gt; and &lt;em&gt;reason&lt;/em&gt; about a problem. In such exploratory work, engineers load data, crunch numbers, produce simple visualizations and &lt;em&gt;iterate…&lt;/em&gt; Progress happens in quick incremental iterations, which is possible when tooling does not get in the way.&lt;/p&gt;
&lt;p&gt;This kind of interactive computing is generally associated with the Python or R programming languages. However, with the advent of the &lt;a href="https://github.com/root-project/cling/"&gt;&lt;strong&gt;Cling&lt;/strong&gt;&lt;/a&gt; C++ interpreter from &lt;a href="https://home.cern/"&gt;CERN&lt;/a&gt;, and the subsequent development of the &lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;&lt;strong&gt;xeus-cling&lt;/strong&gt;&lt;/a&gt; Jupyter kernel, new possibilities have opened up in this space.&lt;/p&gt;
&lt;p&gt;The Jupyter stack — that started in the scientific Python community has evolved into a language-agnostic framework that can now be leveraged by C++ developers. It bridges the gap between the countless scientific computing libraries and tools available in C++ and the Jupyter ecosystem.&lt;/p&gt;
&lt;p&gt;The scientific C++ stack now has numerous projects under its belt — such as &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;xtensor&lt;/a&gt;, &lt;a href="https://github.com/xtensor-stack/xframe"&gt;xframe&lt;/a&gt;, etc. However, there is little support for visualization — especially for interactive plots. While there exist &lt;a href="https://github.com/lava/matplotlib-cpp"&gt;matplotlib-cpp&lt;/a&gt; and &lt;a href="https://github.com/alandefreitas/matplotplusplus"&gt;matplotplusplus&lt;/a&gt; (with their plotting API resembling the original &lt;a href="https://github.com/matplotlib/matplotlib"&gt;matplotlib&lt;/a&gt; library) — they suffer from the same cons as the original library does (such as the imperative API and the confusion between dual object-oriented and state-based interface).&lt;/p&gt;
&lt;p&gt;Owing to all these shortcomings, along with the observation that JupyterLab comes with existing support for Vega and Vega-Lite Charts (through the &lt;a href="https://jupyterlab.readthedocs.io/en/stable/user/file_formats.html#vega-vega-lite"&gt;&lt;code&gt;application/vnd.vegalite.v3+json&lt;/code&gt;&lt;/a&gt; MIME type), one can leverage this support to bridge the gap rather than reinvent the wheel. Apart from standalone use — one could also integrate such a system into other projects such as &lt;a href="https://github.com/jupyter-xeus/xeus-sqlite"&gt;xeus-SQLite&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main idea is to programmatically fill in a JSON that conforms to the Vega-Lite specification and respects the notion of grammar of graphics. It is analogous to what &lt;a href="https://github.com/altair-viz/altair"&gt;Altair&lt;/a&gt; did for Python. We will expose different APIs responsible for filling in certain parts of the JSON.&lt;/p&gt;
&lt;p&gt;The fundamentals with XVega are still the same, i.e. the three essential elements of a &lt;em&gt;Chart&lt;/em&gt; are &lt;em&gt;Data, Marks and Encodings&lt;/em&gt; as usual and importing the library is as simple as writing two statements:&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;xvega/xvega.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="n"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;xv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The experience is similar to what Altair offers and, hence, the central piece to the library is the &lt;em&gt;&lt;strong&gt;Chart()&lt;/strong&gt;&lt;/em&gt; object — which knows how to emit the JSON dictionary representing the data and visualization encodings.&lt;/p&gt;
&lt;p&gt;For those unfamiliar with the Vega ecosystem, a quick recap for the above terms is given below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Marks&lt;/strong&gt;&lt;/em&gt; — What graphic should represent the data?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Encodings&lt;/strong&gt;&lt;/em&gt; — Mapping between Data and Visual Elements of the Chart (such as x-axis, etc.).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Encoding Types&lt;/strong&gt;&lt;/em&gt;: &lt;em&gt;&lt;strong&gt;Quantitative&lt;/strong&gt;&lt;/em&gt; (real-valued), &lt;em&gt;&lt;strong&gt;Nominal&lt;/strong&gt;&lt;/em&gt; (unordered categorical), &lt;em&gt;&lt;strong&gt;Ordinal&lt;/strong&gt;&lt;/em&gt; (ordered categorical), &lt;em&gt;&lt;strong&gt;Temporal&lt;/strong&gt;&lt;/em&gt; (time-series).&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Basic usage of XVega showcasing the essential elements — Data, Marks and Encodings." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/001-1_GCkpVPeF-s7-64hNzyOcjg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Basic usage of XVega showcasing the essential elements — Data, Marks and Encodings.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The core strength of using such a system is the separation of specification and execution. The declarative API makes it easy to specify “&lt;em&gt;&lt;strong&gt;what&lt;/strong&gt;&lt;/em&gt;” should be done rather than focus on incidental details of the “&lt;em&gt;&lt;strong&gt;how&lt;/strong&gt;&lt;/em&gt;”. It means that rather than having a special “&lt;em&gt;&lt;strong&gt;hist()&lt;/strong&gt;&lt;/em&gt;” function for plotting a histogram, passing “&lt;em&gt;&lt;strong&gt;bin=True&lt;/strong&gt;&lt;/em&gt;” does the job.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simply stating bin=True bins the x-axis giving us the Histogram directly — without using a dedicated function." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/002-1_t3w0G2XCiNBw3VajHbGiCw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simply stating &lt;strong&gt;bin=True&lt;/strong&gt; bins the x-axis giving us the Histogram directly — without using a dedicated function.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We can of-course customize the binning parameters with a “&lt;em&gt;&lt;strong&gt;Bin()&lt;/strong&gt;&lt;/em&gt;” object instead. And while we are doing that, let’s add a colour encoding as well to get a sense of the 3rd dimension.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="More control can be achieved using a custom Bin() object — used to set the binning parameters." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/003-1_UkIPGquufhYT7-S62MTECg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;More control can be achieved using a custom &lt;strong&gt;Bin()&lt;/strong&gt; object — used to set the binning parameters.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another plus of using Vega-Lite is the possibility of using transformations within the specification rather than doing it before.&lt;br&gt;
(E.g., one can do linear regression as a part of this declarative API).&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Usage of layering and transformations in XVega." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/004-1_2jpd8rcTdgnLq8fBwL0XXA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Usage of layering and transformations in XVega.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Lastly, support for &lt;em&gt;&lt;strong&gt;Interactions&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;Selections&lt;/strong&gt;&lt;/em&gt; is a no-brainer. It’s as simple as defining what to use and adding it to the &lt;em&gt;&lt;strong&gt;Chart()&lt;/strong&gt;&lt;/em&gt; object.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Zooming and Panning along with Tooltips using Interval Selection in XVega" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/005-1_AQTFHOwHXS3uJUC6WKR6WA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Zooming and Panning along with Tooltips using Interval Selection in XVega&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;p&gt;Developing such a system for C++ comes with its own challenges and to provide a seamless experience like &lt;em&gt;Altair&lt;/em&gt;, several things are needed to be taken care of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiple types for a single entity:&lt;/strong&gt; the Vega-Lite specification allows variables of different kinds (such as a boolean type and an integer type may be equally valid for a particular property). &lt;em&gt;&lt;strong&gt;Variants&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;Visitors&lt;/strong&gt;&lt;/em&gt; in C++ allow us to achieve this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Out of order keyword arguments:&lt;/strong&gt; Method chaining is the classical approach to tackle out-of-order keyword arguments in C++ and is what is used in &lt;em&gt;&lt;strong&gt;XVega&lt;/strong&gt;&lt;/em&gt; indeed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optional fields:&lt;/strong&gt; A lot of values in the Vega-Lite specification are optional, and this is made possible by the optionally contained values in C++ (i.e. using &lt;em&gt;std::optional&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="installation"&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;You can install XVega with conda or &lt;a href="https://github.com/mamba-org/mamba"&gt;mamba&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install -c conda-forge xvega
&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 -c conda-forge xvega
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3 id="what-is-coming"&gt;What is coming?&lt;/h3&gt;
&lt;p&gt;XVega is still at an early stage and under active development. We are currently working on integrating it with the &lt;a href="https://github.com/jupyter-xeus/xeus-sqlite"&gt;xeus-sqlite&lt;/a&gt; and other SQL Jupyter kernels to enable the visualization from SQL queries. We are also working on improving the compilation time of XVega with Cling.&lt;/p&gt;
&lt;h3 id="acknowledgements"&gt;Acknowledgements&lt;/h3&gt;
&lt;p&gt;This work on XVega was funded by &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;. Thanks to &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt; and &lt;a href="https://twitter.com/JohanMabille"&gt;Johan Mabille&lt;/a&gt; for their continuous support.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;It is an exciting time for the interactive C++ ecosystem, as so much innovation is happening in the Cling and Jupyter projects. There is a lot more to come for sure. If you are interested in helping us build that future, come talk to us at &lt;a href="https://gitter.im/QuantStack/Lobby"&gt;Gitter&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="about-the-author"&gt;About the Author&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/006-1_smY4K4tEKudPztWWxpBNvw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/mad_tandon"&gt;Madhur Tandon&lt;/a&gt;, and I currently work with &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; as a Scientific Software Engineer. Before joining QuantStack, I have worked with &lt;a href="https://github.com/iodide-project/pyodide"&gt;Mozilla&lt;/a&gt;, &lt;a href="https://www.deepnote.com/"&gt;Deepnote&lt;/a&gt;, &lt;a href="https://github.com/BIDS-Apps/rsHRF"&gt;INCF&lt;/a&gt; (International Neuroinformatics Coordinating Facility), &lt;a href="https://www.tcs.com/tcs-research"&gt;TCS Research&lt;/a&gt; and &lt;a href="https://elucidata.io/"&gt;Elucidata&lt;/a&gt;. I have also been a speaker at JupyterCon 2020 and PyData Delhi 2017 and 2018. I graduated from &lt;a href="https://iiitd.ac.in/"&gt;IIIT-Delhi&lt;/a&gt; this year with a Bachelor’s degree in Computer Science with Honors. Besides core Data Science and Machine Learning, I am interested in tools that enable and enhance data scientists’ workflow and experience.&lt;/p&gt;
</content><category term="C++"/><category term="visualization"/></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>Field Report on the Kernel Community Workshop</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/" rel="alternate"/><published>2019-10-07T13:24:00+00:00</published><updated>2019-10-16T14:53:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jasongrout.github.io,2019-10-07:/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/</id><summary type="html">&lt;p&gt;From May 27th to May 29th, thirty developers from the Jupyter community met in Paris for a three-days workshop on the Jupyter kernel…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;From May 27th to May 29th 2019, thirty developers from the Jupyter community met in Paris for a three-days workshop on the Jupyter kernel protocol.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Attendees to the Jupyter Community Workshop on Kernels" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/images/001-1_AKYqXS6qtE0k6EcTKl3BEQ.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Attendees to the Jupyter Community Workshop on Kernels&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For three days, attendees worked full time on the Jupyter project, including hacking sessions and discussions on improvements to Jupyter protocols and standards.&lt;/p&gt;
&lt;p&gt;We were lucky to count five core developers to the project and several more regular contributors to the larger ecosystem in the group!&lt;/p&gt;
&lt;p&gt;Beyond the hacking sessions, each day was concluded with a series of presentations and demos of the progress made during the workshop.&lt;/p&gt;
&lt;h2 id="why-a-workshop-on-jupyter-kernels"&gt;Why a workshop on Jupyter kernels?&lt;/h2&gt;
&lt;p&gt;The Jupyter Kernel protocol is one of the main extension points of the Jupyter ecosystem. Dozen of language kernels have been developed by the community, and these languages can then leverage the other components of the stack, such as the notebook, the console, and interactive widgets.&lt;/p&gt;
&lt;p&gt;One of the objectives of this event was to foster collaboration between kernel developers and core contributors and develop common tools used across all language kernels. Another goal was to work improving the protocol, to support visual debugging, parameterized kernels, etc.&lt;/p&gt;
&lt;h2 id="technical-achievements"&gt;Technical Achievements&lt;/h2&gt;
&lt;p&gt;A lot of work was done during the workshop. Several people were working on new Jupyter kernels for programming languages.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We were amazed to see how much was achieved in just three days. Today, we are still working on projects that stemmed from this community workshop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="jupyterlab-debugger"&gt;JupyterLab Debugger&lt;/h3&gt;
&lt;p&gt;One area in which the Jupyter team is actively working is support for &lt;strong&gt;visual debugging in JupyterLab&lt;/strong&gt;. This is a major endeavor spanning from the front-end to the back-end, including changes to the Jupyter protocol.&lt;/p&gt;
&lt;p&gt;The kernel workshop was the occasion for several developers (&lt;a href="https://twitter.com/wuoulf"&gt;Wolf Vollprecht&lt;/a&gt;, &lt;a href="https://twitter.com/maartenbreddels"&gt;Maarten Breddels&lt;/a&gt;, &lt;a href="https://twitter.com/johanmabille"&gt;Johan Mabille&lt;/a&gt;, &lt;a href="https://twitter.com/lgouarin"&gt;Loic Gouarin&lt;/a&gt;) to get together and hack on the implementation of the frontend. A lot of work had been done ahead of the workshop with &lt;a href="https://github.com/QuantStack/xeus-python"&gt;a new Python kernel&lt;/a&gt; based on the &lt;a href="https://github.com/QuantStack/xeus/"&gt;Xeus&lt;/a&gt; library. This new kernel includes a backend to the &lt;strong&gt;Debug Adapter Protocol&lt;/strong&gt; over kernel messages.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The JupyterLab Visual Debugger" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/images/002-1_O0nYHhfEne2BH4XsknaPhg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLab Visual Debugger&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;There are other key contributors to the debugger project who did not attend the community workshop. We should mention &lt;a href="https://twitter.com/jtpio"&gt;Jeremy Tuloup&lt;/a&gt; and &lt;a href="https://twitter.com/micronova"&gt;Afshin Darian&lt;/a&gt; who are spearheading the frontend development.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="a-calculator-jupyter-kernel-based-on-xeus"&gt;A Calculator Jupyter Kernel based on xeus&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://twitter.com/VasavanT"&gt;Vasavan Thirusittampalam&lt;/a&gt; and &lt;a href="https://twitter.com/ThLacharme"&gt;Thibault Lacharme&lt;/a&gt; were in the middle of their summer internships as scientific software developers at QuantStack when they attended the workshop. During the event, they set themselves up to implement a new Jupyter kernel in C++!&lt;/p&gt;
&lt;p&gt;At the end of the workshop, they were able to demonstrate a functional &lt;strong&gt;calculator kernel&lt;/strong&gt; based on &lt;a href="https://github.com/QuantStack/xeus/"&gt;xeus&lt;/a&gt;, a C++ implementation of the Jupyter protocol! This was later polished and resulted in the publication of a blog post on the Jupyter blog: “&lt;a href="/posts/2019/building-a-calculator-jupyter-kernel/"&gt;&lt;em&gt;&lt;strong&gt;Building a Calculator Jupyter Kernel&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;”. This example may serve as an example for people interested in creating new language kernels with xeus.&lt;/p&gt;
&lt;h3 id="a-prototype-julia-backend-to-jupyter-interactive-widgets"&gt;&lt;strong&gt;A prototype Julia backend to Jupyter interactive Widgets.&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;During the workshop &lt;a href="https://twitter.com/SebasGuts"&gt;Sebastian Gutsche&lt;/a&gt; (who is the author of the &lt;a href="https://github.com/sebasguts/jupyter_kernel_singular"&gt;Singular&lt;/a&gt; Jupyter kernel and a co-author of the &lt;a href="https://github.com/gap-packages/JupyterKernel"&gt;GAP&lt;/a&gt; kernel), set himself to develop a backend to Jupyter interactive widgets for the &lt;strong&gt;Julia&lt;/strong&gt; progamming language. The current state of the code can be found &lt;a href="https://github.com/sebasguts/iwidgets"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Julia backend to jupyter widgets is still early-stage but should this project be completed, it would enable other Jupyter widget libraries for the users of the Julia Jupyter kernel, such as ipyvolume, ipyleaflet, bqplot, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="The Julia backend to Jupyter widgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/images/003-1_xv77xrNuUHKLjLinum0dlQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The Julia backend to Jupyter widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="parameterized-kernelspecs"&gt;Parameterized Kernelspecs&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://twitter.com/ivanov"&gt;Paul Ivanov&lt;/a&gt; and &lt;a href="https://twitter.com/rgbkrk"&gt;Kyle Kelley&lt;/a&gt; worked on ironing out the proposal for the support of &lt;strong&gt;parameterized kernelspecs&lt;/strong&gt;. The objective is to make it possible to pass user-specified arguments to kernels upon launch.&lt;/p&gt;
&lt;p&gt;In the proposal, the parameters expected by the kernel executable and the possible values for these parameters may be specified in the kernelspec file or a companion file to the kernelspec in the form of a JSON schema.&lt;/p&gt;
&lt;p&gt;Paul and Kyle produced extensive notes on various aspects on the subjects such as&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the storing of previously used values of the parameters (in notebooks)&lt;/li&gt;
&lt;li&gt;the web UI design on how to specify parameters&lt;/li&gt;
&lt;li&gt;the definition of default values&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More details will be shared at a later stage on the subject of parameterized kernelspecs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: the subject of parameterized kernelspecs was also central in the earlier community workshop about the Jupyter server organized at IBM by Luciano Resende.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="forking-of-jupyter-kernels"&gt;Forking of Jupyter Kernels&lt;/h3&gt;
&lt;p&gt;Starting of kernels is an expensive operation, and executing a whole notebook even more. For certain use cases (such as dashboards based on &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà&lt;/a&gt;), it is useful to have a pre-executed notebook ready, so that dashboards can be presented instantly to a user. To enable this, &lt;a href="https://twitter.com/maartenbreddels"&gt;Maarten Breddels&lt;/a&gt; came up with the idea of forking kernels and put together a proof-of-concept implementation. The implementation can be found in pull requests to &lt;code&gt;jupyter_client&lt;/code&gt; (&lt;a href="https://github.com/jupyter/jupyter_client/pull/441"&gt;PR #441&lt;/a&gt;) and &lt;code&gt;ipykernel&lt;/code&gt; (&lt;a href="https://github.com/ipython/ipykernel/pull/410"&gt;PR #410&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Forking kernels will also allow interesting features such as an undo/rollback of cell execution in the notebook. While it is still a proof of concept, this subject has already sparked interest in the community.&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This event would not have been possible without the generous support provided by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;, who made this workshop series possible&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;a href="https://www.cfm.fr/"&gt;&lt;strong&gt;CFM&lt;/strong&gt;&lt;/a&gt; for gracefully hosting the event.&lt;/p&gt;
&lt;p&gt;We should also thank &lt;a href="https://twitter.com/ruv7?lang=en"&gt;&lt;strong&gt;Ana Ruvalcaba&lt;/strong&gt;&lt;/a&gt; from Project Jupyter for her incredible work on the logistics and finances of the Jupyter Community Workshop series.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/images/004-1_ZWbPC-X8_5rIU_kP03ztog.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="C++"/><category term="events"/><category term="kernels"/><category term="workshops"/></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><entry><title>A new Python kernel for Jupyter</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/" rel="alternate"/><published>2019-01-09T09:16:00+00:00</published><updated>2019-09-30T07:04:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jasongrout.github.io,2019-01-09:/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/</id><summary type="html">&lt;p&gt;Project Jupyter aims at providing a consistent set of tools for interactive computing workflows across multiple programming languages…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Project Jupyter aims at providing a consistent set of tools for interactive computing workflows across multiple programming languages. Jupyter projects are popular at all stages of a research project from the exploration phase to the communication of results and teaching.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/001-1_ySP_XtCM_MMBawtlOOixag.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;br&gt;
&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/002-1_u5Y0cs48UCc5bmGXP2rTIA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The flagship project of Jupyter, the Notebook, and its modernized version, JupyterLab are web applications allowing the creation of documents including prose, executable code, and interactive visualizations.&lt;/p&gt;
&lt;p&gt;The kernel is the part of the backend responsible for executing code written by the user in the web application. For example, in the case of a Python notebook, execution of the code is typically handled by &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt;, the reference implementation.&lt;/p&gt;
&lt;h2 id="history"&gt;History&lt;/h2&gt;
&lt;p&gt;Initially, the &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; project included everything from the notebook web application to the kernel and server implementation. Later on, the language-agnostic parts (the notebook format, messaging protocol, qtconsole, notebook web application) were split into separate projects with a clearer scope, together forming &lt;em&gt;Project Jupyter&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The Big Split(TM) of IPython" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/003-1_PlpiXwbaiHo8VtTqcFyzGA.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The Big Split(TM) of IPython&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Splitting &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; into multiple packages was a good decision in that it brought a clear separation of concerns between the projects. The &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; project was elected as the reference implementation of the Jupyter kernel protocol.&lt;/p&gt;
&lt;p&gt;This came at a cost since &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; brought all the history and technical debt of &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; with it. Besides, Python is not a natural language for a base implementation. As a result, R and Julia kernels don’t use the reference implementation but use their own implementation of the protocol.&lt;/p&gt;
&lt;p&gt;Furthermore, the standard implementation of the Jupyter Interactive Widgets lies in the Python package &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt;. That means that once you, as a kernel developer, implemented the Jupyter kernel protocol, you would still need to make your own backend for the interactive widgets if you want widgets support (and you should want it, honestly…).&lt;/p&gt;
&lt;p&gt;To prevent this useless duplication of effort, which harms sustainability, we set ourselves to implement a solid reusable implementation of the Jupyter kernel protocol, &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="c-implementation-of-the-kernel-protocol"&gt;C++ implementation of the kernel protocol&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/004-1_OWq9aDu1wOvYig3AalBvFg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is a C++ implementation of the Jupyter kernel protocol. It is not a kernel by itself but a library that helps kernel authoring. &lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is very helpful when developing a kernel for a language that has a C or a C++API (Python, Lua, SQL, etc.). It takes the cumbersome task of implementing the &lt;a href="https://jupyter-client.readthedocs.io/en/stable/messaging.html"&gt;Jupyter messaging protocol&lt;/a&gt; for you so you just can focus on the core interpreter tasks: executing code, inspecting, completing, etc.&lt;/p&gt;
&lt;p&gt;C++ is a good choice for a standard implementation of the protocol, it is a common denominator of most of the languages out there, it has a massive developer community and is widely adopted in the industry for performance middleware applications.&lt;/p&gt;
&lt;p&gt;With &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;, it is also very easy to reimplement core logic (server, kernel, history management etc.), if need be, by simply inheriting from &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; library classes.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is already known for being used as a base for the C++ kernel &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="a-xeus-based-c-kernel"&gt;A xeus-based C++ Kernel&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/005-1_vrE1i_8405140XOHfx77LA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus-cling"&gt;Xeus-cling&lt;/a&gt; is a &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;-based C++ kernel for the Jupyter Notebook. It’s very useful for teaching or learning C++. C++ has never been this interactive, thanks to the combined power of Jupyter, &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;, and &lt;a href="https://github.com/root-project/cling"&gt;cling&lt;/a&gt;. And even more impressive than executing interpreted C++, it supports interactive widgets, thanks to the &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt; project.&lt;/p&gt;
&lt;p&gt;Just like &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; is a C++ implementation of the Jupyter kernel protocol, &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt; is a C++ implementation of the Jupyter Interactive Widgets protocol, and it can be used as a base for other implementations.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/006-1_kA8toRCXwwnPmrsSIT7vhw.webp" alt="" loading="lazy" data-body-image=""&gt;&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/QuantStack/xeus-cling/stable?filepath=notebooks/xcpp.ipynb"&gt;&lt;strong&gt;this link&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Interactive C++ in the Jupyter Notebook" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/007-1_OJYy6QP8HSEPUQHhyyCOcQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Interactive C++ in the Jupyter Notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="a-xeus-based-python-kernel"&gt;A xeus-based Python kernel&lt;/h2&gt;
&lt;p&gt;Today, I am pleased to announce a new Python kernel based on &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;: &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/008-1_YIXmS4xfX9MxQ6dHZLU8-g.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus-python"&gt;Xeus-python&lt;/a&gt; supports error formatting, rich display, interactive widgets, input requests, code completion, code inspection, etc.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; and &lt;a href="https://github.com/pybind/pybind11"&gt;pybind11&lt;/a&gt;, it was very straightforward to have a first simple version of a Python kernel written in C++. It took a couple of months to have the features listed above, with a relatively small amount of code (&amp;lt; 3000 lines of C++) and a good coverage of &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt;’s features.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simple code execution" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/009-1_2hHrN4ucrKKv68BJU9hRXQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simple code execution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Error formatting" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/010-1_ewhjr2dkosifi7Qky1A83g.gif" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Error formatting&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Code completion" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/011-1_LgaJ9RcNs0YZK7qaySX4NQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Code completion&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Ipywidgets support" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/012-1_3XxIdWaB7HRmRDY_PzOGaQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Ipywidgets support&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Just like with &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt;, you can try it online without the need of installing anything on your computer following &lt;a href="https://mybinder.org/v2/gh/QuantStack/xeus-python/stable?filepath=notebooks/xeus-python.ipynb"&gt;&lt;strong&gt;this link&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="why-another-python-kernel"&gt;Why another Python kernel?&lt;/h2&gt;
&lt;p&gt;Obviously, &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt; does not cover 100% of the features of &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt;. For examples, &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; magics are not supported yet by &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt;. However:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt; is a lot lighter than &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; and &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; combined, which makes it a lot easier to implement new features on top of it. Our next goal is to augment the protocol to implement a Python debugger in JupyterLab.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;-based kernels are more versatile in that one can overload e.g. the concurrency model. This is something that &lt;a href="https://www.kitware.com/"&gt;Kitware&lt;/a&gt;’s &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt; project takes advantage of to integrate with the Qt event loop of their Qt-based desktop application.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;The development of &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt;, and related packages are led by &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://quantstack.net/"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/a-new-python-kernel-for-jupyter/images/013-1_1YuyD-AQ0fzVOStuxhChWw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This development is sponsored 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;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, he studied at the French Aerospace Engineering School &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt;. He also worked at Logilab in Paris and Enthought in Cambridge. As an open source developer at &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, Martin worked on a variety of projects, from &lt;a href="https://github.com/QuantStack/xsimd"&gt;xsimd&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt;, and &lt;a href="https://github.com/QuantStack/xframe"&gt;xframe&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/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt; in Python and JavaScript.&lt;/p&gt;
</content><category term="C++"/><category term="kernels"/></entry><entry><title>Interpreted C++ for GIS with Jupyter</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/" rel="alternate"/><published>2018-04-24T08:35:00+00:00</published><updated>2019-09-30T07:04:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jasongrout.github.io,2018-04-24:/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/</id><summary type="html">&lt;p&gt;The recent release of the Jupyter kernel for C++, based on the Cling interpreter enabled a number of new workflows for the users of the C++…&lt;/p&gt;
</summary><content type="html">&lt;figure&gt;
&lt;img alt="A live interactive map in a C++ Jupyter notebook" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/001-1_FzUw4j635uJgWHZzc8_QiQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A live interactive map in a C++ Jupyter notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href="/posts/2017/interactive-workflows-for-c-with-jupyter/"&gt;recent release&lt;/a&gt; of the Jupyter kernel for C++, based on the Cling interpreter enabled a number of new workflows for the users of the C++ programming language.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/002-1_vrE1i_8405140XOHfx77LA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Features of the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; C++ kernel for Project Jupyter include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Showing quick-help pages for functions and classes of the STL and user-defined types, by prefixing them with a question mark:&lt;/em&gt;&lt;br&gt;
For example, typing &lt;code&gt;?std::vector&lt;/code&gt; results in a pager displaying the page from &lt;a href="http://en.cppreference.com/w/"&gt;cppreference&lt;/a&gt; on &lt;code&gt;std::vector&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Quick-help page for classes and functions of the STL" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/003-1_B77yBeBtyeIs3CqA2jlxKg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Quick-help page for classes and functions of the STL&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Making use of the rich display features of the Jupyter stack, for user-defined types.&lt;/em&gt;&lt;br&gt;
This can be enabled simply by overloading &lt;code&gt;mime_bundle_repr&lt;/code&gt; in the namespace of the class for which we wish to have a rich representation in the front-end. The overload is picked up by the display system through argument-dependent lookup (ADL).&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Using Jupyter’s rich display mechanism in C++" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/004-1_GZkL0WWGqeuBDrs-INUkgg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using Jupyter’s rich display mechanism in C++&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Another aspect of the newly released C++ kernel is the implementation of the Jupyter widgets protocol, enabling bi-directional communication between the front-end and the kernel.&lt;/em&gt;The &lt;a href="https://github.com/QuantStack/xwidgets/"&gt;xwidgets&lt;/a&gt; package, built upon xeus provides a complete implementation of the protocol, together with the implementation of most of the controls available in the reference &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt; Python package.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Bidirectional communication with the front-end using Jupyter interactive widgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/005-1_GDwfwdQyqprIcHbXCCkDhA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Bidirectional communication with the front-end using Jupyter interactive widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More than a limited set of base controls, Jupyter widgets are a framework upon which one can build arbitrarily complex interactions. A large number of interactive widget libraries has been built upon ipywidgets. Popular examples include &lt;a href="https://github.com/jupyter-widgets/pythreejs"&gt;pythreejs&lt;/a&gt; (a Jupyter-threejs bridge), &lt;a href="https://github.com/bloomberg/bqplot"&gt;bqplot&lt;/a&gt; (an interactive plotting library for Jupyter), and &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; (a Jupyter-leafletjs bridge) allowing rich interactive maps in the Jupyter notebook.&lt;/p&gt;
&lt;p&gt;A common trait of most of these packages is that most of the logic is implemented in the front-end, while the back-end only involves synchronization of data attributes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A fully-specified communication protocol and a thin back-end architecture facilitate the job of kernel authors willing to bring the power of these visualization libraries to their language of choice.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hence, we have taken on the endeavor of providing a C++ implementation of the most popular Jupyter interactive widget libraries. These packages can be used in the C++ kernel, as well as in compiled application making use of the Jupyter kernel protocol.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/006-1_U88dDupn4NP1MVVvE30Twg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Today, we are proud to announce the first release of &lt;code&gt;xleaflet&lt;/code&gt;, the C++ counterpart to the popular &lt;code&gt;ipyleaflet&lt;/code&gt; package, and which makes use of the same front-end component.&lt;/p&gt;
&lt;p&gt;You can get started by simply creating a map inline in the Jupyter notebook.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Specifying a center location and zoom level&lt;/li&gt;
&lt;li&gt;Specifying the tile layers to be displayed among the predefined base maps&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="A simple map with a specified center and zoom level, displaying the default tiles" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/007-1_BcnHhEfFYFPgBdQ6eyeKrA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A simple map with a specified center and zoom level, displaying the default tiles&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A number of other attributes can be set in the map widget. To mimic named parameters, all widgets of &lt;code&gt;xwidgets&lt;/code&gt; and &lt;code&gt;xleaflet&lt;/code&gt; are provided with a generator class which can be used to initialize attributes using method-chaining syntax.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Making use of the generator class to specify any number of attributes of the map upon construction" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/001-1_FzUw4j635uJgWHZzc8_QiQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Making use of the generator class to specify any number of attributes of the map upon construction&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to the base map feature, a broad number of features of the leaflet JavaScript library are exposed to the C++ backend directly. This includes markers, marker clusters, image overlays, a variety of controls.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using the marker widget" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/008-1_BA8-dMRaOf4ikrYqBLnIjA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the marker widget&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Whenever an attribute of a widget is modified in the front-end or in the back-end, the other side will properly reflect the data change.&lt;/p&gt;
&lt;p&gt;For example, setting &lt;code&gt;marker.location&lt;/code&gt; to a new value in the previous example will actually move the marker on the map. Reversely, if the &lt;code&gt;draggable&lt;/code&gt; attribute was set to &lt;code&gt;true&lt;/code&gt;, whenever the marker position changes in the front-end, the value is reflected in the C++ model.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Observer on the marker position" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/009-1_Acd0sgShjoe40M-Ust-aKQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Observer on the marker position&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another example is the support of the GeoJSON format, which allows one to load a JSON file locally and display its content on the map.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Support for the GeoJSON format" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/010-1_ok5lH9V9NUwxMy-I5sey8A.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Support for the GeoJSON format&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;The bidirectional communication between the front-end and the C++ back-end makes it easier for the end user to create interactive web applications without having to write any JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using the rich features of xleaflet, one can start building fully-fledged GIS application in C++.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/011-1_E2blHOSA9Gah1DZe1t8tKA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;If you are interested in trying xleaflet right now in your web browser, we provided a &lt;a href="https://mybinder.org/"&gt;binder&lt;/a&gt; for you.&lt;/p&gt;
&lt;p&gt;Simply click on the following binder link and start playing with interactive GIS in C++ in your web browser:&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/QuantStack/xleaflet/0.2.0?filepath=notebooks"&gt;&lt;img alt="Click on the image to launch the live demo." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/interpreted-c-for-gis-with-jupyter/images/012-1_DodrT-K2jBSmbAbEhmfbEg.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click on the image to launch the live demo.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Check out the &lt;a href="http://xleaflet.readthedocs.io"&gt;documentation&lt;/a&gt; for more detailed information about xleaflet.&lt;/p&gt;
&lt;h3 id="aknowledgements"&gt;Aknowledgements&lt;/h3&gt;
&lt;p&gt;The software presented in this post was built upon the work of a large number of people including the &lt;strong&gt;Jupyter&lt;/strong&gt; team, the &lt;strong&gt;Cling&lt;/strong&gt; developers, the developers of &lt;strong&gt;xeus&lt;/strong&gt; and &lt;strong&gt;xwidgets&lt;/strong&gt;, and the developers of &lt;a href="http://leafletjs.com/"&gt;&lt;strong&gt;leafletjs&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are especially grateful to &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;, &lt;a href="https://twitter.com/lgouarin"&gt;Loic Gouarin&lt;/a&gt;, &lt;a href="https://twitter.com/JohanMabille"&gt;Johan Mabille&lt;/a&gt;, and &lt;a href="https://github.com/wolfv"&gt;Wolf Vollprecht&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The development of xeus, xwidgets and related packages at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; is sponsored by &lt;a href="http://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;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Scientific Software developer at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;. Prior to joining QuantStack, Martin studied at the &lt;a href="https://www.isae-supaero.fr/en"&gt;French Institute of Aeronautics and Space&lt;/a&gt;. As an open source developer, he worked on a variety of projects, notably &lt;a href="https://demo.logilab.fr/SciviJS/"&gt;SciviJS&lt;/a&gt;, a JavaScript library for 3-D mesh visualization.&lt;/p&gt;
</content><category term="C++"/><category term="geoscience"/><category term="science"/></entry><entry><title>Interactive Workflows for C++ with Jupyter</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/" rel="alternate"/><published>2017-11-29T16:33:00+00:00</published><updated>2019-12-25T09:42:00+00:00</updated><author><name>QuantStack</name></author><id>tag:jasongrout.github.io,2017-11-29:/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/</id><summary type="html">&lt;p&gt;Scientists, educators and engineers not only use programming languages to build software systems, but also in interactive workflows, using…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Scientists, educators and engineers not only use programming languages to build software systems, but also in interactive workflows, using the tools available to &lt;em&gt;explore&lt;/em&gt; a problem and &lt;em&gt;reason&lt;/em&gt; about it.&lt;/p&gt;
&lt;p&gt;Running some code, looking at a visualization, loading data, and running more code. Quick iteration is especially important during the exploratory phase of a project.&lt;/p&gt;
&lt;p&gt;For this kind of workflow, users of the C++ programming language currently have no choice but to use a heterogeneous set of tools that don’t play well with each other, making the whole process cumbersome, and difficult to reproduce.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;We currently lack a good story for interactive computing in C++&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In our opinion, this hurts the productivity of C++ developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Most of the progress made in software projects comes from incrementalism. Obstacles to fast iteration hinder progress.&lt;/li&gt;
&lt;li&gt;This also makes C++ more difficult to teach. The first hours of a C++ class are rarely rewarding as the students must learn how to set up a small project before writing any code. And then, a lot more time is required before their work can result in any visual outcome.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="project-jupyter-and-interactive-computing"&gt;Project Jupyter and Interactive Computing&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/001-1_wOHyKy6fl3ltcBMNpCvC6Q.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The goal of Project Jupyter is to provide a consistent set of tools for scientific computing and data science workflows, from the exploratory phase of the analysis to the presentation and the sharing of the results. The Jupyter stack was designed to be agnostic of the programming language, and also to allow alternative implementations of any component of the layered architecture (back-ends for programming languages, custom renderers for file types associated with Jupyter). The stack consists of&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a low-level specification for messaging protocols, standardized file formats,&lt;/li&gt;
&lt;li&gt;a reference implementation of these standards,&lt;/li&gt;
&lt;li&gt;applications built on top of these libraries: the Notebook, JupyterLab, Binder, JupyterHub&lt;/li&gt;
&lt;li&gt;and visualization libraries integrated into the Notebook and JupyterLab.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Adoption of the Jupyter ecosystem has skyrocketed in the past years, with millions of users worldwide, over a million Jupyter notebooks shared on GitHub and large-scale deployments of Jupyter in universities, companies and high-performance computing centers.&lt;/p&gt;
&lt;h2 id="jupyter-and-c"&gt;Jupyter and C++&lt;/h2&gt;
&lt;p&gt;One of the main extension points of the Jupyter stack is the &lt;em&gt;kernel&lt;/em&gt;, the part of the infrastructure responsible for executing the user’s code. Jupyter kernels exist for &lt;a href="https://github.com/jupyter/jupyter/wiki/Jupyter-kernels"&gt;numerous programming languages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most Jupyter kernels are implemented in the target programming language: the reference implementation &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; in Python, &lt;a href="https://github.com/JuliaLang/IJulia.jl"&gt;IJulia&lt;/a&gt; in Julia, leading to a duplication of effort for the implementation of the protocol. A common denominator to a lot of these interpreted languages is that the interpreter generally exposes a C API, allowing the embedding into a native application. In an effort to consolidate these commonalities and save work for future kernel builders, we developed &lt;em&gt;xeus&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/002-1_TKrPv5AvFM3NJ6a7VMu8Tw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is a C++ implementation of the Jupyter kernel protocol. It is not a kernel itself but a library that facilitates the authoring of kernels, and other applications making use of the Jupyter kernel protocol.&lt;/p&gt;
&lt;p&gt;A typical kernel implementation using xeus would in fact make use of the target interpreter &lt;em&gt;as a library.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There are a number of benefits of using xeus over implementing your kernel in the target language:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Xeus provides a complete implementation of the protocol, enabling a lot of features from the start for kernel authors, who only need to deal with the language bindings.&lt;/li&gt;
&lt;li&gt;Xeus-based kernels can very easily provide a back-end for Jupyter interactive widgets.&lt;/li&gt;
&lt;li&gt;Finally, xeus can be used to implement kernels for domain-specific languages such as SQL flavors. Existing approaches use a Python wrapper. With xeus, the resulting kernel won’t require Python at run-time, leading to large performance benefits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/003-1_Cr_cfHdrgFXHlO15qdNK7w.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interpreted C++&lt;/strong&gt; is already a reality at CERN with the &lt;a href="https://root.cern.ch/cling"&gt;Cling&lt;/a&gt; C++ interpreter in the context of the &lt;a href="https://root.cern.ch/"&gt;ROOT&lt;/a&gt; data analysis environment.&lt;/p&gt;
&lt;p&gt;As a first example for a kernel based on xeus, we have implemented &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt;, a pure C++ kernel.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Redirection of outputs to the Jupyter front-end, with different styling in the front-end." src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/004-1_NnjISpzZtpy5TOurg0S89A.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Redirection of outputs to the Jupyter front-end, with different styling in the front-end.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Complex features of the C++ programming language such as, polymorphism, templates, lambdas, are supported by the cling interpreter, making the C++ Jupyter notebook a great prototyping and learning platform for the C++ users. See the image below for a demonstration:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Features of the C++ programming language supported by the cling interpreter" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/005-1_lGVLY4fL1ytMfT-eWtoXkw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Features of the C++ programming language supported by the cling interpreter&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, xeus-cling supports live quick-help, fetching the content on &lt;a href="http://en.cppreference.com/w/"&gt;cppreference&lt;/a&gt; in the case of the standard library.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Live help for the C++standard library in the Jupyter notebook" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/006-1_Igegq0xBebuJV8hy0TGpfg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Live help for the C++standard library in the Jupyter notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;We realized that we started using the C++ kernel ourselves very early in the development of the project. For quick experimentation, or reproducing bugs. No need to set up a project with a cpp file and complicated project settings for finding the dependencies… Just write some code and hit &lt;strong&gt;Shift+Enter&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual output can also be displayed using the rich display mechanism of the Jupyter protocol.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using Jupyter's rich display mechanism to display an image inline in the notebook" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/007-1_t_9qAXtdkSXr-0tO9VvOzQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using Jupyter’s rich display mechanism to display an image inline in the notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/008-1_OVfmXFAbfjUtGFXYS9fKRA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Another important feature of the Jupyter ecosystem are the &lt;a href="http://jupyter.org/widgets"&gt;Jupyter Interactive Widgets&lt;/a&gt;. They allow the user to build graphical interfaces and interactive data visualization inline in the Jupyter notebook. Moreover it is not just a collection of widgets, but a framework that can be built upon, to create arbitrary visual components. Popular interactive widget libraries include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bloomberg/bqplot"&gt;bqplot&lt;/a&gt; (2-D plotting with d3.js)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jovyan/pythreejs"&gt;pythreejs&lt;/a&gt; (3-D scene visualization with three.js)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ellisonbg/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; (maps visualization with leaflet.js)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/maartenbreddels/ipyvolume"&gt;ipyvolume&lt;/a&gt; (3-D plotting and volume rendering with three.js)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/arose/nglview"&gt;nglview&lt;/a&gt; (molecular visualization)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just like the rest of the Jupyter ecosystem, Jupyter interactive widgets were designed as a language-agnostic framework. Other language back-ends can be created reusing the front-end component, which can be installed separately.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QUantStack/xwidgets"&gt;xwidgets&lt;/a&gt;, which is still at an early stage of development, is a native C++ implementation of the Jupyter widgets protocol. It already provides an implementation for most of the widget types available in the core Jupyter widgets package.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="C++ back-end to the Jupyter interactive widgets" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/009-1_ro5Ggdstnf0DoqhTUWGq3A.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;C++ back-end to the Jupyter interactive widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Just like with ipywidgets, one can build upon xwidgets and implement C++ back-ends for the Jupyter widget libraries listed earlier, effectively enabling them for the C++ programming language and other xeus-based kernels: xplot, xvolume, xthreejs…&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/010-1_yCRYoJFnbtxYkYMRc9AioA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xplot"&gt;xplot&lt;/a&gt; is an experimental C++ back-end for the &lt;a href="https://github.com/bloomberg/bqplot"&gt;bqplot&lt;/a&gt; 2-D plotting library. It enables an API following the constructs of the &lt;a href="https://dl.acm.org/citation.cfm?id=1088896"&gt;&lt;em&gt;Grammar of Graphics&lt;/em&gt;&lt;/a&gt; in C++.&lt;/p&gt;
&lt;p&gt;In xplot, every item in a chart is a separate object that can be modified from the back-end, &lt;em&gt;dynamically&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Changing a property of a plot item, a scale, an axis or the figure canvas itself results in the communication of an update message to the front-end, which reflects the new state of the widget visually.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Changing the data of a scatter plot dynamically to update the chart" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/011-1_Mx2g3JuTG1Cfvkkv0kqtLA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Changing the data of a scatter plot dynamically to update the chart&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; the xplot and xwidgets projects are still at an early stage of development and are changing drastically at each release.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Interactive computing environments like Jupyter are not the only missing tool in the C++ world. Two key ingredients to the success of Python as the &lt;em&gt;lingua franca&lt;/em&gt; of data science is the existence of libraries like &lt;a href="http://www.numpy.org/"&gt;NumPy&lt;/a&gt; and &lt;a href="https://pandas.pydata.org/"&gt;Pandas&lt;/a&gt; at the foundation of the ecosystem.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/012-1_HsU43Jzp1vJZpX2g8XPJsg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xtensor/"&gt;xtensor&lt;/a&gt; is a C++ library meant for numerical analysis with multi-dimensional array expressions.&lt;/p&gt;
&lt;p&gt;xtensor provides&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an extensible expression system enabling lazy NumPy-style broadcasting.&lt;/li&gt;
&lt;li&gt;an API following the &lt;em&gt;idioms&lt;/em&gt; of the C++ standard library.&lt;/li&gt;
&lt;li&gt;tools to manipulate array expressions and build upon xtensor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;xtensor exposes an API similar to that of NumPy covering a growing portion of the functionalities. A cheat sheet can be &lt;a href="http://xtensor.readthedocs.io/en/latest/numpy.html"&gt;found in the documentation&lt;/a&gt;:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Scrolling the NumPy to xtensor cheat sheet" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/013-1_PBrf5vWYC8VTq_7VUOZCpA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Scrolling the NumPy to xtensor cheat sheet&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;However, xtensor internals are very different from NumPy. Using modern C++ techniques (template expressions, closure semantics) xtensor is a lazily evaluated library, avoiding the creation of temporary variables and unnecessary memory allocations, even in the case complex expressions involving broadcasting and language bindings.&lt;/p&gt;
&lt;p&gt;Still, from a user perspective, the combination of xtensor with the C++ notebook provides an experience very similar to that of NumPy in a Python notebook.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using the xtensor array expression library in a C++ notebook" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/014-1_ULFpg-ePkdUbqqDLJ9VrDw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the xtensor array expression library in a C++ notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to the core library, the xtensor ecosystem has a number of other components&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xtensor-blas"&gt;&lt;strong&gt;xtensor-blas&lt;/strong&gt;&lt;/a&gt;: the counterpart to the numpy.linalg module.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/egpbos/xtensor-fftw"&gt;&lt;strong&gt;xtensor-fftw&lt;/strong&gt;&lt;/a&gt;: bindings to the &lt;a href="http://www.fftw.org/"&gt;fftw&lt;/a&gt; library.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xtensor-io"&gt;&lt;strong&gt;xtensor-io&lt;/strong&gt;&lt;/a&gt;: APIs to read and write various file formats (images, audio, NumPy’s NPZ format).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/wolfv/xtensor_ros"&gt;&lt;strong&gt;xtensor-ros&lt;/strong&gt;&lt;/a&gt;: bindings for ROS, the robot operating system.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xtensor-python"&gt;&lt;strong&gt;xtensor-python&lt;/strong&gt;&lt;/a&gt;: bindings for the Python programming language, allowing the use of NumPy arrays in-place, using the NumPy C API and the pybind11 library.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/Xtensor.jl"&gt;&lt;strong&gt;xtensor-julia&lt;/strong&gt;&lt;/a&gt;: bindings for the Julia programming language, allowing the use of Julia arrays in-place, using the C API of the Julia interpreter, and the CxxWrap library.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xtensor-r"&gt;&lt;strong&gt;xtensor-r&lt;/strong&gt;&lt;/a&gt;: bindings for the R programming language, allowing the use of R arrays in-place.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailing further the features of the xtensor framework would be beyond the scope of this post.&lt;/p&gt;
&lt;p&gt;If you are interested in trying the various notebooks presented in this post, there is no need to install anything. You can just use &lt;em&gt;binder&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/015-1_9cy5Mns_I0eScsmDBjvxDQ.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/"&gt;The Binder project&lt;/a&gt;, which is part of Project Jupyter, enables the deployment of containerized Jupyter notebooks, from a GitHub repository together with a manifest listing the dependencies (as conda packages).&lt;/p&gt;
&lt;p&gt;All the notebooks in the screenshots above can be run online, by just clicking on one of the following links:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/QuantStack/xeus-cling/stable?filepath=notebooks/xcpp.ipynb"&gt;&lt;strong&gt;xeus-cling&lt;/strong&gt;&lt;/a&gt;: the main xeus-cling example notebook,&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/QuantStack/xtensor/stable?filepath=notebooks/xtensor.ipynb"&gt;&lt;strong&gt;xtensor&lt;/strong&gt;&lt;/a&gt;: the C++ N-D array expression library in a C++ notebook,&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/QuantStack/xwidgets/0.11.1?filepath=notebooks/xwidgets.ipynb"&gt;&lt;strong&gt;xwidgets&lt;/strong&gt;&lt;/a&gt;: the C++ back-end for Jupyter interactive widgets,&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/QuantStack/xplot/0.5.0?filepath=notebooks"&gt;&lt;strong&gt;xplot&lt;/strong&gt;&lt;/a&gt;: the C++ back-end to the bqplot 2-D plotting library for Jupyter.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/interactive-workflows-for-c-with-jupyter/images/016-1_JwqhpMxMJppEepj7U4fV-g.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyterhub/jupyterhub"&gt;JupyterHub&lt;/a&gt; is the multi-user infrastructure underlying open wide deployments of Jupyter like Binder but also smaller deployments for authenticated users.&lt;/p&gt;
&lt;p&gt;The modular architecture of JupyterHub enables a great variety of scenarios on how users are authenticated, and what service is made available to them. JupyterHub deployment for several hundreds of users have been done in various universities and institutions, including the Paris-Sud University, where the C++ kernel was also installed for the students to use.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In September 2017, the 350 first-year students at Paris-Sud University who took the “&lt;a href="http://nicolas.thiery.name/Enseignement/Info111/"&gt;Info 111: Introduction to Computer&lt;br&gt;
Science&lt;/a&gt;” class wrote their first lines of C++ in a Jupyter notebook.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The use of Jupyter notebooks in the context of teaching C++ proved especially useful for the first classes, where students can focus on the syntax of the language without distractions such as compiling and linking.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The software presented in this post was built upon the work of a large number of people including the &lt;strong&gt;Jupyter&lt;/strong&gt; team and the &lt;strong&gt;Cling&lt;/strong&gt; developers.&lt;/p&gt;
&lt;p&gt;We are especially grateful to &lt;a href="https://twitter.com/egpbos"&gt;Patrick Bos&lt;/a&gt; (who authored xtensor-fftw), Nicolas Thiéry, Min Ragan Kelley, Thomas Kluyver, Yuvi Panda, Kyle Cranmer, Axel Naumann and Vassil Vassilev.&lt;/p&gt;
&lt;p&gt;We thank the &lt;a href="http://diana-hep.org"&gt;DIANA/HEP&lt;/a&gt; organization for supporting travel to CERN and encouraging the collaboration between Project Jupyter and the ROOT team.&lt;/p&gt;
&lt;p&gt;We are also grateful to the team at &lt;strong&gt;Paris-Sud University&lt;/strong&gt; who worked on the JupyterHub deployment and the class materials, notably &lt;a href="https://twitter.com/pyviv"&gt;Viviane Pons&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The development of xeus, xtensor, xwidgets and related packages at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; is sponsored by &lt;a href="http://www.techatbloomberg.com"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-authors-alphabetical-order"&gt;About the Authors (alphabetical order)&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;&lt;em&gt;Sylvain Corlay&lt;/em&gt;&lt;/a&gt;, Scientific Software Developer at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/lgouarin"&gt;&lt;em&gt;Loic Gouarin&lt;/em&gt;&lt;/a&gt;, Research Engineer at &lt;a href="https://www.math.u-psud.fr"&gt;Laboratoire de Mathématiques at Orsay&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/johanmabille?lang=en"&gt;&lt;em&gt;Johan Mabille&lt;/em&gt;&lt;/a&gt;, Scientific Software Developer at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/wuoulf"&gt;&lt;em&gt;Wolf Vollprecht&lt;/em&gt;&lt;/a&gt;, Scientific Software Developer at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;&lt;/p&gt;
</content><category term="C++"/><category term="science"/></entry></feed>