<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Code Ballads]]></title><description><![CDATA[Code Ballads]]></description><link>http://code-ballads.net/</link><image><url>http://code-ballads.net/favicon.png</url><title>Code Ballads</title><link>http://code-ballads.net/</link></image><generator>Ghost 2.7</generator><lastBuildDate>Fri, 03 Apr 2026 16:59:08 GMT</lastBuildDate><atom:link href="http://code-ballads.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Dear ImGui Bundle: (web) apps in pure Python with a single code base]]></title><description><![CDATA[Develop sophisticated (web) apps in pure Python with Dear ImGui Bundle.]]></description><link>http://code-ballads.net/dear-imgui-bundle-build-real-time-python-web-applications-with-zero-fuss/</link><guid isPermaLink="false">6864d0bc3907090001a45880</guid><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Sun, 06 Jul 2025 09:47:20 GMT</pubDate><media:content url="http://code-ballads.net/content/images/2025/07/logo_imgui_600.png" medium="image"/><content:encoded><![CDATA[<img src="http://code-ballads.net/content/images/2025/07/logo_imgui_600.png" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"><p>Thanks to <a href="https://pthom.github.io/imgui_bundle/">Dear ImGui Bundle,</a> which is now available inside <a href="https://pyodide.org/en/stable/">Pyodide</a> (a web distribution of Python), it is now possible to develop sophisticated GUI and apps in Python with a code that : </p><ul><li>can be used to deploy to full desktop applications</li><li>or run (with the same code) in the browser, without requiring a distant server, and without relying on any HTML / DOM / Javascript </li><li>provides access to numerous widgets and libraries (widgets, scientific plotting,  image analysis, etc)</li><li>is highly readable</li></ul><h3 id="minimal-demonstration">Minimal demonstration	</h3><p>Here is a minimal <a href="https://traineq.org/imgui_bundle_online/projects/min_bundle_pyodide_app/demo_heart.html">demo</a> that draws an animated heart with and adjustable heart beat.</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-14.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"><figcaption><a href="https://traineq.org/imgui_bundle_online/projects/min_bundle_pyodide_app/demo_heart.html">Launch demo</a></figcaption></figure><p> Its code is surprisingly short: it fits in a single 50 lines file,  almost entirely in Python (with a bit of HTML and JavaScript). </p><p>Since pyodide's distribution is available via a CDN, you can reproduce this on your side : just copy-paste code below into a html file (click <a href="https://traineq.org/imgui_bundle_online/projects/min_bundle_pyodide_app/demo_heart.source.txt">here for a copyable version of the source code</a>). </p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-16.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"></figure><h4 id="online-playground">Online playground</h4><p>An <a href="https://traineq.org/imgui_bundle_online/projects/imgui_bundle_playground/" rel="nofollow">online playground</a> will enable you to run and edit various ImGui applications in the browser without any setup.</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-2.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"><figcaption>An image processing application, with a sophisticated image viewer</figcaption></figure><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-3.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"></figure><h2 id="comparison-with-traditional-web-python-libraries">Comparison with traditional web python libraries</h2><p>Tools like <a href="https://streamlit.io/">Streamlit</a> and <a href="https://www.gradio.app/">Gradio</a> abstract away much of the boilerplate when building a Web Gui with  Python, and simplify the bridge between Python and the browser. <br>However, when things break, you're suddenly wrestling with  JavaScript errors, layout issues in CSS, or debugging the client-server synchronization:</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-8.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"></figure><p>This is where using a tool like ImGui Bundle shines : <em>apps developed with Dear ImGui Bundle never use any HTML element (button, etc), each call is synchronous, and everything that you see is drawn via calls to the GPU. </em></p><hr><h2 id="in-this-article">In this article</h2><ul><li>We explain how Immediate Mode GUI works</li><li>We introduce Dear ImGui, a reputable Immediate Mode GUI library (C++)</li><li>We explore ImGui Bundle, which brings Dear ImGui to Python, together with lots of utilities</li><li>And we show how it all works in your browser, with Pyodide</li></ul><h2 id="the-immediate-mode-gui-paradigm">The Immediate Mode GUI Paradigm</h2><p><strong>What is Immediate Mode GUI?</strong><br>Immediate Mode GUIs (IMGUI) differ from traditional  retained-mode frameworks. Instead of building and maintaining an  abstract UI tree, you declare your widgets at each frame — just like  calling <code>print()</code> repeatedly in a loop.</p><p>This approach leads to:</p><ul><li>Simple, stateless, and readable code</li><li>Full control over rendering and logic, frame-by-frame </li><li>Great debugging and introspection: there's no hidden state behind the GUI</li></ul><p>For instance, displaying button and handling its action in ImGui might just look like:</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-4.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"></figure><p><strong>Compared to retained-mode and web-based GUIs</strong></p><p>Frameworks like Streamlit and Gradio rely on a layered architecture that separates logic from rendering. </p><p><em>In contrast, Immediate Mode GUIs are radically simple:</em><br>There’s no event queue to wire, no hidden reactive state —  just Python code running in a loop, directly rendering the GUI. Whether you run it natively or in the browser via Pyodide, the UI logic stays  local, explicit, and easy to debug.</p><p><strong>Comparison: Immediate Mode vs classic Python Web GUIs</strong></p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2025/07/image-5.png" class="kg-image" alt="Dear ImGui Bundle: (web) apps in pure Python with a single code base"></figure><h2 id="enter-dear-imgui">Enter <strong>Dear ImGui</strong></h2><p><strong><a href="https://github.com/ocornut/imgui">Dear ImGui</a></strong> is a fast, lightweight C++  library designed for building rich graphical user interfaces in  real-time applications. Originally developed for debugging tools in game engines, it's now used across industries for visualization, simulation,  embedded UIs, and more.</p><p>ImGui follows the Immediate Mode GUI paradigm: widgets are declared directly in your rendering loop, which makes it incredibly responsive, debuggable, and easy to integrate.</p><p>Dear ImGui is known for:</p><ul><li>Extremely high performance (everything is drawn via the GPU)</li><li>A focus on developer productivity and iteration speed</li><li>A powerful ecosystem: plotting (ImPlot), markdown, node editors, etc.</li></ul><p>With 66k+ GitHub stars and a passionate community, ImGui has become a go-to for developers who want <strong>full control</strong> and <strong>minimal friction</strong> when building UIs.</p><h2 id="meet-dear-imgui-bundle">Meet <strong>Dear ImGui Bundle</strong></h2><p><strong><a href="https://pthom.github.io/imgui_bundle/">Dear ImGui Bundle</a></strong> builds on top of Dear  ImGui to offer a ready-to-use, cross-platform toolkit for both C++ and  Python. <br>It comes with <a href="https://pthom.github.io/imgui_bundle/introduction.html">batteries included</a>, as it includes the core of ImGui, together with  advanced  widgets and libraries, for plotting (<a href="https://github.com/epezent/implot">ImPlot</a> and <a href="https://github.com/brenocq/implot3d/">ImPlot3d</a>), image handling, markdown rendering, node  editors, and more.</p><p>It provides <a href="https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/imgui/__init__.pyi">documented Python bindings</a> for ImGui and <a href="https://github.com/pthom/imgui_bundle/tree/main/bindings/imgui_bundle">all the included libraries</a>. These bindings are auto-generated, which means, that they will always be up to date with the latest versions.</p><p><strong>An ideal framework for prototyping and exploration</strong></p><p>Dear ImGui Bundle is a great match for data scientists, educators, and toolmakers who want to tests their ideas and build prototypes quickly, without giving up control.</p><p><strong>ImGui Bundle in the Browser (via Pyodide)</strong><br>Thanks to its availability in Pyodide, ImGui Bundle is now a Python GUI framework that works  identically across desktop and browser, with the same codebase.<br><br>Of course, there are some limitations due to the web environment: sandboxing, no filesystem access, etc. The pyodide wheel is relatively small at 4.5MB. </p><h3 id="test-it">Test it</h3><p><strong>On your computer</strong></p><p>Dear ImGui Bundle is <a href="https://pypi.org/project/imgui-bundle/">available on pypi</a>. </p><pre><code class="language-bash">pip install imgui-bundle  # MIT license
</code></pre>
<p><strong>On the web</strong></p><p>You can download the Pyodide distribution with ImGui Bundle pre-installed from the following link: <a href="https://traineq.org/imgui_bundle_online/pyodide_dist.tgz" rel="nofollow">Download Pyodide with ImGui Bundle</a></p><p>ImGui Bundle was just added to the official Pyodide recipes, so you will be able to use it without downloading anything in the future. See relevant <a href="https://github.com/pyodide/pyodide-recipes/pull/116">PR</a></p>]]></content:encoded></item><item><title><![CDATA[An overview of recent progress and challenges in AI]]></title><description><![CDATA[<p>If ChatGPT is today at the heart of the debate, it is already almost part of the past: its successors are being born these weeks.</p><p>New multimodal robots are emerging. Going far beyond image creation, or answering questions, they are conversational robots with long arms: they can read and write</p>]]></description><link>http://code-ballads.net/an-overview-of-recent-progress-and-challenges-in-ai/</link><guid isPermaLink="false">644d429419c36e0001a0a911</guid><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Sat, 29 Apr 2023 16:19:06 GMT</pubDate><content:encoded><![CDATA[<p>If ChatGPT is today at the heart of the debate, it is already almost part of the past: its successors are being born these weeks.</p><p>New multimodal robots are emerging. Going far beyond image creation, or answering questions, they are conversational robots with long arms: they can read and write on the internet, generate and analyze texts, images and videos, recognize and imitate voices, write and execute programs, make phone calls, etc.  They are extremely easy to use, especially because they are programmed in plain English, and bound to become extremely powerful.</p><p>They are also becoming dangerous, since automated mass manipulations and scams are becoming easy. These robots are rapidly being democratized, since versions are now available in open source. 2023 might be a pivotal year.</p><p>The article linked below aims to try to get ahead of the curve by trying to predict what is coming in a few months, and analyses some possible solutions and regulations.</p><p>Links to the article (pdf):</p><ul><li><a href="https://traineq.org/AI/AI_2023_challenges.pdf">An overview of recent progress and challenges in AI</a> (english)</li><li><a href="https://traineq.org/AI/IA_2023_enjeux.pdf">Un état des lieux des progrès et enjeux récents en IA</a> (français)</li></ul><p>I have gathered this data because it is a subject that both fascinates and worries me, and I hope that enlightened information can help to better understand it.</p><p>On the same subject, the authors of "<a href="https://www.thesocialdilemma.com/">The Social Dilemma</a>" have also published a video that I recommend: <a href="https://www.youtube.com/watch?v=xoVJKj8lcNQ">The AI Dilemma</a>.</p><hr><p>Si ChatGPT est aujourd'hui au cœur du débat, il fait déjà presque partie du passé : ses successeurs naissent ces semaines-ci.</p><p>De nouveaux robots multimodaux émergent. Bien au-delà de la création d'images ou de la réponse à des questions, ce sont des robots conversationnels avec de longs bras : ils peuvent lire et écrire sur internet, générer et analyser des textes, des images et des vidéos, reconnaître et imiter des voix, écrire et exécuter des programmes, passer des appels téléphoniques, etc.  Ils sont extrêmement faciles à utiliser, notamment parce qu'ils sont programmés en anglais de tous les jours, et sont appelés à devenir extrêmement puissants.<br></p><p>Ils deviennent également dangereux, car les manipulations de masse automatisées et les escroqueries sont de plus en plus faciles. Ces robots se démocratisent rapidement, puisque des versions sont désormais disponibles en open source. 2023 pourrait être une année charnière.</p><p>L'article ci-dessous a pour but d'essayer de prendre de l'avance en essayant de prédire ce qui se passera dans quelques mois, et analyse quelques solutions et réglementations possibles.</p><p>Liens vers l'article (pdf) :</p><ul><li><a href="https://traineq.org/AI/AI_2023_challenges.pdf">An overview of recent progress and challenges in AI</a> (english)</li><li><a href="https://traineq.org/AI/IA_2023_enjeux.pdf">Un état des lieux des progrès et enjeux récents en IA</a> (français)</li></ul><p>J'ai rassemblé ces données car c'est un sujet qui me passionne et m'inquiète à la fois. Il est grand temps que les citoyens s'en emparent et j'espère qu'une information éclairée pourra y contribuer.</p><p>Sur le même sujet, les auteurs de "<a href="https://www.thesocialdilemma.com/">The Social Dilemma</a>" ont également publié une vidéo que je recommande : <a href="https://www.youtube.com/watch?v=xoVJKj8lcNQ">The AI Dilemma</a>.</p>]]></content:encoded></item><item><title><![CDATA[Annoucing ImmVision]]></title><description><![CDATA[<p><a href="https://github.com/pthom/immvision/">ImmVision</a> (a.k.a Immediate Vision) is an image debugger and viewer.</p><h2 id="immdebug-standalone-image-debugger-during-execution-and-post-mortem-">ImmDebug: standalone Image Debugger (during execution, <em>and</em> post-mortem)</h2><p><a href="https://www.youtube.com/watch?v=ztVBk2FN6_8" rel="nofollow">Video tutorial on Youtube</a></p><p>immvision includes an advanced image debugger for OpenCV which you  can easily plug into your C++ projects in order to be able to visually  debug images</p>]]></description><link>http://code-ballads.net/annoucing-immvision/</link><guid isPermaLink="false">63d43e4d1e64240001f6708e</guid><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Fri, 27 Jan 2023 21:18:36 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://github.com/pthom/immvision/">ImmVision</a> (a.k.a Immediate Vision) is an image debugger and viewer.</p><h2 id="immdebug-standalone-image-debugger-during-execution-and-post-mortem-">ImmDebug: standalone Image Debugger (during execution, <em>and</em> post-mortem)</h2><p><a href="https://www.youtube.com/watch?v=ztVBk2FN6_8" rel="nofollow">Video tutorial on Youtube</a></p><p>immvision includes an advanced image debugger for OpenCV which you  can easily plug into your C++ projects in order to be able to visually  debug images inside your image processing algorithms, during execution  or even <em>after</em> execution (post-mortem).</p><p>This requires <strong>no dependency</strong> apart from OpenCV, and you do <strong>not</strong> need to link your program to immvision (you will just need to copy 4 cpp files in your project).</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2023/01/image-2.png" class="kg-image"><figcaption>The immdebug application</figcaption></figure><h2 id="image-viewer">Image Viewer</h2><p><a href="https://youtu.be/nuJW21-BCkE" rel="nofollow">Video tutorial on YouTube</a></p><p>This image viewer runs inside <a href="https://github.com/ocornut/imgui">ImGui</a> (and thus your program must be linked to it).</p><p>This viewer is also included inside <a href="https://github.com/pthom/imgui_bundle">ImGui Bundle</a>, where it can also be used from python.</p><p>The API can be summarized as</p><pre><code>IMMVISION_API void Image(const std::string&amp; label, const cv::Mat&amp; mat, ImageParams* params);
</code></pre><p>See <a href="https://github.com/pthom/immvision/blob/master/src/immvision/image.h">Full API</a></p><p>See <a href="https://traineq.org/ImGuiBundle/emscripten/bin/demo_immvision_launcher.html" rel="nofollow">online demo!</a></p>]]></content:encoded></item><item><title><![CDATA[Announcing Dear ImGui Bundle]]></title><description><![CDATA[<figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2023/01/logo_imgui_bundle_256-1.png" class="kg-image"></figure><p><a href="https://github.com/pthom/imgui_bundle">Dear ImGui Bundle</a> is a quick-start and all-batteries-included framework to create cross-platform apps with <a href="https://github.com/ocornut/imgui">Dear ImGui</a>. It enables to easily create ImGui applications in <strong>C++ and Python</strong>, under Windows, macOS, Linux, and emscripten (and also iOS).</p><p>It is aimed at application developers, researchers, and who want to quickly develop apps</p>]]></description><link>http://code-ballads.net/annoucing-dear-imgui-bundle/</link><guid isPermaLink="false">63d431d115729500019aac6e</guid><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Fri, 27 Jan 2023 20:21:29 GMT</pubDate><media:content url="http://code-ballads.net/content/images/2023/01/ss_immvision-1.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2023/01/logo_imgui_bundle_256-1.png" class="kg-image" alt="Announcing Dear ImGui Bundle"></figure><img src="http://code-ballads.net/content/images/2023/01/ss_immvision-1.jpg" alt="Announcing Dear ImGui Bundle"><p><a href="https://github.com/pthom/imgui_bundle">Dear ImGui Bundle</a> is a quick-start and all-batteries-included framework to create cross-platform apps with <a href="https://github.com/ocornut/imgui">Dear ImGui</a>. It enables to easily create ImGui applications in <strong>C++ and Python</strong>, under Windows, macOS, Linux, and emscripten (and also iOS).</p><p>It is aimed at application developers, researchers, and who want to quickly develop apps and prototypes, taking advantage of the Immediate Gui paradigm. </p><ul><li>Click here for a <a href="https://traineq.org/ImGuiBundle/emscripten/bin/demo_imgui_bundle.html">fully interactive demo</a> (in your browser, using emscripten)</li><li><a href="https://pthom.github.io/imgui_bundle/">Documentation</a></li></ul><hr><h3 id="included-libraries-">Included libraries:</h3><p>Dear ImGui Bundle includes the following libraries:</p><ul><li> <a href="https://github.com/ocornut/imgui.git">imgui</a> : Dear ImGui, bloat-free Graphical User interface for C++ with minimal dependencies </li><li> <a href="https://github.com/epezent/implot">implot</a>: Immediate Mode Plotting </li><li> <a href="https://github.com/pthom/hello_imgui.git">Hello ImGui</a>: cross-platform Gui apps with the simplicity of a "Hello World" app </li><li> <a href="https://github.com/CedricGuillemet/ImGuizmo.git">ImGuizmo</a>: Immediate mode 3D gizmo for scene editing and other controls based on Dear ImGui </li><li> <a href="https://github.com/BalazsJako/ImGuiColorTextEdit">ImGuiColorTextEdit</a>: Colorizing text editor for ImGui </li><li> <a href="https://github.com/thedmd/imgui-node-editor">imgui-node-editor</a>: Node Editor built using Dear ImGui </li><li> <a href="https://github.com/altschuler/imgui-knobs">imgui-knobs</a>: Knobs widgets for ImGui </li><li> <a href="https://github.com/pthom/ImFileDialog.git">ImFileDialog</a>: A file dialog library for Dear ImGui </li><li> <a href="https://github.com/samhocevar/portable-file-dialogs">portable-file-dialogs</a>  Portable GUI dialogs library (C++11, single-header) </li><li> <a href="https://github.com/mekhontsev/imgui_md.git">imgui_md</a>: Markdown renderer for Dear ImGui using MD4C parser </li><li> <a href="https://github.com/dalerank/imspinner">imspinner</a>: Set of nice spinners for imgui </li><li> <a href="https://github.com/cmdwtf/imgui_toggle">imgui_toggle</a>: A toggle switch widget for Dear ImGui. </li><li> <a href="https://github.com/pthom/immvision.git">ImmVision</a>: Immediate image debugger and insights </li><li> <a href="https://github.com/andyborrell/imgui_tex_inspect">imgui_tex_inspect</a>: A texture inspector tool for Dear ImGui </li><li> <a href="https://github.com/hnOsmium0001/imgui-command-palette.git">imgui-command-palette</a>: A Sublime Text or VSCode style command palette in ImGui </li></ul><hr><p>This annoucement is voluntarily short, since ImGui Bundle also introduces a somewhat innovative way to present its documentation, since <a href="https://traineq.org/ImGuiBundle/emscripten/bin/demo_imgui_bundle.html">the online demo is also the manual</a> (you can also look at the <a href="https://pthom.github.io/imgui_bundle/">web manual</a>)</p><hr><h2 id="some-highlights-with-screenshots-below-">Some highlights with screenshots below:</h2><p>Lots of widgets</p><figure class="kg-card kg-image-card"><img src="https://user-images.githubusercontent.com/7694091/214685396-e0dc9e4f-71f5-4688-a6c4-e3e575e3fdd9.png" class="kg-image" alt="Announcing Dear ImGui Bundle"></figure><p>Documentation via a markdow and snippets renderer</p><figure class="kg-card kg-image-card"><img src="https://user-images.githubusercontent.com/7694091/214684593-99a9cc1f-1e25-4fb3-86b6-1d4ed1b6efcd.png" class="kg-image" alt="Announcing Dear ImGui Bundle"></figure><p>Example of a image processing tool developped with the included node editor (imgui-node-editor) and Image analysis (ImmVision) tools </p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2023/01/fiat_image-1.jpg" class="kg-image" alt="Announcing Dear ImGui Bundle"></figure><p>A example with python inside Jupyter Notebook</p><figure class="kg-card kg-image-card"><img src="https://user-images.githubusercontent.com/7694091/214683436-74d10077-76b5-4538-b003-ea75af2a634a.png" class="kg-image" alt="Announcing Dear ImGui Bundle"></figure><p>Theming</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2023/01/ss_theming.jpg" class="kg-image" alt="Announcing Dear ImGui Bundle"></figure><p>Hello World, in C++ and Python</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2023/01/image.png" class="kg-image" alt="Announcing Dear ImGui Bundle"><figcaption>Note: this a a screenshot from the online interactive demo! ImGui Bundle includes its own documentation and snippets renderer</figcaption></figure><blockquote>The python and C++ api are extremely close and fully documented, enabling an almost line by line transcription, which makes it a great fit for R&amp;D teams who want to quickly develop research tools in python, and still be able to easily port them in production.</blockquote><h3 id="announcements">Announcements</h3><ul><li><a href="https://twitter.com/ocornut/status/1617963615503659008">Twitter announcement</a> by Omar Cornut  </li><li><a href="https://github.com/pthom/imgui_bundle/discussions/categories/announcements">Announcements &amp; technical detail for all included libraries</a></li><li><a href="https://github.com/pthom/imgui_bundle/discussions/67">Announcement &amp; technical details for ImGui integration</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Discoverable algorithms in C++]]></title><description><![CDATA[Searching  for algorithms based on the signatures of the transformations they can apply to data is invaluable. ]]></description><link>http://code-ballads.net/discoverable-algorithms/</link><guid isPermaLink="false">5f9fde9cafe6800001160235</guid><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Mon, 02 Nov 2020 14:18:01 GMT</pubDate><media:content url="http://code-ballads.net/content/images/2020/11/prog_pearls.png" medium="image"/><content:encoded><![CDATA[<h2 id="tl-dr">TL;DR</h2><img src="http://code-ballads.net/content/images/2020/11/prog_pearls.png" alt="Discoverable algorithms in C++"><p>Searching  for algorithms based on the signatures of the transformations they can apply to data is invaluable. </p><p>For example, <a href="https://hoogle.haskell.org/?hoogle=int->[a]->[a]">this link</a> demonstrates a search engine used to discover all the available algorithms in Haskell for transformation given a signature "(int, [a]) -&gt; [a]".</p><p>In C++, one library offers such a facility : <a href="https://github.com/Dobiasd/FunctionalPlus">FunctionalPlus</a>.  Access its <a href="http://www.editgym.com/fplus-api-search/">API search page</a> and enter this in the search box:</p><pre><code>(int, [a]) -&gt; [a]
</code></pre>
<p> ... and you will find many useful algorithms based on this signature (drop, repeat, stride, drop_idx, take_cyclic, partial_sort, etc, etc.). </p><p>I wish more libraries would follow this idea, since reasoning about values and their transformations is a powerful way to render the code more readable and correct at the same time.</p><h5 id="a-short-c-coding-session-using-this-technique">A short C++ coding session using this technique</h5><p>As an illustration, the video below shows a development session where a simple program is developed using such a search facility:</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/i5Xots8dtDU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p></p><p>Links to solutions on Compiler Explorer:<br>Version with named variables: <a href="https://godbolt.org/z/YnK4bj">https://godbolt.org/z/YnK4bj</a><br>Version with a composed function: <a href="https://godbolt.org/z/n3Yh6s">https://godbolt.org/z/n3Yh6s</a> </p><h1 id="goal-no-raw-loop">Goal: no raw loop</h1><p>Sean Parent said:</p><blockquote>If you want to improve the code quality in your organization, replace all of your coding guidelines with one goal: no raw loop</blockquote><p>(See <a href="https://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning">C++ Seasoning video</a> at 8'44")</p><p>In his mind, a "goal" shall not be thought as a "one must" or a "one must not", <br>but rather as a target you set out to follow to as much as possible.</p><p>In this context, having a search tool that helps your team to find the needed algorithms in order to avoid raw loops is invaluable IMHO. The previous video is a demonstration centered on this topic.</p><h1 id="an-old-programing-pearl">An old programing pearl</h1><p>This  video is based on famous problem that was posed to Donald Knuth in 1986:</p><blockquote>Given a text file and an integer k, print the k most common words in the file (and the number of their occurrences) in decreasing frequency.</blockquote><p>Donald Knuth proposed a very advanced solution, demonstrating his style of “Literate Programming” through the WEB system. In his solution, he introduced innovative data structures (hash tries, etc.).  His solution was however quite lengthy, and limited to text documents: it was not so easy to turn it into a solution that could be adapted to similar problems.</p><p>In his review of Knuth's solution, Doug Mcllroy acknowledges the brilliance of the solution, and the elegance of the WEB system for literate programming. However, he proposed an alternate solution in 6 lines using standard Unix utilities:</p><figure class="kg-card kg-image-card"><img src="http://code-ballads.net/content/images/2020/11/image-2.png" class="kg-image" alt="Discoverable algorithms in C++"><figcaption>c</figcaption></figure><p>For those interested in the original discussion, refer to <a href="https://www.cs.tufts.edu/~nr/cs257/archive/don-knuth/pearls-2.pdf">a pdf of the original article</a><a>.</a></p><p>The unix shell solution is surprisingly elegant, as it solves the problem in simple and <em>composable</em> <em>transformations. </em>However, it can also be a little intimidating, and one might wonder "am I supposed to learn all those cryptic commands (sed, uniq, tr, etc.) and their arguments by heart?</p><p>The same is true for C++: how do we find the equivalent algorithms and transformations,that would be needed in order to reproduce such an elegant solution?</p><h1 id="discoverable-algorithms-and-transformations">Discoverable algorithms  and transformations</h1><h3 id="identifying-an-algorithm-s-signature">Identifying an algorithm's signature</h3><p>Let's examine one of those shell transformations: "uniq -c": it will replace each sequence of consecutive identical lines with one line that gives i) the number of lines and ii) the content of the line. In C++ terms, it could have the following signature:</p><pre><code class="language-cpp">vector &lt; pair &lt;size_t, string&gt; &gt; uniq_c(const vector&lt;string&gt;&amp; v) { ... }
</code></pre>
<p>In more generic terms we could look for an algorithm with the following signature:</p><pre><code class="language-cpp">template&lt;typename T&gt;
vector&lt; pair&lt;size_t, T&gt; &gt; uniq_c(const vector&lt;T&gt;&amp; v) { ... }
</code></pre>
<p>And in a more language agnostic way, we would say that the type of the signature of "uniq_c" is: </p><pre><code>[a] -&gt; [ (int, a) ]
</code></pre>
<p>i. e, given an array of type "a" (where a is a string for example), it returns an array of pair of type (number_of_occurrence, value of type a).</p><h3 id="searching-for-algorithms-based-on-their-signatures">Searching for algorithms based on their signatures</h3><p>In C++ , finding the good algorithm can sometimes be difficult. Knowing where to find the algorithm you need, and finding its name is all too often a barrier. <br>Jonathan Boccara has provided a <a href="https://www.fluentcpp.com/getthemap/">helpful map</a>, of which a picture can be found <a href="https://www.reddit.com/r/cpp/comments/8faq2p/wallpaper_the_world_of_c_stl_algorithms_1800_x/">here</a>, but apart from this, the search options are limited. <br>You are supposed to learn the different algorithms: this is a required part of the C++ background (and rightly so).</p><p>However, searching for algorithms based on their signature is surprisingly efficient. Let's for example think for one moment of all the algorithms that take as input an integer + an array, and return a modified array as an output. <br>Their signature is:</p><pre><code>(int, [a]) -&gt; [a]
</code></pre>
<p>Haskell offers a search engine, named <a href="https://hoogle.haskell.org">Hoogle</a>. With this tool, you would search for "int-&gt;[a]-&gt;[a]" (the signature is a bit different, since Haskell uses currying by default, which is beyond the scope of this post). And the results can be seen with <a href="https://hoogle.haskell.org/?hoogle=int->[a]->[a]">this link</a>.  </p><p>In C++, one library offers such a facility : <a href="https://github.com/Dobiasd/FunctionalPlus">FunctionalPlus</a>. It's api search, is located at <a href="http://www.editgym.com/fplus-api-search/">http://www.editgym.com/fplus-api-search/</a>. Open the link and enter "(int, [a]) -&gt; [a]" in the search box, and you will find the following list:</p><pre><code>    (int,[a])-&gt;[a]
    
        drop : (Int, [a]) -&gt; [a]
            Skip the first n elements of a sequence xs.
            If n &gt; length(xs) an empty sequence is returned.
            drop(3, [0,1,2,3,4,5,6,7]) == [3,4,5,6,7]
            Also known as skip.
        
        take : (Int, [a]) -&gt; [a]
            Return the first n elements of a sequence xs.
            In case n &gt;= length(xs), xs is returned.
            take(3, [0,1,2,3,4,5,6,7]) == [0,1,2]
            take(10, [0,1,2]) == [0,1,2]
        
        repeat : (Int, [a]) -&gt; [a]
            Create a sequence containing xs concatenated n times.
            repeat(3, [1, 2]) == [1, 2, 1, 2, 1, 2]
        
        stride : (Int, [a]) -&gt; [a]
            Keeps every nth element.
            stride(3, [0,1,2,3,4,5,6,7]) == [0,3,6]
            Container stride(std::size_t step, const Container&amp; xs)
        
        shuffle : (Int, [a]) -&gt; [a]
            Returns a randomly shuffled version of xs.
            Example call: shuffle(std::mt19937::default_seed, xs);
            Example call: shuffle(std::random_device()(), xs);
        
        drop_idx : (Int, [a]) -&gt; [a]
            Remove the element at a specific index from a sequence.
            drop_idx(2, [1,2,3,4,5,6,7]) == [1,2,4,5,6,7]
        
        drop_last : (Int, [a]) -&gt; [a]
            Skip the last n elements of a sequence xs.
            If n &gt; length(xs) an empty sequence is returned.
            drop_last(3, [0,1,2,3,4,5,6,7]) == [0,1,2,3,4]
        
        take_last : (Int, [a]) -&gt; [a]
            Return the last n elements of a sequence xs.
            In case n &gt;= length(xs), xs is returned.
            take_last(3, [0,1,2,3,4,5,6,7]) == [5,6,7]
            take_last(10, [0,1,2]) == [0,1,2]
        
        drop_exact : (Int, [a]) -&gt; [a]
            Skip exactly the first n elements of a sequence xs.
            Unsafe! Crashes when xs is too short.
            drop_exact(3, [0,1,2,3,4,5,6,7]) == [3,4,5,6,7]
            drop_exact(10, [0,1,2,3,4,5,6,7]) == crash
        
        take_exact : (Int, [a]) -&gt; [a]
            Return exactly the first n elements of a sequence xs.
            Unsafe! Crashes then sequence is too short.
            take_exact(3, [0,1,2,3,4,5,6,7]) == [0,1,2]
            take_exact(10, [0,1,2]) == crash
        
        take_cyclic : (Int, [a]) -&gt; [a]
            Takes n elements from a sequence considering it as cyclic.
            take_cyclic(5, [0,1,2,3]) == [0,1,2,3,0]
            take_cyclic(7, [0,1,2,3]) == [0,1,2,3,0,1,2]
            take_cyclic(7, [0,1]) == [0,1,0,1,0,1,0]
            take_cyclic(2, [0,1,2,3]) == [0,1]
            take_cyclic(3, [0]) == [0,0,0]
            take_cyclic(3, []) == crash!
            Also known as take_wrap.
            xs must be non-empty.
        
        partial_sort : (Int, [a]) -&gt; [a]
            Partially sort a sequence in ascending order using std::less.
            Returns only the sorted segment.
        
        replicate_elems : (Int, [a]) -&gt; [a]
            Replicate every element n times, concatenate the result.
            replicate_elems(3, [1,2]) == [1, 1, 1, 2, 2, 2]
            Container replicate_elems(std::size_t n, const Container&amp; xs)

</code></pre>
<p>A fast and elegant to search for algorithms and transformation!</p><h3 id="re-discovering-rle-run-length-encode-">Re-discovering RLE (run-length-encode)</h3><p>Let's go back to "uniq -c".  If we go back to Fplus's <a href="http://www.editgym.com/fplus-api-search/">search engine</a>, and search for <br>[a] -&gt; [ (int, a) ]<br>we discover the following functions.</p><pre><code>    [a] -&gt; [(Int, a)]
    
    enumerate : [a] -&gt; [(Int, a)]
        Attach its index to every element of a sequence.
        enumerate([6,4,7,6]) == [(0, 6), (1, 4), (2, 7), (3, 6)]
    
    run_length_encode : [a] -&gt; [(Int, a)]
        run_length_encode([1,2,2,2,2,3,3,2)) == [(1,1),(4,2),(2,3),(1,2)]


</code></pre>
<p>And, that's it! <br><a href="https://en.wikipedia.org/wiki/Run-length_encoding">Run length encoding</a> is exactly what "uniq -c" is doing. We did not know the name of the algorithm, but the search engine geared us in the good direction.</p><p>I wish other libraries would follow this idea of being "searchable by signature".</p><h1 id="composing-algorithms">Composing algorithms</h1><p>Composing algorithms is a powerful way to develop new features, and to be more certain of the correctness of your program.</p><p>For comparison, the shell script:</p><pre><code>tr -cs A-Za-z '\n' |  # 1 word per line
tr A-Z a-z |          # lowercase
sort |                # sort words (with possible repetitions)
uniq -c |             # group identical words and keep and count per group
sort -rn |            # numerical sort, inverted
sed $1q               # Display the n first lines
</code></pre>
<p>becomes, when translated to C++, using similar transformations:</p><pre><code class="language-cpp">std::function&lt;string(string)&gt; make_word_stats_processor(size_t nb_results)
{
  return fplus::compose(
      fplus::fwd::split_words(false)
    , fplus::fwd::transform(fplus::to_lower_case&lt;string&gt;) 
    , fplus::sort&lt;std::vector&lt;std::string&gt;&gt;
    , fplus::run_length_encode&lt;std::vector&lt;string&gt;&gt;
    , fplus::fwd::sort_by(greater&lt;pair&lt;size_t, string&gt;&gt;())
    , fplus::fwd::transform(show_word_count)
    , fplus::fwd::take(nb_results)
    , fplus::fwd::join(std::string(&quot;\n&quot;))
  );
}
</code></pre>
<p>I'll be brutally honest about it: when writing such code, you will inevitably make type errors which the C++ compiler will "reward" with cryptic template error messages.  The first attempts might be painful. <br>However, the final code is very readable IMHO, and most of the time, a code that compiles will be correct at the first run! <br>Moreover, parallelization is then almost free (see fplus::transform_parallely for example). </p><h1 id="using-pure-higher-order-functions-an-example-with-interact">Using pure higher order functions: an example with "interact"</h1><p>fplus::interact enables to transform a string-&gt;string function into a complete stdin/stdout program. It is thus a higher order function that takes a function as parameter, and returns another  function. </p><p>Here is its signature:</p><pre><code>interact : (String -&gt; String) -&gt; Io ()

Takes a function F of type (String -&gt; String)
and returns a function that
reads the entire input from standard input,
passes it through the given function,
and writes the result to standard output.
</code></pre>
<p>The Io() at the end of the signature signals that the returned function will be able, <em>when called</em>, to perform side effects (e.g read from stdin and write to stdout). </p><p>However, fplus::interact is in itself a pure function. It will not perform the side effect by itself, since you have to run the returned function in order to perform the side effect. This way, this function remains pure and composable. </p>]]></content:encoded></item><item><title><![CDATA[REPL in C++: types to the rescue]]></title><description><![CDATA[Being able to  display readable types and content for your variables and functions can greatly improve the user experience inside a C++ REPL.]]></description><link>http://code-ballads.net/repl-in-c-types-to-the-rescue/</link><guid isPermaLink="false">5c6706ca4fc4df00013ccc67</guid><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Fri, 15 Feb 2019 18:45:38 GMT</pubDate><content:encoded><![CDATA[<p>This post is a follow-up to my <a href="http://code-ballads.net/read-eval-print-loop-repl-in-c/">hands-on session article about C++ REPL</a>. </p><p>Being able to  display readable types and content for your variables and functions can greatly improve the user experience inside a C++ REPL. </p><p>This article is very short, so that you can jump to the short (2 minutes) demonstration video below. It is based on <a href="https://github.com/pthom/cleantype">CleanType</a>, a C++ header-only library whose intent is to get readable types and content. </p><p>For those in a hurry, you can skip to the video transcript at the end of this page.</p><a href="https://asciinema.org/a/iOntaIf6tVET0l6ESMX5r48tR?t=18&speed=1.65"><img src="https://asciinema.org/a/227876.svg"></a><p><em>Some links before concluding this article:</em></p><ul><li>The demo code for this REPL demo <a href="https://github.com/pthom/cleantype/blob/master/demos/demo_cling.cpp">is available here</a> </li><li>For those who were interested in the jupyter notebook C++ REPL environment, you can also t<a href="https://mybinder.org/v2/gh/pthom/cleantype/master?filepath=notebooks%2Fcleantype%2Fcleantype.ipynb">ry it inside jupyter notebook</a> (beware, this may require a minute or two to load, mybinder.org is sometimes sluggish)</li><li>For those who prefer a demo in a more standard C++ environment, here is a <a href="https://github.com/pthom/cleantype/blob/master/demos/demo_simple.cpp">simple demo</a>, which you can also try interactively on <a href="https://gitpod.io/#https://github.com/pthom/cleantype/blob/master/demos/demo_simple.cpp">gitpod</a> (registration required)</li></ul><h3 id="video-transcript">Video Transcript</h3><p>Note: Here is link to the <a href="https://gist.github.com/pthom/c6091c952623b545bbfc6e63a13d9837">same transcript as a gist</a>, with nicer colors.</p><pre><code class="language-cpp">
// REPL in C++: display readable types and
// variable contents.

