<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Christian Parpart</title>
    <description>The latest articles on DEV Community by Christian Parpart (@christianparpart).</description>
    <link>https://dev.to/christianparpart</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F136285%2F95b5a0c7-9553-4d5e-867f-fe58f631baf7.jpeg</url>
      <title>DEV Community: Christian Parpart</title>
      <link>https://dev.to/christianparpart</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/christianparpart"/>
    <language>en</language>
    <item>
      <title>A Look into a terminal emulator's text stack</title>
      <dc:creator>Christian Parpart</dc:creator>
      <pubDate>Tue, 07 Sep 2021 19:02:43 +0000</pubDate>
      <link>https://dev.to/christianparpart/look-into-a-terminal-emulator-s-text-stack-3poe</link>
      <guid>https://dev.to/christianparpart/look-into-a-terminal-emulator-s-text-stack-3poe</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I am going to describe how I implement rendering text in my terminal emulator so that we get programming ligatures, emoji, variation selectors, and yes, even ZWJ emoji.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Text rendering in a virtual terminal emulator can be as simple as just iterating over each grid cell's character, mapping it to a Font's bitmap glyph, and rendering it to the target surface at the appropriate position. But it can also be as complex as a web browser's text stack[1] if one may want to do it right.&lt;/p&gt;

&lt;p&gt;In contrast to web browsers (or word processors),&lt;br&gt;
terminal emulators are still rendering text the way they did render text 50 years ago - plus some non-standard extensions that did arise over the decades.&lt;/p&gt;

&lt;p&gt;Also, terminal screens weren't made with Unicode in mind, Unicode did not even exist back then, so there were a few workarounds and non-standardized ideas implemented in order to display complex Unicode text and symbols in terminals without a common formal ground that terminal application developers can rely on.&lt;/p&gt;

&lt;p&gt;Text rendering in a terminal emulator puts some additional constraints on how to render, mostly because character placement is decided before text shaping is performed and must align to a fixed-size grid, which makes it almost impossible to properly render traditional Japanese text into the terminal, or Hewbrew right-to-left text (though, there is a handful of virtual terminal emulators that specialize&lt;br&gt;
on the latter and an informal agreement on how to deal with wide characters on the terminal screen).&lt;/p&gt;

&lt;p&gt;Not every character, or to be displayed symbol (such as Emoji) is as wide as exactly one grid cell's width, so additional measurements have to be taken into account for dealing with these characters as well.&lt;/p&gt;

&lt;p&gt;Terminals and terminal applications until now did depend on a standard library API call &lt;code&gt;wcwidth()&lt;/code&gt; that does ideally return the number of grid cells that an input character will occupy. This however became useless as soon as multi codepoint grapheme clusters have been introduced that still form a single user perceived character. &lt;code&gt;wcswidh()&lt;/code&gt; should return the total number of grid cells of a sequence of characters, but these do not handle grapheme clusters nor variation selectors either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unicode - a very quick rundown in the context of terminals
&lt;/h2&gt;

&lt;p&gt;Unicode is aiming to have one huge universal space where every imaginable "user perceived character" can be represented. A "user perceived character" is what the user that looks at that character thinks of as one unit. This is in direct contrast to what a character is in computer science. A "user perceived character" can be as simple as one single codepoint (32-bit value representing that&lt;br&gt;
character) and as complex as an ordered sequence of 7 unbreakable codepoints to compose one single "user perceived character".&lt;/p&gt;

&lt;p&gt;This places additional requirements to a virtual terminal emulator where each grid cell SHOULD contain exactly one &lt;em&gt;"user perceived character"&lt;/em&gt; (also known as &lt;em&gt;grapheme cluster&lt;/em&gt;), that is, an unbreakable codepoint sequence of one or more codepoints that must not be broken up into multiple grid cells before the actual text shaping or screen rendering has been performed.&lt;/p&gt;

&lt;p&gt;Also, some grapheme clusters take up more than one grid cell in terms of display width, such as Emoji usually take two grid cells in width in order to merely match the Unicode (TR 51, section 2.2) specification's wording that the best practice to display Emoji is to render them in a square block to match the behavior of the old japanese phone companies that that first introduced Emoji.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering text - a top level view
&lt;/h2&gt;

&lt;p&gt;A terminal emulator's screen is divided into fixed width and (not necessarily equal) fixed height grid cells.&lt;br&gt;
When rendering this grid, it is sufficient to iterate over each line and column and render each grid cell individually, at least when doing basic rendering.&lt;/p&gt;