// This demo uses cling, a fully compliant C++14 REPL,
// and asciinema, a terminal session recorder.
// It is based on CleanType (a C++ type introspection
// library)
// You can pause at any time, and copy-paste samples from it.

#include &lt;cleantype/cleantype.hpp&gt;

// The dumbest logger in the west...
#define LOG(...) std::cout &lt;&lt; __VA_ARGS__ &lt;&lt; &quot;\n&quot;;

// First, let's define a variable for demonstration purpose
std::set&lt;std::string&gt; my_set { &quot;Hello&quot;, &quot;There&quot;};

// let's ask CleanType to give us the type of &quot;my_set&quot;
// cleantype::full will return the *full* type info
LOG(  cleantype::full(my_set)  );
--&gt; std::set&lt;std::__cxx11::basic_string&lt;char&gt;, std::less&lt;std::__cxx11::basic_string&lt;char&gt;&gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char&gt;&gt;&gt; &amp;


// Ouch, that was barely readable!
// cleantype::clean will return a *readable* type
LOG(  cleantype::clean(my_set) );
--&gt; std::set&lt;std::string&gt; &amp;

// Let's now show the content of &quot;my_set&quot; together
// with its type
LOG(  cleantype::show_details(my_set) );
--&gt; std::set&lt;std::string&gt; &amp; = [Hello, There]


// Yes, but what about lambdas? Could you guess
// the signature of the lambda below?
auto lambda_example = []() {
    // when C++ meets js...
    return +!!&quot;&quot;;
    // See https://blog.knatten.org/2018/10/12/1662
};

// cleantype::lambda_clean returns the signature of lambda functions
LOG(  cleantype::lambda_clean(lambda_example) );
--&gt; lambda: () -&gt; int

// Ok, maybe this was too easy.
// Let's try with a generic lambda!
auto add = [](auto a, auto b) {
    return a + b;
};

// Now, can we see its signature?
// Yes, we just need to specify the args types.
LOG(  cleantype::lambda_clean&lt;std::string, char&gt;(add)  );
--&gt; lambda: (std::string, char) -&gt; std::string



// Can CleanType understand some more complex libraries
// like range-v3 where most variables, functions
// and lambdas are of type &quot;auto&quot;?
// Well...    yes!

#include &lt;range/v3/all.hpp&gt;

using namespace ranges;

auto square_yield_fn(int x) {
  return ranges::yield(x * x);
}
auto squares_view = view::for_each(view::ints(1), square_yield_fn);

// What is the type of squares_view?
// Let's see...
LOG( cleantype::clean(squares_view)  );
--&gt; ranges::v3::join_view&lt;ranges::v3::transform_view&lt;ranges::v3::iota_view&lt;int, void&gt;, ranges::v3::single_view&lt;int&gt;(*)(int)&gt;, void&gt; &amp;