&lt;p&gt;Now, when non-trivial user perceived characters need to be supported, the rendering cannot just render each character individually, but must be first grouped into smaller chunks of text with common shared properties, across the grid cell boundaries.&lt;/p&gt;

&lt;p&gt;Here we enter the world text shaping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Shaping
&lt;/h2&gt;

&lt;p&gt;Simply put, text shaping is the process of translating a sequence of codepoints into glyphs and their glyph positions. This differs from normal text processors and web browsers in a way because glyph placement in virtual terminal emulators are constrained.&lt;/p&gt;

&lt;p&gt;When shaping text of a single grid line, the line is split into words, delimited by spaces, gaps and SGR attributes, that is, each word must represent the same SGR attributes for every "user perceived character" - for example the text's font style (such as bold or italic) or background color must be equal for each position in this sequence, from now on called "word").&lt;/p&gt;

&lt;p&gt;The word can be used as a cacheable unit, in order to significantly speed up rendering for future renders.&lt;br&gt;
The cache key is composed of the codepoint sequence of that word, as well as, the common shared SGR attributes.&lt;/p&gt;

&lt;p&gt;This cacheable word is further segmented into sub runs by a series categories before text shaping can occur, that is, by Unicode script attribute (such as Latin or Hangul) and by symbol presentation (such as Emoji text presentation or Emoji presentation). This is important because one cannot just pass a string of text to the underlying text shaping engine with mixed properties, such as Hebrew text along with some Latin and Kanji or Emoji in between or a font style change for obvious reasons.&lt;br&gt;
Each segment (usually called run) must be shaped individually with its own set of fallback fonts. Emoji are using a different font and font fallback list than regular text which uses a different font and font fallback list then bold, italic, or bold italic fonts.&lt;br&gt;
Emoji also have two different presentation styles, the one that everybody expects and is named Emoji Emoji presentation (double-width colored Emoji) and the other one is named Emoji text presentation, which renders Emoji in non-colored text-alike pictograms.&lt;/p&gt;

&lt;p&gt;The result of all sub runs is composing the sequence of glyph indices and glyph positions and is used as the cache value for the cacheable word to be passed to the next stage, the text renderer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Rendering
&lt;/h2&gt;

&lt;p&gt;The text renderer receives an already pre-shaped string of glyphs and glyph positions relative to screen coordinates of the first glyph to be rendered onto the screen.&lt;/p&gt;

&lt;p&gt;In order to lower the pressure on the GPU and reduce synchronization times between CPU and GPU, all glyph bitmaps are stored into a texture atlas on the GPU, such that the text rendering (when everything has been already uploaded once) just needs to deal with indices to those glyph bitmaps into the appropriate texture atlas as well as screen coordinates where to render those glyphs on the target surface.&lt;/p&gt;

&lt;p&gt;There is one texture atlas for gray scaled glyphs (this is usually standard text) as well as one texture atlas for colored glyphs (usually colored Emoji). Additionally there can be a third type of texture atlas for storing LCD anti-aliased bitmap glyphs.&lt;/p&gt;

&lt;p&gt;Now, when rendering a string of glyphs and glyph positions, each glyph's texture atlas ID and atlas texture coordinate is appended into an atlas coordinate array along with each glyph's absolute screen coordinate and color attributes into a vertex buffer to be uploaded to the GPU.&lt;/p&gt;