// Let's make it more complex yet:
auto squares_take_10 = squares_view | view::take(10);

// As you will see below, CleanType can indent
// the types when they get more complex!

LOG(  cleantype::clean(squares_take_10)  );
--&gt; ranges::v3::detail::take_exactly_view_&lt;
    ranges::v3::join_view&lt;
        ranges::v3::transform_view&lt;
            ranges::v3::iota_view&lt;
                int,
                void
            &gt;,
            ranges::v3::single_view&lt;
                int
            &gt; (*)(int)
        &gt;,
        void
    &gt;,
    false
&gt; &amp;



// Thanks for watching!

</code></pre>
]]></content:encoded></item><item><title><![CDATA[CleanType - Readable and consistent C++ type introspection - Compiler Decipherer]]></title><description><![CDATA[Readable and consistent C++ type introspection - Compiler Decipherer]]></description><link>http://code-ballads.net/cleantype/</link><guid isPermaLink="false">5c4328a4dab1fe0001fd54b4</guid><category><![CDATA[C++]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[type]]></category><category><![CDATA[reflection]]></category><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Tue, 22 Jan 2019 19:42:23 GMT</pubDate><media:content url="http://code-ballads.net/content/images/2019/02/cleantype_logo_2.png" medium="image"/><content:encoded><![CDATA[<blockquote><a href="https://github.com/pthom/cleantype">CleanType</a>  is a small C++14 header only library which offer <em>readable</em> type names, with a <em>consistent naming scheme across compilers</em>, at <em>run-time</em> and <em>compile-time</em>. It can also output the <em>signature of lambda</em> functions, and the result type of any auto function.<br><br>The included tool (ct_compiler_decipher) simplifies the template noise in your compiler output: just pipe ("|") your build tool to it.</blockquote><a href="https://asciinema.org/a/227666?t=14" target="_blank"><img src="https://asciinema.org/a/227666.svg" width="400" alt="CleanType - Readable and consistent C++ type introspection - Compiler Decipherer"></a><img src="http://code-ballads.net/content/images/2019/02/cleantype_logo_2.png" alt="CleanType - Readable and consistent C++ type introspection - Compiler Decipherer"><p>This project started as a simple "what if" project: I wanted to be able to get more information about the types hidden behind <code>auto</code> variables, lambdas, etc; and I wanted to be able to get this information interactively (e.g. inside a <a href="http://code-ballads.net/read-eval-print-loop-repl-in-c/">C++ REPL</a>, or from the compiler output). </p><h2 id="features">Features</h2><blockquote>If you are interested in this project, stop reading here! Instead, go to the <a href="https://github.com/pthom/cleantype#table-of-content">full manual</a> which is much more complete and interesting than this introductory article. This manual is also available in a <a href="https://mybinder.org/v2/gh/pthom/cleantype/master?filepath=notebooks%2Fcleantype%2Fcleantype.ipynb">fully interactive version</a> (beware, it may require about 1 minute to load; but then you will be able to run the code live from your browser!)</blockquote><ul><li><em>Readable type names</em><br>e.g <code>std::string</code>  <br>instead of <code>std::basic_string&lt;char, std::allocator&lt;char&gt;&gt;</code></li><li><em>Readable type names in the compiler error output</em><br>Because no one likes to be punished with template gibberish when trying to correct an error.</li><li><em>Identify the auto return type of functions and the signature of lambdas</em><br>Because it is a great way to understand what's going on in the code.</li><li><em>Identify types in the compiler output</em><br>Because sometimes we are lost in a forest of auto return types; and we would like the compiler to tell us what he knows (and is hiding from us!) </li><li><em>Compile time constexpr type names</em></li></ul><h2 id="highlights">Highlights</h2><p>Below are some non interactive highlights for the impatient reader.</p><h3 id="readable-types-and-signatures">Readable types and signatures</h3><p>Suppose you have a lambda (<code>cache_int_strings</code>) that will create a sort of cache between the n first integers and their string representation (natural representation, and roman number representation). Using cleantype, you can get its signature like this:</p><pre><code>std::cout &lt;&lt; cleantype::lambda_clean(cache_int_strings);
==&gt; lamda: (int) -&gt; std::map&lt;int, std::array&lt;std::string, 2&gt;&gt;
</code></pre>
<p>or, depending on the indent limit, which is <a href="https://github.com/pthom/cleantype/blob/master/.cleantype.json">configurable</a>:</p><pre><code>lambda: (int) -&gt; std::map&lt; // lambda signature
    int,                   // cleantype can indent the types
    std::array&lt;
        std::string,  // note: cleantype will decipher the type
        2             // (i.e basic_string&lt;char,......&gt;&gt; in this case)
    &gt;
&gt;
</code></pre>
<p>You can also print the type and content of any container</p><pre><code>auto five_numbers = make_cache_int_strings(5);
std::cout &lt;&lt; CT_show_details(five_numbers);
</code></pre>
<p>will output</p>
<pre><code>[std::map&lt;
    int,
    std::array&lt;
        std::string,
        2
    &gt;
&gt;] five_numbers = [(1, [&quot;1&quot;, &quot;I&quot;]), (2, [&quot;2&quot;, &quot;II&quot;]), (3, [&quot;3&quot;, &quot;III&quot;]), (4, [&quot;4&quot;, &quot;IV&quot;]), (5, [&quot;5&quot;, &quot;V&quot;])]

</code></pre>
<p>Notes: the full source for this demo is available <a href="https://github.com/pthom/cleantype/blob/master/notebooks/cleantype/examples/quick_demo.ipynb">here</a>. Of course, CleanType handles more than just lambdas, and is able to output any type. </p><h3 id="decipher-the-compiler-output">Decipher the compiler output</h3><p>Suppose you have an error and you are being punished by the compiler. The tool <code>ct_compiler_decipher</code>   can make your life easier. Just pipe your build command line to it:</p><pre><code>&gt; clang++ --std=c++14 -c code.cpp 2&gt;&amp;1 | ct_compiler_decipher
code.cpp:10:42: error: invalid operands to binary expression ('std::map&lt;std::string, int&gt; ' and 'int')
    auto add_one = [](auto x) { return x + 1; };
                                       ~ ^ ~