&lt;p&gt;When iterating over the whole screen buffer has finished, the atlas texture and vertex buffer are filled with all glyphs and related information that are required for rendering one frame. These buffers are then uploaded to the GPU to be drawn in a single GPU render command (such as &lt;code&gt;glDrawArrays&lt;/code&gt;, or &lt;code&gt;glDrawElements&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Terminal Emulator related Challenges
&lt;/h2&gt;

&lt;p&gt;Most terminal applications use &lt;code&gt;wcwidth()&lt;/code&gt; to detect the width of a potential "wide character". This is broken by design and a terminal emulator has to deal with such broken client applications. Some however use utf8proc's &lt;code&gt;utf8proc_charwidth&lt;/code&gt;, another library to deal with Unicode,&lt;br&gt;
and maybe some are using &lt;code&gt;wcswidth()&lt;/code&gt;, which doesn't handle grapheme clusters nor variation selectors either.&lt;/p&gt;

&lt;p&gt;The suggested way for future applications (emulator and client) would be to introduce feature detection and mode switching on how to process grapheme clusters and their width, if legacy apps are of concern.&lt;/p&gt;

&lt;p&gt;Just looking at the algorithm, implementing grapheme cluster segmentation isn't too hard but in execution very expensive. Also grapheme cluster width computation is expensive. But luckily, in the context of terminal emulators, both can be optimized for the general case in terminal emulators, which is mostly US-ASCII, and yields almost no penalty with optimizations or a ~60% performance penalty when naively implemented.&lt;/p&gt;

&lt;p&gt;Also, implementing proper text shaping into a fixed-grid terminal wasn't really the easiest when there is no other project or text to look at. I used "Blink's text stack" documentation and the Blink's source code (the Web renderer of Google Chrome) as bases and source of truth to understand this complex topic and then mapped my findings to the terminal world.&lt;/p&gt;

&lt;p&gt;Since text shaping &lt;em&gt;IS&lt;/em&gt; expensive, this cannot be done without caching without severely hurting user experience.&lt;/p&gt;

&lt;p&gt;After investigating into the above optimization possibilities however, I do not see why a terminal emulator should &lt;em&gt;not&lt;/em&gt; do provide support for complex Unicode, as the performance I have achieved so far is above average at least, and therefore should be sufficient for everyday use.&lt;/p&gt;

&lt;p&gt;Bidirectional text was not addressed in this document nor in the implementation in the Contour terminal yet, as this imposes a new set of challenges that have to be dealt with separately. If that is of interest, there are a few terminals (such as mlterm) that have put great effort in getting such scripts into the terminal.&lt;br&gt;
Hopefully this will be eventually added (or contributed) to my project at any time in the future, too and if so, I'll update this document accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If one went through all the pain on how Unicode, text segmentation, and text shaping works, you will be rewarded with a terminal emulator that is capable of rendering complex Unicode. At least as much as most of us desire - being able to use (power user/) programming ligatures and composed Emoji.&lt;/p&gt;

&lt;p&gt;Some terminal emulators do partly support ligatures or rendering trivial single codepoint Emoji or a few of the composed Emoji codepoint sequences, but sadly, most seem to get Emoji wrong. While this is a great start, I'd say we can deliver better and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;I'd like to see the whole virtual terminal emulator world to join forces and agree on how to properly deal with complex text in a somewhat future-proof way.&lt;/p&gt;

&lt;p&gt;And while we would be in such an ideal world, we could even throw away all the other legacies that are inevitably inherited from the ancient VT standards that are partly even older than I am. What would we be without dreams. ;-)&lt;/p&gt;

&lt;p&gt;Some other terminal emulator developers and I have&lt;br&gt;
&lt;a href="https://github.com/contour-terminal/contour/issues/404"&gt;started to address&lt;/a&gt; at least some of the many Unicode problems that are up until now undefined behavior by creating a &lt;a href="https://github.com/contour-terminal/terminal-unicode-core"&gt;formal specification&lt;/a&gt; on how a terminal emulator should behave in a backward and forward compatible way so that app developers and users will benefit.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/platform/fonts/README.md"&gt;Blink's text stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://unicode.org/reports/tr11/"&gt;UTS 11&lt;/a&gt; - character width&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://unicode.org/reports/tr24/"&gt;UTS 24&lt;/a&gt; - script property&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://unicode.org/reports/tr29/"&gt;UTS 29&lt;/a&gt; - text segmentation (grapheme cluster, word boundary)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://unicode.org/reports/tr51/"&gt;UTS 51&lt;/a&gt; - Emoji&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>terminal</category>
      <category>unicode</category>
      <category>emoji</category>
    </item>
    <item>
      <title>Builtin Solidity Language Server</title>
      <dc:creator>Christian Parpart</dc:creator>
      <pubDate>Tue, 06 Apr 2021 12:23:57 +0000</pubDate>
      <link>https://dev.to/christianparpart/builtin-solidity-language-server-267n</link>
      <guid>https://dev.to/christianparpart/builtin-solidity-language-server-267n</guid>
      <description>&lt;p&gt;Hey fellows!&lt;/p&gt;

&lt;p&gt;At Ethereum I am currently part time developing a language server mode as part of the solidity compiler.&lt;br&gt;
While this is still in early development stage, the 3 features I am currently concentrating on are already working:&lt;/p&gt;

&lt;p&gt;✅ compiler diagnostics&lt;br&gt;
✅ goto definition (also works across files)&lt;br&gt;
✅ find all references (does not &lt;em&gt;yet&lt;/em&gt; work across files)&lt;br&gt;
✅ semantic highlighting&lt;/p&gt;

&lt;p&gt;While this is not much, it is a good starting point to not reinvent the wheel but reuse the existing compiler infrastructure to implement a language server on top of it.&lt;/p&gt;

&lt;p&gt;For those of you being curious, I would now like to show you how to use it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Vim/NeoVim with coc.nvim
&lt;/h2&gt;

&lt;p&gt;This is actually what I am using and your &lt;code&gt;coc-settings.json&lt;/code&gt; would be extended like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"languageserver"&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="err"&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="nl"&gt;"solidity"&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="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/solc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"args"&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="s2"&gt;"--lsp"&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="nl"&gt;"trace.server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"verbose"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"rootPatterns"&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="s2"&gt;".git/"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"filetypes"&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="s2"&gt;"solidity"&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So assuming you already have &lt;a href="//coc.nvim"&gt;https://github.com/neoclide/coc.nvim&lt;/a&gt; installed and working that is all you need to add to it. Now of course you need to have a &lt;code&gt;solc&lt;/code&gt; binary available that does indeed support the new command line parameter &lt;code&gt;--lsp&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download a &lt;code&gt;solc&lt;/code&gt; with LSP support
&lt;/h3&gt;

&lt;p&gt;I've uploaded a prototype version here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/christianparpart/solidity-language-client-vscode/releases/download/TP_1/solc-linux64"&gt;https://github.com/christianparpart/solidity-language-client-vscode/releases/download/TP_1/solc-linux64&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Visual Studio Code!
&lt;/h2&gt;

&lt;p&gt;When you are on a 64bit Linux, you are lucky. The VScode extension does provide a builtin LSP server that you can use. Other platforms (such as OS/X or Windows) I will provide some precompiled LSP-compatible &lt;code&gt;solc&lt;/code&gt; executables and even some syntax highlighting, but give me some time on that.&lt;/p&gt;

&lt;p&gt;So for VScode, I have just written the glue code extension last week and you can download here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/christianparpart/solidity-language-client-vscode/releases/tag/TP_1"&gt;https://github.com/christianparpart/solidity-language-client-vscode/releases/tag/TP_1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fetch the &lt;code&gt;.vsix&lt;/code&gt; file and then run the following command in your virtual terminal emulator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code &lt;span class="nt"&gt;--install-extension&lt;/span&gt; solidity-0.0.1.vsix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start (or restart) your VScode and you should be all set. If you now want to use your own &lt;code&gt;solc&lt;/code&gt; binary (which should more frequently update), then you can configure that in your local &lt;code&gt;settings.json&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Solidity.solc.path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/solc"&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="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;builtin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;should&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;used&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Solidity.trace.server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"messages"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bare in mind, if you already had another solidity related extension loaded in VScode you may want to see if you should disable that to not cause any conflicts or confusions. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Editors
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;solc&lt;/code&gt;'s &lt;code&gt;--lsp&lt;/code&gt; mode does use standard Input/Output streams (&lt;code&gt;stdio&lt;/code&gt;) for communicating with the client. This is fairly standard. In QtCreator for example you can just go to the IDE's config page and put in the path to the &lt;code&gt;solc&lt;/code&gt; executable, and configure on what file extensions to use that LSP for and you're done with it. I want to try out Neovim's native language client interface at some point, but I am certain it'll just work like any other in this sense. :-)&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Outlook
&lt;/h2&gt;

&lt;p&gt;🔨 improving goto definition / find all references / semantic highlighting&lt;br&gt;
🔨 show type signature on hover&lt;br&gt;
🔨 show natspec documentation on hover&lt;br&gt;
🔨 show IR / EVM byte code / gas costs on hover&lt;br&gt;
🔨 code completion at least on &lt;code&gt;.&lt;/code&gt;&lt;br&gt;
🔨 publish the VScode extension to the VScode marketplace&lt;br&gt;
🔨 configurable list of warning/error codes to suppress?&lt;br&gt;
🔨 and maybe we can integrate that in Remix, too?&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;I really hope you enjoy doing some early testing on this Solidity language server. Please keep in mind that the features are indeed minimal but slowly I would like to improve on that. Tell me what you feel about it, what you would like to have the most and/or what should be different.&lt;/p&gt;