</code></pre>
<p>Here, <code>'std::map&lt;std::__cxx11::basic_string&lt;char&gt;,.... &gt;'</code> was deciphered to <code>std::map&lt;std::string, int&gt;</code></p>
<h2 id="miscellaneous-remarks-and-questions">Miscellaneous remarks and questions</h2><p>With this project, I am experiencing with a new <em>interactive</em> way of presenting a project manual. I decided not to use a static documentation web pages since the manual provides an auto-generated <a href="https://github.com/pthom/cleantype#table-of-content">table of content</a>. Then, I also decided to <a href="https://mybinder.org/">binder</a> in order to turn this manual into a <a href="https://mybinder.org/v2/gh/pthom/cleantype/master?filepath=notebooks%2Fcleantype%2Fcleantype.ipynb">fully interactive manual</a> (beware, it may require about 1 minute to load). What is your opinion about this? If you are interested in this interactive way of development, you can also read <a href="http://code-ballads.net/read-eval-print-loop-repl-in-c/">my article about it</a>.</p><p>Also I am gathering input concerning the time to load binder: in my experience the load time can vary between 10 seconds and 3 minutes! I do hope that binder gains traction and becomes faster in the near future. What was your mileage? <br>Note: if your page seems to be stuck during loading, try to reload it after 1 minute (and meanwhile, you can read the manual in the preview). </p><p>I do not claim that this library is 100% foolproof: it is still in its infancy, so that you may expect some bugs. However, I still think it is usable and useful. </p><p>I did some efforts in order to get readable representations for most of the STL types, but I certainly forgot some aspects. Cleantype is highly <a href="https://github.com/pthom/cleantype/blob/master/src/include/cleantype/cleantype_configuration.hpp">configurable</a>, so that I think it could be adapted to most users needs, as long as they are not torturing the compiler with highly complex templates. Please do try the interactive demos: do you see some types for which some additional deciphering would be required?</p><p>As you can see, this library is standalone and header-only. It does not depend on clang libtooling. This is a choice because I wanted it to be as simple as possible to adopt, and as portable as possible. <br>Of course, this means that the compilation time may increase. So, you may as well consider this library as a drop-in solution: just <code>#include "cleantype.hpp"</code> whenever you need it in your cpp file (or inside your C++ REPL), and then remove it once it helped you find the type you were looking for. </p><p>Is it worthwhile to try to define a "normalized" string version of a type? In my opinion, the "east-const" vs "west-const" is just the tip of the iceberg. It is a sign that more established "spelling conventions" would be needed, as far as the types are concerned. They should not be enforced by the compiler, but they should exist someway . <br>Sadly, the C++ ecosystem is heavily fragmented between different cultures, compilers and toolchains. Humans, compilers, libc implementations : everyone disagrees on what should be the normalized string representation of a type. See an interactive analysis here:<a href="http://code-ballads.net/typesetting-the-east-vs-west-pointless-holy-war/"> typesetting : the east vs west pointless holy war?</a></p>]]></content:encoded></item><item><title><![CDATA[REPL (Read-Eval-Print-Loop) in C++: hands-on session]]></title><description><![CDATA[An efficient way to prototype  C++ applications, research work and to write demonstrations and teaching material using C++]]></description><link>http://code-ballads.net/read-eval-print-loop-repl-in-c/</link><guid isPermaLink="false">5c113b7786ce2e00013f420e</guid><category><![CDATA[C++]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Pascal Thomet]]></dc:creator><pubDate>Wed, 12 Dec 2018 16:51:45 GMT</pubDate><media:content url="http://code-ballads.net/content/images/2018/12/opencv_and_shell.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://code-ballads.net/content/images/2018/12/opencv_and_shell.jpg" alt="REPL (Read-Eval-Print-Loop) in C++: hands-on session"><p><em>An efficient way to prototype  C++ applications &amp; research work and to write demonstrations or teaching material using C++</em></p><p>A Read-Eval-Print-Loop (REPL) enables to leverage very rapid and robust application development, prototyping and testing. This kind of development environment originates from the early days of functional programming (Lisp machines and the like), and is common in functional and scripting languages.</p><p>As a compiled language, C++ was out of the loop for a long time.</p><h3 id="enters-cling">Enters CLING</h3><p><a href="https://github.com/root-project/cling">Cling</a> realizes the read-eval-print loop (REPL) concept for the C++ language. Thus, you can gain in speed of development while the compiler (clang) still checks your code and guarantees a native speed of execution.</p><h3 id="hands-on-demonstrations">Hands-on demonstrations</h3><p>This article demonstrates how easy and useful it can sometimes be to work in this kind of environment in C++. This is especially useful in order to develop with a functional approach (such as with the <a href="https://github.com/ericniebler/range-v3">range-v3</a> library), and for research and/or training applications.</p><p>This article is voluntarily very short, so that you can jump to the hands-on demonstrations. You will be able to use the a C++ REPL online, without even having to install anything.</p><h4><a href="https://code-ballads.net/generated-notebooks/cpp/repl_cling/markdown/" target="_blank">Go to the demonstration notebooks</a></h4> (opens in a new window)<h3 id="about-the-tools-that-were-used-to-write-these-notebooks">About the tools that were used to write these notebooks</h3><p>These notebooks  were written using REPL tools, namely <a href="https://jupyter.org/" rel="nofollow">jupyter notebook</a>,  <a href="https://xeus-cling.readthedocs.io/en/latest/" rel="nofollow">xeus cling</a> and of course <a href="https://root.cern.ch/cling">cling</a>. More info <a href="https://code-ballads.net/generated-notebooks/cpp/repl_cling/markdown/">in the notebooks themselves.</a></p><p></p><p></p><p></p><p></p>]]></content:encoded></item></channel></rss>