&lt;p&gt;If you are interested in how to build Solidity compiler (including the language server) from source, please drop me a comment and I can do that in a separate post then.&lt;/p&gt;

&lt;p&gt;Have fun and take care!&lt;br&gt;
Christian.&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>lsp</category>
      <category>vscode</category>
      <category>vim</category>
    </item>
    <item>
      <title>Functional C++</title>
      <dc:creator>Christian Parpart</dc:creator>
      <pubDate>Thu, 03 Oct 2019 12:30:17 +0000</pubDate>
      <link>https://dev.to/christianparpart/functional-c-9g4</link>
      <guid>https://dev.to/christianparpart/functional-c-9g4</guid>
      <description>&lt;h1&gt;
  
  
  Functional Programming in C++
&lt;/h1&gt;

&lt;p&gt;When I learned about C++, around 28 years ago, it's been just labeled as an object oriented programming language, or C with classes and a stronger type system than C.&lt;/p&gt;

&lt;p&gt;Now, with the rise of functional programming outside universities since quite some years, the hype has also landed in C++, starting at C++11 and the introduction of lambdas.&lt;/p&gt;

&lt;p&gt;One may very well code purely procedural in C++, or purely object oriented. It's just a matter of style. C++ is a very complex programming language, sadly, but that doesn't mean you &lt;strong&gt;have&lt;/strong&gt; to use it all, just because your tool provides this - a common beginners mistake.&lt;/p&gt;

&lt;p&gt;However, there are some advantages in using a functional programming style, and what I like most about, are algebraic data types (ADT), that are most sexy declared in first-class functional programming languages (such as F# and alike), but also possible in C++ (one may want to read a future post on this subject right here).&lt;/p&gt;

&lt;p&gt;So what's so bad about the imperative style?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;doSomething&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="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Having a look at this example, the first thing one may note is the index variable being of type &lt;code&gt;int&lt;/code&gt;. However, the comparison operator &lt;code&gt;&amp;lt;&lt;/code&gt; on its right side has an operand of type &lt;code&gt;size_t&lt;/code&gt; (unsigned, most importantly). You can't always compare this, and nowadays some compilers warn (some not), which can render into a bug. Not to mention, that sometimes the loop body may become bigger, and then it's not entirely clear that the index variable &lt;code&gt;i&lt;/code&gt; is only and really only modified in the loop header, which isn't guaranteed because it is a mutable variable.&lt;br&gt;
Also, &lt;code&gt;i&lt;/code&gt; is only used for referencing the elemeent, nothing else, so we would ideally not reserve another variable just for this - can we avoid that?&lt;/p&gt;

&lt;p&gt;So in functional programming style, you'd write that as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// using namespace std;&lt;/span&gt;
&lt;span class="c1"&gt;// using std::placeholders::_1;&lt;/span&gt;

&lt;span class="n"&gt;for_each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;begin&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="n"&gt;end&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="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This limits the class of errors and uncertainties I mentioned above.&lt;/p&gt;

&lt;p&gt;So how would one now sum up an array or list of elements?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="k"&gt;constexpr&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accumulate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&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;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"sum of elements: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The function &lt;code&gt;accumulate&lt;/code&gt; is from the numeric header, check out &lt;a href="https://en.cppreference.com/w/cpp/algorithm/accumulate"&gt;cppreference.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So what is so good about it?&lt;/p&gt;

&lt;p&gt;It not potentially reduces the lines of code by reusing existing STL functions (such as &lt;code&gt;std::accumulate&lt;/code&gt; or &lt;code&gt;std::for_each&lt;/code&gt;) but also eliminates mutability, which greatly helps code maintenance due to lesser questions to care about when reading foreign code, but also helps the compiler generating more efficient code.&lt;/p&gt;

&lt;p&gt;By using algorithms that have been implemented by others, and used by many, such as the C++ standard library, the chances that those code parts are buggier is also lesser likely than doing it all by your own.&lt;/p&gt;

&lt;p&gt;This way of thinking, even in C++, helps you writing more clean code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In the end, it's always a personal matter of taste. Do you like imperative, procedural, object oriented, or functional programming paradigms? It's at least good to know, that with modern C++ (my code snippets require C++17 above) you have the choice.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Sneak Peak
&lt;/h1&gt;

&lt;p&gt;I'd also like to talk about algebraic data types in C++17, all the good parts that make C++17 fantastic, and all the amazing improvements about to come in C++20.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>cpp17</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
