<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>Luca Bolognese's Blog</title>
        <link>https://www.lucabol.com</link>
        <description>Personal blog of Luca Bolognese</description>
        <language>en-us</language>
        <lastBuildDate>Tue, 05 May 2026 10:46:27 GMT</lastBuildDate>
        
        <item>
            <title>The Hooks</title>
            <link>https://www.lucabol.com/posts/2026-05-05-the-hooks.html</link>
            <description>&lt;p&gt;&lt;img src="/img/butcher.jpg" alt="A butcher shop with hooks" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;The money was gone. The husband&amp;rsquo;s business had dried up.&lt;/p&gt;
&lt;p&gt;Elena had long black hair. She was small. Her hands were soft. She had never used them for work.&lt;/p&gt;
&lt;p&gt;She went to the village and to the butcher.&lt;/p&gt;
&lt;p&gt;Bruno was a big man with thick arms. His hands were red and split at the knuckles.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You cut?&amp;rdquo; Bruno said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;No.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You will,&amp;rdquo; he said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I will learn.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Apron.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The shop smelled of sawdust and meat.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Not like that,&amp;rdquo; Bruno said.&lt;/p&gt;
&lt;p&gt;She did not stop.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Again.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She did it again. Bruno took the parcel and pressed it flat with his palm.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Too loose.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She did not change it.&lt;/p&gt;
&lt;p&gt;Bruno looked at it. &amp;ldquo;Again.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She tightened the string.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Better,&amp;rdquo; he said.&lt;/p&gt;
&lt;p&gt;The next day, a man came in. Tall and thin.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;She doesn&amp;rsquo;t talk.&amp;rdquo;, he said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;She works,&amp;rdquo; Bruno said.&lt;/p&gt;
&lt;p&gt;The man looked past him. Bruno did not move. The man paid and left.&lt;/p&gt;
&lt;p&gt;One day, rain fell hard against the glass. The shop was empty.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Lock the door,&amp;rdquo; Bruno said.&lt;/p&gt;
&lt;p&gt;She locked it.&lt;/p&gt;
&lt;p&gt;Bruno finished the cut and set the knife down. He wiped his hands.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Come,&amp;rdquo; he said.&lt;/p&gt;
&lt;p&gt;He took her wrist.&lt;/p&gt;
&lt;p&gt;They went into the cellar.&lt;/p&gt;
&lt;p&gt;The hooks hung in their rows, pale and still.&lt;/p&gt;
&lt;p&gt;After, Bruno set the knives in the sink.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Wash.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She washed them. The water ran pink, then clear.&lt;/p&gt;
&lt;p&gt;At dinner Tomas watched her hands.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You work late,&amp;rdquo; he said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Yes.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;He cut his food.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You stay late.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She did not answer.&lt;/p&gt;
&lt;p&gt;He nodded.&lt;/p&gt;
&lt;p&gt;The next day, the door of the shop was unlocked.&lt;/p&gt;
&lt;p&gt;Tomas entered. He saw them go into the cellar. He did not move.&lt;/p&gt;
&lt;p&gt;When they came out, he stepped forward.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You forgot to close the door,&amp;rdquo; he said.&lt;/p&gt;
&lt;p&gt;Bruno looked at him. &amp;ldquo;No.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Tomas nodded.&lt;/p&gt;
&lt;p&gt;Later, it was warm and they all sat on the terrace.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;The meat is good,&amp;rdquo; Tomas said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;It is the best,&amp;rdquo; Bruno said.&lt;/p&gt;
&lt;p&gt;Tomas poured the wine.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You should come to the sea with us,&amp;rdquo; Tomas said.&lt;/p&gt;
&lt;p&gt;Bruno looked at him.&lt;/p&gt;
&lt;p&gt;Tomas waited.&lt;/p&gt;
&lt;p&gt;Elena did not move.&lt;/p&gt;
&lt;p&gt;Tomas saw her and did not look away.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Yes,&amp;rdquo; Bruno said.&lt;/p&gt;
&lt;p&gt;Inside the house, Tomas stood.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Come,&amp;rdquo; he said.&lt;/p&gt;
&lt;p&gt;They all went into the bedroom.&lt;/p&gt;
&lt;p&gt;The door closed.&lt;/p&gt;
&lt;p&gt;Later, in the shop, the air was cold. The hooks hung in their rows, clean and still.&lt;/p&gt;
&lt;p&gt;Elena stood with the paper in her hands. Bruno was at the block. Tomas stood in the doorway.&lt;/p&gt;
&lt;p&gt;She did not look away.&lt;/p&gt;
&lt;p&gt;A hook moved once. Slow.&lt;/p&gt;</description>
            <pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-05-05-the-hooks.html</guid>
        </item>
        
        <item>
            <title>Too Light to Hold</title>
            <link>https://www.lucabol.com/posts/2026-04-16-too-light-to-hold.html</link>
            <description>&lt;p&gt;&lt;img src="/img/girlriver.jpg" alt="A girl standing by a river" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Dust lay thick on the path and held her weight. The sun was low. It was a long walk to the river, but the house was hot and smelled of tobacco and the men. Maria walked with her hips stiff. Red marks showed at the small of her back. Her thighs carried a dull, heavy heat.&lt;/p&gt;
&lt;p&gt;The river ran fast. Cold. It broke over grey stones in the shallows and made a sound like wind moving through leaves. Maria sat on a flat rock and took off her boots. She stepped into the water. Skin-stinging cold. Good. The current pulled at her ankles, trying to carry her downstream, but she stood firm. The river did not care about the house or the money. It moved.&lt;/p&gt;
&lt;p&gt;She took a piece of grey lye soap from her pocket and began to wash. Her legs first. Then the places where the men had been. Cold water over her skin. Quick. Hard. A kingfisher dived into the pool near the reeds. It struck the water fast and came up with nothing, then lifted to a high branch to wait again. Maria watched it and scrubbed until her skin was pink and the soap was gone.&lt;/p&gt;
&lt;p&gt;She sat on the bank to dry. A yellow butterfly landed on a piece of damp, rotting drift log near her feet. It opened and closed its wings. Bright against the rot. It rested for a moment, searching in the decay, and then a gust of wind took it. Too light to hold, carried toward the dark trees and gone.&lt;/p&gt;
&lt;p&gt;Evening chill. She pulled on her dress. The fabric was damp and clung to her skin like a second layer of sweat, but it was clean. The working face coming back. The mask settling into place. She looked at the river one last time. Darker now. It carried the silt and the suds and the memories of the afternoon away toward the sea. The river stayed clean by moving. She could not stop.&lt;/p&gt;
&lt;p&gt;Back up the path. The incline shortened her breath. The house appeared through the trees, its porch light a yellow smear against the purple sky. Moths gathered thick around the bulb, striking the glass with soft, blind thuds.&lt;/p&gt;
&lt;p&gt;The men were there. In a line near the fence. Leaning against the wood or checking their watches. The Baker, smelling of flour and stale sweat. The Clerk with the nervous eyes who always looked at his boots.&lt;/p&gt;
&lt;p&gt;And the Young Man.&lt;/p&gt;
&lt;p&gt;A clean white shirt. Hair combed back with water. He saw Maria coming up the path and stepped forward. His face held an imagined thing. He looked at her as if they shared a secret. As if he were the one who would take her away from the river and the house and the dust. He stood as if his love would hold.&lt;/p&gt;
&lt;p&gt;Maria looked at him. The white shirt. The hope in his eyes. The yellow butterfly on the rotting log.&lt;/p&gt;
&lt;p&gt;No malice.&lt;/br&gt;
No hate.&lt;/br&gt;
Only the weight of the night beginning again.&lt;/p&gt;
&lt;p&gt;She nodded as she passed the line.&lt;/br&gt;
He smiled.&lt;/br&gt;
A quick, breaking smile.&lt;/br&gt;
He thought it would hold.&lt;/p&gt;
&lt;p&gt;It only meant he was next.&lt;/p&gt;</description>
            <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-04-16-too-light-to-hold.html</guid>
        </item>
        
        <item>
            <title>I wrote a C runtime from scratch</title>
            <link>https://www.lucabol.com/posts/2026-03-27-i-wrote-a-c-runtime-from-scratch.html</link>
            <description>&lt;p&gt;I wanted to understand what happens between my C code and the hardware. Not in theory — I&amp;rsquo;ve read the textbooks. I wanted to feel it: write the syscalls, handle the startup, own every byte in the binary.&lt;/p&gt;
&lt;p&gt;So I wrote a small C runtime from scratch: &lt;a href="https://github.com/lucabol/laststanding"&gt;lucabol/laststanding&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s three header files. &lt;code&gt;l_os.h&lt;/code&gt; gives you the basics — strings, memory, file I/O, processes, pipes, terminal control. All implemented with direct syscall wrappers, no libc anywhere. &lt;code&gt;l_gfx.h&lt;/code&gt; adds pixel graphics — drawing primitives, a bitmap font, keyboard and mouse input. &lt;code&gt;l_ui.h&lt;/code&gt; builds on that with immediate-mode UI widgets: buttons, sliders, checkboxes, text inputs.&lt;/p&gt;
&lt;p&gt;It runs on Linux (x86_64, ARM, AArch64) and Windows. Binaries are statically linked, stripped, and typically 2–10 KB. A hello world on ARM compiles to 676 bytes.&lt;/p&gt;
&lt;p&gt;The repo includes a dozen small Unix-style utilities (grep, sort, wc, ls), a Vim-style text editor, a shell that can run itself, a snake game, a Mandelbrot renderer, and several graphical demos — plasma, starfield, Doom-style fire, Conway&amp;rsquo;s Life, an analog clock. Plus a couple of UI demos showing forms and sliders. Everything compiles with &lt;code&gt;-ffreestanding -nostdlib&lt;/code&gt; and nothing links to libc.&lt;/p&gt;
&lt;p&gt;The whole thing is built around static inline functions, so you only pay for what you use. On Linux, syscalls go through inline assembly. On Windows, it calls Win32 APIs directly with UTF-8 to UTF-16 conversion at the boundary. The graphics layer writes to the Linux framebuffer or opens a native GDI window. The UI is immediate-mode: no heap, no widget tree, just declare your widgets every frame.&lt;/p&gt;
&lt;p&gt;AI helped enormously. I used it to scaffold the initial code, write tests across four architectures, debug platform differences, and iterate on the API design. What would have taken weeks of manual cross-platform plumbing happened in days. The CI runs 22 targets — Windows, Linux, ARM32, AArch64, each with gcc and clang — and AI helped get them all green.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not a production library. It&amp;rsquo;s a learning project that got slightly out of hand. But there&amp;rsquo;s something satisfying about a binary that contains nothing you didn&amp;rsquo;t put there yourself.&lt;/p&gt;</description>
            <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-03-27-i-wrote-a-c-runtime-from-scratch.html</guid>
        </item>
        
        <item>
            <title>Notes: The Metamorphosis — Franz Kafka</title>
            <link>https://www.lucabol.com/posts/2026-03-27-notes-the-metamorphosis-franz-kafka.html</link>
            <description>&lt;h2&gt;Part I: The Discovery&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Transformation:&lt;/strong&gt; Gregor Samsa, a traveling salesman, wakes up to find himself transformed into a &amp;ldquo;monstrous vermin.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anxiety Over Work:&lt;/strong&gt; Despite his condition, his primary fear is being late for his train. He is the sole financial provider for his parents and sister.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Reveal:&lt;/strong&gt; His office manager arrives to check on him. When Gregor finally opens the door, the manager flees in horror, and his mother collapses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The First Injury:&lt;/strong&gt; His father violently herds Gregor back into his room using a cane and a newspaper, causing Gregor to bleed as he is shoved through the narrow doorway.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Part II: Adaptation and Isolation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Grete&amp;rsquo;s Care:&lt;/strong&gt; His sister, Grete, becomes his sole caretaker. She discovers he now prefers eating rotting scraps over fresh food.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Losing Humanity:&lt;/strong&gt; Grete and their mother decide to remove the furniture from Gregor&amp;rsquo;s room to give him more space to crawl. Gregor feels his humanity slipping away and tries to &amp;ldquo;save&amp;rdquo; a framed picture of a woman in furs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Apple Incident:&lt;/strong&gt; Seeing Gregor out of his room, his mother faints. His father, misinterpreting the situation, chases Gregor and pelts him with apples. One apple lodges in Gregor&amp;rsquo;s back and is left there to rot, causing a severe, permanent wound.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Part III: The Decline and Aftermath&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Financial Strain:&lt;/strong&gt; The family&amp;rsquo;s finances dwindle. They take in three boarders to make money, and Gregor&amp;rsquo;s room becomes a storage area for trash and old furniture.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Violin Performance:&lt;/strong&gt; Drawn by the sound of Grete playing the violin for the boarders, a dusty and weakened Gregor creeps into the living room.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Breaking Point:&lt;/strong&gt; The boarders are horrified and refuse to pay. Grete, exhausted by the burden, declares that the family must get rid of &amp;ldquo;it,&amp;rdquo; claiming that if it were truly Gregor, he would have left them long ago to spare them suffering.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gregor&amp;rsquo;s Death:&lt;/strong&gt; Hearing this, Gregor retreats to his room. He dies that night, feeling a sense of love and &amp;ldquo;empty peace&amp;rdquo; toward his family.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Renewal:&lt;/strong&gt; The family feels an immediate sense of relief. They take a day off, go for a walk in the countryside, and realize that Grete has grown into a beautiful woman with a bright future ahead of her.&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-03-27-notes-the-metamorphosis-franz-kafka.html</guid>
        </item>
        
        <item>
            <title>Notes: The Picture of Dorian Gray - Oscar Wilde</title>
            <link>https://www.lucabol.com/posts/2026-03-27-notes-the-picture-of-dorian-gray-oscar-wilde.html</link>
            <description>&lt;h2&gt;Part I: The Innocent Muse&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Portrait:&lt;/strong&gt; The talented artist Basil Hallward paints a full-length portrait of the strikingly beautiful and innocent young Dorian Gray.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lord Henry&amp;rsquo;s Influence:&lt;/strong&gt; At Basil&amp;rsquo;s studio, Dorian meets Lord Henry Wotton, a cynical aristocrat who espouses a philosophy of &amp;ldquo;New Hedonism,&amp;rdquo; claiming that youth and beauty are the only things worth living for.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Fatal Wish:&lt;/strong&gt; Terrified of aging, Dorian utters a fateful wish: that he could remain young while the portrait bears the marks of time and his sins instead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sybil Vane:&lt;/strong&gt; Dorian falls in love with a young, talented actress named Sybil Vane. However, after he brings Basil and Henry to see her perform, she acts poorly because her love for Dorian has made her realize the &amp;ldquo;hollowness&amp;rdquo; of the stage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The First Change:&lt;/strong&gt; Dorian cruelly rejects Sybil, telling her she has killed his love. When he returns home, he notices a touch of cruelty in the mouth of his portrait. Sybil commits suicide shortly after.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Part II: The Life of Sin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Hidden Room:&lt;/strong&gt; Following Lord Henry&amp;rsquo;s advice to view Sybil&amp;rsquo;s death as a &amp;ldquo;theatrical tragedy,&amp;rdquo; Dorian embraces a life of sensory pleasure. He hides the portrait in a locked attic to conceal its physical decay.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Yellow Book:&lt;/strong&gt; Lord Henry gives Dorian a &amp;ldquo;poisonous&amp;rdquo; French novel that chronicles the life of a man seeking every possible sensation. This book becomes Dorian&amp;rsquo;s blueprint for the next 18 years.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Social Ruin:&lt;/strong&gt; As the years pass, Dorian remains physically flawless, but rumors circulate about his &amp;ldquo;corrupting&amp;rdquo; influence. Many of his friends are socially ruined or driven to suicide after associating with him.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Murder of Basil:&lt;/strong&gt; Basil Hallward confronts Dorian about these rumors. Dorian shows Basil the hideous, rotting figure in the portrait. When Basil begs him to repent, Dorian, overcome by a sudden burst of hatred, stabs Basil to death.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disposing of the Evidence:&lt;/strong&gt; Dorian blackmails an old friend, a chemist named Alan Campbell, into using chemicals to dissolve Basil&amp;rsquo;s body.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Part III: The Final Reckoning&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;James Vane&amp;rsquo;s Revenge:&lt;/strong&gt; Sybil&amp;rsquo;s brother, James, hunts Dorian down to avenge her death. He is nearly successful but is momentarily fooled by Dorian&amp;rsquo;s youthful face. James is later killed accidentally during a hunting party.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A Failed Attempt at Virtue:&lt;/strong&gt; Dorian decides to &amp;ldquo;be good&amp;rdquo; and spares a young girl&amp;rsquo;s heart to see if the portrait improves. Upon checking the painting, he sees that the face has become even more hypocritical and loathsome.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The End of the Mirror:&lt;/strong&gt; In a fit of rage and desperation to destroy the evidence of his soul&amp;rsquo;s decay, Dorian stabs the portrait with the same knife he used to kill Basil.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Transformation:&lt;/strong&gt; A crash and a scream are heard. The servants enter to find the portrait restored to its original, beautiful state. On the floor lies a withered, wrinkled, and &amp;ldquo;loathsome&amp;rdquo; old man with a knife in his heart, identifiable only by his rings.&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-03-27-notes-the-picture-of-dorian-gray-oscar-wilde.html</guid>
        </item>
        
        <item>
            <title>I built my own notes app (with a lot of help from AI)</title>
            <link>https://www.lucabol.com/posts/2026-03-26-i-built-my-own-notes-app-with-a-lot-of-help-from-ai.html</link>
            <description>&lt;p&gt;I recently moved away from a paid notes product and built my own replacement: &lt;a href="https://github.com/lucabol/notes"&gt;lucabol/notes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a long time I used a paid notes product because it was convenient, polished, and already there. But over time I realized I was mostly paying to work around someone else&amp;rsquo;s idea of how my notes should behave.&lt;/p&gt;
&lt;p&gt;So I did the most reasonable thing possible: I replaced it with a custom-made markdown notes tool built surprisingly fast with AI.&lt;/p&gt;
&lt;p&gt;Now my notes are just plain files. I have a CLI, a desktop GUI, import tools, tags, search, and no monthly fee quietly judging me from my credit card statement.&lt;/p&gt;
&lt;p&gt;What I like most is not just that it works — it feels mine. It matches how I think, how I organize things, and how I want the tool to evolve.&lt;/p&gt;
&lt;p&gt;Also, there is something deeply satisfying about leaving a subscription behind and replacing it with a folder full of markdown and a slightly unreasonable amount of PowerShell.&lt;/p&gt;
&lt;p&gt;AI made the build dramatically faster, but the interesting part wasn&amp;rsquo;t speed alone. It let me iterate on ideas quickly, fix annoyances immediately, and turn &amp;ldquo;I wish this app did X&amp;rdquo; into &amp;ldquo;fine, now it does.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not a giant startup product. It&amp;rsquo;s just my notes app. And honestly, that&amp;rsquo;s the whole point.&lt;/p&gt;</description>
            <pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-03-26-i-built-my-own-notes-app-with-a-lot-of-help-from-ai.html</guid>
        </item>
        
        <item>
            <title>A Good Life</title>
            <link>https://www.lucabol.com/posts/2026-03-12-a-good-life.html</link>
            <description>&lt;p&gt;&lt;img src="/img/girldevil.jpg" alt="A girl with a devilish smile" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;She woke late to a throbbing headache and the rhythmic flash of her phone&amp;rsquo;s blue light. Five likes and one dislike. One dislike! Her morning was ruined. She wondered if it was the new hair, but then dismissed it. It was the latest fashion; everyone was doing it. That couldn&amp;rsquo;t be it.&lt;/p&gt;
&lt;p&gt;She looked in the mirror. Her chubby face stared back, but she wasn&amp;rsquo;t worried; a chubby face was an easy fix. Her stream filter would streamline her jaw and deepen her skin tone, an &amp;ldquo;earth-toned&amp;rdquo; aesthetic was in vogue this week. Her natural skin was too pale for the Top 5. She knew the metrics; hence, the filter.&lt;/p&gt;
&lt;p&gt;The team had sourced a boyfriend for the week, selecting him from a pool of hundreds. They were streaming together later. In post-production, she would deepen her voice slightly to sound more &amp;ldquo;trustworthy.&amp;rdquo; The sound guy would handle the frequencies.&lt;/p&gt;
&lt;p&gt;Her morning routine was a work of art. It had been voted &amp;ldquo;BEST MORNING ROUTINE&amp;rdquo; in the 12-15 category two years running. The camera was hidden behind the bathroom mirror, capturing her as she brushed her teeth. Sometimes she would sing in the shower, not too well, not too poorly. You don&amp;rsquo;t want to show off. People hate that.&lt;/p&gt;
&lt;p&gt;She cultivated her mediocrity with intense discipline. It was her secret weapon. She wasn&amp;rsquo;t too funny, just enough to prompt an easy smile. She avoided anything difficult or deep. You don&amp;rsquo;t want to make anyone think.&lt;/p&gt;
&lt;p&gt;Her day was planned to the minute. You can&amp;rsquo;t make things up as you go; that&amp;rsquo;s the fastest way to drop in the CHART. You have to live deliberately.&lt;/p&gt;
&lt;p&gt;The morning was for &amp;ldquo;activities,&amp;rdquo; playing with the dog, for instance. Her ratings always spiked when she did that. But these things are temporary; the audience will eventually tire of the dog. She&amp;rsquo;ll have to phase him out. Maybe a &amp;ldquo;tragic accident&amp;rdquo; or a disappearance. Tragedies are excellent for the algorithm. For now, though, she cuddled him like there was no tomorrow. She called him Fluffy, the top choice of the focus group. Every detail counts.&lt;/p&gt;
&lt;p&gt;At lunch, she would perform the weight-loss arc. The standard script: the struggle, the relapse, the &amp;ldquo;journey.&amp;rdquo; Maybe some purging? Definitely some tears. She had the eye drops ready in her kit.&lt;/p&gt;
&lt;p&gt;The afternoon was equally full. That was when the &amp;ldquo;relationship&amp;rdquo; story would unfold. Maybe a breakup today, maybe not. It all depended on the live audience reaction. There were plenty of other accessories, other boyfriends, waiting in the wings.&lt;/p&gt;
&lt;p&gt;The evenings were for the chat. That was the trickiest part: staying lightly informal. She had to make it look personal without ever saying anything actually personal. Above all, she stayed away from the substantive. If you say something controversial, someone is bound to disagree. Disagreement is dangerous. It is not rocket science, folks.&lt;/p&gt;
&lt;p&gt;Before bed, she checked the Chart one last time. She had climbed a dozen positions in the past year alone. Not first class yet, but respectable.&lt;/p&gt;
&lt;p&gt;As she closed her eyes, she felt a deep sense of serenity. This was the life she had worked so hard for. She might as well enjoy it.&lt;/p&gt;</description>
            <pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-03-12-a-good-life.html</guid>
        </item>
        
        <item>
            <title>When the Tide Comes</title>
            <link>https://www.lucabol.com/posts/2026-01-03-when-the-tide-comes.html</link>
            <description>&lt;p&gt;&lt;img src="/img/OldManByTheSea.jpg" alt="Old man on the beach" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;The old man moves slowly now. It takes him longer to walk all the way to the beach. He goes through the mangrove trees following the narrow path to the shore. The sky is clouded. The wind is strong and the trees sway.&lt;/p&gt;
&lt;p&gt;When he reaches the beach, he stops. He takes off his sandals and walks on the wet sand. It is winter and he knows he should not do that.&lt;/p&gt;
&lt;p&gt;He looks at the road through the trees. The woman from the village arrives in an hour on her bicycle. She is forty now, he thinks. He never asked her age. They do not talk much. She comes to clean the house but that is not it.&lt;/p&gt;
&lt;p&gt;He suggested it. Once a week, he pays her well. The husband is a fisherman and is away. He doesn&amp;rsquo;t mind the cash, the old man reckons.&lt;/p&gt;
&lt;p&gt;They drink wine first. It gives her strength. There is nothing to like in an old man. But she comes and does what he asks. No passion, just the act. That is enough.&lt;/p&gt;
&lt;p&gt;Afterward she makes coffee. They chat. She tells him about her kids and he gives advice. She listens. Sometimes she smiles.&lt;/p&gt;
&lt;p&gt;The old man watches the sea. The waves are rough. The wind is cold. He does not know about kids. He was never a father to his child. He was on the oil rigs, earning a living, living away from them.&lt;/p&gt;
&lt;p&gt;Now it is late. His son is in another country. Finance or marketing. They talk on the phone. He does not understand the boy. The boy has a child of his own and they never visit.&lt;/p&gt;
&lt;p&gt;A gull flies over him, crying. The old man hunches to avoid it. His back hurts. He stands up and continues walking.&lt;/p&gt;
&lt;p&gt;It is a small beach. A stretch of sand between the trees and the sea. When he was home from the rigs, he came here with his wife. They made small talk and then there was silence. She resented him for being away. He didn&amp;rsquo;t blame her.&lt;/p&gt;
&lt;p&gt;Now he misses her. He misses the silence.&lt;/p&gt;
&lt;p&gt;There is a rock by the water. The dog used to run around it chasing the birds. A big white dog. He would be behind the door when he came home and wag his tail.&lt;/p&gt;
&lt;p&gt;The old man reaches the end of the beach. An old house sits on the rocks. The couple moved away years ago. They used to have cocktails on the porch. The man of the house liked the old man’s wife too much. He drank too much. It does not matter now. It never mattered.&lt;/p&gt;
&lt;p&gt;The old man turns back. The wind hits his face and he staggers. He closes his eyes and breathes. He feels the cold in his chest. It is a sharp cold.&lt;/p&gt;
&lt;p&gt;He sits down by the rock. The sand is wet and the tide is coming in. He thinks about the white dog. He does not see the dog, but he remembers the weight of the dog’s head on his knee.&lt;/p&gt;
&lt;p&gt;He lies back against the stone. The wind blows the spray from the waves over him. He does not get up.&lt;/p&gt;
&lt;p&gt;They find him a week later. The birds did not touch him. The tide had come and gone, leaving salt on his coat.&lt;/p&gt;</description>
            <pubDate>Sat, 03 Jan 2026 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2026-01-03-when-the-tide-comes.html</guid>
        </item>
        
        <item>
            <title>The Girl of the Lake</title>
            <link>https://www.lucabol.com/posts/2025-10-29-the-girl-of-the-lake.html</link>
            <description>&lt;p&gt;&lt;img src="/img/girllake.jpg" alt="A woman's looking at a lake" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Twice in my life, I saw the girl&amp;rsquo;s image in the lake. The first time I was just a little girl. My mama had sent me there to wash the dishes. I was walking down the pier when I saw it.&lt;/p&gt;
&lt;p&gt;They say the lake remembers. They say the lake is an old man with blue eyes who sleeps and dreams about us. They say a lot of stuff about the lake, but I never believed any of it. I was a child and didn&amp;rsquo;t believe in magic.&lt;/p&gt;
&lt;p&gt;The image I saw was just a reflection, like many the lake throws your way now and then to confuse you. A speck of light in the corner of your eye, quickly forgotten.&lt;/p&gt;
&lt;p&gt;But this was different. The image stayed with me. It stayed with me all these years. I didn&amp;rsquo;t understand it then. Now I do.&lt;/p&gt;
&lt;p&gt;I saw the image again yesterday. It was clearer this time. The old man had decided that I was worthy of its confidence. I was ready to see.&lt;/p&gt;
&lt;p&gt;It was a girl. She looked sad, as if something bad had happened to her, as if asking for help. Her eyes open wide, like a scared deer.&lt;/p&gt;
&lt;p&gt;I know the girl of the lake. We grew up together. We would build boats with the leaves of the mangrove trees and laugh loudly when the lake pushed them around. The old man - the lake - would drown our boats, but we didn&amp;rsquo;t care. We would build new ones.&lt;/p&gt;
&lt;p&gt;Later on, we went dancing together. We drank together and did foolish things. She kissed the sawmill boy—crooked teeth, broad shoulders, red hair. The kind that never stays.&lt;/p&gt;
&lt;p&gt;The girl was ashamed of it because he was no good and because he left the day after and because there was no future in it. I told her that no one ever died because of a bad kiss, but it wasn&amp;rsquo;t just a kiss. It was worse. It had consequences.&lt;/p&gt;
&lt;p&gt;Her father beat her badly because of it. I don&amp;rsquo;t know how he found out. Maybe someone saw them. She walked with a limp and her eyes were puffy and she stopped laughing.&lt;/p&gt;
&lt;p&gt;The girl married the town barber. He didn&amp;rsquo;t mind her big belly, he said. He was crazy for her, he said.&lt;/p&gt;
&lt;p&gt;Then the child came and it all went to hell. Love turns bad when a child cries all night and you don&amp;rsquo;t have any money and people laugh at a son that is not your son.&lt;/p&gt;
&lt;p&gt;The girl went away. Took the child to the big city far away and forgot, but she didn&amp;rsquo;t forget. She lived and she laughed and drank and danced and was often ashamed because of it all.&lt;/p&gt;
&lt;p&gt;Her hair went gray and her son grew up and she learned to live with it because she found the beauty in her sadness.&lt;/p&gt;
&lt;p&gt;As I was walking by the pier, a little limp in my step still, the wind picked up. A wave danced over the old man. It made tiny ripples in the water.&lt;/p&gt;
&lt;p&gt;The image was broken briefly, but then came back, clearer than before.&lt;/p&gt;
&lt;p&gt;And there it was. My own reflection.&lt;/p&gt;
&lt;p&gt;The lake remembered. The old man dreamed of me. I understood then.&lt;/p&gt;</description>
            <pubDate>Wed, 29 Oct 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-10-29-the-girl-of-the-lake.html</guid>
        </item>
        
        <item>
            <title>The Death of Henry</title>
            <link>https://www.lucabol.com/posts/2025-10-28-the-death-of-henry.html</link>
            <description>&lt;p&gt;&lt;img src="/img/henry4.jpg" alt="An old man sleeping on the floor surrounded by occult books and tarot cards" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;It was about to happen. Henry knew it. The process was complete. The moment had arrived. He was going to die.&lt;/p&gt;
&lt;p&gt;The external world held no interest for him anymore—just one disappointment after another. Grey nights followed grey days. Some happiness, some sadness. Nothing to write home about, really.&lt;/p&gt;
&lt;p&gt;Henry had taken the best life had to offer. He had money. He had women. He had friends. He traveled the world. He saw everything. But none of it meant anything. Nothing made sense.&lt;/p&gt;
&lt;p&gt;Death, though—death was different. Death was interesting.&lt;/p&gt;
&lt;p&gt;Henry had been working on it for a while, willing himself to die. Day after day, night after night, he would lie in bed, trying to lower his heartbeat, relax his muscles, slow his breath. But it isn&amp;rsquo;t easy to will yourself dead. It takes control. A lot of it. It is the ultimate test.&lt;/p&gt;
&lt;p&gt;Today, he was sure, was the day. He was ready. Or so he hoped&amp;hellip;&lt;/p&gt;
&lt;p&gt;But it was not to be. Every time he got close, something pulled him back. His mind refused to let go. But why? What was holding him back?&lt;/p&gt;
&lt;p&gt;He had no friends. No family. No interests. So why then? What was he living for?&lt;/p&gt;
&lt;p&gt;He wondered. And the night came. And he dreamt of her.&lt;/p&gt;
&lt;p&gt;She was dancing on the pier, like she often did. The moon shone over them both. The sea sang. The wind screamed. He walked toward her, but she floated away in the wind. He was alone again, in the dark.&lt;/p&gt;
&lt;p&gt;He never understood the dream. He didn&amp;rsquo;t know the girl. He had never met her.&lt;/p&gt;
&lt;p&gt;There were prophecies, of course. He knew that. There are always prophecies. He had seen the signs—the red star, the voices, the lights.&lt;/p&gt;
&lt;p&gt;Maybe it was the girl keeping him alive. Maybe she meant something&amp;hellip;&lt;/p&gt;
&lt;p&gt;And the months passed. And the years passed. And still, he did not die. Everyone around him was gone. He was old—very old—but he remained.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Then he saw her.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;She was walking her dog one warm summer evening. He tried to speak to her, but she ran away, frightened by his appearance. But he didn&amp;rsquo;t give up. There was too much at stake.&lt;/p&gt;
&lt;p&gt;He found her again. He made her listen. He had to restrain her. He talked and talked, deep into the night. At times, he had to be forceful. Why wouldn&amp;rsquo;t she just listen?&lt;/p&gt;
&lt;p&gt;This went on for days. Weeks. Maybe months. It was hard to tell. He lost track. Eventually, she stopped answering his questions.&lt;/p&gt;
&lt;p&gt;The day they found him, it was hot. He was sleeping on the floor, surrounded by rotten food and strange books. Scary books, with devils and angels. Tarot cards. Saints.&lt;/p&gt;
&lt;p&gt;A skeleton was chained to the radiator.  It made the front page of the local newspaper.&lt;/p&gt;
&lt;p&gt;I was given Henry&amp;rsquo;s books. I&amp;rsquo;ve read them all. Twice. Some pages are blank. Others seem to shift when I look away.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve started keeping notes. I&amp;rsquo;ve seen the red star. I&amp;rsquo;ve heard the voices.&lt;/p&gt;
&lt;p&gt;I think I saw her once—walking her dog, just like he said.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sleeping much anymore.&lt;/p&gt;
&lt;p&gt;Need to find her.&lt;/p&gt;</description>
            <pubDate>Tue, 28 Oct 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-10-28-the-death-of-henry.html</guid>
        </item>
        
        <item>
            <title>Winter feelings</title>
            <link>https://www.lucabol.com/posts/2025-09-17-winter-feelings.html</link>
            <description>&lt;p&gt;&lt;img src="/img/winter-feelings.jpg" alt="Snow falling outside a coffee shop window with an empty chair" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Tom Campbell goes to the desk to punch his card.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Good session, professor. Are you training for something?&amp;rdquo;, the woman says, beamily.&lt;/p&gt;
&lt;p&gt;He flushes.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;If you want to take your training to the next level, I am a personal trainer.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Tom looks at her. &amp;ldquo;I am fine.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Okay, see you next week,&amp;rdquo; eyes already on the next customer.&lt;/p&gt;
&lt;p&gt;Tom walks to the bookstore, picks up a book, reads the back cover, puts it back. Picks up another book, same.&lt;/p&gt;
&lt;p&gt;He walks to the coffee shop, orders a coffee, sits down by the window. Looks at the empty chair across from him. Sighs.&lt;/p&gt;
&lt;p&gt;He takes out his phone. A picture of his wife. Smiles. Puts the phone away. Outside it is snowing.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Sorry to bother you, but I saw you in the bookstore. I want to learn about investing.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Tom looks up at the woman. She is young, with an accent. His eyes wander to her legs, to her arms. He looks away.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I used to teach.&amp;rdquo;, he says.&lt;/p&gt;
&lt;p&gt;He gives her a few book recommendations. She thanks him and leaves. Tom watches her go. He picks up his coffee and takes a sip.&lt;/p&gt;
&lt;p&gt;He goes home. The doormat is crooked. He fixes it. Hangs up his coat, lines up his shoes. The apartment is quiet.&lt;/p&gt;
&lt;p&gt;He touches the photo of his wife. Takes it down. Pauses. Puts it back.&lt;/p&gt;
&lt;p&gt;In the kitchen, he makes a sandwich and eats it standing.&lt;/p&gt;
&lt;p&gt;He watches sports, then a documentary, then the news. Picks up a book. Puts it down. Looks at the photo again.&lt;/p&gt;
&lt;p&gt;Outside, snow falls.&lt;/p&gt;
&lt;p&gt;A week later, she is in the queue to get coffee. She looks at him. He moves his hand to wave, but she is staring past him. He turns his chair toward the window. She didn&amp;rsquo;t see him.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Tom?&amp;rdquo;, a voice from behind.&lt;/p&gt;
&lt;p&gt;She smiles. &amp;ldquo;We met last week in the bookstore. You helped me with some books.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Oh, yes, of course. I&amp;rsquo;m sorry, I have a bad memory for faces.&amp;rdquo;, he lies.&lt;/p&gt;
&lt;p&gt;She sits down and they talk. Tom waves his hand around, animatedly. She listens with wide eyes, interjecting questions. Tom&amp;rsquo;s eyes wander to her legs. He clears his throat and looks away.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Can I have your phone number? In case I have more questions.&amp;rdquo;, she asks.&lt;/p&gt;
&lt;p&gt;He writes his number on a napkin, his hand shakes. She smiles and leaves with her coffee. Tom watches her go from the window. He sips his coffee. It is cold now.&lt;/p&gt;
&lt;p&gt;A few days later he gets a message from her. The question is very difficult.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;It is too long for a message&amp;rdquo;, he writes back.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Maybe we could meet for coffee?&amp;rdquo;, she replies.&lt;/p&gt;
&lt;p&gt;They meet again. She sits closer to him and waves her hands around. Tom nods approvingly.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;My wife was not very interested.&amp;rdquo;, Tom says, hesitating. He cleans his glasses nervously.&lt;/p&gt;
&lt;p&gt;She looks at him, waiting.&lt;/p&gt;
&lt;p&gt;Tom stays silent for a long time.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I am sorry.&amp;rdquo;, he stammers.&lt;/p&gt;
&lt;p&gt;She puts her hand on his. &amp;ldquo;It&amp;rsquo;s okay.&amp;rdquo;, she says.&lt;/p&gt;
&lt;p&gt;They talk for a while.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Would you like to meet again?&amp;rdquo;, she asks, &amp;ldquo;I will call you.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;They go to dinner. She talks.&lt;/p&gt;
&lt;p&gt;Her body sways. Tom looks at her lips, her eyes, her hands.&lt;/p&gt;
&lt;p&gt;She touches his hand. He shakes. She looks at him, smiles and says nothing.&lt;/p&gt;
&lt;p&gt;When the coffee arrives, their chairs are closer together. Tom&amp;rsquo;s glasses are fogged up. He cleans them, looks at her.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;My car is over there. I can give you a ride home.&amp;rdquo;, she says.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Maybe we could &amp;hellip;&amp;rdquo;, he starts.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I would like that.&amp;rdquo;, she replies, smiling.&lt;/p&gt;
&lt;p&gt;They go to his apartment. She looks around. They sit down on the couch. Tom takes her hand and she doesn&amp;rsquo;t pull away. They kiss.&lt;/p&gt;
&lt;p&gt;He is shaking, but she is gentle. She guides him, shows him what she likes. They make love and fall asleep in each other&amp;rsquo;s arms.&lt;/p&gt;
&lt;p&gt;The morning comes and she is gone. There is a message on his phone.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Thank you for last night. I will see you soon.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;But she doesn&amp;rsquo;t call or message.&lt;/p&gt;
&lt;p&gt;Tom cleans the apartment, goes to the gym, bookstore, coffee shop. He waits for her message. Days pass. He can&amp;rsquo;t sleep. He tries to call her, but the phone rings and rings. No answer.&lt;/p&gt;
&lt;p&gt;He sends a message, but no reply.&lt;/p&gt;
&lt;p&gt;Then: &amp;ldquo;Crazy week. Can we meet?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;They meet at the café. She wears a new coat. Her nails are done. She kisses his cheek, sits down.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;There&amp;rsquo;s a seminar in Geneva,&amp;rdquo; she says. &amp;ldquo;It&amp;rsquo;s expensive. But it could change everything for me.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Her hand rests on his arm.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I trust you.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;He nods and stirs his coffee.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You&amp;rsquo;re amazing,&amp;rdquo; she says, smiling.&lt;/p&gt;
&lt;p&gt;They walk together. She laughs at things he doesn&amp;rsquo;t say.&lt;/p&gt;
&lt;p&gt;At his house, she looks around. Touches the books and the photo on the wall.&lt;/p&gt;
&lt;p&gt;She takes off her coat. Sits on the couch. Crosses her legs and looks at him.&lt;/p&gt;
&lt;p&gt;He sits beside her. She leans in and they kiss. Her hand moves to his chest. His hand to her waist. They move to the bedroom.&lt;/p&gt;
&lt;p&gt;In the morning, she is gone.&lt;/p&gt;
&lt;p&gt;A note on the table:  &amp;ldquo;Thank you. I&amp;rsquo;ll call you.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;He waits. Days pass. No call. He sends a message. No reply.&lt;/p&gt;
&lt;p&gt;He sees her across the street, from the coffee shop. She is with another man. Younger. She wears the same coat. Her hand is on his arm and she laughs. The man smiles.&lt;/p&gt;
&lt;p&gt;Tom watches, but she doesn&amp;rsquo;t see him. They get into a taxi and drive away.&lt;/p&gt;
&lt;p&gt;Tom rises and walks home.&lt;/p&gt;
&lt;p&gt;The doormat is crooked. He fixes it. Takes off his coat. Puts away his shoes.&lt;/p&gt;
&lt;p&gt;He looks at the photo on the wall and straightens it. Goes to the kitchen and makes tea.&lt;/p&gt;
&lt;p&gt;He sits by the window. Snow is falling and he watches it for a long time.&lt;/p&gt;
&lt;p&gt;Then he stands up and smiles.&lt;/p&gt;</description>
            <pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-09-17-winter-feelings.html</guid>
        </item>
        
        <item>
            <title>Notes: The Iliad - By Homer</title>
            <link>https://www.lucabol.com/posts/2025-09-09-notes-the-iliad-chapter-summary-and-canonical-text.html</link>
            <description>&lt;h2&gt;The Iliad: A Chapter-by-Chapter Summary&lt;/h2&gt;
&lt;h3&gt;Book 1: The Rage of Achilles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Achaean (Greek) army has been fighting the Trojans for ten years.&lt;/li&gt;
&lt;li&gt;The priest &lt;strong&gt;Chryses&lt;/strong&gt; asks the Greek commander, &lt;strong&gt;Agamemnon&lt;/strong&gt;, to return his captured daughter. Agamemnon&amp;rsquo;s refusal leads to a plague sent by the god &lt;strong&gt;Apollo&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;To end the plague, Agamemnon agrees to return Chryseis but takes &lt;strong&gt;Briseis&lt;/strong&gt;, the war prize of the great warrior &lt;strong&gt;Achilles&lt;/strong&gt;, as a replacement.&lt;/li&gt;
&lt;li&gt;Enraged by the insult, Achilles withdraws from battle. He prays to his mother, the sea-nymph &lt;strong&gt;Thetis&lt;/strong&gt;, to ask &lt;strong&gt;Zeus&lt;/strong&gt; to turn the war against the Achaeans.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 2: The Dream and the Catalogue of Ships&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Zeus sends a deceptive dream to Agamemnon, telling him he can take Troy.&lt;/li&gt;
&lt;li&gt;Agamemnon tests his troops, and they try to flee, but &lt;strong&gt;Odysseus&lt;/strong&gt; rallies them.&lt;/li&gt;
&lt;li&gt;The book provides a detailed &lt;strong&gt;catalogue of ships&lt;/strong&gt;, listing the Greek contingents and leaders.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 3: The Duel of Menelaus and Paris&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Trojan prince &lt;strong&gt;Paris&lt;/strong&gt; challenges the Achaean king &lt;strong&gt;Menelaus&lt;/strong&gt; to a one-on-one duel to decide the war.&lt;/li&gt;
&lt;li&gt;Before the duel, &lt;strong&gt;Helen&lt;/strong&gt; points out the Greek heroes from the walls of Troy to King &lt;strong&gt;Priam&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Menelaus dominates Paris, but before he can kill him, the goddess &lt;strong&gt;Aphrodite&lt;/strong&gt; saves Paris.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 4: The Truce is Broken&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The gods debate the fate of Troy. &lt;strong&gt;Athena&lt;/strong&gt; incites the Trojan archer &lt;strong&gt;Pandarus&lt;/strong&gt; to shoot an arrow at Menelaus, breaking the truce.&lt;/li&gt;
&lt;li&gt;A full-scale battle erupts.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 5: Diomedes&amp;rsquo; Aristeia&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Achaean hero &lt;strong&gt;Diomedes&lt;/strong&gt;, empowered by Athena, goes on a rampage.&lt;/li&gt;
&lt;li&gt;He wounds the gods Aphrodite and Ares in a great display of valor known as an &lt;strong&gt;aristeia&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 6: Hector and Andromache&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Trojan hero &lt;strong&gt;Hector&lt;/strong&gt; returns to the city to find his mother and wife, &lt;strong&gt;Andromache&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;He shares a tender farewell with his wife and infant son, &lt;strong&gt;Astyanax&lt;/strong&gt;, before returning to battle. &lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 7: The Duel of Hector and Ajax&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hector challenges any Achaean to a duel.&lt;/li&gt;
&lt;li&gt;The great warrior &lt;strong&gt;Ajax&lt;/strong&gt; (the Greater) accepts, but the duel is stopped as night falls.&lt;/li&gt;
&lt;li&gt;Both sides agree to a temporary truce to bury their dead.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 8: The Achaean Rout&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Zeus forbids the gods from interfering and tips the scales of battle in favor of the Trojans, driving the Achaeans back to their ships.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 9: The Embassy to Achilles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Achaeans are in despair. Agamemnon sends a delegation, including Odysseus, Ajax, and &lt;strong&gt;Phoenix&lt;/strong&gt;, to Achilles.&lt;/li&gt;
&lt;li&gt;They offer him many gifts and the return of Briseis if he will rejoin the fight.&lt;/li&gt;
&lt;li&gt;Achilles, still filled with pride and rage, rejects the offer.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 10: The Doloneia&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus and Diomedes sneak into the Trojan camp at night.&lt;/li&gt;
&lt;li&gt;They capture and interrogate the Trojan spy &lt;strong&gt;Dolon&lt;/strong&gt; before killing him and slaughtering a number of Thracian soldiers.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 11: Agamemnon&amp;rsquo;s Aristeia&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Agamemnon performs a great deed on the battlefield, but he and other key Achaean leaders are wounded.&lt;/li&gt;
&lt;li&gt;The Trojans continue to push the Achaeans back.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 12: The Trojans Storm the Wall&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Trojans, led by Hector, successfully break through the Achaean defenses and storm their camp.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 13: Poseidon Rallies the Achaeans&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The god &lt;strong&gt;Poseidon&lt;/strong&gt; secretly intervenes, bolstering the morale of the Achaeans and turning the tide of battle.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 14: The Deception of Zeus&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hera&lt;/strong&gt; seduces Zeus and lulls him to sleep, allowing Poseidon to further aid the Achaeans without Zeus&amp;rsquo;s interference.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 15: The Achaeans Driven Back to the Ships&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Zeus awakens and is furious. He forces the other gods to stop meddling and orders Apollo to give Hector new strength.&lt;/li&gt;
&lt;li&gt;Hector drives the Achaeans all the way back to their ships.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 16: The Death of Patroclus&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Achilles&amp;rsquo; best friend, &lt;strong&gt;Patroclus&lt;/strong&gt;, wears Achilles&amp;rsquo; armor to inspire the Achaean troops.&lt;/li&gt;
&lt;li&gt;Patroclus disobeys Achilles&amp;rsquo; warning and is killed in battle by Hector, with the aid of Apollo.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 17: The Fight over Patroclus&amp;rsquo; Body&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A fierce battle rages over Patroclus&amp;rsquo;s body and armor, as Menelaus and Ajax fight to recover it.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 18: The Shield of Achilles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Achilles learns of Patroclus&amp;rsquo;s death and is overwhelmed with grief and rage.&lt;/li&gt;
&lt;li&gt;He decides to re-enter the battle. His mother, Thetis, has the god &lt;strong&gt;Hephaestus&lt;/strong&gt; forge him new armor, including a magnificent &lt;strong&gt;shield of Achilles&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 19: Achilles&amp;rsquo; Reconciliation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Achilles receives his new armor and reconciles with Agamemnon, who returns Briseis and offers many gifts.&lt;/li&gt;
&lt;li&gt;Achilles officially re-enters the battle.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 20: The Gods Join the Battle&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Zeus allows the gods to directly intervene, leading to chaotic duels.&lt;/li&gt;
&lt;li&gt;Achilles&amp;rsquo; rage is fully unleashed on the Trojans.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 21: Achilles&amp;rsquo; Rampage and the River Scamander&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Achilles slaughters many Trojans.&lt;/li&gt;
&lt;li&gt;The river god &lt;strong&gt;Scamander&lt;/strong&gt; becomes angry at the number of bodies and rises against Achilles, who is only saved by the intervention of the gods.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 22: The Death of Hector&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Achilles chases Hector around the walls of Troy.&lt;/li&gt;
&lt;li&gt;Athena, disguised as Hector&amp;rsquo;s brother, tricks him into stopping and facing Achilles, who kills him and then dishonors the body.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 23: The Funeral Games for Patroclus&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Achilles holds elaborate &lt;strong&gt;funeral games&lt;/strong&gt; in honor of Patroclus, including chariot racing, boxing, and wrestling.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Book 24: Priam and Achilles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;King Priam, guided by the god Hermes, journeys to the Achaean camp to beg Achilles for Hector&amp;rsquo;s body.&lt;/li&gt;
&lt;li&gt;Achilles is moved to compassion and returns the body, granting a truce for the funeral rites.&lt;/li&gt;
&lt;li&gt;The poem ends with the burial of Hector.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;History of the text and canonical sources&lt;/h2&gt;
&lt;p&gt;The canonical text of the &lt;strong&gt;Iliad&lt;/strong&gt; doesn&amp;rsquo;t come from a single, original historical document, but rather from a long tradition of oral and written transmission. The oldest and most important documents that inform our modern version are papyri and medieval manuscripts.&lt;/p&gt;
&lt;h3&gt;Papyri&lt;/h3&gt;
&lt;p&gt;The earliest surviving fragments of the &lt;em&gt;Iliad&lt;/em&gt; are on papyrus scrolls. These are crucial because they date back to antiquity, providing a direct link to the text as it existed in the Greco-Roman world.
* &lt;strong&gt;The oldest fragment:&lt;/strong&gt; The earliest known fragment is the &lt;strong&gt;&amp;ldquo;Derveni Papyrus&amp;rdquo;&lt;/strong&gt; from the 4th century BC, though it contains commentary on a section rather than a direct copy of the text.
* &lt;strong&gt;The most significant papyri:&lt;/strong&gt; Many papyri fragments, some dating to the 3rd century BC, have been found in places like Oxyrhynchus, Egypt. These often contain only parts of the poem, but they show that the text was relatively stable, although small variations and different versions did exist.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Medieval Manuscripts&lt;/h3&gt;
&lt;p&gt;Medieval manuscripts are complete copies of the &lt;em&gt;Iliad&lt;/em&gt; text, written on parchment or paper. They are the most complete and valuable sources for the canonical version of the poem.
* &lt;strong&gt;Venetus A:&lt;/strong&gt; This 10th-century manuscript is considered the most important source for the &lt;em&gt;Iliad&lt;/em&gt;. It contains not only the full text of the poem but also extensive scholia—ancient marginal notes and commentaries by scholars like Aristarchus of Samothrace and Aristophanes of Byzantium. These notes often discuss different versions of lines, textual variants, and interpretations, making the manuscript an invaluable resource for understanding the history of the text. 
* &lt;strong&gt;Venetus B:&lt;/strong&gt; Also from the 10th century, this manuscript is another key source. It contains similar scholia and helps to corroborate or clarify the readings in Venetus A.
* &lt;strong&gt;Other medieval manuscripts:&lt;/strong&gt; Many other Byzantine manuscripts exist, which scholars use to compare readings and create a comprehensive picture of the text.&lt;/p&gt;
&lt;p&gt;In short, the canonical &lt;strong&gt;&lt;em&gt;Iliad&lt;/em&gt;&lt;/strong&gt; is a reconstructed text based on a critical analysis of these various documents. Modern editions are created by comparing the readings from the fragmentary papyri with the more complete medieval manuscripts to arrive at a version that is believed to be the closest to the one used in the ancient world.&lt;/p&gt;</description>
            <pubDate>Tue, 09 Sep 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-09-09-notes-the-iliad-chapter-summary-and-canonical-text.html</guid>
        </item>
        
        <item>
            <title>Notes: A general intro to the Great Books - By Adler</title>
            <link>https://www.lucabol.com/posts/2025-09-09-notes-great-books-liberal-education-mortimer-adler.html</link>
            <description>&lt;h3&gt;&lt;strong&gt;1. Plato, &lt;em&gt;Apology&lt;em&gt; and &lt;/em&gt;Crito&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Apology&lt;/em&gt;&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Socrates defends himself against charges of corrupting the youth and impiety.&lt;/li&gt;
&lt;li&gt;He recounts the Oracle at Delphi&amp;rsquo;s claim that no man is wiser than he, which led him on a quest to question others.&lt;/li&gt;
&lt;li&gt;He argues that his mission is divine and that an unexamined life is not worth living.&lt;/li&gt;
&lt;li&gt;He is found guilty and sentenced to death.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Crito&lt;/em&gt;&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Crito visits Socrates in prison with a plan to help him escape.&lt;/li&gt;
&lt;li&gt;Socrates rejects the offer, arguing that one should only listen to the opinions of the wise.&lt;/li&gt;
&lt;li&gt;He personifies the Laws of Athens to argue that he has an implicit social contract with the city, and to escape would be an act of injustice against the laws that have protected him.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;2. Plato, &lt;em&gt;The Republic&lt;/em&gt;, Books I &amp;amp; II&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Book I&lt;/em&gt;&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Socrates debates the meaning of justice with his friends.&lt;/li&gt;
&lt;li&gt;He refutes the definitions of justice given by Cephalus (paying debts) and Polemarchus (helping friends and harming enemies).&lt;/li&gt;
&lt;li&gt;He confronts the Sophist Thrasymachus, who claims &amp;ldquo;justice is nothing else than the interest of the stronger.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Book II&lt;/em&gt;&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Glaucon challenges Socrates to prove that justice is good for its own sake using the story of the &lt;strong&gt;Ring of Gyges&lt;/strong&gt;, which grants invisibility.&lt;/li&gt;
&lt;li&gt;Socrates proposes they define justice in a city first, then apply the definition to an individual, setting up the central metaphor of the book.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;3. Sophocles, &lt;em&gt;Oedipus the King&lt;em&gt; and &lt;/em&gt;Antigone&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Oedipus the King&lt;/em&gt;&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Oedipus, king of Thebes, vows to find the murderer of the previous king, Laius, to end a plague.&lt;/li&gt;
&lt;li&gt;He consults the prophet Tiresias, who reveals that Oedipus himself is the murderer.&lt;/li&gt;
&lt;li&gt;Through a series of revelations, Oedipus discovers he has unknowingly killed his father and married his mother, fulfilling a prophecy.&lt;/li&gt;
&lt;li&gt;His mother/wife Jocasta kills herself, and Oedipus blinds himself and goes into exile.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Antigone&lt;/em&gt;&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Antigone&amp;rsquo;s brothers die fighting each other. Creon, the new king, decrees that one will be buried while the other is left unburied.&lt;/li&gt;
&lt;li&gt;Antigone defies Creon&amp;rsquo;s law, believing her duty to the gods is a higher law than the state&amp;rsquo;s.&lt;/li&gt;
&lt;li&gt;Creon sentences her to be buried alive.&lt;/li&gt;
&lt;li&gt;The prophet Tiresias warns Creon that his pride will lead to tragedy.&lt;/li&gt;
&lt;li&gt;Antigone, Creon&amp;rsquo;s son, and Creon&amp;rsquo;s wife all die, leaving Creon alone with his grief.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;4. Aristotle, &lt;em&gt;Nicomachean Ethics&lt;/em&gt;, Book I&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Highest Good:&lt;/strong&gt; Aristotle argues that all human actions aim at some good, with the highest good being &lt;strong&gt;happiness&lt;/strong&gt; (&lt;em&gt;eudaimonia&lt;/em&gt;), which is pursued for its own sake.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Function of Man:&lt;/strong&gt; Happiness is an &amp;ldquo;activity of the rational soul in accordance with virtue.&amp;rdquo; To be truly happy, a person must use their unique human capacity for reason.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Virtue and Habit:&lt;/strong&gt; He distinguishes between intellectual virtue (gained through teaching) and moral virtue (gained through habit).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;External Goods:&lt;/strong&gt; He acknowledges that external goods like wealth and friends are necessary as instruments for a happy life, but not as ends in themselves.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;5. Aristotle, &lt;em&gt;Politics&lt;/em&gt;, Book I&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Nature of the State:&lt;/strong&gt; Aristotle argues that the &lt;strong&gt;city-state&lt;/strong&gt; is the highest form of human association, formed to achieve the highest good.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;Political Animal&amp;rdquo;:&lt;/strong&gt; He introduces the idea that &amp;ldquo;man is by nature a political animal&amp;rdquo; and that the city-state is a natural development from the family and village.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Household Management:&lt;/strong&gt; He examines the three relationships within a household: master and slave, husband and wife, and parent and child, arguing that understanding these is key to understanding the state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On Slavery and Acquisition:&lt;/strong&gt; He discusses the concept of &amp;ldquo;natural slavery&amp;rdquo; and contrasts the &lt;strong&gt;&amp;ldquo;art of acquisition&amp;rdquo;&lt;/strong&gt; for a household with the unnatural pursuit of wealth for its own sake.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;6. Plutarch, &lt;em&gt;The Lives&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lycurgus:&lt;/strong&gt; He established a new constitution for Sparta, including a system of equal land distribution, the &lt;strong&gt;agoge&lt;/strong&gt; (a rigorous education), and a focus on simplicity and civic virtue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Numa Pompilius:&lt;/strong&gt; The second king of Rome, he ruled peacefully by focusing on religious and legal reforms, instilling a sense of piety in the Roman people.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alexander:&lt;/strong&gt; Tutored by Aristotle, he conquered the Persian Empire and created a vast Hellenistic empire, remembered as a brilliant but complex leader.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Caesar:&lt;/strong&gt; Plutarch chronicles Caesar&amp;rsquo;s rise to power, his military conquests in Gaul, his civil war, and his eventual assassination, which ended the Roman Republic.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;7. &lt;em&gt;The Old Testament&lt;/em&gt;, The Book of Job&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Wager:&lt;/strong&gt; God allows Satan to test the piety of Job, a righteous and wealthy man.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Affliction:&lt;/strong&gt; Job loses his children, wealth, and health but refuses to curse God.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Friends&amp;rsquo; Challenge:&lt;/strong&gt; Three friends visit him and argue that his suffering must be a punishment for some sin. Job maintains his innocence and questions God&amp;rsquo;s justice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;God&amp;rsquo;s Response:&lt;/strong&gt; God appears in a whirlwind and speaks of his own power and wisdom, humbling Job, who accepts his own limited understanding.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restoration:&lt;/strong&gt; God restores Job&amp;rsquo;s health and wealth, and gives him a new family.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;8. St. Augustine, &lt;em&gt;The Confessions&lt;/em&gt;, Books I–VIII&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spiritual Journey:&lt;/strong&gt; Written as a prayer to God, Augustine&amp;rsquo;s work is a spiritual autobiography recounting his early life and struggles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Early Sins:&lt;/strong&gt; He reflects on the nature of evil, confessing to minor sins of his youth, and sees his own lusts and worldly ambitions as a primary barrier to his faith.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intellectual Crisis:&lt;/strong&gt; He recounts his long adherence to the Manichaean religion and his eventual embrace of Neoplatonism, which helped him see evil as the absence of good.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Garden Conversion:&lt;/strong&gt; His spiritual journey climaxes in a garden when he hears a voice telling him to &amp;ldquo;Take up and read!&amp;rdquo; He opens a book of Paul&amp;rsquo;s Epistles and is immediately convinced to give up his sinful life.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;9. Montaigne, &lt;em&gt;The Essays&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Essay:&lt;/strong&gt; Montaigne pioneered the essay genre, writing personal, reflective pieces that explore a wide range of topics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-Examination:&lt;/strong&gt; His main focus is on the study of the self, reflecting his skeptical motto, &lt;strong&gt;&amp;ldquo;Que sçay-je?&amp;rdquo;&lt;/strong&gt; (&amp;ldquo;What do I know?&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Human Nature:&lt;/strong&gt; He presents a complex view of human nature, critiquing human arrogance and advocating for humility and a healthy skepticism.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On Death:&lt;/strong&gt; He famously argues that to philosophize is to learn how to die and that facing one&amp;rsquo;s mortality can help one to live more fully.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Specific Essays:&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;Of Pedantry&amp;rdquo;:&lt;/strong&gt; Montaigne criticizes the pedants of his time for valuing book learning and memorization over true wisdom and judgment. He argues that knowledge is useless if not integrated and applied to life.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;That It Is Folly to Measure Truth and Error by Our Own Capacity&amp;rdquo;:&lt;/strong&gt; He argues against intellectual arrogance and dogmatism, suggesting that we should not assume our own limited reason is the measure of all things. He emphasizes the vastness of the unknown and the diversity of human beliefs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;Of Cannibals&amp;rdquo;:&lt;/strong&gt; He uses the example of a &amp;ldquo;savage&amp;rdquo; tribe to critique the barbarism and ethnocentrism of European society.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;That the Relish of Good and Evil Depends in a Great measure upon the Opinion we Have of Them&amp;rdquo;:&lt;/strong&gt; Montaigne explores the power of our minds to shape our experience of the world. He argues that our opinions, attitudes, and imaginings have a greater impact on our happiness and suffering than external events themselves.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;Of the Education of Children&amp;rdquo;:&lt;/strong&gt; He advocates for an education that emphasizes reason and judgment over rote memorization and encourages exposure to different cultures.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;10. Shakespeare, &lt;em&gt;Hamlet&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Plot:&lt;/strong&gt; The ghost of Prince Hamlet&amp;rsquo;s father appears, revealing he was murdered by his brother, Claudius, who has now married the queen and seized the throne.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feigned Madness:&lt;/strong&gt; Hamlet feigns madness to investigate the crime, leading to a series of tragic misunderstandings and events.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Play-Within-a-Play:&lt;/strong&gt; Hamlet stages a play to confirm Claudius&amp;rsquo;s guilt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tragedy:&lt;/strong&gt; His indecision and delay lead to the deaths of Polonius, Ophelia, Gertrude, Laertes, Claudius, and himself in the final duel.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;11. John Locke, &lt;em&gt;Concerning Civil Government&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;State of Nature:&lt;/strong&gt; Locke argues that in the state of nature, individuals are free and equal, with natural rights to life, liberty, and property.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Social Contract:&lt;/strong&gt; To protect these rights, people enter a &lt;strong&gt;social contract&lt;/strong&gt; to create a government.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consent and Tyranny:&lt;/strong&gt; Legitimate government is based on the &lt;strong&gt;consent of the governed&lt;/strong&gt;. If a government becomes tyrannical and infringes on these rights, the people have a right to revolt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separation of Powers:&lt;/strong&gt; He advocates for a separation of powers, primarily between the legislative and executive branches, to prevent tyranny.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;12. Jonathan Swift, &lt;em&gt;Gulliver&amp;rsquo;s Travels&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Satire:&lt;/strong&gt; The book is a satirical critique of human nature and European society.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Voyages:&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;In &lt;strong&gt;Lilliput&lt;/strong&gt;, a land of tiny people, Swift satirizes the pettiness of political and religious conflicts.&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;Brobdingnag&lt;/strong&gt;, a land of giants, Gulliver is small, and the king&amp;rsquo;s disgust at English society highlights its moral corruption.&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;Laputa&lt;/strong&gt;, a flying island populated by people obsessed with mathematics and music but lacking common sense, he satirizes abstract and impractical thinking.&lt;/li&gt;
&lt;li&gt;In the land of the &lt;strong&gt;Houyhnhnms&lt;/strong&gt;, rational horses rule over the brutish, human-like &lt;strong&gt;Yahoos&lt;/strong&gt;. Gulliver becomes so disgusted with humanity that he longs to be a horse.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;13. Edward Gibbon, &lt;em&gt;The Decline and Fall of the Roman Empire&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Scope:&lt;/strong&gt; The reading selection focuses on Gibbon&amp;rsquo;s controversial analysis of Christianity&amp;rsquo;s role in the fall of the empire.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 15: The Progress of the Christian Religion:&lt;/strong&gt; Gibbon investigates the &amp;ldquo;five secondary causes&amp;rdquo; for the rapid spread of Christianity, beyond divine intervention. These include the &lt;strong&gt;zeal of the early Christians&lt;/strong&gt;, their doctrine of a future life (including the concept of heaven and hell), the claim to miraculous powers, the &lt;strong&gt;pure and austere morals&lt;/strong&gt; of the believers, and the tight-knit &lt;strong&gt;union and discipline of the Christian Church&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 16: The Conduct of the Roman Government toward the Christians:&lt;/strong&gt; This chapter details the various persecutions of the Christians. Gibbon argues that the Roman government&amp;rsquo;s intolerance was rooted in the Christians&amp;rsquo; refusal to participate in the traditional pagan rites, which the Romans viewed as a civic duty. He contrasts the Roman policy of general religious tolerance with their harshness toward the Christians&amp;rsquo; &amp;ldquo;inflexible obstinacy.&amp;rdquo; He also controversially estimates the number of Christian martyrs to be far lower than traditional Christian accounts, and attributes their willingness to face death to fanaticism rather than pure faith.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;14. American State Papers and &lt;em&gt;The Federalist&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Declaration of Independence:&lt;/strong&gt; This document asserts the &lt;strong&gt;unalienable rights&lt;/strong&gt; to &amp;ldquo;Life, Liberty and the pursuit of Happiness,&amp;rdquo; and states that governments derive their power from the &lt;strong&gt;consent of the governed&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Constitution of the United States of America:&lt;/strong&gt; This establishes the framework for the U.S. government, including the &lt;strong&gt;three branches of government&lt;/strong&gt; (legislative, executive, and judicial), the &lt;strong&gt;system of checks and balances&lt;/strong&gt;, and the division of powers between the federal government and the states.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;em&gt;Federalist Papers&lt;/em&gt;&lt;/strong&gt;: A collection of 85 essays written by James Madison, Alexander Hamilton, and John Jay to persuade citizens to ratify the U.S. Constitution.&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No. 1 (Hamilton):&lt;/strong&gt; An introduction to the series, outlining the need for a new Constitution and the topics to be covered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 2 (Jay):&lt;/strong&gt; Argues that the United States should remain a single nation and not be broken up into separate confederacies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 3 (Jay):&lt;/strong&gt; Argues that a united nation is better equipped to protect against foreign threats and avoid wars.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 4 (Jay):&lt;/strong&gt; Continues the argument from No. 3, focusing on the ability of a strong central government to raise and maintain a unified military.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 5 (Jay):&lt;/strong&gt; Argues that if the states were divided into separate confederacies, they would likely fall into conflict with each other.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 6 (Hamilton):&lt;/strong&gt; Warns against the potential for civil war and disputes between the states if they do not unite under a strong government.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 7 (Hamilton):&lt;/strong&gt; Discusses specific causes of conflict among the states if they were not united, such as disputes over territory and commerce.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 8 (Hamilton):&lt;/strong&gt; Argues that a standing army, which would be necessary for separate states, poses a greater threat to liberty than a unified federal government.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 9 (Hamilton):&lt;/strong&gt; Advocates for a strong union as a safeguard against domestic faction and insurrection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 10 (Madison):&lt;/strong&gt; Famously argues that a large republic is the best way to control the negative effects of &lt;strong&gt;factions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 15 (Hamilton):&lt;/strong&gt; Outlines the fundamental weaknesses of the Articles of Confederation and the need for a stronger federal government with the power to enforce its laws directly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 31 (Hamilton):&lt;/strong&gt; Argues that the federal government must have an unlimited power to tax and raise revenue to function effectively.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 47 (Madison):&lt;/strong&gt; Defends the separation of powers by citing Montesquieu and clarifying that the branches are not entirely distinct but have a partial agency in the others&amp;rsquo; affairs to prevent tyranny.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 51 (Madison):&lt;/strong&gt; Explains the system of &lt;strong&gt;checks and balances&lt;/strong&gt; and argues that &amp;ldquo;ambition must be made to counteract ambition.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 62 (Madison):&lt;/strong&gt; Describes the Senate, its purpose as a check on the House of Representatives, and the qualifications and election process for senators.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 63 (Madison):&lt;/strong&gt; Continues the defense of the Senate, arguing for the necessity of a stable body that can provide a sense of national character and policy continuity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 64 (Jay):&lt;/strong&gt; Explains the Senate&amp;rsquo;s role in treaty-making, arguing that it is best suited for this task due to its small size and longer terms.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 65 (Hamilton):&lt;/strong&gt; Explains the Senate&amp;rsquo;s power to conduct impeachment trials, arguing it is the proper body for such a solemn and political function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 66 (Hamilton):&lt;/strong&gt; Defends the impeachment power of the Senate against various objections.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 68 (Hamilton):&lt;/strong&gt; Explains the process for electing the President through the Electoral College, arguing it protects against corruption and foreign influence.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 69 (Hamilton):&lt;/strong&gt; Contrasts the powers of the American President with those of the British monarch and a New York governor, showing the president&amp;rsquo;s powers are more limited.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 70 (Hamilton):&lt;/strong&gt; Argues for a single, energetic executive as essential for good governance, national defense, and the administration of law.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 71 (Hamilton):&lt;/strong&gt; Defends the four-year term for the president, arguing it provides stability and allows the executive to act with firmness.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No. 72 (Hamilton):&lt;/strong&gt; Justifies the re-eligibility of the President, arguing it encourages good behavior and allows for experienced leadership.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;15. Karl Marx and Friedrich Engels, &lt;em&gt;Manifesto of the Communist Party&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Class Struggle:&lt;/strong&gt; The &lt;em&gt;Manifesto&lt;/em&gt; presents a history of society as a history of class struggle, simplified under capitalism into two classes: the &lt;strong&gt;bourgeoisie&lt;/strong&gt; (owners) and the &lt;strong&gt;proletariat&lt;/strong&gt; (workers).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Revolution:&lt;/strong&gt; It argues that the exploitation of the proletariat will inevitably lead to a revolution in which the workers overthrow the bourgeoisie and seize control of the means of production.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Program:&lt;/strong&gt; It outlines a ten-point program for a new, communist society, including the abolition of private property and a heavy progressive income tax.&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Tue, 09 Sep 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-09-09-notes-great-books-liberal-education-mortimer-adler.html</guid>
        </item>
        
        <item>
            <title>Notes: The Odyssey - By Homer</title>
            <link>https://www.lucabol.com/posts/2025-09-09-notes-the-odyssey-chapter-summary-and-canonical-text.html</link>
            <description>&lt;h2&gt;Book 1: A Goddess Intervenes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The gods meet on Mount Olympus and discuss the fate of &lt;strong&gt;Odysseus&lt;/strong&gt;, who has been trapped on the island of the nymph &lt;strong&gt;Calypso&lt;/strong&gt; for seven years.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Athena&lt;/strong&gt;, his patron goddess, asks Zeus to intervene. Zeus agrees and sends Hermes to order Calypso to release Odysseus.&lt;/li&gt;
&lt;li&gt;Athena then travels to Ithaca in disguise and encourages Odysseus&amp;rsquo;s son, &lt;strong&gt;Telemachus&lt;/strong&gt;, to search for news of his father.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 2: A Hero&amp;rsquo;s Son Rises&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Telemachus calls an assembly of the Ithacan people to complain about the &lt;strong&gt;suitors&lt;/strong&gt; who are trying to marry his mother, &lt;strong&gt;Penelope&lt;/strong&gt;, and are consuming his household&amp;rsquo;s wealth.&lt;/li&gt;
&lt;li&gt;He announces his plan to sail to Pylos and Sparta to seek news of Odysseus.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 3: A Journey for Answers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Telemachus and Athena (still in disguise) arrive in Pylos and are welcomed by King &lt;strong&gt;Nestor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Nestor tells Telemachus about the return journeys of other Greek heroes but has no information about Odysseus&amp;rsquo;s fate. He advises Telemachus to visit Sparta.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 4: The Kingdom of Menelaus&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Telemachus and Nestor&amp;rsquo;s son, Peisistratus, travel to Sparta and are welcomed by King &lt;strong&gt;Menelaus&lt;/strong&gt; and Queen &lt;strong&gt;Helen&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Menelaus recounts his own difficult journey home and tells Telemachus that he learned from the sea god Proteus that Odysseus is alive and being held captive on Calypso&amp;rsquo;s island.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 5: Calypso&amp;rsquo;s Island&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Hermes arrives at Calypso&amp;rsquo;s island and delivers Zeus&amp;rsquo;s command to release Odysseus.&lt;/li&gt;
&lt;li&gt;Calypso reluctantly helps Odysseus build a raft.&lt;/li&gt;
&lt;li&gt;After eighteen days at sea, Odysseus&amp;rsquo;s raft is shattered by a storm sent by the sea god &lt;strong&gt;Poseidon&lt;/strong&gt;, who holds a grudge against him.&lt;/li&gt;
&lt;li&gt;Odysseus is rescued by the goddess Ino and eventually washes ashore on the island of Scheria.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 6: The Princess and the Stranger&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;On Scheria, the princess &lt;strong&gt;Nausicaa&lt;/strong&gt; discovers Odysseus.&lt;/li&gt;
&lt;li&gt;She is washing her clothes near the shore with her maidens when they find the exhausted and naked Odysseus.&lt;/li&gt;
&lt;li&gt;Nausicaa gives him clothing and instructions on how to approach her parents, the king and queen of the &lt;strong&gt;Phaeacians&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 7: A Royal Welcome&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus is welcomed into the palace of King &lt;strong&gt;Alcinous&lt;/strong&gt; and Queen &lt;strong&gt;Arete&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;He receives a warm reception but hides his identity, telling them only of his time on Calypso&amp;rsquo;s island.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 8: Games and a Song&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The Phaeacians host games in Odysseus&amp;rsquo;s honor.&lt;/li&gt;
&lt;li&gt;A blind bard, &lt;strong&gt;Demodocus&lt;/strong&gt;, sings a song about the Trojan War, and Odysseus weeps at the memories.&lt;/li&gt;
&lt;li&gt;Alcinous notices his distress and asks him to reveal his true identity.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 9: The Cyclops&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus begins to tell his story. He and his men land on the island of the &lt;strong&gt;Cyclops&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;They are captured by &lt;strong&gt;Polyphemus&lt;/strong&gt;, the giant son of Poseidon, who eats several of his men.&lt;/li&gt;
&lt;li&gt;Odysseus blinds the Cyclops by driving a heated stake into his eye and escapes by clinging to the underside of the Cyclops&amp;rsquo;s sheep.&lt;/li&gt;
&lt;li&gt;As they sail away, Odysseus reveals his identity, and Polyphemus prays to his father, Poseidon, to curse Odysseus&amp;rsquo;s journey.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 10: Circe&amp;rsquo;s Island&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus and his men land on the island of the enchantress &lt;strong&gt;Circe&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;She turns some of his men into pigs.&lt;/li&gt;
&lt;li&gt;With the help of the god Hermes, Odysseus outsmarts Circe and forces her to turn his men back.&lt;/li&gt;
&lt;li&gt;They stay with Circe for a year, and she eventually tells Odysseus he must visit the Underworld to speak with the prophet Tiresias to find his way home.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 11: The Underworld&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus travels to the Underworld.&lt;/li&gt;
&lt;li&gt;He meets the ghosts of his mother, Anticlea, and fallen comrades like Achilles and Agamemnon.&lt;/li&gt;
&lt;li&gt;The prophet &lt;strong&gt;Tiresias&lt;/strong&gt; warns him not to harm the cattle of the sun god Helios and foretells his long, difficult journey home.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 12: Sirens, Scylla, and Charybdis&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus and his men sail past the &lt;strong&gt;Sirens&lt;/strong&gt;, whose beautiful songs lure sailors to their deaths. Odysseus has his men plug their ears with wax and has himself tied to the mast so he can hear their song safely.&lt;/li&gt;
&lt;li&gt;They navigate between &lt;strong&gt;Scylla&lt;/strong&gt;, a six-headed sea monster, and &lt;strong&gt;Charybdis&lt;/strong&gt;, a whirlpool.&lt;/li&gt;
&lt;li&gt;His men ignore Tiresias&amp;rsquo;s warning and eat the cattle of Helios, angering the gods.&lt;/li&gt;
&lt;li&gt;Zeus sends a storm that destroys their ship, and only Odysseus survives, washing ashore on Calypso&amp;rsquo;s island.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 13: Return to Ithaca&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The Phaeacians sail Odysseus back to Ithaca.&lt;/li&gt;
&lt;li&gt;He is disguised as a beggar by Athena so he can safely assess the situation in his home.&lt;/li&gt;
&lt;li&gt;He is reunited with his faithful swineherd, &lt;strong&gt;Eumaeus&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 14: The Swineherd&amp;rsquo;s Home&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus stays with Eumaeus, who, unaware of his master&amp;rsquo;s identity, tells him how the suitors have been harassing Penelope and consuming the household&amp;rsquo;s wealth.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 15: Telemachus&amp;rsquo;s Return&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Athena visits Telemachus and tells him to return home.&lt;/li&gt;
&lt;li&gt;Telemachus and Odysseus are reunited at Eumaeus&amp;rsquo;s hut, and Odysseus reveals his true identity.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 16: The Father and Son Reunion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Telemachus returns to the palace, and Odysseus, still in disguise, follows.&lt;/li&gt;
&lt;li&gt;The two plan how they will defeat the suitors.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 17: The Beggar in the Palace&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus enters his palace as a beggar. He is only recognized by his dying dog, &lt;strong&gt;Argos&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;He is insulted by the suitors.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 18: The Beggar&amp;rsquo;s Brawl&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus gets into a fistfight with another beggar, &lt;strong&gt;Irus&lt;/strong&gt;, and easily defeats him, earning the respect of some of the suitors.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 19: The Scar&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus and Penelope have a long conversation.&lt;/li&gt;
&lt;li&gt;While washing his feet, Odysseus&amp;rsquo;s old nurse, &lt;strong&gt;Eurycleia&lt;/strong&gt;, recognizes a scar on his leg from a childhood hunting accident. She promises to keep his identity a secret.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 20: The Looming Battle&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Odysseus, unable to sleep, observes the suitors&amp;rsquo; actions and grows increasingly angry.&lt;/li&gt;
&lt;li&gt;The suitors continue their disrespectful behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 21: The Contest of the Bow&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Penelope announces a contest: she will marry the suitor who can string Odysseus&amp;rsquo;s great bow and shoot an arrow through the handles of twelve axes.&lt;/li&gt;
&lt;li&gt;None of the suitors can even string the bow.&lt;/li&gt;
&lt;li&gt;The disguised Odysseus asks for a turn, and after being mocked, he easily strings the bow and shoots the arrow, revealing his true identity.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 22: The Slaughter of the Suitors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;With his identity revealed and the bow in hand, Odysseus, with the help of Telemachus, Eumaeus, and a few loyal servants, begins to slaughter the suitors.&lt;/li&gt;
&lt;li&gt;It is a bloody and merciless massacre.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 23: The Great Test&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Penelope, still unsure of the beggar&amp;rsquo;s identity, devises a test for Odysseus.&lt;/li&gt;
&lt;li&gt;She tells him that she has moved their marital bed, which is built from the trunk of a living olive tree.&lt;/li&gt;
&lt;li&gt;Odysseus reveals his knowledge of the bed&amp;rsquo;s unique construction, and Penelope, now certain, embraces him.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Book 24: Peace and Restitution&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The ghosts of the suitors travel to the Underworld.&lt;/li&gt;
&lt;li&gt;Odysseus goes to see his father, Laertes, and reveals himself.&lt;/li&gt;
&lt;li&gt;The families of the suitors rise in rebellion against Odysseus, but the rebellion is stopped by Athena and Zeus.&lt;/li&gt;
&lt;li&gt;The epic ends with peace being restored to Ithaca.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Canonical Text History&lt;/h3&gt;
&lt;p&gt;The canonical text of &lt;strong&gt;&lt;em&gt;The Odyssey&lt;/em&gt;&lt;/strong&gt;, like the &lt;em&gt;Iliad&lt;/em&gt;, is a reconstructed text based on a critical analysis of various historical documents. These documents are primarily:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Papyri fragments:&lt;/strong&gt; The earliest surviving fragments of the &lt;em&gt;Odyssey&lt;/em&gt; are on papyrus scrolls, some dating to the 3rd century BC. These fragments, found in places like Oxyrhynchus, Egypt, show that the text was relatively stable in antiquity, although some small variations existed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Medieval manuscripts:&lt;/strong&gt; These are the most complete and valuable sources for the canonical version of the poem. The most important is likely a &lt;strong&gt;10th-century Byzantine manuscript&lt;/strong&gt;, which contains the full text and ancient commentaries (scholia) by Alexandrian scholars. Scholars compare readings from these manuscripts to create the comprehensive modern editions we use today.&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Tue, 09 Sep 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-09-09-notes-the-odyssey-chapter-summary-and-canonical-text.html</guid>
        </item>
        
        <item>
            <title>Notes: The Prince - By Machiavelli</title>
            <link>https://www.lucabol.com/posts/2025-09-09-notes-the-prince-chapter-summary-and-canonical-text.html</link>
            <description>&lt;h3&gt;&lt;strong&gt;The Prince: A Chapter-by-Chapter Summary&lt;/strong&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;strong&gt;Chapters 1-11: Types of Principalities&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 1:&lt;/strong&gt; Machiavelli opens by categorizing principalities, or states ruled by a single person, as either hereditary or new.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 2:&lt;/strong&gt; He argues that &lt;strong&gt;hereditary principalities&lt;/strong&gt; are easier to rule because people are accustomed to the ruling family.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 3:&lt;/strong&gt; This is one of the longest chapters, detailing the difficulties in governing &lt;strong&gt;mixed principalities&lt;/strong&gt;—newly acquired territories added to an older state. He advises that a ruler should either live in the new territory or establish colonies there.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 4:&lt;/strong&gt; Machiavelli explains why the kingdom of Darius, conquered by Alexander the Great, did not rebel after Alexander&amp;rsquo;s death. He distinguishes between two types of monarchies: one where the prince rules with a powerful nobility, and another where he rules as an absolute authority.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 5:&lt;/strong&gt; He discusses how to govern states that were previously free. The most secure way is to destroy them, the next best is for the prince to reside there, and the riskiest is to allow them to keep their old laws and just impose a tax.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 6:&lt;/strong&gt; This chapter focuses on &lt;strong&gt;new principalities acquired by a prince&amp;rsquo;s own ability and arms&lt;/strong&gt;. He uses figures like Moses, Cyrus, Romulus, and Theseus as examples, arguing that great difficulty lies in establishing a new order but that once it&amp;rsquo;s established, it becomes stable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 7:&lt;/strong&gt; This chapter is a contrast to the last, focusing on &lt;strong&gt;principalities acquired by the arms of others or by fortune&lt;/strong&gt;. He uses &lt;strong&gt;Cesare Borgia&lt;/strong&gt; as his primary example, showing that while such a prince may rise quickly, he lacks a strong foundation and is vulnerable to misfortune.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 8:&lt;/strong&gt; Machiavelli examines principalities acquired through wicked means or crime. He argues that while a prince may gain power this way, it will not bring him glory or a lasting reputation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 9:&lt;/strong&gt; He discusses &lt;strong&gt;civil principalities&lt;/strong&gt;, where a ruler gains power with the support of the people or the nobles. He argues it&amp;rsquo;s better to have the support of the people, as they are a more reliable base of power than the fickle nobles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 10:&lt;/strong&gt; This chapter discusses how to measure the strength of a principality, specifically whether a prince can defend himself or needs external help.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 11:&lt;/strong&gt; He explains how to govern &lt;strong&gt;ecclesiastical principalities&lt;/strong&gt; (like the Papal States), which he says are the easiest to maintain because they are upheld by religious institutions and tradition.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;Chapters 12-14: Military Matters&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 12:&lt;/strong&gt; This chapter is a sharp critique of different types of military forces. Machiavelli argues that the foundation of any state is a strong military and that a prince must rely on his &lt;strong&gt;own troops&lt;/strong&gt;, not mercenaries. He argues that mercenaries are disloyal and dangerous.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 13:&lt;/strong&gt; He extends his critique to &lt;strong&gt;auxiliary troops&lt;/strong&gt; (forces borrowed from another prince), stating that they are even more dangerous than mercenaries. A wise prince would rather lose with his own army than win with another&amp;rsquo;s.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 14:&lt;/strong&gt; The prince&amp;rsquo;s primary focus should be on military matters. He must constantly study the art of war, both in practice (through hunting and knowing the terrain) and in theory (by studying history and the actions of great commanders).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;Chapters 15-23: The Prince&amp;rsquo;s Qualities and Conduct&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 15:&lt;/strong&gt; Machiavelli outlines the qualities that a prince should and shouldn&amp;rsquo;t have. He famously states that a prince must learn &lt;strong&gt;&amp;ldquo;how not to be good&amp;rdquo;&lt;/strong&gt; when necessary, as acting virtuously at all times can lead to ruin.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 16:&lt;/strong&gt; He explores the tension between &lt;strong&gt;generosity and parsimony&lt;/strong&gt;. He advises that it is better for a prince to be parsimonious (stingy) to avoid burdening the people with taxes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 17:&lt;/strong&gt; This is one of the most famous chapters, addressing whether it&amp;rsquo;s better to be &lt;strong&gt;feared or loved&lt;/strong&gt;. Machiavelli concludes that a prince should wish to be both but, since it is difficult, it is much safer to be feared. However, he must avoid being hated.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 18:&lt;/strong&gt; Machiavelli argues that a prince must be both a &lt;strong&gt;lion&lt;/strong&gt; (to frighten off wolves) and a &lt;strong&gt;fox&lt;/strong&gt; (to recognize traps). He states that a prince should not always keep his word if it puts him at a disadvantage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 19:&lt;/strong&gt; He explains the importance of avoiding contempt and hatred, which are caused by being perceived as greedy, effeminate, or indecisive. A prince should appear dignified, courageous, and resolute.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 20:&lt;/strong&gt; This chapter explores various security measures, like building fortresses, and whether a prince should disarm his subjects or sow divisions among them. He advises that fortresses are useful but not a substitute for the goodwill of the people.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 21:&lt;/strong&gt; He discusses what a prince must do to gain reputation, such as engaging in great enterprises and being a firm ally or enemy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 22:&lt;/strong&gt; Machiavelli advises on choosing ministers. He states that a good minister must be loyal and honest, and that a prince can tell a minister&amp;rsquo;s quality by how he acts in the prince&amp;rsquo;s best interest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 23:&lt;/strong&gt; He warns the prince to avoid flatterers and to choose a few wise advisers who will tell him the truth.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;Chapters 24-26: The State of Italy and a Call to Action&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chapter 24:&lt;/strong&gt; Machiavelli discusses why the princes of Italy have lost their states. He attributes their failures to their reliance on mercenaries, their failure to prepare for adversity, and their lack of a strong connection with their people.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 25:&lt;/strong&gt; He explores the role of &lt;strong&gt;fortune&lt;/strong&gt; versus free will. He argues that fortune controls about half of our actions, but that a prince must be prepared to act decisively and take risks to control the other half. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chapter 26:&lt;/strong&gt; This final chapter is a passionate plea for a new prince to liberate Italy from foreign powers. He presents a vision for a strong, unified Italian state led by a prince who can apply the lessons of the book.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;Canonical Text History&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The canonical text of &lt;strong&gt;&lt;em&gt;The Prince&lt;/em&gt;&lt;/strong&gt; is not based on a long line of ancient manuscripts like Homer&amp;rsquo;s epics. Instead, its textual history is relatively straightforward. The text is based on a single, original manuscript from the 16th century.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Original Manuscript:&lt;/strong&gt; The book was written by Machiavelli around &lt;strong&gt;1513&lt;/strong&gt; while he was exiled from Florence. He wrote it as a gift to Lorenzo de&amp;rsquo; Medici, though it was not formally published during his lifetime.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;First Published Editions:&lt;/strong&gt; The first official editions of &lt;em&gt;The Prince&lt;/em&gt; were published posthumously in &lt;strong&gt;1532&lt;/strong&gt;. These early printed books are the basis for all modern editions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Later Revisions and Editions:&lt;/strong&gt; While later editions have corrected minor typographical errors and standardized punctuation, the core text has remained largely unchanged since the first publication. The book&amp;rsquo;s controversial nature led to it being banned by the Catholic Church, but this did not stop its widespread circulation and influence.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Tue, 09 Sep 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-09-09-notes-the-prince-chapter-summary-and-canonical-text.html</guid>
        </item>
        
        <item>
            <title>Notes: The Good Life - by Robert Waldinger &amp; Marc Schulz</title>
            <link>https://www.lucabol.com/posts/2025-09-06-notes-the-good-life-lessons-from-the-worlds-longest-scientific-study-of-happiness.html</link>
            <description>&lt;p&gt;I found the book a bit slow and repetitive. Most of it common sense, but there were some frameworks that might be worth preserving here.&lt;/p&gt;
&lt;h2&gt;1. Social Fitness Model&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;List your key relationships (family, friends, colleagues).&lt;/li&gt;
&lt;li&gt;Map each relationship on a chart:&lt;/li&gt;
&lt;li&gt;X-axis: How often do you interact?&lt;/li&gt;
&lt;li&gt;Y-axis: Does this person energize or deplete you?&lt;/li&gt;
&lt;li&gt;Identify gaps: Who do you want to see more? Who drains you?&lt;/li&gt;
&lt;li&gt;Schedule regular “relationship workouts” (calls, coffees, walks).&lt;/li&gt;
&lt;li&gt;Check in with yourself: Are you investing enough in your most important connections?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. W.I.S.E.R. Model&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Watch:&lt;/strong&gt; Pause and notice your feelings and the situation before reacting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interpret:&lt;/strong&gt; Ask yourself, “What’s really going on? What’s at stake for me and others?”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Select:&lt;/strong&gt; Consider your options for responding—don’t just react automatically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Engage:&lt;/strong&gt; Choose and act on the best response, thoughtfully and intentionally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reflect:&lt;/strong&gt; Afterward, review what happened and what you learned for next time.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;3. Attention as Asset&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Track where your attention goes each day (work, family, friends, screens).&lt;/li&gt;
&lt;li&gt;Prioritize: Decide who/what deserves your best attention.&lt;/li&gt;
&lt;li&gt;Create rituals: Set device-free times (meals, walks, bedtime).&lt;/li&gt;
&lt;li&gt;Practice “micro-attention”: Give full focus, even for a few minutes, to people you care about.&lt;/li&gt;
&lt;li&gt;Regularly review: Are you spending your attention in line with your values?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;4. Relationship Keystones&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Assess which types of support you give and receive:&lt;/li&gt;
&lt;li&gt;Safety &amp;amp; security&lt;/li&gt;
&lt;li&gt;Learning &amp;amp; growth&lt;/li&gt;
&lt;li&gt;Emotional closeness/confiding&lt;/li&gt;
&lt;li&gt;Identity affirmation/shared experience&lt;/li&gt;
&lt;li&gt;Romantic intimacy&lt;/li&gt;
&lt;li&gt;Practical help&lt;/li&gt;
&lt;li&gt;Fun &amp;amp; relaxation&lt;/li&gt;
&lt;li&gt;Identify missing keystones in your relationships.&lt;/li&gt;
&lt;li&gt;Diversify: Don’t expect one person to meet all needs—nurture a variety of connections.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;5. Generosity &amp;amp; Curiosity Spirals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Look for opportunities to help, support, or show kindness—even in small ways.&lt;/li&gt;
&lt;li&gt;Express gratitude: Thank people for what they do, big or small.&lt;/li&gt;
&lt;li&gt;Ask deeper questions: Move beyond “How are you?” to “What’s something that made you smile today?”&lt;/li&gt;
&lt;li&gt;Be curious about others’ experiences, perspectives, and feelings.&lt;/li&gt;
&lt;li&gt;Notice how generosity and curiosity create more connection and positivity.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;6. Embrace Change &amp;amp; Corrective Experiences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Remind yourself: Your past does not dictate your future.&lt;/li&gt;
&lt;li&gt;Stay open to new people, experiences, and ways of relating.&lt;/li&gt;
&lt;li&gt;Notice when reality is better than your fears or expectations—let it update your beliefs.&lt;/li&gt;
&lt;li&gt;Seek and accept help when needed; offer it to others.&lt;/li&gt;
&lt;li&gt;Allow yourself to be changed by positive experiences, even if they’re small.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;7. Friendships &amp;amp; Weak Ties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Value all connections: Close friends, acquaintances, even friendly strangers.&lt;/li&gt;
&lt;li&gt;Engage in small talk: Smile, greet, or chat with people you see regularly (barista, neighbor, coworker).&lt;/li&gt;
&lt;li&gt;Maintain old friendships: Reach out, even if it’s been a while.&lt;/li&gt;
&lt;li&gt;Say yes to invitations or opportunities to connect, even if they seem minor.&lt;/li&gt;
&lt;li&gt;Recognize that even brief, positive interactions can boost your mood and sense of belonging.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;8. Work Relationships&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Invest in work friendships: Eat lunch together, chat, or collaborate on projects.&lt;/li&gt;
&lt;li&gt;Mentor or be mentored: Share knowledge, ask for advice, support others’ growth.&lt;/li&gt;
&lt;li&gt;Acknowledge contributions: Thank coworkers, celebrate team wins.&lt;/li&gt;
&lt;li&gt;Look for meaning in teamwork and helping others at work.&lt;/li&gt;
&lt;li&gt;Balance: Bring positive energy from work home, and vice versa.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;</description>
            <pubDate>Sat, 06 Sep 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-09-06-notes-the-good-life-lessons-from-the-worlds-longest-scientific-study-of-happiness.html</guid>
        </item>
        
        <item>
            <title>Notes: The Wealth Ladder - by Nick Maggiulli</title>
            <link>https://www.lucabol.com/posts/2025-08-05-notes-the-wealth-ladder-by-nick-maggiulli.html</link>
            <description>&lt;p&gt;It is rare these days for me to read a book about money that I like. I have read too many of them, so I am a bit jaded. But this one I liked. Here are my notes.&lt;/p&gt;
&lt;p&gt;I loved the salt metaphor, something like: &amp;ldquo;Salt doesn&amp;rsquo;t add taste to food; it enhances the existing flavors. Similarly, money doesn&amp;rsquo;t create happiness; it amplifies the happiness you already have.&amp;rdquo;&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Building wealth isn’t just about working harder; it’s about using the right strategies for your situation.&lt;/li&gt;
&lt;li&gt;Wealth is best understood as a series of levels, each requiring different approaches.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 1: Spending up the Wealth Ladder&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Spend based on your net worth, not your income, since income can fluctuate.&lt;/li&gt;
&lt;li&gt;The “0.01% Rule” suggests you can safely spend 0.01% of your net worth daily without eroding your wealth.&lt;/li&gt;
&lt;li&gt;Avoid overspending, but extreme frugality isn’t necessary.&lt;/li&gt;
&lt;li&gt;Use your liquid net worth (readily available assets) as a conservative guide for spending.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 2: Earning up the Wealth Ladder&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Income is the foundation of wealth; high income and high wealth usually go together.&lt;/li&gt;
&lt;li&gt;Different forms of leverage (labor, capital, content, code) become more important as you move up the ladder.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 3: Investing up the Wealth Ladder&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Those with less wealth tend to own cash, vehicles, and homes; those with more wealth own investments that generate income.&lt;/li&gt;
&lt;li&gt;Moving up the ladder means shifting from assets that cost money to those that make money.&lt;/li&gt;
&lt;li&gt;Owning a business or stocks is common at higher levels, but ownership alone doesn’t guarantee success.&lt;/li&gt;
&lt;li&gt;The key is to gradually increase your share of income-producing assets.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 4: Level 1 (&amp;lt;$10k) — Atypical Results Require Atypical Actions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Focus on reducing debt and building a financial safety net.&lt;/li&gt;
&lt;li&gt;Prioritize developing skills that can increase your income, ideally without taking on more debt.&lt;/li&gt;
&lt;li&gt;Rely on relationships for support if needed, and be prepared to reciprocate.&lt;/li&gt;
&lt;li&gt;Avoid large financial risks like high-interest debt or unnecessary loans.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 5: Level 2 ($10k–$100k) — Learn Today, Earn Forever&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Identify where your skills, interests, and market demand overlap.&lt;/li&gt;
&lt;li&gt;Education that leads to higher earnings is a worthwhile investment at this stage.&lt;/li&gt;
&lt;li&gt;Beware of dead-end jobs and missed opportunities.&lt;/li&gt;
&lt;li&gt;The mindset: invest in learning now to benefit for a lifetime.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 6: Level 3 ($100k–$1M) — Just Keep Buying&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Research investments that suit you and consider side hustles to diversify income.&lt;/li&gt;
&lt;li&gt;Focus on acquiring income-producing assets and creating multiple income streams.&lt;/li&gt;
&lt;li&gt;Overspending, especially on big purchases like homes, is a major risk.&lt;/li&gt;
&lt;li&gt;Consistency in investing is key; keep building wealth steadily.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 7: Level 4 ($1M–$10M) — What Got You Here Won’t Get You There&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Decide whether to stay at this level or pursue business ownership for further growth.&lt;/li&gt;
&lt;li&gt;Continued investment and possibly starting or joining a business are main opportunities (you need equity).&lt;/li&gt;
&lt;li&gt;Avoid speculative investments and businesses that are just jobs in disguise (aka they depend on you).&lt;/li&gt;
&lt;li&gt;The strategies that got you to this level may not be enough to move higher.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 8: Level 5 ($10M–$100M) — Only the Paranoid Survive&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Decide whether to sell your business, start a new one, or stop climbing.&lt;/li&gt;
&lt;li&gt;Scaling or selling businesses is a common path at this level.&lt;/li&gt;
&lt;li&gt;Watch out for concentrated investments, personal liabilities, and the psychological challenges of wealth.&lt;/li&gt;
&lt;li&gt;Protect your wealth and relationships; risk management is crucial.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 9: Level 6 ($100M+) — Legacy = Action × Wealth&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Focus on safeguarding your wealth and prioritizing non-monetary aspects of life, like relationships and health.&lt;/li&gt;
&lt;li&gt;Consider the impact and legacy you want to leave.&lt;/li&gt;
&lt;li&gt;Major risks include divorce, lawsuits, and taking unnecessary risks.&lt;/li&gt;
&lt;li&gt;At this stage, your actions and how you use your wealth define your legacy.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Chapter 10: How Long Does It Take to Climb the Wealth Ladder?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Wealth accumulation is a long-term process; most millionaires are in their sixties.&lt;/li&gt;
&lt;li&gt;Upward mobility is possible, especially over decades, but most people remain in the same wealth level over ten years.&lt;/li&gt;
&lt;li&gt;Time and patience are essential; expect gradual progress, not overnight success.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Insights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Money can increase happiness, especially at lower levels, but its impact diminishes as wealth grows.&lt;/li&gt;
&lt;li&gt;True wealth includes social, mental, physical, and time wealth—not just financial assets.&lt;/li&gt;
&lt;li&gt;Balance is key: financial wealth multiplies the value of other forms of wealth, but can’t replace them (salt metaphor).&lt;/li&gt;
&lt;li&gt;The journey up the Wealth Ladder is as much about enjoying life and relationships as it is about accumulating money.&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Tue, 05 Aug 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-08-05-notes-the-wealth-ladder-by-nick-maggiulli.html</guid>
        </item>
        
        <item>
            <title>Natalie</title>
            <link>https://www.lucabol.com/posts/2025-07-25-natalie.html</link>
            <description>&lt;p&gt;&lt;img src="/img/natalie.jpg" alt="A woman looking outside the window at the rain" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Natalie is on the sofa of her mountainside villa. Rain hits the window, carried by the wind from the sea. Her shoulders are relaxed; the children&amp;rsquo;s rooms are quiet.&lt;/p&gt;
&lt;p&gt;Her face looks back from the dark glass. Beautiful. She makes herself widen her eyes, part her lips. She knows this, and the weariness that lies underneath. She frowns.&lt;/p&gt;
&lt;p&gt;The phone lies on the table in front of her. Her schedule for tomorrow. She rehearses faces, phrases and jokes. They pay after all. It&amp;rsquo;s only fair.&lt;/p&gt;
&lt;p&gt;She hears the spin cycle of the washing machine finishing. Her shoulders stiffen. The phone pings and she picks it up. It&amp;rsquo;s a message from her husband. There&amp;rsquo;s music in the background and the sound of people laughing.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Sorry I forgot to call you. It is going fantastically! Everyone here loves me! It&amp;rsquo;s going to be huge! I am going to take you and the kids to Hawaii this summer.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Jakob, come here!&amp;rdquo; a voice calls out.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Gotta go now. Don&amp;rsquo;t forget the kids&amp;rsquo; dentist appointment and the football match this week. Ahh, and my mum wants you to call her.  Love ya&amp;rsquo;. Bye.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;As the message is playing, a forced smile flickers across her face.&lt;/p&gt;
&lt;p&gt;The washing machine finishes and plays its little jingle. She tenses her legs to stand up but sinks back down onto the sofa.&lt;/p&gt;
&lt;p&gt;She sees the photograph. Old. Yellow edges. A girl dancing on a table, men watching, mouths open. She puts a hand to her mouth and smiles. Her eyes are wet.&lt;/p&gt;
&lt;p&gt;The rain is falling hard now. Natalie removes her socks and shivers as her feet touch the floor. She stands, moves to the window and opens it. The sound of the rain and the scent of pine trees fills the room.&lt;/p&gt;
&lt;p&gt;&amp;ndash; AND &amp;ndash;&lt;/p&gt;
&lt;p&gt;She walks into the rain and into the night toward the sea.&lt;/p&gt;
&lt;p&gt;&amp;ndash; OR &amp;ndash;&lt;/p&gt;
&lt;p&gt;She gets out in the rain. He is there. She takes his hand and brings him inside. They walk to the sofa leaving wet tracks on the floor.&lt;/p&gt;
&lt;p&gt;&amp;ndash; OR &amp;ndash;&lt;/p&gt;
&lt;p&gt;She looks into the night and sees the man waiting for her. She steps forward and the water wets her bare feet. She sighs, steps backward and closes the window.&lt;/p&gt;</description>
            <pubDate>Fri, 25 Jul 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-07-25-natalie.html</guid>
        </item>
        
        <item>
            <title>JediMaster: LLM assigns issues to Coding Agent</title>
            <link>https://www.lucabol.com/posts/2025-06-19-jedimaster-llm-assigns-issues-to-coding-agent.html</link>
            <description>&lt;p&gt;I have been working on JediMaster: a Python package that uses an LLM to assign issues to the GitHub coding agent.&lt;/p&gt;
&lt;p&gt;The idea is to use the LLM to analyze the issue and determine if it is suitable for the coding agent to work on. If it is, the LLM will assign the issue to the coding agent (or just label it).&lt;/p&gt;
&lt;p&gt;You can use it either as a script, as a library, or as a set of Azure Functions (i.e., to automatically assign the issues on a timer).&lt;/p&gt;
&lt;p&gt;The code is available on GitHub: &lt;a href="https://github.com/lucabol/JediMaster"&gt;JediMaster&lt;/a&gt;.&lt;/p&gt;</description>
            <pubDate>Thu, 19 Jun 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-06-19-jedimaster-llm-assigns-issues-to-coding-agent.html</guid>
        </item>
        
        <item>
            <title>Anna and Frank</title>
            <link>https://www.lucabol.com/posts/2025-06-08-anna-and-frank.html</link>
            <description>&lt;style&gt;
.language-woman {
    font-family: var(--font-mono);
    font-size: var(--base-size);
    text-wrap: pretty;
    line-height: 1.3;
    color: #C71585;
    white-space: pre-wrap;
    font-style: italic;
}

.language-man {
    font-family: var(--font-mono);
    font-size: var(--base-size);
    font-style: italic;
    text-wrap: pretty;
    line-height: 1.3;
    color: #4169E1;
    white-space: pre-wrap;
}

pre {
    margin: 2rem 1rem;
    background: none !important;
}

pre:has(.language-man) {
    position: relative;
    padding: 2rem 0;
}

pre:has(.language-man)::before,
pre:has(.language-man)::after {
    content: "";
    display: block;
    height: 2px;
    width: 100%;
    background: linear-gradient(to right, 
        transparent,
        #C71585,
        #4169E1,
        transparent
    );
    position: absolute;
    left: 0;
}

pre:has(.language-man)::before {
    top: 0;
}

pre:has(.language-man)::after {
    bottom: 0;
}
&lt;/style&gt;
&lt;p&gt;&lt;img src="/img/letters.jpg" alt="A table full of letters." width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dear unknown hero,
I am writing without knowing who you are, but knowing that you are out there fighting for us all. I don't know war, but I know how it feels to be alone, to be afraid without anyone to turn to for help.

My name is Anna, I live in a small village in the south. The war has not reached us yet. The fields are still green, the sun shines and the birds sing. The lilacs are blooming and the trees are full of fruits.

I wish I could show you how beautiful it is here. My words cannot bring you the peace and joy I feel.

I feel secure knowing that you are out there protecting us all. Never forget that you are a hero and you are not alone. We are all there with you in spirit.

Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

I am Frank. I am at the Western front. I am with the 8th Infantry Division.

It was good to receive your letter. Made me want to be there. Nice, the lilacs.

Please write again.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dear Frank,

It warms my heart that you liked the lilacs. Their scent so sweet and strong fills the air around my house. I wish you could smell them too.

Today I baked a pie with the first apples of the season. It came out well, soft on the inside and crunchy on the outside. I ate it on the terrace, as the sun went down.

I thought of you. How your world looks like now. Maybe you would have liked my pie.

I hope it is ok to write to you like this. I hope you don't mind.

Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

My world has no color. The sky is cement and the ground is mud. Your letter painted it in colors I had forgotten.

Today I had to repair a truck. Transmission problems. My hands are still dirty for it and with little cuts. Not much water around here to clean them.

Your pie sounds good. I would have liked it. I like apples.

Please keep writing.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dear Frank,

Today I was in the garden. The sun was warm on my back, but a cool breeze made the leaves dance and my skin tingle.

I had a hard time pulling the weeds. Maybe you would have helped me? I could have used your strong hands and hearing your voice would have made the task go faster.

The evening was colder, so I tucked myself in a blanket and sat on the terrace.

I don't know if I should tell you these small things. I hope you don't mind.

Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

A boy died today. He was 19 and a good boy. A sniper got him. We are all sad and angry and tired.  Your letter made me feel better.

My hands are strong. I would have pulled the weeds for you.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dearest Frank,

I am sorry about the boy. The world is so cruel. I am happy that my letter helped you feel better, even if just a little.

Perhaps I should not say this, as we have never met, but yesterday night I dreamed of you. We were sitting on my terrace as the sun went down. We were not talking, just enjoying the silence, the breeze and the smell of lilacs.

It is not right that you don't know what I look like. I am sending you a picture of me.

Maybe you won't write to me again once you see it, but I hope you do.

Yours,
Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

You are beautiful. I didn't expect that. I am glad you sent me the picture. I keep it in my pocket and look at it when I can.

I don't have a picture to send you. My comrade has drawn a sketch of me. I am sending it to you. It is not as good as your picture, but it is me.

Please keep writing. Your letters give me strength.
-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dearest Frank,

You look handsome in the sketch. It arrived all crumpled up but I ironed it and made it flat again. I keep it in a frame on my nightstand.

At night, the wind brings the smell of lilacs through the window. I look at you and imagine you are here with me.

Is it wrong to think of you like this? I don't know. It feels right, safe and warm. I feel like I know you, even if we have never met.

Yours,
Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

You made me remember the smell of lilacs. I had forgotten it. I wish I could smell them with you.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dearest Frank,

I will send you a pressed lilac flower. Maybe a little smell will reach you through the paper.

I think about your hands. How strong they must be. How rough they must feel on my skin. I wonder if you would like to hold me. I wonder if you would like to kiss me.

Oh gosh. I am sorry. I should not write this. I am sorry if I made you uncomfortable.

Yours,
Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dear Frank,
It has been a while since you last wrote to me. Did I say something wrong? Was I too forward?

I am sorry if I did. I hope you are ok.

Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

Delivery is slow here. I just received your last two letters. I thought you had stopped writing to me. My heart skipped a beat when I saw your name on the envelope.

I always look forward to your letters. Please keep writing.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dearest Frank,

I felt so lonely without your letters. I am so happy to hear from you again.

You are the only person that can really see me. You make me feel wanted and happy. I feel like I can tell you anything.

I think about you way too much. I wonder if you think about me too. I wonder if you would like to meet me one day.

I promise to keep writing. I will write to you until you tell me to stop.

Yours,
Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,
I think about you too. I wonder what it would be like to meet you. I wonder if you would like me.

I don't speak too much but I am a good listener and my feelings are deep.

Perhaps one day we will meet. I would like that.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dearest Frank,

Today the sun was shining and the sky was blue. I was cooking in the kitchen and I felt like dancing. I imagined you were there with me, holding me in your arms and spinning me around.

I felt your strong hands on my waist, your breath on my neck. I felt so happy and alive.

Please think of me like this. I am here for you.

Yours,
Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

Your letter made me smile. It sent away the dust and the mud. I want to hold you and dance with you.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-woman"&gt;Dearest Frank,

The nights are getting colder. I read your letters in bed and they warm me up. They make me feel all soft and fuzzy inside.

What is this feeling? Am I falling in love with you? I think I am. I think I love you.

Yours always,
Anna
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-man"&gt;Anna,

I love you too. I think about you all the time.

I have good news. I will be home in a few weeks. I will come and find you. Wait for me.

-F
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The old woman mutters to herself in the kitchen. Her voice high and thin, like a girl.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Frank, don&amp;rsquo;t come home. You can&amp;rsquo;t come home.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;There is garbage all around her feet. The floor is sticky with old food and spilled drinks. There is the carcass of a rat in the corner, eyes wide open, staring at the ceiling.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Don&amp;rsquo;t find me. Don&amp;rsquo;t find me.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She sits down on the chair in front of the small table. She picks up the pen and starts writing on a piece of paper.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Dear Frank &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She finishes the letter, seals it in an envelope and puts it on the side of the table. She looks at it for a moment then stands up and goes back to her cooking.&lt;/p&gt;
&lt;p&gt;There is a strong bang from the other room. The wind has opened a window and it slams against the wall: bang &amp;hellip; bang &amp;hellip; bang.&lt;/p&gt;
&lt;p&gt;The old woman straightens her back and grows taller. She starts talking to herself again, but her voice is deeper now, more guttural.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Anna, why do you say &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She moves around in the kitchen retracing her steps. She moves fast with a lot of energy. She doesn&amp;rsquo;t look old anymore. She doesn&amp;rsquo;t look like a girl now.&lt;/p&gt;
&lt;p&gt;Then she stops and sits on the other side of the table. There are pen and paper on that side too. She picks up the pen and starts writing.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Anna, why I should not come home? &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She writes for a long time, the hand uncertain, shaking a little. She finishes the letter, seals it in an envelope and puts it on that side of the table.&lt;/p&gt;
&lt;p&gt;There is a mountain of envelopes on the table, on both sides. Some are dirty with old food, the newest ones are clean and white.&lt;/p&gt;
&lt;p&gt;The old woman stands up and goes back to her cooking. The window in the other room still bangs against the wall: bang &amp;hellip; bang &amp;hellip; bang.&lt;/p&gt;</description>
            <pubDate>Sun, 08 Jun 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-06-08-anna-and-frank.html</guid>
        </item>
        
        <item>
            <title>The butler</title>
            <link>https://www.lucabol.com/posts/2025-05-15-the-butler.html</link>
            <description>&lt;p&gt;&lt;img src="/img/butler.jpg" alt="A black butler carrying a woman asleep" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;The car arrived at the plantation at midday, which is a time of sweat in the south. The help lined up in front of the house sweat running down their faces and their backs creating darker patches on their white uniforms. The air smelled of banana leaves.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;She the wife?&amp;rdquo; asked Myrtle, adjusting the headband on her head. Eugene didn&amp;rsquo;t reply.&lt;/p&gt;
&lt;p&gt;The car stopped in the driveway and sprayed dust in the air. The colonel stepped out and opened the door for her and she came out holding her hat for protection against the sun. They walked up the stairs and in front of the help.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;This is the help, dear. Eugene here has been with us for more than twenty years. He is our butler.&amp;rdquo;, said the colonel.&lt;/p&gt;
&lt;p&gt;Eugene looked at the girl, and she was a girl, twenty at most to the colonel&amp;rsquo;s fifty. Her skin was very white with red patches because of the sun. Her eyes were pale blue and large and with long lashes. She tilted her head to one side and smiled at Eugene. He smiled back.&lt;/p&gt;
&lt;p&gt;The colonel introduced the rest of the help bruskly and energetically waving his hands as he talked. Myrtle gave a slight bow, tripped over her feet and Eugene caught her. The colonel regarded them with a frown and continued with the introductions.&lt;/p&gt;
&lt;p&gt;He finished. He marched into the house, pulling the girl with him. The help went back to work. It was harvest season. There was much to do. The heat slowed everything.&lt;/p&gt;
&lt;p&gt;The night brought cooler air and Eugene went to the library. He was the only one to use it. The colonel could read, but he had no interest in it. The help could not read and at times Eugene read to them but he preferred to read alone.&lt;/p&gt;
&lt;p&gt;As he sat with his book he heard a drunken giggling from the corridor and he saw the couple in the doorframe embracing tightly, her wavering sideways because of their weight difference. She stopped and looked at Eugene with curiosity and a frozen smile on her lips.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Oh, I let Eugene come and read here when he is done with his work&amp;rdquo;, said the colonel, looking away. Eugene stiffened and the colonel tightened his grip on the girl&amp;rsquo;s waist and dragged her, frozen smile and all, toward the bedroom.&lt;/p&gt;
&lt;p&gt;As the days went by the help started gossiping. There were shouts of pleasure and shouts of pain coming from the bedroom at night. They could hear hard words spoken and they could hear crying. Myrtle said with admiration that the colonel was an animal. Eugene didn&amp;rsquo;t say anything.&lt;/p&gt;
&lt;p&gt;The girl cheeks got redder because of the sun and she was more comfortable in the house talking to the help with authority but also with kindness and respect while the colonel made his rounds around the plantation. They went to the city together and they often had people over for dinner and the men drank whisky in the library while the women sit down and talked in the dining room. The colonel taught her how to ride and left her roses on her bed.&lt;/p&gt;
&lt;p&gt;Eugene didn&amp;rsquo;t like any of it because it was too much and no flame can burn both bright and long. He looked at the girl and hoped she had good bones for what was coming but he doubted it because she was so slight. He thought about Evaline and her big bones and her big ass and how she died in the plantation when their third child was born.&lt;/p&gt;
&lt;p&gt;Evaline was strong and she died strongly. She had a solid quality to her as if she occupied more space on this earth that her frame would allow. Evaline was gone and now there was this girl and he hoped she would be ok but he doubted it because she didn&amp;rsquo;t occupy any space at all.&lt;/p&gt;
&lt;p&gt;One night Eugene saw them from the library door and the colonel wasn&amp;rsquo;t holding her waist quite as tight and they weren&amp;rsquo;t giggling and Eugene knew what was about to come.&lt;/p&gt;
&lt;p&gt;After a while the trips started and the colonel was rarely home. There was always something in the city that required his attention and the plantation overseer was making the colonel&amp;rsquo;s rounds. Eugene found glasses around the house that smelled of whiskey and he knew the girl was drinking and he knew that she was not ok.&lt;/p&gt;
&lt;p&gt;The girl was losing her kindness and she treated the help with little respect and Eugene thought that it was because she had no respect for herself because of the drinking and the loss of her man.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;What are you reading, Eugene?&amp;rdquo; she asked one night, words coming out of her mouth with fatigue. She took the whisky bottle from the cabinet and two glasses.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I don&amp;rsquo;t drink, Madame&amp;rdquo;, he said hesitantly and she put one glass back reluctantly.&lt;/p&gt;
&lt;p&gt;She poured a big one for herself, sat down in front of him, gulped most of it down and started talking: &amp;ldquo;You know Eugene that I can&amp;rsquo;t read? No-one taught me. Why would a belle like me read? I can&amp;rsquo;t read. Is it difficult? Am I still a belle now that I am married? It&amp;rsquo;s true, I can&amp;rsquo;t read.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Her voice slurred and he couldn&amp;rsquo;t understand all she was saying and he didn&amp;rsquo;t reply. She gulped the rest of the glass down and her eyes widened with intention.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Would you read to me, Eugene?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I am not a good reader.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;But you can read, can&amp;rsquo;t you?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Yes.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Then read to me!&amp;rdquo; she spit out, with excessive force.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;What do you want me to read?&amp;rdquo; he asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Something &amp;hellip; something &amp;hellip;&amp;rdquo; and her voice fell to a whisper &amp;ldquo;Something &amp;hellip; you know &amp;hellip; to make me better &amp;hellip; smarter &amp;hellip; I am not smart &amp;hellip; They didn&amp;rsquo;t teach me smartness &amp;hellip; just to be a belle &amp;hellip; something to make me smart.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Eugene was uncertain. These were dangerous waters, he thought, my reading to this girl or my refusing to do it. Either way it is unfit for my position. He looked at the girl and her watery blue eyes streaked with small red veins because of the whisky and her lips parted and her slim white arms. He looked at the girl and started reading.&lt;/p&gt;
&lt;p&gt;As he read he watched the girl and saw that she was falling asleep. He tried to vary his tone and speak louder to avoid it but there was no avoiding it and she fell asleep on the chair. The nightgown had opened and Eugene could see her white legs coming out of it and he could see the top of her white breast.&lt;/p&gt;
&lt;p&gt;He looked away but then looked back at her and his eyes narrowed and he couldn&amp;rsquo;t understand it because it had been such a long time without it. He shook his head to dispatch the feelings and reclaim clarity. He tried to wake her up but she just shuffled on the chair and her head fell to one side.&lt;/p&gt;
&lt;p&gt;I cannot leave her like this but I cannot touch her either. He looked at the open door. What if someone comes in? What if they find us like this? The fear and the embarrassment and the dark room fueled his feelings and he felt hunger and desire for her and didn&amp;rsquo;t know why because she was so slight.&lt;/p&gt;
&lt;p&gt;He stood up and walked to her and closed her nightgown. He picked her up in his arms and carried her to the bedroom. He put her on the bed and covered her with the blanket. He looked at her for a while, then left the room. He went back to the library and tried to read but couldn&amp;rsquo;t. He looked at the dark window and thought of nothing.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Can you read to me, Eugene?&amp;rdquo; she asked the next night.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I am an old man, Madame. I get tired from reading too much.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Please, Eugene. It would mean a lot to me.&amp;rdquo; she said petulantly.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Let&amp;rsquo;s make a deal. You fill up the small glass because I am too old to last until you finish the big one and I will read to you until the glass is empty.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She widened her eyes in surprise and poured the small glass full of whisky. Eugene started reading and she was very careful not to drink too much.&lt;/p&gt;
&lt;p&gt;They went on like this for a while and she asked him if Darcy and Elizabeth were going to end up together and he said she had to wait a little longer and she asked him if they should end up together and he said that it depends on the reader and to be more careful with the word &amp;lsquo;should&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Darcy is a fool&amp;rdquo;, she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Why do you say that, Madame?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Because he is proud and arrogant. He thinks he is better than everyone else.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The girl&amp;rsquo;s eyelids were heavy and she was fighting to keep them open and the whisky was all gone.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Good night, Eugene&amp;rdquo;, she said without looking at him and she went to bed.&lt;/p&gt;
&lt;p&gt;Eugene sat in the library for a long time and thought about the girl and thought about the colonel and thought about Evaline and all his thoughts were jumbled and he couldn&amp;rsquo;t make sense of them.&lt;/p&gt;
&lt;p&gt;The colonel was away for a long time and Eugene read to the girl every night and she drank less and less and the kindness and the respect came back to her.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Why don&amp;rsquo;t they get together now, Eugene?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;There are many things in the way, Madame.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;But they are of no consequence!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;There are many things in the way and they are of great consequence, Madame.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Maybe you are right. Life is not that simple, is it Eugene?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Life is not that simple, Madame, and there are things of great consequence.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;One night the girl told Eugene that the colonel was coming back the next day and they had to finish the book before that. Eugene read to her for a long time and she drank many small glasses of whisky and they were both tired but happy that the book was finished.&lt;/p&gt;
&lt;p&gt;Before going to bed the girl kissed Eugene on the forehead and said: &amp;ldquo;Thank you, Eugene.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Eugene froze because of the audacity of her and because he didn&amp;rsquo;t expect it and felt his face getting all warm and his stomach turning. The sun was coming up and he heard a rooster crowing and smelt the morning air coming in through the window.&lt;/p&gt;
&lt;p&gt;The colonel arrived in a fury of dust, sweat and noise. The business in the city had been good and there was a lot to say and a lot to do. Plans had to be drawn for the harvest and the overseer had to be called and the workers had to be organized. The house filled with shouts and orders and the sound of feet stamping on the floor.&lt;/p&gt;
&lt;p&gt;The night came and Eugene was in the library and he saw the colonel and the girl passing by the door. The colonel was holding her waist tight and she was laughing and they were both drunk. He heard the bedroom door slam and the colonel shout and the girl cry. He heard a loud bang and stood up and walked to the door of their bedroom. The door was ajar because they slammed it too hard and through the crack he saw them.&lt;/p&gt;
&lt;p&gt;They were on the big bed and the colonel was on top of her and holding her arms down with his hands. The colonel was kissing her neck and the girl&amp;rsquo;s face was turned toward Eugene and her eyes were closed and her mouth was soft and her body was limp. Eugene stepped back from the door; clenched his fists and walked back toward the library.&lt;/p&gt;
&lt;p&gt;He sat down and stared out the window. The night was dark and the crickets were singing. He sat for a long time until no more sounds came from the bedroom. He sat and thought about Evaline and her big bones and the white of the girl&amp;rsquo;s legs and her soft lips.&lt;/p&gt;
&lt;p&gt;He stood up and opened the tall cabinet and took out the rifle. He got the bullets from the drawer and loaded it and got out of the library. The corridor was dark except for the light coming from the bedroom. Eugene walked toward the light, got to the door, stepped inside and stopped in front of the bed.&lt;/p&gt;
&lt;p&gt;The lovers slept and the light came from the moon outside the window and the girl&amp;rsquo;s legs stuck out of the blanket and they were very white.&lt;/p&gt;
&lt;p&gt;The help woke up to the loud bang of the gunshot and the dogs barked and the crickets stopped singing. The night went silent.&lt;/p&gt;</description>
            <pubDate>Thu, 15 May 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-05-15-the-butler.html</guid>
        </item>
        
        <item>
            <title>SandScore: app to track stats of a beach volley match</title>
            <link>https://www.lucabol.com/posts/2025-05-13-sandscore-app-to-track-stats-of-a-beach-volley-match.html</link>
            <description>&lt;p&gt;I have created a phone friendly application to track the score and stats for a beach volley game. It is &lt;a href="https://github.com/lucabol/SandScore"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/img/SandScore.jpg" alt="Image of the app." width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Here are the main user features:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Doesn&amp;rsquo;t need an internet connection. It is a single html file that can be saved on the phone and keeps state in the browser.&lt;/li&gt;
&lt;li&gt;Has a Beginner and Advanced mode depending of the level of statistical sophistication.&lt;/li&gt;
&lt;li&gt;Tracks serve turns and score.&lt;/li&gt;
&lt;li&gt;Keeps a log of all rallies visible to the user.&lt;/li&gt;
&lt;li&gt;Display statistics in both an automatic and bespoken way.&lt;/li&gt;
&lt;li&gt;Unlimited undo/redo.&lt;/li&gt;
&lt;li&gt;Save and load of a match to file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The stats tracking part is still buggy. If there is interested in it, I can fix it. Email me.&lt;/p&gt;
&lt;p&gt;From a technical perspective the main idea is to have a state machine driving everything: from the UI to the user interaction to the help to the stats displaying.&lt;/p&gt;
&lt;p&gt;Here is how it looks for the beginner mode (you might have to scroll right to see all properties):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;    &amp;quot;Serve&amp;quot;: {
        &amp;quot;displayName&amp;quot;: &amp;quot;{servingTeam} Serve&amp;quot;,
        &amp;quot;transitions&amp;quot;: [
            { &amp;quot;action&amp;quot;: &amp;quot;Ace&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;point&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Direct point from serve&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;serve&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;0&amp;quot; }, // Simplified stat player
            { &amp;quot;action&amp;quot;: &amp;quot;SErr&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Service error&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;serve&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;0&amp;quot; }, // Simplified stat player
            { &amp;quot;action&amp;quot;: &amp;quot;RE1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Reception error by player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;reception&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;RE2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Reception error by player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;reception&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;R1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Attack Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;regular&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Reception by player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;reception&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;R2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Attack Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;regular&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Reception by player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;reception&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; }
        ]
    },
    &amp;quot;Attack Receiver&amp;quot;: {
        &amp;quot;displayName&amp;quot;: &amp;quot;{receivingTeam} Attack&amp;quot;,
        &amp;quot;transitions&amp;quot;: [
            { &amp;quot;action&amp;quot;: &amp;quot;Win1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;point&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Winning attack by player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Win2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;point&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Winning attack by player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Err1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Attack error by player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Err2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Attack error by player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Blk1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Blocked player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Blk2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Blocked player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Def1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Attack Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;regular&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Defended player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Def2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Attack Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;regular&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Defended player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Receiving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; }
        ]
    },
    &amp;quot;Attack Server&amp;quot;: {
        &amp;quot;displayName&amp;quot;: &amp;quot;{servingTeam} Attack&amp;quot;,
        &amp;quot;transitions&amp;quot;: [
            { &amp;quot;action&amp;quot;: &amp;quot;Win1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;point&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Winning attack by player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Win2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Server&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;point&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Winning attack by player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Err1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Attack error by player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Err2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Attack error by player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Blk1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Blocked player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Blk2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Point Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Blocked player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Def1&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Attack Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;regular&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Defended player 1&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;1&amp;quot; },
            { &amp;quot;action&amp;quot;: &amp;quot;Def2&amp;quot;, &amp;quot;nextState&amp;quot;: &amp;quot;Attack Receiver&amp;quot;, &amp;quot;style&amp;quot;: &amp;quot;regular&amp;quot;, &amp;quot;help&amp;quot;: &amp;quot;Defended player 2&amp;quot;, &amp;quot;category&amp;quot;: &amp;quot;attack&amp;quot;, &amp;quot;statTeam&amp;quot;: &amp;quot;Serving&amp;quot;, &amp;quot;statPlayer&amp;quot;: &amp;quot;2&amp;quot; }
        ]
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From a high level perspective, the state machine contains everything needed to run the app: the name of the buttons to display, the next state, the style of display, help message, stat category, stat team and player.&lt;/p&gt;
&lt;p&gt;The UI, stats and logic is generated dynamically by walking over the state machine.&lt;/p&gt;
&lt;p&gt;As an experiment, I described to an AI agent how I wanted the code to look (i.e., the usage of a state machine) and iterate on it without looking at the generated code while doing it (aka vibe coding). That&amp;rsquo;s why the stats part is still buggy as the AI has an hard time figuring it out.&lt;/p&gt;</description>
            <pubDate>Tue, 13 May 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-05-13-sandscore-app-to-track-stats-of-a-beach-volley-match.html</guid>
        </item>
        
        <item>
            <title>A very polite girl met an Ogre in the woods</title>
            <link>https://www.lucabol.com/posts/2025-04-09-a-very-polite-girl-met-an-ogre-in-the-woods.html</link>
            <description>&lt;p&gt;&lt;img src="/img/ogre.jpg" alt="A woman looking at an Ogre by the fire in the woods." width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;A very polite girl met an Ogre in the woods. She was gathering mushrooms and herbs for her children&amp;rsquo;s dinner. He was eating a roast on a stick. It was cold, the forest was covered in ice and the girl was trembling.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Good evening Mr. Ogre.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Evn&amp;rsquo;ing.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Your meat smells delicious.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Want a slice? Might warm you up.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The girl looked doubtfully at the fat drooling down from the stick and answered: &amp;ldquo;I thank you for your kind offer, but we are vegetarians. No meat for us but I fully respect your choice of -&amp;ldquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Why then you said it looked delicious?&amp;rdquo; interrupted the Ogre.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Just making conversation&amp;rdquo;, replied the girl condescendingly.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You lied?&amp;rdquo; said the Ogre surprised.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Just making conversation&amp;rdquo;, she repeated, slowing down her speech as if she were talking to a child.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You look awfully cold there. Come by the fire. You can snuggle inside my coat and warm up.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Ogre!&amp;rdquo;, exclaimed the girl, &amp;ldquo;This is not a proper thing to propose to a married young girl, or to any young girl.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;My body is warm and you are cold. What is there to shout about?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The girl sighed with exasperation: &amp;ldquo;What would your wife say if she knew you held a girl in your arms?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;We are not doing too well with my wife after the Shenabadumsdumla situation.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Which situation was that? If you don&amp;rsquo;t mind me asking.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Shenabadumsdumla &amp;hellip; she is our neighbour. She has a great ass. We screwed like rabbits for months hiding in her cave, we tried all positions, even &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Ogre!&amp;rdquo; shouted the girl indignantly &amp;ldquo;You don&amp;rsquo;t say &amp;lsquo;screw&amp;rsquo;, you say &amp;lsquo;made love&amp;rsquo;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Isn&amp;rsquo;t it the same thing?&amp;rdquo;, asked the Ogre befuddled.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;No! Love is passion and -&amp;ldquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;We had plenty of passion!&amp;rdquo; laughed the Ogre.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;And you don&amp;rsquo;t go into details like that&amp;rdquo;, continued the girl resigned.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;But I think about the details all the time. Imagine that once -&amp;ldquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Stop there, Ogre! And now you lost your wife. How sad.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I have not lost her. She is still in the cave. She&amp;rsquo;s just upset. She&amp;rsquo;ll get over it.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The girl was losing her cool and was forgetting her &amp;lsquo;please&amp;rsquo; and &amp;lsquo;thank you&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You are so beautiful&amp;rdquo; said the Ogre out of the blue.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I thank you for your kind remark, but I would like you to praise my intelligence instead&amp;rdquo;, replied the girl, finally remembering her manners.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I don&amp;rsquo;t know if you are intelligent, but sure you are beautiful&amp;rdquo;, stated the Ogre matter of fact.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;The way you say it &amp;hellip; it is like you mean it too much. Our friends also have noticed it but say it more subtly and I like that better. Oh, except when we are drunk &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;What happens when you get drunk?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;It is not our fault, it is the wine. It is civilized to behave badly when you are drunk. No-one is perfect!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;So, what happens?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Ok &amp;hellip; we talk grossly and misbehave. Once a man pat me on my behind and I wanted to kiss a young fella, but didn&amp;rsquo;t, or did I?&amp;rdquo; &lt;/p&gt;
&lt;p&gt;&amp;ldquo;You become Ogres!&amp;rdquo;, exclaimed the Ogre with satisfaction.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Don&amp;rsquo;t say such things. We are civilized people. We know our manners. Our mothers taught us well. Except &amp;hellip; maybe &amp;hellip; the wine &amp;hellip;&amp;rdquo;, the girl sounded uncertain.&lt;/p&gt;
&lt;p&gt;The Ogre was getting bored of all that talking.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Come by the fire&amp;rdquo;, he whispered.&lt;/p&gt;
&lt;p&gt;The girl made a tentative step forward as she was very cold, but then tightened her vest and stepped backward again.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Come on!&amp;rdquo;, said the Ogre, getting upset, &amp;ldquo;Do you really need alcohol to behave properly?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I don&amp;rsquo;t need anything! Don&amp;rsquo;t speak to me that way!&amp;rdquo;, shouted the girl, suddenly alive, &amp;ldquo;For your knowledge, at the village feast while my husband was home with the kids, I slept with a very nice man &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;See!&amp;rdquo; said the Ogre triumphantly.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;It wasn&amp;rsquo;t like that at all. He was quite nice, gentle, and very polite. I found it quite enjoyable. He asked me what I wanted and it was very civilized. I confessed it to my husband and he said that it was ok because it had been so civilized and the butcher - oh, I shouldn&amp;rsquo;t have said its name - is a good business partner.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The Ogre yawned. &amp;ldquo;Yeah, it doesn&amp;rsquo;t sound like my thing with Shenabadumsdumla at all. Are you coming by the fire or not?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The girl stepped forward as she was very cold and the Ogre looked very warm, but then she stopped.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You are so beautiful&amp;rdquo;, said the Ogre and the girl smiled.&lt;/p&gt;</description>
            <pubDate>Wed, 09 Apr 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-04-09-a-very-polite-girl-met-an-ogre-in-the-woods.html</guid>
        </item>
        
        <item>
            <title>The last ferry</title>
            <link>https://www.lucabol.com/posts/2025-04-03-the-last-ferry.html</link>
            <description>&lt;p&gt;&lt;img src="/img/ferry.jpg" alt="A girl watching a couple on a ferry." width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I have to talk to the school and to the tennis coach after work and need steaks for tonight&amp;rsquo;s dinner and mum wants to chat about my sister  &amp;hellip; but, no wait &amp;hellip; don&amp;rsquo;t think like that &amp;hellip; first things first &amp;hellip; that&amp;rsquo;s what the book says &amp;hellip; first thing, my presentation today &amp;hellip;  did the Boss like it?  He is a smart man, but I wish he could speak more clearly &amp;hellip; must be Diana&amp;rsquo;s graphics &amp;hellip; yeah, a bit unusual but come on! &amp;hellip; and just today the ferry is late &amp;hellip; I am going to be late for work again &amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;and what the fuck does this guy want?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You have beautiful hazel eyes.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What??&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;m sorry. I didn&amp;rsquo;t mean to intrude.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The man was young, embarrassed and went back to his table. Claudia looked at him sternly; thin, nervy, faded jeans, a book on his laps - &amp;lsquo;Siddhartha&amp;rsquo; - and he wasn&amp;rsquo;t young. He had gray in his hair. He wasn&amp;rsquo;t young, but she &amp;lsquo;felt him&amp;rsquo; young. &lt;/p&gt;
&lt;p&gt;At work, she wasn&amp;rsquo;t sure if the presentation went well or badly.  &lt;em&gt;Focus, Claudia, focus &amp;hellip; what is the problem with you? Go &amp;hellip; ask for feedback &amp;hellip; smile &amp;hellip; smile &amp;hellip; too many things going on in my life &amp;hellip; need more discipline.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Do you think I have hazel eyes?&amp;rdquo; she asked her husband, while cooking the steaks.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;m not sure. It&amp;rsquo;s not even a color. I like your ass more!&amp;rdquo; and slapped it for confirmation. That night they made love for the first time in weeks and she relaxed into it.&lt;/p&gt;
&lt;p&gt;The morning came and it was raining, and she looked for the man on the ferry and he wasn&amp;rsquo;t there. The day passed and she was not thinking about him. People complimented her for how happy she seemed, but she felt confused.&lt;/p&gt;
&lt;p&gt;That night they made love again, but she didn&amp;rsquo;t like it as before. Her husband didn&amp;rsquo;t notice. &amp;ldquo;Quite a record we are setting here&amp;rdquo;, he said before falling asleep.&lt;/p&gt;
&lt;p&gt;In the morning she took a later ferry. The water was choppy and she spilled her coffee.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;My wardrobe &amp;hellip; nothing wearable &amp;hellip; need new clothes, brighter clothes &amp;hellip; show off my ass &amp;hellip; and need to call John for the contract &amp;hellip; isn&amp;rsquo;t &amp;lsquo;Siddhartha&amp;rsquo; for teenagers? &amp;hellip; and who wears faded jeans anymore?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That night her husband was all over her, but she said no. He turned to the other side and picked up a book. &amp;ldquo;I guess the streak is over&amp;rdquo;, he commented wryly.&lt;/p&gt;
&lt;p&gt;On the last ferry of the day she was looking for him.  &lt;em&gt;Claudia, please, what are you doing? &amp;hellip; Is this desperation? For what? What are you desperate for?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The ferry went through a fog bank, small waves hitting the hull and she saw him walking slowly, coffee in hand, careful with it. She felt a lump in her stomach and breathed deeply to calm herself.&lt;/p&gt;
&lt;p&gt;She followed him but stopped because she saw where he was going. There was a woman at his table and the woman took the coffee he was carrying, hands careful to avoid any spillage, a timid smile on her face. He touched her arm and her smile widened with uncertainty and delight.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;She is not beautiful. I am more beautiful and I have always been beautiful and she is older than me. I had &amp;hellip; have &amp;hellip; the most beautiful eyes &amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Her throat burned, her fists clasped &amp;hellip; but then she felt something leaving her, something that was there all along and wasn&amp;rsquo;t there anymore and will not come back.&lt;/p&gt;
&lt;p&gt;She was free of it and maybe she would make her husband happy again tonight for he is a good man and father and you got to know what is important in life.&lt;/p&gt;
&lt;p&gt;From the booth where the couple sat came a crystal laugh. While outside it was dark and foggy, there was light over the booth, and the man was whispering and the woman had beautiful hazel eyes.&lt;/p&gt;</description>
            <pubDate>Thu, 03 Apr 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-04-03-the-last-ferry.html</guid>
        </item>
        
        <item>
            <title>The cold touch</title>
            <link>https://www.lucabol.com/posts/2025-04-01-the-cold-touch.html</link>
            <description>&lt;p&gt;&lt;img src="/img/girlcar.jpg" alt="A girl outside the car under the rain." width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;She got the call late at night, while reading in bed, his voice flat like an answering machine. She sat up putting her back against the pillow, throat tightening. &lt;/p&gt;
&lt;p&gt;&amp;ldquo;Are you serious?&amp;rdquo; she croaked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Yes,&amp;rdquo; the flat voice said and hung up. &lt;/p&gt;
&lt;p&gt;Tears blurred her vision. Her gaze settled on the open wardrobe. &amp;ldquo;No!&amp;rdquo; she said to the room and swang her long legs out of bed. She put on a soft dress, her best boots, combed her hair tight and went into the city to see him.&lt;/p&gt;
&lt;p&gt;The rain pounded the roof of the car. She kept steady speed to calm down, thoughts flitting through the car&amp;rsquo;s cabin like fireflies, head tilted sideways doubtfully.&lt;/p&gt;
&lt;p&gt;It must be a misunderstanding. Maybe she laughed too much at the boys&amp;rsquo; jokes. She should be sexier. She should be more mysterious. Like her sister. Wear high heels.&lt;/p&gt;
&lt;p&gt;She got there, but he wasn&amp;rsquo;t home. He wasn&amp;rsquo;t at their usual place by the river. She hunkered down in the car. It was cold and she started shivering. She turned on the engine to warm up, but felt guilty about running it still. She turned it off and crossed her legs to keep them warmer. The rain kept falling and she was tired.&lt;/p&gt;
&lt;p&gt;They had meet at Jim&amp;rsquo;s birthday party two weeks earlier. They talked about stars, beers in hand, eyes uncertain on the right procedure. He was tall with a cloud of curly black hair. He moved his hands theatrically, sometimes touching her arm for emphasis or rolling his eyes. His laugh was strong and warm.&lt;/p&gt;
&lt;p&gt;They made love that night. He was different from the other guys she used to date. He wasn&amp;rsquo;t hungry for her. He didn&amp;rsquo;t lose control. He went about it slow and calm, like an artist painting a difficult subject. She tried to unsettle him with her body and with her mouth, his calmness getting on her nerves. It could all be done very deliberately, she discovered. She didn&amp;rsquo;t know it could be like that.&lt;/p&gt;
&lt;p&gt;The days that followed were the best.&lt;/p&gt;
&lt;p&gt;He called her every night. &amp;ldquo;How was your day? Who did you meet? I thought about you all day.&amp;rdquo; His voice warm and soft like honey liquor. She sat in bed, legs curled, caressing her nightgown, eyes closed, drinking his voice.&lt;/p&gt;
&lt;p&gt;That week end, they went dancing. He danced energetically, muscles bulging, eyes darting like an animal. He attracted attention from the girls and anger from the boys. She stood beside him, spectator to his show.&lt;/p&gt;
&lt;p&gt;After, they sat on red sofas in the dim lights of the disco, drinking rum and coke. She kissed him and hugged him and touched him. He stiffened first and then assaulted her with strong hands, pushing his body against hers. She pulled away from him then, ashamed of other people&amp;rsquo;s eyes.&lt;/p&gt;
&lt;p&gt;When they talked, anything she said was a revelation to him, brown eyes boring into hers, head nodding in agreement. He laughed off any disagreement, any tension. His eyes were just for her. Not even a glance to the other girls. They were not worth his attention. Only she was.&lt;/p&gt;
&lt;p&gt;At her birthday, he showed up with a single red rose, dressed in a formal shirt and bright shoes. His laugh filled the room as he mingled with all her friends and they all commented on her new boyfriend. &amp;ldquo;Charming! Lucky you!&amp;rdquo; bright smiles and pats on the back. Her mum said that he was very beautiful, and she waited for her to continue, but that was it.&lt;/p&gt;
&lt;p&gt;Yesterday, he said that he loved her. He said it with the tone a conspirator revealing a secret, curious eyes fixed on hers. She shifted, shuffled. The reply stayed trapped inside. She awkwardly threw her arms around him, kissing his neck. He patted her head and stroke her hair. &lt;/p&gt;
&lt;p&gt;Now she was sitting in the car waiting for him. Humidity fogged the windows. Wet leaves smell inside. She put her hand on the glass to clean out the fog and felt it cold to her touch. She also was cold.&lt;/p&gt;
&lt;p&gt;He arrived in his black Mercedes and parked just beside her. She opened the door and got in. The car smelled like laundry and the seats were brown. Hard rock music filled the air and he bent forward to turn it off, his hand brushing on her knee.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Hello,&amp;rdquo; she said flat. No reply.&lt;/p&gt;
&lt;p&gt;She touched his face, shoulders, lower toward his pants. He grabbed her hand and held it still. &amp;ldquo;Doesn&amp;rsquo;t change anything. We can still see each other, have fun.&amp;rdquo; &lt;/p&gt;
&lt;p&gt;He guided her hand, small in his, down, his forearm strong, tendons pushing out. She heard a siren going off in the distance. A dog barked. She knew. She had always known.&lt;/p&gt;
&lt;p&gt;She got out of the car and looked back at him. He was looking at her, curiously, noting. She stopped for a moment, car door open, waiting for him to say anything, but he didn&amp;rsquo;t. She closed the door slowly, without anger. She had known all along.&lt;/p&gt;
&lt;p&gt;Years later in the street of her town she saw him again. He was older now with grey hair and a brown coat. He walked surely, like someone who knows where he is going.&lt;/p&gt;
&lt;p&gt;She felt nothing. He nodded. She nodded back.&lt;/p&gt;</description>
            <pubDate>Tue, 01 Apr 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-04-01-the-cold-touch.html</guid>
        </item>
        
        <item>
            <title>No money</title>
            <link>https://www.lucabol.com/posts/2025-03-20-no-money.html</link>
            <description>&lt;p&gt;&lt;img src="/img/gaspump.jpg" alt="A house with a large antenna" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;The sun kisses the gas pump and hits the old man on the bench. His pants are dark with oil and sweat. He breathes slowly. His eyes are closed.&lt;/p&gt;
&lt;p&gt;Outside, the desert.&lt;/p&gt;
&lt;p&gt;The car arrives, old and rusty, and the couple gets out in a hurry. They are young; eyes red, skin burned by the sun; torn clothes.&lt;/p&gt;
&lt;p&gt;The boy starts filling up the gas tank. The girl gets close to the old man and touches his arm.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;No money&amp;rdquo; she whispers.&lt;/p&gt;
&lt;p&gt;The old man stands up. He towers over the girl for a moment, then shuffles inside the shop, knees popping as he walks.&lt;/p&gt;
&lt;p&gt;When the boy finishes, the old man comes back and holds out his hand. The sun catches something metal.&lt;/p&gt;
&lt;p&gt;The boy steps backward. The girl&amp;rsquo;s eyes widen. The wind whistles through the cactuses.&lt;/p&gt;
&lt;p&gt;But now the girl sees. She takes the bag: sandwiches and water. She nods her thanks - eyes fill with tears.&lt;/p&gt;
&lt;p&gt;The old man sits down again. His breath is shallow. He closes his eyes.&lt;/p&gt;
&lt;p&gt;Outside, the desert.&lt;/p&gt;</description>
            <pubDate>Thu, 20 Mar 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-03-20-no-money.html</guid>
        </item>
        
        <item>
            <title>L'uomo con un antenna enorme 1 - Pasquale</title>
            <link>https://www.lucabol.com/posts/2025-03-18-luomo-con-un-antenna-enorme-1-pasquale.html</link>
            <description>&lt;p&gt;&lt;img src="/img/antenna.jpg" alt="A house with a large antenna" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;era una volta un tipo che aveva un&amp;rsquo;antenna enorme sul tetto di casa. La gente pensava che la usasse per parlare con radioamatori in tutto il mondo, ma non era così. La realtà era ben diversa.&lt;/p&gt;
&lt;p&gt;Il tipo in questione si chiamava Alfredo e veniva da una famiglia agiata della zona che però era andata in disgrazia. Gli erano rimasti abbastanza soldi per non dover lavorare, ma non abbastanza per vivere bene. Faceva infatti una vita oziosa e riservata, sempre chiuso in casa a fare chissà cosa.&lt;/p&gt;
&lt;p&gt;I vicini pensavano che fosse una spia Russa del KGB. Il verduriere all&amp;rsquo;angolo giurava di averlo visto insieme ad un noto politico di sinistra in un ristorante della zona. Insomma, nessuno sapeva nulla, se non per il fatto che fosse un radioamatore; fatto su cui erano tutti d&amp;rsquo;accordo.&lt;/p&gt;
&lt;p&gt;E avevano torto. L&amp;rsquo;antenna di Alfredo serviva ad altro. Era infatti un apparecchio di grado militare costosissimo che lui aveva acquistato alla fine della guerra fredda e speso anni ad apprenderne il funzionamento.&lt;/p&gt;
&lt;p&gt;Uno zingaro Rumeno gli aveva anche tradotto il manuale dal Russo, anche se la traduzione risultava spesso incomprensibile. &amp;ldquo;Inserire il fustacchio nella bobina magnetica fino allo srotolamento del pennacchio&amp;rdquo;. Immaginati un manuale dell&amp;rsquo;Ikea di 1538 pagine tradotto dal Russo da uno zingaro Rumeno &amp;hellip;&lt;/p&gt;
&lt;p&gt;Ma lui aveva perseverato ed alla fine ce l&amp;rsquo;aveva fatta. Finalmente funzionava tutto. Alfredo poteva sentire le conversazioni telefoniche di tutti gli abitanti del paese. E non solo questo. Vedeva anche tutti i messaggi e poteva intervenire nelle conversazioni. Poteva inviare messaggetti che parevano provenire da un utente in particolare.&lt;/p&gt;
&lt;p&gt;Insomma, controllava completamente il flusso dell&amp;rsquo;informazione.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;era però un problema di volume: troppe cose da ascoltare. Servivano dei filtri. Primo, eliminare tutte le conversazioni degli adolescenti. Cosa te ne frega di quello che dicono? Secondo, registrare solo le discussioni interessanti. Ma come definire &amp;lsquo;interessanti&amp;rsquo;?&lt;/p&gt;
&lt;p&gt;Alfredo si affido ad un &amp;lsquo;hacker&amp;rsquo; Islandese che creò un programma di riconoscimento vocale che ascoltasse tutto, ma registrasse solo le conversazioni contenenti alcune parole chiave, con opportune variazioni. Per esempio, lui inseriva &amp;lsquo;Mangiare&amp;rsquo; ed il programma registrava tutte le conversazioni con &amp;lsquo;mangiato&amp;rsquo;, &amp;lsquo;mangiai&amp;rsquo; etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;Ci volle un po a perfezionare il sistema, ma alla fine tutto funzionava. Al termine della giornata gli arrivava un email con tutte le conversazioni e messaggi interessanti che poi lui si ascoltava in tutta calma. Alfredo era diventato onnisciente.&lt;/p&gt;
&lt;p&gt;Ma cosa farsene di tutto questo ben di Dio? Sicuramente c&amp;rsquo;era una ragione. La provvidenza non gli aveva dato tutto questo potere per nulla. Non poteva sprecare questo dono ascoltando passivamente. Doveva agire; influenzare il corso degli eventi. Ma come farlo? E con quale intento?&lt;/p&gt;
&lt;p&gt;Alfredo decise di cominciare con qualcosa di semplice: Pasquale. Pasqù, come era chiamato in paese, era un contadino grosso e rozzo. Aveva fatto solo la prima elementare e non aveva un vocabolario molto vasto. Si faceva bastare una una dozzina di parole, che utilizzava in varie situazioni, affidandosi all&amp;rsquo;intonazione e ai gesti per variarne il significato. In pratica, risultava incomprensibile.&lt;/p&gt;
&lt;p&gt;Lo trovavi al bar del paese ogni venerdì sera a bere vino e straparlare, inanellando queste poche parole in configurazioni inverosimili.&lt;/p&gt;
&lt;p&gt;Alfredo decise di accoppiarlo alla professoressa Milani, zitella di lunga data e esperta internazionale dei sonetti in rima alternata dell&amp;rsquo;Ariosto, di cui ne esistono tre, includendo l&amp;rsquo;enigmatico: &amp;ldquo;Io, come il falco, mi astengo&amp;rdquo;. Quest&amp;rsquo;ultimo era la causa della notorietà della professoressa che ne aveva proposto un&amp;rsquo;interpretazione audace. L&amp;rsquo;ipotesi Milani, come è chiamata, si può riassumere, seppure in maniera incompleta, con la costatazione: &amp;ldquo;Quando lo ha scritto, era ubriaco&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Così arrivò il primo messaggio del finto Pasqù: &amp;ldquo;Oh mia dolce pulzella, mirarti riempe di ardore il mio cuore&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;La professoressa rispose: &amp;ldquo;Pasquale, mi sa che hai preso un virus&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Pasqù: &amp;ldquo;Il mio unico malanno è l&amp;rsquo;affanno di non poterti avere&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Milani: &amp;ldquo;Pasquale, ma cosa dici, hai bevuto?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Pasqù: &amp;ldquo;Ti aspetto, ardente come sempre, presso il terzo tavolo dell&amp;rsquo;amorosa osteria&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Milani: &amp;ldquo;Amorosa osteria?? Ma intendi il bar Sport?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Pasqù: &amp;ldquo;Il dolce luogo del nostro amor&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Milani: &amp;ldquo;Ma se fa schifo. È pieno di ubriachi!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Pasqù: &amp;ldquo;Bacco sarà il nostro chaperone. Se anche tu mi desideri, pronuncia le parole in codice &amp;lsquo;sono la tua anguilla&amp;rsquo;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Milani: &amp;ldquo;Ma che anguilla! Pasqù, ma sei impazzito?&amp;rdquo;
Milani (dopo un po): &amp;ldquo;Su Pasqù, rispondi, ma ti sei arrabbiato?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Pasqù arrivò al bar Sport come ogni venerdì sera. Si sedette al suo solito tavolo. Era in gran forma quella sera. Aveva scoperto un nuovo espletivo che ora usava, in forma aggettivale, attaccandolo ad ogni parola. L&amp;rsquo;aggettivo era &amp;lsquo;straficchioso&amp;rsquo;. Lo aveva usato un suo amico pastore per descrivere un gallo che si rifiutava di cantare all&amp;rsquo;ora stabilita. A Pasqù era parso un termine raffinatissimo.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;ora si era fatta tarda. Le tenebre calavano sul bar Sport. Pasqù, ormai bello ubriaco, cominciava ad assopirsi con la testa sul tavolino. Una musica sdolcinata riempiva l&amp;rsquo;aria, coprendo le bestemmie del barista che voleva mandare tutti a casa. Il fumo delle sigarette avvolgeva i tavoli creando una nebbia primordiale stile Borneo.&lt;/p&gt;
&lt;p&gt;In questo ambiente rarefatto da sogno tropicale arrivò lei. Bella come un confetto. Luccicante come la macchina quando esce dall&amp;rsquo;autolavaggio automatico. Uscì dalla nebbia come una star di Hollywood: occhialoni da sole, cappello all&amp;rsquo;Inglese e vestito attillatissimo.&lt;/p&gt;
&lt;p&gt;Uno degli avventori, più coraggioso, accennò un fischio di apprezzamento. La prof lo fulminò con lo sguardo in modo tale che l&amp;rsquo;aria gli rientrò nei polmoni, come se l&amp;rsquo;avesse rimangiata. Il suono che ne uscì sembrava più un sospiro che un fischio. &amp;ldquo;Lo scusi professoressa, è un imbecille&amp;rdquo; disse il barista premuroso.&lt;/p&gt;
&lt;p&gt;La Milani si avviò con passo deciso verso il tavolo di Pasquale che, nel suo stato stupefatto, non si era accorto di nulla. Fissandolo intensamente, gli sussurrò, in tono cospiratorio: &amp;ldquo;Sono la tua anguilla&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Non ho capito&amp;rdquo; rispose Pasqù innocente.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Sono la tua anguilla&amp;rdquo; reiterò lei in tono perentorio.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Ah si?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Pasquale, non dire cazzate per favore. Se dico che sono la tua anguilla, vuol dire che lo sono!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Se lo dice lei&amp;hellip; Cioè tu &amp;hellip; o lei &amp;hellip; forse.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Non ti sarai mica raffreddato verso di me, vero?&amp;rdquo; ribadì lei stizzita.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;No&amp;hellip; No&amp;hellip; raffreddato? Io ho sempre caldo&amp;hellip; ma in che senso?&amp;rdquo; rispose lui, ormai nella confusione più totale.&lt;/p&gt;
&lt;p&gt;Visto che la situazione non progrediva, la prof cominciò a perdere la pazienza: &amp;ldquo;Pasqù, per piacere, non fare lo spiritoso. Andiamo via di qui&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;E dove andiamo?&amp;rdquo; domandò lui.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Certo non nella tua cascina, che c&amp;rsquo;è puzza di capra. Andiamo a casa mia&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Pasquale, ridendo come un cretino, buttò li una frase a caso composta dalle poche parole a lui conosciute: &amp;ldquo;Casa è dove la capra dorme&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;La prof spalancò gli occhi, come folgorata: &amp;ldquo;Pasqù, ma è tuo questo verso?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Quale verso?&amp;rdquo; rispose lui, temendo di avere scorreggiato.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Ma allora non lo sai neanche di essere un poeta!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;No&amp;rdquo; rispose lui sincero.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Hai qualche altro verso per me?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Pasqù timidamente improvvisò: &amp;ldquo;La capra è dove il gallo dorme&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;La prof lo guardò dubbiosa: &amp;ldquo;Questa è una minchiata, però&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Scherzavo&amp;rdquo; buttò li lui, intuendo di avere fallito qualche tipo di test.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Va beh, andiamo a casa dai. Non si può pretendere troppo da colui che è ignaro dei propri doni&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Eh si &amp;hellip;&amp;rdquo; rispose lui incerto.&lt;/p&gt;
&lt;p&gt;Alfredo, osservando la scena da uno sgabello all&amp;rsquo;angolo della sala, sorrideva compiaciuto. Il suo piano stava funzionando.&lt;/p&gt;</description>
            <pubDate>Tue, 18 Mar 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-03-18-luomo-con-un-antenna-enorme-1-pasquale.html</guid>
        </item>
        
        <item>
            <title>Candy at the Bar</title>
            <link>https://www.lucabol.com/posts/2025-03-14-candy-at-the-bar.html</link>
            <description>&lt;p&gt;&lt;img src="/img/girlatbar.jpg" alt="gino looks at pina" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Candy sits at the counter of the posh hotel bar, eyes fixed on her untouched cocktail; her finger drumming on the dark mahogany. She is dolled up in a short skirt, red lipstick, and dark mascara.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;The first time is a bitch, but you get used to it,&amp;rdquo; Molly had said. &amp;ldquo;Most of the clients are good, first class.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The bar door opens abruptly. Startled, she fixes her gaze on the glass while the barman watches—he knows.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;You have to follow your dream,&amp;rdquo; her granny used to say. &amp;ldquo;Whatever the cost. You do what you have to do.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Her purse hangs from the back of the stool. That&amp;rsquo;s the signal: red purse. He is going to come to her. No need to look at the door. But still, she looks.&lt;/p&gt;
&lt;p&gt;All of a sudden, an old woman takes the stool beside her. &amp;ldquo;Mum! What are you -&amp;rdquo; but the images hit her.&lt;/p&gt;
&lt;p&gt;Candy sees the inside of a hotel room: her dress on a chair, a pack of cigarettes on a desk. The scene changes: another hotel room, a line of cocaine on the bedside table and muffled laughers.&lt;/p&gt;
&lt;p&gt;And it&amp;rsquo;s all gone. She is in the bar again. She looks for the old woman, but she is not there. Of course she is not there.&lt;/p&gt;
&lt;p&gt;The bar door opens. It&amp;rsquo;s him. Candy knows it&amp;rsquo;s him; no need to look. She grabs her red purse, hides it behind her back and walks toward the door. He doesn&amp;rsquo;t even see her. He is scanning the room above her head. She smells cologne on him as she passes by.&lt;/p&gt;
&lt;p&gt;And she is out in the street. The smoke from the factory paints the night grey. Horns blare in the air.&lt;/p&gt;
&lt;p&gt;Candy spies a waitress in the restaurant on the other side of the road. Her hair is grey and oily. She shuffles from table to table, shoulders hunched, eyes empty, mouth set in a forced grin - perhaps a desperate one.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;What else, Candy?&amp;rdquo; Molly had said. &amp;ldquo;What else?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Candy turns. Her hand rests on the bar door. She pushes it open; music and laughter spill out. Then she withdraws her hand, only to raise it again, trembling, on the handle.&lt;/p&gt;
&lt;p&gt;A taxi stops by. A couple gets out. They smile at Candy. She smiles back.&lt;/p&gt;</description>
            <pubDate>Fri, 14 Mar 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-03-14-candy-at-the-bar.html</guid>
        </item>
        
        <item>
            <title>Gino è sparito</title>
            <link>https://www.lucabol.com/posts/2025-02-24-gino-e-sparito.html</link>
            <description>&lt;p&gt;&lt;img src="/img/gino.jpg" alt="gino looks at pina" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Gino era un bambino di otto anni magro magro. Sembrava uscito da un film in bianco e nero del dopoguerra. Era un bambino allegro dal sorriso facile e sdentato. La gente in paese lo conosceva bene e lo fermava per strada per regalargli dolcetti, figurine o anche solo una parola buona. Lui ringraziava timido e ripartiva a razzo verso le avventure che aspettano i bambini troppo attivi.&lt;/p&gt;
&lt;p&gt;Io lo ricordo giocare a calcio in piazza mentre noi prendevamo l&amp;rsquo;aperitivo. &amp;ldquo;Ciao Gino, tutto bene? Vieni, prendi una patatina&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Poi, un giorno, Gino è sparito.&lt;/p&gt;
&lt;p&gt;Come sempre accade in casi simili, la famiglia fu la prima sospettata. Il padre era un camionista; un lavoro sempre sospetto agli occhi della gente. Poi la madre: troppo bella o forse troppo curata per la sua età. Lo zio ricco che viveva in Germania. Il nonno reduce di guerra ormai semi-rincoglionito. Ma tutte le piste si rivelarono inconclusive. Nessuno sapeva dove era finito.&lt;/p&gt;
&lt;p&gt;Passati i primi giorni, le teorie si fecero più audaci. C&amp;rsquo;era sicuramente un giro di pedofili in paese. O la mafia. Anche il professore di ginnastica fu tirato dentro come possibile amante della madre, o del padre, vista la risaputa omosessualità di entrambi.&lt;/p&gt;
&lt;p&gt;Ricordo la signora che fa le carte accusare pubblicamente il verduriere, noto ateo e forse anche comunista - comunque molto antipatico a tutti.&lt;/p&gt;
&lt;p&gt;La situazione si chiarificò quando la Pina si presentò in commissariato con passo deciso e si mise ad urlare: &amp;ldquo;Allora me lo togliete dai coglioni?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;La Pina viveva in una cascina abbandonata ai bordi del paese. Un giorno Gino si era presentato con la sua bicicletta e le aveva fatto una proposta: &amp;ldquo;Il tuo tetto fa schifo, è tutto rotto. Te lo riparo io se mi compri un gelato.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Ma il lavoro era lungo e i gelati tanti. Alla fine lei si era stancata di quel bambino che non faceva altro che mangiare a sbafo senza fare nulla per il suo tetto. Così era andata in paese a restituirlo al mittente.&lt;/p&gt;
&lt;p&gt;La polizia non sapeva bene cosa fare. Non è che la Pina avesse commesso un vero e proprio reato. A lei quel bambino non era neanche così simpatico. Gino, da parte sua, diceva di essere stato trattato benissimo. La Pina, secondo lui, era un&amp;rsquo;ottima cuoca e raccontava storie di guerra eccezionali.&lt;/p&gt;
&lt;p&gt;Quando gli fu chiesto se non gli fossero mancati i genitori, rispose di no. C&amp;rsquo;era quel problema del tetto da risolvere &amp;hellip;&lt;/p&gt;
&lt;p&gt;La signora che fa le carte dichiarò che in fondo aveva ragione lei. La Pina era stata fidanzata con il verduriere in gioventù, quando lei era bellissima e lui bruttissimo, ma molto ricco - e comunque sempre antipatico.&lt;/p&gt;
&lt;p&gt;Ho letto ieri sui giornali che la Pina è morta e così mi è tornata in mente tutta la storia. Erano rimasti amici, quei due.&lt;/p&gt;
&lt;p&gt;Lui ha continuato ad andarla a trovare in tutti questi anni, malgrado le proteste di lei, a cui non era poi così simpatico.&lt;/p&gt;
&lt;p&gt;Non credo che il tetto sia mai stato riparato.&lt;/p&gt;</description>
            <pubDate>Mon, 24 Feb 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-02-24-gino-e-sparito.html</guid>
        </item>
        
        <item>
            <title>A few good books</title>
            <link>https://www.lucabol.com/posts/2025-02-10-a-few-good-books.html</link>
            <description>&lt;p&gt;I am a voracious reader. Multiple books a week kind of crazy. Occasionally people ask me for a list of good books in the various areas I am interested in. This is it. Just a few books on each topic, perhaps not even the best ones, but the ones that left an impression on me.&lt;/p&gt;
&lt;h2&gt;Investing for accumulation&lt;/h2&gt;
&lt;p&gt;In 2012 I have written &lt;a href="/posts/2012-04-05-letter-on-investing.html"&gt;a post&lt;/a&gt; about investing with books recommendations. I mostly stand by it still, with the exception that I now consider dividend investing as a viable alternative even in the accumulation phase. It is less tax-friendly, but the income stream helps you not to panic when the principal decreases in some years.&lt;/p&gt;
&lt;h2&gt;Investing for income&lt;/h2&gt;
&lt;p&gt;Once you have accumulated enough assets, you need to generate an inflation-resistant income from them. At this point in time, no insurance company sells inflation-linked annuities, so you are left with two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Asset allocation: selling some assets every year hoping that the principal grows enough to replenish what you spend and overcome inflation.&lt;/li&gt;
&lt;li&gt;Dividend investing: you live on the increasing dividends from your stock holdings without touching the principal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I don&amp;rsquo;t consider real estate investing as passive income. Too much work for me.&lt;/p&gt;
&lt;p&gt;On asset allocation, &lt;a href="https://www.amazon.com/Intelligent-Asset-Allocator-Portfolio-Maximize/dp/1260026647?dib=eyJ2IjoiMSJ9.wxBXR29qvvH8_90YBXgf-ybwhg5jmLmhB_8WwISFS83hkqYTovEwzOgQBqwHGLYLfWYbHelBy357WZQkJWzQRLkWFXBg4k9HTwiVXPbGSBrlqa6awvNZZaTbMeL0o1NguspyN6WAw5YXiwldmhFq-hsSg7WPVgI1H_este9JyJi2_UTvXsecIIssSZZTO1FB.qCO1QW6c7-W-WjlCmSI_sTZhAMQDOctwHayPH6jXK8U&amp;amp;dib_tag=se&amp;amp;keywords=Intelligent-Asset-Allocator-Portfolio-Maximize&amp;amp;qid=1739203919&amp;amp;sr=8-1"&gt;The intelligent asset allocator&lt;/a&gt;. On dividend investing, I like anything by &lt;a href="https://www.amazon.com/Ownership-Dividend-Daniel-Peris/dp/1032273194/?_encoding=UTF8&amp;amp;pd_rd_w=ODThJ&amp;amp;content-id=amzn1.sym.bc3ba8d1-5076-4ab7-9ba8-a5c6211e002d&amp;amp;pf_rd_p=bc3ba8d1-5076-4ab7-9ba8-a5c6211e002d&amp;amp;pf_rd_r=130-3351783-2457339&amp;amp;pd_rd_wg=u8le9&amp;amp;pd_rd_r=7f7dcabf-237a-4f68-9953-f78f53b84569&amp;amp;ref_=aufs_ap_sc_dsk"&gt;Daniel Peris&lt;/a&gt; and the more advanced &lt;a href="https://www.amazon.com/Ultimate-Dividend-Playbook-Independence-Investor-ebook/dp/B008L0458Y?crid=1UM9CARG51F96&amp;amp;dib=eyJ2IjoiMSJ9.cMrAJkkIYizvlD-LrOcOKeuMSPFvz4d2HWOPXDwBfmwo3uCkq8HgtP6Kkp8_xUocToaOPudfK7aR009f0-3b1CI_C_jj7MjE3C1xZp1d1NY.jEKyEJmnoADU-z5kB2wl7UOPjEUESkBV4_rtL8BwQ6A&amp;amp;dib_tag=se&amp;amp;keywords=paris+dividend+playbook&amp;amp;qid=1739203952&amp;amp;sprefix=peris+dividend+playbook%2Caps%2C206&amp;amp;sr=8-1"&gt;Josh Peters&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Of the two strategies, I am partial to dividend investing, which can be simply implemented in ETF form these days (i.e., SCHD or others).&lt;/p&gt;
&lt;h2&gt;Classics&lt;/h2&gt;
&lt;p&gt;In the past few years I have started a classical education on my own. I went to a classical secondary school and was left with an itch to pursue it more. The Great Books of the Western World series is now free on &lt;a href="https://archive.org/details/encyclopaediabritannicagreatbooksofthewesternworld/Encyclopædia%20Britannica%20-%20Great%20Books%20of%20the%20Western%20World%2C%20Volume%201%20-%20The%20Great%20Conversation%2f"&gt;Archive.org&lt;/a&gt;. The first few books contain reading plans, but instead I have finished &lt;a href="https://www.amazon.com/general-introduction-liberal-education-program/dp/B0006AW7S2?crid=2QKWASSJF08IR&amp;amp;dib=eyJ2IjoiMSJ9.wMlDEMxFLIEC7FZJRUKRiiZur8j43H0qd1JKtUXcJRdUveBL0P5MvTuEkBlSY_B8T8dyaLQtwCL21WcPGlIreFxopMvnyZFuv8D2DMe2ZFRtVZhFnp3IeIf7RHgmyyZZ5kbB6kBIf2fDbVzTIJzqMFgOrlcizQzsNwOW6a2jeUNhClQra6Pkg2W84pKrBG_zuw0gWagEpTagKnNOm19hR4bNYHrQnShz11Av5m-eqTM.yvOwioul8xqmmRsnkPLCzX9DAQwrwcueWZyn4L2b7AE&amp;amp;dib_tag=se&amp;amp;keywords=adler+general+introduction+great+books&amp;amp;qid=1739204247&amp;amp;s=books&amp;amp;sprefix=adler+general+introduction+great+boo%2Cstripbooks-intl-ship%2C211&amp;amp;sr=1-1"&gt;this one&lt;/a&gt;. I am currently in the middle of &lt;a href="https://www.amazon.com/Harvard-Classics-Year-Liberal-Education-ebook/dp/B00OF9SEYG?crid=1GA4IKIVXW1OQ&amp;amp;dib=eyJ2IjoiMSJ9.9nJhrILAbmF3BsNXm-2mEjETbTc_L5T-7BHbIKIpfz8CvKIpD7bnCggfVJP6OJ5bcIVv0P5coiisZvLrKY7JORMEw9rQ71oqO_wXMTqLXapRk4E5pJreMNXIxsLcEtAWoTryl3J7CCdv8T9y7B8MF_wiBtFDDqm_OqQXckDf5GF-fiKkP3QLD2UkWMsQ-kqFc0bzecRv1X5oKvRyw5meeJl-XglMNKczWFCVwsv52pg.oMVEhz8G7WqkCtiWK_uqAFGF82IRRp_iD3AIGoa9XoQ&amp;amp;dib_tag=se&amp;amp;keywords=harvard+classics&amp;amp;qid=1739204389&amp;amp;s=books&amp;amp;sprefix=harvard+classic%2Cstripbooks-intl-ship%2C244&amp;amp;sr=1-8"&gt;this one&lt;/a&gt;, which I like less.&lt;/p&gt;
&lt;h2&gt;Philosophy&lt;/h2&gt;
&lt;p&gt;My introduction to stoic ideas came from &lt;a href="https://www.amazon.com/A-Guide-to-Good-Life-audiobook/dp/B00G6WCGKI?crid=2JNGWTYKAJBSH&amp;amp;dib=eyJ2IjoiMSJ9.iOS8tabPfDpjrEA3-Pu71bCZce3of9GbBNCv3gG9B5fUSZk0HjbVPaB1wIIxeJXyt5aY9S3o59dfQNy7gUpfqdY3tQHLt9DXwjzRKSUMQeLf93zU5UxPOvOKv7R_eATRB-kUwVhzw7Zgi8hhXF5p1gBtG4cSFe7tGEF94MMJo869teR2j0aplg-pt_YQ2PczKQOgO6Xgavc1MQB0ZBIWj4rJvS3fnN-TVJsXpEoLE1Q.zaJtfS0JRhZj_7wrmE86frTFKvH-3JVm9il27BWBdv4&amp;amp;dib_tag=se&amp;amp;keywords=irving+stoicism&amp;amp;qid=1739204528&amp;amp;s=books&amp;amp;sprefix=irving+stoicism%2Cstripbooks-intl-ship%2C258&amp;amp;sr=1-4"&gt;Irvine&lt;/a&gt;. One quickly moves to Seneca&amp;rsquo;s &amp;lsquo;Letters to Lucilius&amp;rsquo; and the rest of the Roman stoic literature, which I prefer to read in Italian (no links).&lt;/p&gt;
&lt;h2&gt;Management &amp;amp; Leadership&lt;/h2&gt;
&lt;p&gt;I have been a manager for a good part of my career, but didn&amp;rsquo;t read too many books about it. Perhaps I considered it as a learn-by-experience kind of thing &amp;hellip; A few books I like are &lt;a href="https://www.amazon.com/Crucial-Conversations-Third-Talking-Stakes/dp/B09MV3818X?crid=16CG1SQL4S03K&amp;amp;dib=eyJ2IjoiMSJ9.JGRdYjHsARvKgg2FqlGrMeqQ9pew4dFxN-TmRY63T3xLIoNd7VY13KT2vF4J7Lx5dAMMEs35X9GcGGZ8wd3lvL3vrqpcoklxMZxfx_d5t2e_aJTkbap2qLEP9ylxErhf35gH0QSEF6aWaUY_81TcpakCLpKXVHFJ0jHuWtAqV-0g5SFHCA5zGvCR7HH09HCg51_2LKc19DPDFi5pjh0A08ZDU2RzIetT7cbFrFgaiNM.4xSDkWvfSedobVPnqLVU15U4TS8ZokHqSnH24ffgOnw&amp;amp;dib_tag=se&amp;amp;keywords=crucial+conversations&amp;amp;qid=1739204754&amp;amp;sprefix=crucial+conversation%2Caps%2C258&amp;amp;sr=8-1"&gt;Crucial Conversations&lt;/a&gt; and &lt;a href="https://www.amazon.com/Leadership-Self-Deception-Getting-Out-Box/dp/1626566240"&gt;Leadership and self deception&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Time management&lt;/h2&gt;
&lt;p&gt;I had too many emails in my mailbox every day. I needed a system to manage my workload. The philosophy underpinning it is in &lt;a href="https://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0143126563?crid=3G0ZCEWKTDUKQ&amp;amp;dib=eyJ2IjoiMSJ9.JPu08UYkU4zwl38D65fqtHs5WdjMvGXKvCCqQyacQBMha9uVSIp2RYPsVQ7fUr2jNj1u81hdnTNYM0JKmLNeDS-x_e1whsAmtOyAYacVvrAcgmYO5gdlA96HcKmRZp8F27S4prh4xT5BBxq2jISULY5lZydnO6mBjyppDmPswMm-gur0iJU0tJdjC-jl08xV5qlK0mffg_e1ZN9TcMZ3ZWtI1dxd-jFLKhNuXoGp47M.YZvf8pXYyLYDF7RitE1_Juijrv0KRD3cPYJd7-sUKFU&amp;amp;dib_tag=se&amp;amp;keywords=getting+things+done&amp;amp;qid=1739205204&amp;amp;s=books&amp;amp;sprefix=getting+things+done%2Cstripbooks-intl-ship%2C238&amp;amp;sr=1-1"&gt;Getting things done&lt;/a&gt;. That is useful in many situations, apart from email overload. The practical implementation is a variation of &lt;a href="https://www.amazon.com/Total-Workday-Control-Microsoft-Outlook/dp/0983364761?crid=1UVYRSVJIXQTH&amp;amp;dib=eyJ2IjoiMSJ9.p4SxB6mtKZnVUsxRCVvSdnhq9cxvFvaQM7CT6vM18eiSSxB7EePv_qb1fIG7TlU2FgV1K-UoQKssrdFtTZiNSAIl3m3DMHfH_KBe-TL7sFq-nUFtDHgVTJW0ckKfSFBXwoNdwgwBoBe_ZrTsA7O4SXhYMxnXwqf6tu0CPD-1m5qo05WKMgnJmH8KMJu6E5IV.kZdnnJgEpfrwTGRp1dx0EpaixP3QSaii50wfZhwoiEk&amp;amp;dib_tag=se&amp;amp;keywords=outlook+workday+control&amp;amp;qid=1739205241&amp;amp;s=books&amp;amp;sprefix=outlook+workday+contro%2Cstripbooks-intl-ship%2C200&amp;amp;sr=1-1"&gt;Total Workday Control&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Statistics&lt;/h2&gt;
&lt;p&gt;You never understand statistics enough. I don&amp;rsquo;t remember how I got introduced to the main concepts, maybe at school? A simple tour to uncertainty is &lt;a href="https://www.amazon.com/Flaw-Averages-Underestimate-Risk-Uncertainty/dp/1118073754?crid=FBFRQDQJ3UW9&amp;amp;dib=eyJ2IjoiMSJ9.13wj9GvQlBFnDjU5BH-sntE7g51qVSNH40Lsl9f7KOEFVKL6yXK9OyeQgti5-oGw1UC0aGU0qcAzD5napDT88C6gN3X_DVCPCcXzIkzguKCB1Z9U_lAiHnQ-ZKWjKELXRNjMDNB5mccbwvW0ETbh8yLtyyeDF5ccS6Beij-nhJDyiKFClmonc6dCJvhrJr1q2ll47ak91KV4SR6PSpb4QKIns0Bw-0ra0_MBmDTtR2hkkqVhlGh-s87qaR8JaUh83arRPDBqzPwkqDiAUR7L-A5hU3DaOExHtJoNw_LufrgM9ivXsvsglWobK2a4mGmc.Q5AOL87e7GR0APgYD9jKA9xqDxqHvIVxnxPsWg9dcUs&amp;amp;dib_tag=se&amp;amp;keywords=savage+law+of+averages&amp;amp;qid=1739205429&amp;amp;s=books&amp;amp;sprefix=savage+law+of+average%2Cstripbooks-intl-ship%2C235&amp;amp;sr=1-1"&gt;Savage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am partial to Bayesian statistics, but I learned it directly from a somehow complex book that I really liked: &lt;a href="https://www.amazon.com/Bayesian-Analysis-Chapman-Statistical-Science/dp/1439840954?crid=1UTIIXBS01Y7S&amp;amp;dib=eyJ2IjoiMSJ9.p_dORYQzc-S1fX1uG0_A5lDdDdzz5DjjgtV2_sopGGC0Y0yN4PaAd23ql1kZWgOKy0NEwh8X6oAeRjHu4XXtdzFgrqGX8h6zJ4ASFLJeAAnTsLMoh-h-Z-wJgTRSMw33Na6KGAM1K-IDB32IoXC55cLNLckm1zirCAa5_LuLX-U.zd0cURJvaLAFAmME3S9v0tvx54yhTu3YsoO_xRAB_uU&amp;amp;dib_tag=se&amp;amp;keywords=gelmann+bayesian+statistics&amp;amp;qid=1739205593&amp;amp;s=books&amp;amp;sprefix=gelmann+bayesian+statistic%2Cstripbooks-intl-ship%2C198&amp;amp;sr=1-2"&gt;Gelman&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I also like Exploratory Data Analysis. The classic is &lt;a href="https://www.amazon.com/Exploratory-Data-Analysis-Classic-Version/dp/0134995457?crid=3UILDKSLCIHH9&amp;amp;dib=eyJ2IjoiMSJ9.6tmn4JS7nZ1InZj9DMRdArAig0I3yY8LnAF1XDgS50p_r-35raLUQLGDfd85Dq4irsYihIJE7WPY9Sa2toa4iCUP0ZR3gmqMW-CzM8JDQ5JDRsMzvhLxL30hPsdAMaOLmCXutFj5RA50dcqHxgUfV1C20ch06Fwb89lxH5t6wlrLG8-VKjCRY5j22PEK7Aeg6vhmU5YV5Fk3H5-DkWoTgo_m1Ghbv39EmVkbPEFDNPM.4AM7bycHfwoC2iXfgi-FHnZP4OBhmI1v8B6curKckuM&amp;amp;dib_tag=se&amp;amp;keywords=exploratory+data+analysis&amp;amp;qid=1739205775&amp;amp;s=books&amp;amp;sprefix=exploratory+data+analysis%2Cstripbooks-intl-ship%2C227&amp;amp;sr=1-3"&gt;Tukey&lt;/a&gt;, but there must be something more modern, certainly in Python &amp;hellip;&lt;/p&gt;
&lt;h2&gt;Health&lt;/h2&gt;
&lt;p&gt;I encourage everyone to read anything by Gary Taubes. &lt;a href="https://www.amazon.com/Good-Calories-Bad-Controversial-Science/dp/B08PDQGPCY?crid=3G9TNF48ZFN1U&amp;amp;dib=eyJ2IjoiMSJ9.1zr_lXjdYHTqlDCHdwS9Og.a25gKA5JdIYKwiZK237_9pHyHCcCuiGENJVlN1Kch8Q&amp;amp;dib_tag=se&amp;amp;keywords=peter+taub+good+calorie+bad+calories&amp;amp;qid=1739205955&amp;amp;s=books&amp;amp;sprefix=peter+taub+good+calori+bad+calorie%2Cstripbooks-intl-ship%2C192&amp;amp;sr=1-1"&gt;Good Calories, Bad Calories&lt;/a&gt; changed my life.&lt;/p&gt;
&lt;p&gt;I also read extensively about weight lifting. I think most people don&amp;rsquo;t realize that you can do it with different goals in mind. Getting bigger is just one of them and perhaps the less important one. Among the trove of crap, there are a few good books.&lt;/p&gt;
&lt;p&gt;Because of my age, I am partial to lifting weights slowly, &lt;a href="https://www.amazon.com/Slow-Burn-Fitness-Revolution-Exercise/dp/0767913868/130-3351783-2457339?pd_rd_w=FNRwq&amp;amp;content-id=amzn1.sym.53b72ea0-a439-4b9d-9319-7c2ee5c88973&amp;amp;pf_rd_p=53b72ea0-a439-4b9d-9319-7c2ee5c88973&amp;amp;pf_rd_r=79RAHSBADYDD7PK77RH7&amp;amp;pd_rd_wg=kGRxO&amp;amp;pd_rd_r=2bafedc2-5424-4e63-9a9b-0bb780d541ae&amp;amp;pd_rd_i=0767913868&amp;amp;psc=1"&gt;Slow Burn&lt;/a&gt; style. Because of my laziness, I like spending the least amount of time doing it as in &lt;a href="https://www.amazon.com/Body-Science-Research-Strength-Training/dp/0071597174/130-3351783-2457339?pd_rd_w=nC00b&amp;amp;content-id=amzn1.sym.53b72ea0-a439-4b9d-9319-7c2ee5c88973&amp;amp;pf_rd_p=53b72ea0-a439-4b9d-9319-7c2ee5c88973&amp;amp;pf_rd_r=444EZ7AWNSS8R38YD84R&amp;amp;pd_rd_wg=fhqIh&amp;amp;pd_rd_r=10ead2a9-f77a-4ad0-9176-26db370d35f7&amp;amp;pd_rd_i=0071597174&amp;amp;psc=1"&gt;Body by science&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Coding&lt;/h2&gt;
&lt;p&gt;I have a post for that &lt;a href="/posts/2024-02-21-best-programming-languages.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Typography&lt;/h2&gt;
&lt;p&gt;I know, right? Too many good books to mention. Let&amp;rsquo;s do one: &lt;a href="https://www.amazon.com/Elements-Typographic-Style-Version-Anniversary/dp/088179211X?ref_=ast_author_dp&amp;amp;dib=eyJ2IjoiMSJ9.JrOxOmGE8ZXm72sdq-2ObsZr5NUPGG2cvEl9LPZ92WvKd4LR2d2fLPxlNoakLKv5NE8fwQuGL5oF-R9WML9c6UPdxhcMPx8MyBdHcU1NfwmTgofVlImZXxol1D5hVyt6ROash4QjBFhZ2I_ySxeJxBDyapsIv83RXw1wSNJmTL1mN83D8SXrzJ-qHZyRVIyg5Rr2Hm-mbefBPunFZUc70kE2lzICI5U9yogPLzUj7jk.iwuLwTaxrDqeeVCSIjzK43L9Ob2Mo2ViApDG6r0ALS8&amp;amp;dib_tag=AUTHOR"&gt;The elements of typographic style&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Narrative&lt;/h2&gt;
&lt;p&gt;Apart from classics, I read a lot of sci-fi and fantasy. Try &lt;a href="https://www.amazon.com/stores/Ted-Chiang/author/B001HCZ6OA?ref=sr_ntt_srch_lnk_1&amp;amp;qid=1739207284&amp;amp;sr=1-1&amp;amp;isDramIntegrated=true&amp;amp;shoppingPortalEnabled=true"&gt;Ted Chiang&lt;/a&gt; and &lt;a href="https://www.amazon.com/stores/Patrick-Rothfuss/author/B001DAHXZQ?ref=sr_ntt_srch_lnk_1&amp;amp;qid=1739207340&amp;amp;sr=1-1&amp;amp;isDramIntegrated=true&amp;amp;shoppingPortalEnabled=true"&gt;Patrick Rothfuss&lt;/a&gt;. The former is mind opening, the latter writes fantastically (read &lt;a href="https://www.goodreads.com/quotes/7271610-the-waystone-inn-lay-in-silence-and-it-was-a"&gt;this&lt;/a&gt;).&lt;/p&gt;
&lt;h2&gt;Others&lt;/h2&gt;
&lt;p&gt;Many other topics touched my fancy here and there (chess, photography, economy, fonts, design, art history, big history, world politics, &amp;hellip;). My library has 100s of books. Mostly I have read, some skimmed, some nothing. Enough for now.&lt;/p&gt;</description>
            <pubDate>Mon, 10 Feb 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-02-10-a-few-good-books.html</guid>
        </item>
        
        <item>
            <title>Il quadernetto giallo</title>
            <link>https://www.lucabol.com/posts/2025-01-30-il-quadernetto-giallo.html</link>
            <description>&lt;p&gt;AVVISO DI CONTENUTO: linguaggio volgare e contenuti potenzialmente offensivi.&lt;/p&gt;
&lt;p&gt;&lt;img src="/img/paese.jpg" alt="woman wring at a table" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;era una volta una puttana che amava la matematica. O meglio, amava i numeri. Come qualcuno colleziona francobolli, lei invece collezionava misure.&lt;/p&gt;
&lt;p&gt;Visto che era molto bella e ricercata, i clienti la lasciavano fare. A loro pareva quasi un gioco erotico quando lei, magari sul più bello, tirava fuori il righello.&lt;/p&gt;
&lt;p&gt;I suoi commenti erano poi ottimisti, ma verosimili. Non è che puoi dire a uno che ce l&amp;rsquo;ha piccolissimo che è un gigante. Così lei diceva che era &amp;lsquo;sopra la media&amp;rsquo;. Lo passava alla categoria superiore, per così dire, e loro se ne andavano belli contenti nel corpo e nell&amp;rsquo;anima.&lt;/p&gt;
&lt;p&gt;Però i clienti non sapevano che lei si segnava tutto in un piccolissimo quadernetto giallo con molta precisione: esattamente una pagina per cliente. Per esempio:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-markdown"&gt;NOME: commissario De Vito Andrea
DIMENSIONE A RIPOSO: 20 centimetri
MASSIMA ESTENSIONE: 25 centimetri
CURVATURA MEMBRO: destra
NOTE ADDIZIONALI: carattere nervoso, ma gioviale,
    evidenzia segni di acne giovanile, non menzionare.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A ogni visita, lei aggiungeva qualche dato alla scheda: numero di scarpe, circonferenza del polso &amp;hellip; cose così. Inventava anche categorie mai sentite, ma dal suono scientifico: pelosità, coefficiente di mammonaggine &amp;hellip; e anche altre misure francamente incomprensibili: ballosità, svergata massima da posizione supina &amp;hellip;&lt;/p&gt;
&lt;p&gt;Uno può immaginarsi questa piccola scienziata convincere i clienti ad assumere le posizioni più imbarazzanti per ottenere dati molto precisi. Doveva essere molto persuasiva visto che il quadernetto era pieno zeppo.&lt;/p&gt;
&lt;p&gt;Come tutto sia venuto alla luce, non è molto chiaro. Lei se ne era già andata da un annetto quando il quadernetto venne pubblicato su un sito web anonimo. L&amp;rsquo;autore si era anche premunito di fornire liste speciali per facilitarne la consultazione. Così uno poteva più facilmente individuare i &amp;ldquo;Superdotati&amp;rdquo;, i &amp;ldquo;Microdotati&amp;rdquo;, quelli con una ballosità superiore e così via. Insomma, un vero e proprio catalogo.&lt;/p&gt;
&lt;p&gt;Dapprima in paese si cercò di negare. Sicuramente si trattava di uno scherzo. Qualcuno si era inventato tutto. Però c&amp;rsquo;erano troppi dettagli accurati, troppe informazioni segrete. Per esempio, nessuno sapeva che l&amp;rsquo;avvocato Caputo avesse un testicolo così pendente che, per comodità, venisse arrotolato intorno all&amp;rsquo;altro come una liana.&lt;/p&gt;
&lt;p&gt;Oppure il fatto che il ragionier Cocchi, quando al culmine del piacere, nitrisse come un cavallo. Per anni il dottor Scalzi aveva cercato nel bosco adiacente quel cavallo maledetto che lo svegliava in piena notte. Alla fine si era convinto che si trattasse di un fenomeno paranormale. Lo aveva in fine registrato e fatto analizzare. &amp;ldquo;Nessun cavallo nutrisce così&amp;rdquo; fu il verdetto, che ne confermo l&amp;rsquo;origine soprannaturale.&lt;/p&gt;
&lt;p&gt;Ce ne erano molte di rivelazioni simili. Il quadernetto era autentico.&lt;/p&gt;
&lt;p&gt;La seconda fase venne definita &amp;lsquo;la diaspora&amp;rsquo;. Le mogli cacciarono di casa i mariti infedeli. Tutto cominciò quando la signora Arrighi, che faceva le pulizie al prete, cacciò di casa il suo consorte con le parole minacciose: &amp;ldquo;Dio ti punirà per ciò che hai fatto!&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Vista la posizione autoritaria della signora, le altre dovettero fare lo stesso. Lo fecerò però a malincuore. In fondo, non gli e ne fregava molto di essere state fatte cornute.&lt;/p&gt;
&lt;p&gt;Quanto ai mariti, passato l&amp;rsquo;iniziale smarrimento, cominciarono a organizzarsi. Si misero in piedi tornei di biliardo, cirulla e bocce. Ci fu anche una sfida di calcio scapoli contro (ex)ammogliati che si risolse in rissa per un intervento a piedi uniti sul testicolo cadente del Caputo.&lt;/p&gt;
&lt;p&gt;I più intraprendenti cominciarono a frequentare il night club locale. Le signorine Lituane non potevano credere alla loro fortuna di fronte a quell&amp;rsquo;influsso improvviso di babbei. I babbei, a loro volta, non potevano credere che esistessero signorine così belle e gentili.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Cosa mi sono perso in tutti questi anni!&amp;rdquo; dichiarò il Cocchi, brandendo felice la sua bottiglia di Champagne da 250 euro. Il cavallo soprannaturale nutrì con molto entusiasmo in quel periodo.&lt;/p&gt;
&lt;p&gt;Le mogli, di fronte a questo inaspettato giro di eventi, furono costrette a riprendersi in casa i mariti ora doppiamente fedifraghi. Pareva si divertissero troppo. E poi quanto spendevano!&lt;/p&gt;
&lt;p&gt;I mariti, un po a malincuore, tornarono all&amp;rsquo;ovile. Però non proprio tutti. Un gruppo di furboni si era studiato un piano per continuare ad andare al night club con il benestare delle mogli. L&amp;rsquo;idea era quella di fingersi afflitti da una malattia molto in voga tra gli attori Americani: la &amp;lsquo;Sex Addiction&amp;rsquo;. Loro dovevano smettere gradualmente, come Michael Douglas.&lt;/p&gt;
&lt;p&gt;Lo schema fallì per due motivi.&lt;/p&gt;
&lt;p&gt;In primo luogo &amp;lsquo;Addiction&amp;rsquo; non è una parola dalla pronuncia semplice. Malgrado le istruzioni dettagliate sul posizionamento della lingua date dal commendatore Francetti, che si vantava di essere un &amp;lsquo;anglofago&amp;rsquo;, nessuno ci aveva capito nulla.&lt;/p&gt;
&lt;p&gt;Così, sul più bello, si sono tutti incartati. La pronuncia prevalente risultò &amp;lsquo;Addisssion&amp;rsquo;, con una esse sibilata stile serpente a sonagli. Le mogli, anch&amp;rsquo;esse non propriamente anglofobe, li fissavano con sguardo interrogativo, così loro dovettero spiegare.&lt;/p&gt;
&lt;p&gt;Purtroppo, questa condizione medica, la &amp;lsquo;Sex Addisssion&amp;rsquo;, suona bene quando la leggi sul giornale, ma quando spiegata si rivela una minchiata totale.&lt;/p&gt;
&lt;p&gt;In secondo luogo, ai maschi del paese, questi nomi di attori Americani sembravano tutti uguali. Così ognuno portò ad esempio attori diversi, molti dei quali non afflitti da questa malattia. A confondere ulteriormente le acque c&amp;rsquo;era il fatto che alcuni degli attori menzionati fossero notoriamente gay. Le moglie pensarono che i mariti stessero confessando una omosessualità nascosta.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;unico che riuscì a farsi capire fu il Francetti, l&amp;rsquo;anglofaro, che però si senti rispondere dalla moglie: &amp;ldquo;Sono così sollevata! Ce la ho anche io l&amp;rsquo;addisssion! È cinque anni che ti faccio le corna con il Caputo. E io che pensavo di essere una comune troia!&amp;rdquo; Preso alla sprovvista, lui domandò: &amp;ldquo;Ma quello con le palle cadenti?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;era poi la questione delle misure. Al principio si finse indifferenza. Persino al bar del paese l&amp;rsquo;argomento non si toccava. Ma questo durò poco. Bastò una sconfitta a cirulla per scatenare il putiferio.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Con un uccello così meno male che vinci a carte!&amp;rdquo;. Quella frase ruppe l&amp;rsquo;incantesimo. Da li in poi si perse ogni ritegno.&lt;/p&gt;
&lt;p&gt;Per cominciare furono i nomignoli legati alle misure o a note presenti nel quadernetto. Il barista divenne &amp;lsquo;Minimo&amp;rsquo;, per ovvi motivi. Il postino, su cui già si sospettava, divenne &amp;lsquo;Gran Minchione&amp;rsquo; o &amp;lsquo;Granmi&amp;rsquo; per semplicità.&lt;/p&gt;
&lt;p&gt;Un povero vecchietto, che girava per il paese con la sua bici scassata, venne rinominato &amp;lsquo;lo Svergatore&amp;rsquo; o anche &amp;lsquo;Svergator&amp;rsquo;, per dirla con il Francetti. Malgrado nessuno sapesse decifrare il significato di &amp;lsquo;coefficiente di svergata&amp;rsquo;, i giovani del paese presero ad applaudirlo quando passava in bici, facendolo incazzare a più non posso e quasi cadere.&lt;/p&gt;
&lt;p&gt;Le donne, inizialmente, si rifiutarono di adottare questi soprannomi vergognosi, ma con il tempo si dovettero conformare all&amp;rsquo;uso comune. Così per il pese si udivano frasi tipo: &amp;ldquo;Passo dal minchione a prendere il pane, poi dal moscio per la carne. Spero di incontrare penetrator, che mi deve riparare la calderina&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Questi nomignoli lentamente persero la loro connotazione originaria e divennero il modo principale di identificare i maschi del paese. &amp;ldquo;Hai parlato con l&amp;rsquo;Ambrosi?&amp;rdquo; &amp;ldquo;Chi?&amp;rdquo; &amp;ldquo;Lo Strizzatette&amp;rdquo; &amp;ldquo;Ah, no&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Alcune donne più intraprendenti cercarono di rendere popolare un soprannome di loro invenzione per elevare lo stato sociale del coniuge. Ma questi sotterfugi non ebbero molto successo, visto che tutti avevano accesso alle misure reali. Ad esempio, la moglie del Minimo provò a dire a una amica &amp;ldquo;Black &amp;lsquo;n&amp;rsquo; Decker&amp;rdquo;, pronunciato come si scrive, o anche peggio, &amp;ldquo;vuole le melanzane per cena.&amp;rdquo; &amp;ldquo;Chi?&amp;rdquo; &amp;ldquo;Mio marito, non lo sai che lo chiamano così?&amp;rdquo;. E l&amp;rsquo;amica rispose dubbiosa &amp;ldquo;Sarà&amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Il quadernetto svelò anche uno dei misteri di più lunga data del paese: perché molte signore si accanissero a farsi fare i capelli da Robertino, malgrado l&amp;rsquo;evidenza incontrovertibile che, come parrucchiere, facesse proprio schifo. Faceva a tutte una permanente alta e molto voluminosa. Quando si riunivano di fronte alla chiesa sembrava di stare alla corte di Verseille, pronunciato come si scrive, che non è così. If fatto è che, malgrado il nome e la professione. Non era poi gay. Anzi.&lt;/p&gt;
&lt;p&gt;A un certo punto, sul sito web del quadernetto comparve un messaggio che diceva: &amp;ldquo;Se ritenete che la vostra misura sia incorretta, spedite foto comprovante con faccia, membro in piena estensione e righello di riferimento&amp;rdquo;. &amp;ldquo;Una specie di selfie con il tuo uccello.&amp;rdquo; commentò il Francetti.&lt;/p&gt;
&lt;p&gt;Malgrado i molti tentativi, nessuno fu in grado di assumere una posizione tale da avere nella stessa foto quelle due parti anatomiche che la natura ha posto così distanti. Si penso quindi che l&amp;rsquo;autore intendesse una foto frontale a mezzo busto impugnando un righello posto in modo tale da misurare la piena estensione fallica.&lt;/p&gt;
&lt;p&gt;Così rassicurato sulle meccaniche dell&amp;rsquo;operazione, il Minimo pensò a un modo di riabilitare la propria reputazione. Fece giurare al Granmi un voto di segretezza e lo convinse, previa lauta compensazione, a partecipare all&amp;rsquo;impresa. Codesta impresa consisteva nel trasformarlo, usando baffi finti e parrucca di pelo di cavallo, in una copia del Minimo da fotografare.&lt;/p&gt;
&lt;p&gt;Il problema però rimaneva come fargli raggiungere uno stato di massima estensione. Si provò con giornaletti, video e siti web, ma niente pareva stimolarlo. Allora l&amp;rsquo;Adelina, fedele moglie del Minimo e pia donna di chiesa, sbottò: &amp;ldquo;Va be&amp;rsquo;, mi sacrifico io&amp;rdquo;. E la foto si fece.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;email fu spedita con titolo conciso: &amp;ldquo;Correzione misure signor Amadei barista - vedere foto allegata&amp;rdquo;. La replica arrivo stile telegramma: &amp;ldquo;Bella foto Granmi in maschera - riservo diritto condivisione sito motociclisti gay&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Immagino vi chiediate come faccia io a sapere tutte queste cose. All&amp;rsquo;inizio l&amp;rsquo;idea era di collezionare dati per la mia tesi di laurea per l&amp;rsquo;Imperial College of London dal titolo: &amp;ldquo;Quanto è grosso? A field study of penis dimension of the average Italian male&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Al sito web ci ho pensato dopo. Lo ho creato per la mia seconda laurea in sociologia. Anche questa tesi fu ben ricevuta, forse anche per il titolo: &amp;ldquo;A Big Ben? An experiment in radical anatomical transparency.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Sono pentita di ciò che ho fatto? Alcuni ci hanno un po patito; altri ci hanno guadagnato. Dopo qualche anno non gli e ne fregava più niente a nessuno. Solo i nomignoli sono rimasti.&lt;/p&gt;
&lt;p&gt;Il Granmi vive qui con me a Londra. Non ha imparato una singola parola di inglese, ma a me non interessa. Sono altre le cose importanti nella vita.&lt;/p&gt;</description>
            <pubDate>Thu, 30 Jan 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-01-30-il-quadernetto-giallo.html</guid>
        </item>
        
        <item>
            <title>How I changed my blog (again)</title>
            <link>https://www.lucabol.com/posts/2025-01-13-how-i-changed-my-blog-again.html</link>
            <description>&lt;p&gt;I wanted to try out &lt;a href="https://github.com/cline/cline"&gt;Cline&lt;/a&gt; on a medium-sized project. For a long time I wanted to move away from a static generator like &lt;code&gt;Eleventy&lt;/code&gt; to a simple &lt;code&gt;bash&lt;/code&gt; or &lt;code&gt;Python&lt;/code&gt; script that generates &lt;code&gt;html&lt;/code&gt; and &lt;code&gt;css&lt;/code&gt; that I can ftp to wherever.&lt;/p&gt;
&lt;p&gt;I ended up doing much more than that. All in all I worked on it for a couple of days. Without Cline it would have taken me more than a week, I suspect.&lt;/p&gt;
&lt;h2&gt;Creating the Python script&lt;/h2&gt;
&lt;p&gt;I didn&amp;rsquo;t want to reuse my existing &lt;code&gt;Eleventy&lt;/code&gt; partial html fragments and css, so I instructed AI to generate a static website starting from the list of posts in in the posts directory. I then showed AI a picture of my site and asked it to generate a similar one.&lt;/p&gt;
&lt;p&gt;We then worked on the list of Code projects generated from the &lt;code&gt;projects.yaml&lt;/code&gt; file (I should auto-generate this from specially marked projects on github &amp;hellip;). Also, we created the &lt;code&gt;Tags&lt;/code&gt; page looking at the front matter of the posts.&lt;/p&gt;
&lt;p&gt;After a few iterations, refactorings, and bug fixes, we had a working site similar to the one I had before.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web.archive.org/web/20231003045700/https://www.lucabol.com/"&gt;Old site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.lucabol.com/"&gt;New site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The new one is slightly simpler graphically, not because I couldn&amp;rsquo;t do it, but because I chose not to.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/lucabol/MyBlog/blob/master/src/generate_blog.py"&gt;This&lt;/a&gt; is the 232 lines of Python code that generates the site. To my eyes, the situation is vastly simplified, as I don&amp;rsquo;t need to understand the intricacies of &lt;code&gt;Eleventy&lt;/code&gt; anymore. Everything has become embarrassingly obvious.&lt;/p&gt;
&lt;h2&gt;Adding a commenting system&lt;/h2&gt;
&lt;p&gt;In my folly, I don&amp;rsquo;t want any Javascript on my site.&lt;/p&gt;
&lt;p&gt;In the past, I used &lt;code&gt;Disqus&lt;/code&gt;, then &lt;code&gt;webmentions&lt;/code&gt;, then nothing. But &lt;code&gt;nothing&lt;/code&gt; is a bit on the harsh side of life.&lt;/p&gt;
&lt;p&gt;I decided to use Github issues as database for the comments. I know about &lt;code&gt;utterances&lt;/code&gt;, but I don&amp;rsquo;t want to use it as it is Javascript based. So I came up with a super simple scheme, where each post has a link to a github query containing the post title. That brings up the correct issue for the post and you can add comments to that.&lt;/p&gt;
&lt;p&gt;It is very primitive as you cannot create a comment from the site itself, you need a Github account, etc&amp;hellip; etc&amp;hellip; But it is simple and it works, no Javascript required.&lt;/p&gt;
&lt;p&gt;I also had a bunch of json files with comments from the past. I instructed AI to create a script that automatically generates issues from the posts and comments from the json files. It created &lt;a href="https://github.com/lucabol/MyBlog/blob/master/src/bulk_create_many_issues.py"&gt;another 300 lines of Python&lt;/a&gt; (mostly because of the bizarre rate limitations on the Github API).&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t even looked at the script. It is enough that it worked once (took it one night, who knows??).&lt;/p&gt;
&lt;p&gt;So now I have imported all the comments from the past and have a working commenting system, for some definition of &amp;ldquo;working&amp;rdquo;.&lt;/p&gt;
&lt;h2&gt;Fixing badly formatted old posts&lt;/h2&gt;
&lt;p&gt;And now for something that I would have never done without AI. I had a bunch of very old posts that contained very badly formatted and broken code.&lt;/p&gt;
&lt;p&gt;The system I used at the time embedded html tags in the markdown. Properly formatting them one by one would have taken a lot of time as there is no automatic way of doing it.&lt;/p&gt;
&lt;p&gt;Most of those posts are obsolete, but still I didn&amp;rsquo;t like them to be in such bad shape. It bugged me.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;AI, buddy, please fix them for me&amp;rdquo;. And it did. It took a few hours, but it did it. I had to spend a few dollars on consumption, but it worked like a charm.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web.archive.org/web/20240720002637/https://www.lucabol.com/posts/2008-04-21-a-c-library-to-write-functional-code-part-iii-records/"&gt;old post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.lucabol.com/posts/2008-04-21-a-c-library-to-write-functional-code-part-iii-records/"&gt;new post&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 13 Jan 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-01-13-how-i-changed-my-blog-again.html</guid>
        </item>
        
        <item>
            <title>Out at sea</title>
            <link>https://www.lucabol.com/posts/2025-01-12-out-at-sea.html</link>
            <description>&lt;p&gt;&lt;img src="/img/fishermen.jpg" alt="fishermen" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;It had been a long night for the two brothers. They didn&amp;rsquo;t catch much. They didn&amp;rsquo;t talk much either.&lt;/p&gt;
&lt;p&gt;Gabriel was the oldest. Carlos, the wisest. &lt;/p&gt;
&lt;p&gt;That night, it was as if the sea had smashed their faces against the rocks.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I know about you and Tina,&amp;rdquo; Carlos started. Gabriel glanced at him, face turning red.&lt;/p&gt;
&lt;p&gt;A wave hit the boat. Gabriel swore. They struggled to regain their balance.&lt;/p&gt;
&lt;p&gt;Carlos looked down: &amp;ldquo;This is the last time we ever talk about this.&amp;rdquo; Gabriel nodded, tears glistening in his eyes.&lt;/p&gt;
&lt;p&gt;They pulled up the nets and headed home.&lt;/p&gt;
&lt;p&gt;As they reached shore, a wave hit the boat. Gabriel swore. The sun came out and turned the night red.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edited by: Maia&lt;/em&gt;&lt;/p&gt;</description>
            <pubDate>Sun, 12 Jan 2025 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2025-01-12-out-at-sea.html</guid>
        </item>
        
        <item>
            <title>The sea calls</title>
            <link>https://www.lucabol.com/posts/2024-12-29-the-sea-calls.html</link>
            <description>&lt;p&gt;&lt;img src="/img/girl.jpg" alt="little girl looking at sea" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;The beach was long and empty. The sea moved like a prairie, and the sky smelled of lavender. From above, the sun cast its warm, indifferent gaze.
At the boundary between sand and water stood the little girl. A passing glance might have missed her. Just another log washed out by the sea.&lt;/p&gt;
&lt;p&gt;But she was there all right. Perfectly still, her feet in the water, her head tilted, coal eyes gleaming, black hair streaming down her back. There she was, with the seagulls screaming at the sky and tracing geometries above her.&lt;/p&gt;
&lt;p&gt;“Pequeña, ven! You have been out there too long.”&lt;/p&gt;
&lt;p&gt;As the years go by, the girl thinks of the sea often. It calls her when she walks among the sharp buildings of the city, inside the elegant hotels and restaurants. She hears it when she puts on her high-heeled shoes; as she holds her child; when she makes love to her husband. At times, she forgets, but never for long.&lt;/p&gt;
&lt;p&gt;And time will pass. The old girl finds herself in a hospital bed. She looks down into the coal eyes of another little girl, so much like her own. She moves aside the girl’s long hair and whispers in her ear what the sea taught her all those years ago.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edited by: Maia&lt;/em&gt;&lt;/p&gt;</description>
            <pubDate>Sun, 29 Dec 2024 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2024-12-29-the-sea-calls.html</guid>
        </item>
        
        <item>
            <title>Volley (or racketball or beach-volley) simulation &amp; probability distribution</title>
            <link>https://www.lucabol.com/posts/2024-06-14-volley-simulation.html</link>
            <description>&lt;p&gt;This is a Jupyter notebook converted to blog post by &lt;a href="https://nbconvert.readthedocs.io/en/latest/"&gt;nbconvert&lt;/a&gt;. The notebook is &lt;a href="https://github.com/lucabol/sportsim/blob/main/volley.ipynb"&gt;here&lt;/a&gt;. To comment or contribute, please open an issue or a pull request on &lt;a href="https://github.com/lucabol/sportsim"&gt;the repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The aim is to discover the probability of winning a set/game/match in volleyball/beach volley/racketball/badmington/&amp;hellip;, given the probability of winning a point. The model is based on the assumption that the probability of winning a point is constant and independent of the previous points. This is a simplification, but it is a good starting point to understand the game.&lt;/p&gt;
&lt;p&gt;Later, we will derive analytical formulas and compare the results of the simulation with the analytical formulas.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the simulation.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import random
import pandas as pd

def simulate_volley(a_win_prob=0.52, max_games=1000, sets_to_win=2, points_to_win_standard=21, points_to_win_last=15):
    &amp;quot;&amp;quot;&amp;quot;
    Simulate a volleyball match between two teams with given probabilities of winning a point.

    Parameters:
    a_win_prob (float): Probability of team A winning a point.
    max_games (int): Maximum number of games to simulate.
    sets_to_win (int): Number of sets to win the match.
    points_to_win_standard (int): Number of points to win a set unless it's the last set and we are tied.
    points_to_win_last (int): Number of points to win the last set if we are tied.
    &amp;quot;&amp;quot;&amp;quot;
    a_wins = b_wins = a_tot_points = b_tot_points = a_tot_sets = b_tot_sets = 0
    rows = []

    while a_wins + b_wins &amp;lt; max_games:
        a_sets = b_sets = 0

        while a_sets &amp;lt; sets_to_win and b_sets &amp;lt; sets_to_win:
            a_points = b_points = 0
            points_to_win = points_to_win_standard if a_sets + b_sets &amp;lt; 2 * sets_to_win - 1 else points_to_win_last

            while not (a_points &amp;gt;= points_to_win and a_points - b_points &amp;gt;= 2) and not (b_points &amp;gt;= points_to_win and b_points - a_points &amp;gt;= 2):
                flag = 1
                a_win_point = random.random() &amp;lt; a_win_prob
                if a_win_point:
                    a_points += 1; a_tot_points += 1
                if not a_win_point:
                    b_points += 1; b_tot_points += 1

                if a_points &amp;gt;= points_to_win and a_points - b_points &amp;gt;= 2:
                    a_sets += 1; a_tot_sets += 1; flag = 2
                if b_points &amp;gt;= points_to_win and b_points - a_points &amp;gt;= 2:
                    b_sets += 1; b_tot_sets += 1; flag = 2

                if a_sets == sets_to_win:
                    a_wins += 1; flag = 3
                if b_sets == sets_to_win:
                    b_wins += 1; flag = 3

                rows.append({'F': flag, 'P': int(a_win_point), 'AS': a_sets, 'BS': b_sets, 'AP': a_points, 'BP': b_points,  'AW': a_wins, 'BW': b_wins, 'ATS': a_tot_sets, 'BTS': b_tot_sets, 'ATP': a_tot_points, 'BTP': b_tot_points})

    return rows
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Check for convergence&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s check that the various probabilities converge to a stable value.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;rows = simulate_volley(0.52)

df = pd.DataFrame(rows, columns=['F', 'P', 'AS', 'BS', 'AP', 'BP', 'AW', 'BW', 'ATS', 'BTS','ATP', 'BTP'])
df['WP'] = df['AW'] / (df['AW'] + df['BW'])
df['SP'] = df['ATS'] / (df['ATS'] + df['BTS'])
df['PP'] = df['ATP'] / (df['ATP'] + df['BTP'])

# Avoids SettingWithCopyWarning
pd.options.mode.copy_on_write = True

# Create a dataset containing just rows where Flag is 2
dfp = df[df['F'] == 1]
dfs = df[df['F'] == 2]
dfw = df[df['F'] == 3]

# Plot first N, N1 rows
N = 150
N1 = int(len(dfp['PP']) / 4)
dfw = dfw.head(N)
dfs = dfs.head(N)
dfp = dfp.head(N1)

# Create an increasing integer sequence for x-values
dfw['x'] = range(0, N)
dfs['x'] = range(0, N)
dfp['x']  = range(0, N1)

print(df[['WP', 'SP', 'PP']].tail(1))

# On the same plot, plot the winning probability, set winning probability, and point winning probability in time
import matplotlib.pyplot as plt

fig, ax = plt.subplots(3, 1, figsize=(10, 10))

dfw.plot(x='x', y='WP', ax=ax[0], title='Winning Probability');
dfs.plot(x='x', y='SP', ax=ax[1], title='Set Winning Probability');
ax[2].set_xscale('log')
dfp.plot(x='x', y='PP', ax=ax[2], title='Point Winning Probability');
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;          WP        SP        PP
92266  0.652  0.609325  0.520164
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img alt="png" src="/img/volley_3_1.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Simulation&lt;/h2&gt;
&lt;p&gt;Then we simulate beach volley (2 sets to win, to 21 points each set except the last to 15) and volley (3 sets to win, to 25 each set except the last to 15).&lt;/p&gt;
&lt;p&gt;The results look similar to the real data in &lt;a href="https://garyhorvath.com/percentage-of-points-won-stanford-nebraska-and-cu-volleyball/"&gt;this blog post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We simulate just in the range of 0.5 to 0.65 for the probability of winning a point, as the probability of winning a set/match become 1 very quickly for higher values.&lt;/p&gt;
&lt;p&gt;The results show two things:
- the probability of winning a set/match is not linear with the probability of winning a point and it is much higher. I.E. if you win 60% of the points, you win 90% of the sets and much more of the matches. Honestly, I was not expecting this, but it makes sense as the probability of winning a point gets multiplied many times, so small differences end up being very significant.
- the longer the set/match, the more the probability of winning a set/match is higher than the probability of winning a point, for the same reason as above (more chances for the better team to win points).&lt;/p&gt;
&lt;p&gt;This code can be useful to figure out other characteristics of the game that might be difficult to model with the analytical formulas developed below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;def simulate_volley_prob(low_prob=0.5, high_prob=0.6, step=0.01, max_games=10000, n_sets = 2, points_to_win_standard=21, points_to_win_last=15):
    result = []
    for i in range(int(low_prob * 100), int(high_prob * 100), int(step * 100)):
        rows = simulate_volley(i / 100, max_games=max_games, sets_to_win=n_sets, points_to_win_standard=points_to_win_standard, points_to_win_last=points_to_win_last)
        stats = rows[-1]
        result.append({'Prob': i / 100, 'WP': stats['AW'] / (stats['AW'] + stats['BW']),
                      'SP': stats['ATS'] / (stats['ATS'] + stats['BTS']),
                      'PP': stats['ATP'] / (stats['ATP'] + stats['BTP'])})
    return result

result_2sets = simulate_volley_prob(0.5, 0.65, 0.01, n_sets=2, points_to_win_standard=21, points_to_win_last=15)
result_3sets = simulate_volley_prob(0.5, 0.65, 0.01, n_sets=3, points_to_win_standard=25, points_to_win_last=15)

import matplotlib.pyplot as plt

fig, axs = plt.subplots(1, 2, figsize=(12, 6))

df_2sets = pd.DataFrame(result_2sets)
df_2sets.plot(x='Prob', y=['WP', 'SP', 'PP'], title='Winning Probability 2 Sets', ax=axs[0]);

df_3sets = pd.DataFrame(result_3sets)
df_3sets.plot(x='Prob', y=['WP', 'SP', 'PP'], title='Winning Probability 3 Sets', ax=axs[1]);

plt.tight_layout()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img alt="png" src="/img/volley_5_0.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Fitting a function&lt;/h2&gt;
&lt;p&gt;Here we fit a function to the data in the interval shown. As it turns out, a sigmoid does so pretty well. This is a brute force empirically derived result. Maybe there is a theory behind it, but I don&amp;rsquo;t know it.&lt;/p&gt;
&lt;p&gt;The fit looks pretty good.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from scipy.optimize import curve_fit
import scipy.stats as stats
import matplotlib.pyplot as plt

def func(x, a, b, c):
    return a / (1 + np.exp(-b * (x - c)))

def fit_curve(df, column):
    popt, pcov = curve_fit(func, df['Prob'], df[column])
    return popt

popt_2sets_WP = fit_curve(df_2sets, 'WP')
popt_3sets_WP = fit_curve(df_3sets, 'WP')
popt_2sets_SP = fit_curve(df_2sets, 'SP')
popt_3sets_SP = fit_curve(df_3sets, 'SP')

fig, axs = plt.subplots(2, 2, figsize=(12, 12))

df_2sets.plot(x='Prob', y='WP', title='Winning Probability 2 Sets', ax=axs[0, 0]);
axs[0, 0].plot(df_2sets['Prob'], func(df_2sets['Prob'], *popt_2sets_WP), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt_2sets_WP))

df_3sets.plot(x='Prob', y='WP', title='Winning Probability 3 Sets', ax=axs[0, 1]);
axs[0, 1].plot(df_3sets['Prob'], func(df_3sets['Prob'], *popt_3sets_WP), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt_3sets_WP))

df_2sets.plot(x='Prob', y='SP', title='Set Probability 2 Sets', ax=axs[1, 0]);
axs[1, 0].plot(df_2sets['Prob'], func(df_2sets['Prob'], *popt_2sets_SP), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt_2sets_SP))

df_3sets.plot(x='Prob', y='SP', title='Set Probability 3 Sets', ax=axs[1, 1]);
axs[1, 1].plot(df_3sets['Prob'], func(df_3sets['Prob'], *popt_3sets_SP), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt_3sets_SP))

for ax in axs.flat:
    ax.legend()

plt.tight_layout()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img alt="png" src="/img/volley_7_0.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Fit using a Bernoulli trial model&lt;/h2&gt;
&lt;p&gt;We can model a set as a Bernoulli trial, answering the question of getting at least $k$ successes before the $r-th$ failure where $k$ and $r$ are the same: the number of points needed to win a set. Similarly, we can apply the same formula to the probability of winning a match given the probability of winning a set.&lt;/p&gt;
&lt;p&gt;The approximation works quite well, despite the imperfection of having to win a set by at least 2 points, which is not considered in the analytical formula, but it is in the simulation. My intuition is that once you get to 24-24 and continue playing, the probability doesn&amp;rsquo;t change.&lt;/p&gt;
&lt;p&gt;The formula is taken from &lt;a href="https://math.stackexchange.com/questions/915353/the-probability-of-having-k-successes-before-r-failures-in-a-sequence-of-ind"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is this:&lt;/p&gt;
&lt;p&gt;$$ P = \sum_{j=0}^{r-1} \binom{k-1+j}{k-1} p^k (1-p)^j $$&lt;/p&gt;
&lt;p&gt;My intuitive explanation for the formula above follows.&lt;/p&gt;
&lt;p&gt;Imagine you want the probability of 3 successes before 3 failures, given the probability of success $p$.&lt;/p&gt;
&lt;p&gt;There is just one way to get to 3-0, by 3 successes in a row -&amp;gt; WWW&lt;/p&gt;
&lt;p&gt;$ P(3-0) = p^3 $&lt;/p&gt;
&lt;p&gt;There are 4 ways to get to 3-1, but WWWL doesn&amp;rsquo;t count as the match stops at 3-0, hence we are left with LWWW WLWW WWLW.
Which can be tought of as &amp;lsquo;all the way to pick 2 wins out out of the first 3 slots, hence $\binom{3}{2}$.&lt;/p&gt;
&lt;p&gt;$P(3-1) =  \binom{3}{2} p^3 (1 - p)^1$&lt;/p&gt;
&lt;p&gt;Equally, you can think at the binomial below as all the ways to get 2 wins in the first 4 slots.&lt;/p&gt;
&lt;p&gt;$ P(3-2) = \binom{4}{2} p^3 (1-p)^2 $&lt;/p&gt;
&lt;p&gt;The fit is pretty good here too, but now we have a theoretical explanation for it, which is always nice.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from scipy.special import comb

# Range ends in j instead of j-1 as in the formula because the range function is exclusive
def prob_at_least_k_successes_before_r_failures(k, r):
    return lambda x: sum([comb(k - 1 + j, k -1 ) * x**k * (1 - x)** j for j in range(0, r)])

prob_at_least_21 = lambda x: prob_at_least_k_successes_before_r_failures(21, 21)(x)
prob_at_least_25 = lambda x: prob_at_least_k_successes_before_r_failures(25, 25)(x)

prob_win_2sets = lambda x: prob_at_least_k_successes_before_r_failures(2, 2)(prob_at_least_21(x))
prob_win_3sets = lambda x: prob_at_least_k_successes_before_r_failures(3, 3)(prob_at_least_25(x))

fig, axs = plt.subplots(2, 2, figsize=(12, 12))

df_2sets.plot(x='Prob', y='WP', title='Winning Probability 2 Sets', ax=axs[0, 0]);
axs[0, 0].plot(df_2sets['Prob'], prob_win_2sets(df_2sets['Prob']), 'g-', label='P(win 2 sets before opponent wins 2 sets)')

df_3sets.plot(x='Prob', y='WP', title='Winning Probability 3 Sets', ax=axs[0, 1]);
axs[0, 1].plot(df_2sets['Prob'], prob_win_3sets(df_2sets['Prob']), 'g-', label='P(win 3 sets before opponent wins 3 sets)')

df_2sets.plot(x='Prob', y='SP', title='Set Probability 2 Sets', ax=axs[1, 0]);
axs[1, 0].plot(df_2sets['Prob'], prob_at_least_21(df_2sets['Prob']), 'g-', label='P(&amp;gt;=21 successes before 21 failures)')

df_3sets.plot(x='Prob', y='SP', title='Set Probability 3 Sets', ax=axs[1, 1]);
axs[1, 1].plot(df_3sets['Prob'], prob_at_least_25(df_3sets['Prob']), 'g-', label='P(&amp;gt;=25 successes before 25 failures)')

# show labels
for ax in axs.flat:
    ax.legend()

plt.tight_layout()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img alt="png" src="/img/volley_9_0.png" /&gt;&lt;/p&gt;
&lt;h2&gt;A linear approximation&lt;/h2&gt;
&lt;p&gt;In the more reasonable range, 0.50 - 0.55 a linear approximation works pretty good. So, if you are tight on resources, you can use this approximation without too much loss of fidelity.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;# Take just the rows with probability less than 0.56
df_2sets_low = df_2sets[df_2sets['Prob'] &amp;lt; 0.56]
df_3sets_low = df_3sets[df_3sets['Prob'] &amp;lt; 0.56]

# Do a linear fit on the data and plot the data and the fit
from scipy.stats import linregress

def fit_linear(df):
    slope, intercept, r_value, p_value, std_err = linregress(df['Prob'], df['WP'])
    return slope, intercept

slope_2sets, intercept_2sets = fit_linear(df_2sets_low)
slope_3sets, intercept_3sets = fit_linear(df_3sets_low)

print(slope_2sets, intercept_2sets)
print(slope_3sets, intercept_3sets)

fig, axs = plt.subplots(1, 2, figsize=(12, 6))

df_2sets_low.plot(x='Prob', y='WP', title='Winning Probability 2 Sets', ax=axs[0]);
axs[0].plot(df_2sets_low['Prob'], slope_2sets * df_2sets_low['Prob'] + intercept_2sets, 'r-', label='fit: a=%5.3f, b=%5.3f' % (slope_2sets, intercept_2sets))

df_3sets_low.plot(x='Prob', y='WP', title='Winning Probability 3 Sets', ax=axs[1]);
axs[1].plot(df_3sets_low['Prob'], slope_3sets * df_3sets_low['Prob'] + intercept_3sets, 'r-', label='fit: a=%5.3f, b=%5.3f' % (slope_3sets, intercept_3sets))

# show labels
for ax in axs:
    ax.legend()

plt.tight_layout()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;6.837142857142849 -2.906399999999996
8.25314285714285 -3.6039333333333294
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img alt="png" src="/img/volley_11_1.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The probability of winning a set/match is not linear with the probability of winning a point and it is much higher. The longer the set/match, the more the probability of winning a set/match is higher than the probability of winning a point. A sigmoid function fits the data pretty well, but a linear approximation works well in the range 0.50-0.55. A Bernoulli trial model can be used to approximate the probability of winning a set/match given the probability of winning a point.&lt;/p&gt;</description>
            <pubDate>Sun, 16 Jun 2024 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2024-06-14-volley-simulation.html</guid>
        </item>
        
        <item>
            <title>Display math equations in Azure AI Studio Chat</title>
            <link>https://www.lucabol.com/posts/2024-05-31-display-math-equations-in-azure-ai-studio-chat.html</link>
            <description>&lt;p&gt;Your mileage might vary. This is a dirty trick, likely to break the internet, but it kind of works.&lt;/p&gt;
&lt;p&gt;Mathematical equations are displayed in LaTex format, basically unreadable.&lt;/p&gt;
&lt;p&gt;I have tried to make GPT-4o
to format them in a human readable way in the Azure AI Studio Chat Playground, but failed.&lt;/p&gt;
&lt;p&gt;So it is like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-latex"&gt;$$
P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)}
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You instead might want something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="equation" src="/img/Bayes.png" /&gt;&lt;/p&gt;
&lt;p&gt;The trick is to inject Javascript code that executes on a timer and uses MathJax to transform the Latex code
to an image.&lt;/p&gt;
&lt;p&gt;There are probably better ways to do it. Here is what I did:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://www.tampermonkey.net/"&gt;Tampermonkey&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click on the extension and pick &lt;code&gt;Create a new script&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Paste the script below (modified from &lt;a href="https://www.reddit.com/r/ChatGPT/comments/11uc9x4/just_found_this_out_today_you_can_get_chatgpt_to/"&gt;this thread&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;// ==UserScript==
// @name         ChatGPT LaTeX Display
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://chat.openai.com/*
// @match        https://ai.azure.com/playground/*
// @icon         https://www.google.com/s2/favicons?sz=64&amp;amp;domain=openai.com
// @grant        GM_setValue
// @run-at       document-start
// ==/UserScript==


//Prompt should end with&amp;gt;&amp;gt;&amp;gt; Please format any equations in LaTeX.
//TODO: Intercept WebSocket messages and re-typeset every second until the chatbot is done talking.


(function() {
    'use strict';

    console.log(&amp;quot;Getting ready to set up MathJax&amp;quot;);



    let tmpMathJax = {
        tex: {
            inlineMath: [['$', '$'], ['\\(', '\\)']],
            displayMath: [ ['$$','$$'], ['\[','\]'] ]
        }
    };

    var prescript = document.createElement('script');
    prescript.type = 'text/javascript';
    prescript.innerText = `
    MathJax = {
        tex: {
            inlineMath: [['$', '$'], ['\\(', '\\)']],
            displayMath: [ ['$$','$$'], ['\[','\]'] ]
        }
    };`;
    prescript.onload = function() {
        console.log(&amp;quot;MathJax customizations loaded&amp;quot;);
    }
    document.getElementsByTagName('head')[0].appendChild(prescript);



    console.log(&amp;quot;Setting up MathJax&amp;quot;);

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.onload = function() {
        console.log(&amp;quot;MathJax loaded!!&amp;quot;);

        setInterval(function() {
            console.log(&amp;quot;Re-typesetting...&amp;quot;);
            MathJax.typeset();
        },5000);
    }
    script.src = &amp;quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&amp;quot;;
    document.getElementsByTagName('head')[0].appendChild(script);

})();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Caveats:
1. Running something on a timer is ugly. In this case you have to wait 5 seconds to see the nice formulas.
2. It doesn&amp;rsquo;t work correctly for some inline formulas.&lt;/p&gt;
&lt;p&gt;All in all, it is a dirty hack. Perhaps it could be made &amp;lsquo;more working&amp;rsquo;, but maybe there is a better way altogheter.&lt;/p&gt;</description>
            <pubDate>Fri, 31 May 2024 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2024-05-31-display-math-equations-in-azure-ai-studio-chat.html</guid>
        </item>
        
        <item>
            <title>How I changed my blog</title>
            <link>https://www.lucabol.com/posts/2024-03-05-how-I-changed-my-blog.html</link>
            <description>&lt;p&gt;My blog has been going for more than 20 years. In this timespan there has been just one
change in architecture: going from &lt;code&gt;WordPress&lt;/code&gt; to &lt;code&gt;Eleventy + Netlify&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At the time, I was looking for the simplest possible solution. I didn&amp;rsquo;t go far enough.&lt;/p&gt;
&lt;p&gt;For a technical blog like mine, you don&amp;rsquo;t need a static generator like &lt;code&gt;Eleventy&lt;/code&gt;. A &lt;code&gt;bash&lt;/code&gt; or
&lt;code&gt;Python&lt;/code&gt; script is enough - so you are not forced to re-learn the static generator every time you pick up
the blog again.&lt;/p&gt;
&lt;p&gt;Also, you don&amp;rsquo;t need a web provider that knows about your static generator, like &lt;code&gt;Netlify&lt;/code&gt; and compiles
your code. You can compile it on your laptop and ftp the &lt;code&gt;html&lt;/code&gt; to wherever.&lt;/p&gt;
&lt;p&gt;Also, the &lt;code&gt;html&lt;/code&gt; and &lt;code&gt;css&lt;/code&gt; I was generating was too complex.
* Too many &lt;code&gt;div&lt;/code&gt; tags to obtain pixel perfect display.
* Server side syntax highlighting creating a tangle mess of tags in the &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; tag.
* Frivoulous eye candies like TOC, time of reading, web-mentions, &amp;hellip;
* Too many &lt;code&gt;css&lt;/code&gt; variables and indirection for the sake of modularization.&lt;/p&gt;
&lt;p&gt;The last point is interesting. In my &lt;code&gt;css&lt;/code&gt;, you could change a few typographic variables
(i.e., font-size, measure, &amp;hellip;) and the whole site would changes. That sounds fantastic, except
that it isn&amp;rsquo;t. I am not Microsoft/Google/Netflix/&amp;hellip;&lt;/p&gt;
&lt;p&gt;When I pick up the blog again after a few months, I forget how it all works
and end up spending hours figuring it out again. Fixing issues means wading through bogs of
indirection: is it a browser bug? My framework? &amp;hellip;&lt;/p&gt;
&lt;p&gt;This is a lesson I had to learn many times, and I am still learning:
radical simplicity means you don&amp;rsquo;t create a framework. You just code the damn thing.&lt;/p&gt;
&lt;p&gt;You can see how it used to look by doing a &lt;code&gt;View source&lt;/code&gt;
on &lt;a href="https://march2024--lucabol.netlify.app/posts/2022-03-07-implementing-forth-dotnet/"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The new website is still &lt;code&gt;Eleventy + Netlify&lt;/code&gt;, but I fixed the &lt;code&gt;HTML + CSS&lt;/code&gt; to be radically simple.
* Not a single &lt;code&gt;div&lt;/code&gt; tag: just semantic tags (&lt;code&gt;article&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &amp;hellip;).
* No syntax highlighting. Do you really need it for small code snippets?
* No eye candies at all. Just text all the way.
* No &lt;code&gt;css&lt;/code&gt; variables. Just a trivial stylesheet for the typography.&lt;/p&gt;
&lt;p&gt;You can see the difference in the source code &lt;a href="https://www.lucabol.com/posts/2022-03-07-implementing-forth-dotnet/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A few simplification came about as a bonus. When you radically simplify things, you often get to their hidden core.&lt;/p&gt;
&lt;p&gt;I used to have different &amp;lsquo;templates&amp;rsquo; for different categories of pages (i.e., post, list of posts, home page, &amp;hellip;).
I now have just one template. The content in the middle of the page is the only thing that changes.&lt;/p&gt;
&lt;p&gt;One thing I have not removed is a processing pass that insert typographic niceties (like Hanging Punctuation).
You can see an example on the line that says: &amp;ldquo;I want a piece &amp;hellip;&amp;rdquo; &lt;a href="https://www.lucabol.com/posts/2022-03-09-horchata/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is frivolous, but for someone who is into typography like me
(I have created &lt;a href="https://www.lucabol.com/posts/2021-06-23-i-have-created-a-font-italiko/"&gt;my own font&lt;/a&gt; after all),
it does matter.&lt;/p&gt;
&lt;p&gt;The old website was already at 100% in all google &lt;code&gt;lighthouse&lt;/code&gt; categories. The new one is even faster.
Not that it matters, but you know &amp;hellip;&lt;/p&gt;
&lt;p&gt;The next step is to remove the dependency from the static site generator and provider. Just a simple script
that iterates over all the posts and generates the &lt;code&gt;Notes&lt;/code&gt;, &lt;code&gt;Tags&lt;/code&gt;, &lt;code&gt;Code&lt;/code&gt; pages should be about it. Next time.&lt;/p&gt;
&lt;p&gt;Oh, and I also need to re-introduce a way to comment on the posts. I am thinking some kind of public email box with
one thread for each post, but I have not investigated further.&lt;/p&gt;</description>
            <pubDate>Sun, 03 Mar 2024 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2024-03-05-how-I-changed-my-blog.html</guid>
        </item>
        
        <item>
            <title>The best programming languages to learn in 2024</title>
            <link>https://www.lucabol.com/posts/2024-02-21-best-programming-languages.html</link>
            <description>&lt;p&gt;As few people have asked for my opinion. Here it is in very concise form.&lt;/p&gt;
&lt;p&gt;It depends on your goal and it is all very debatable.&lt;/p&gt;
&lt;p&gt;To fundamentally understand programming, I like a &amp;lsquo;barbell&amp;rsquo; strategy. One language close to the machine
and one that is very abstract:
* C (the machine)
* Haskell (the abstractions)&lt;/p&gt;
&lt;p&gt;Bonus shouts to Racket (macros), Prolog (logical programming) and Erlang (concurrency).&lt;/p&gt;
&lt;p&gt;The other languages are pragmatic compromises of the fundamental concepts that are learned
more purely with the languages above this line.&lt;/p&gt;
&lt;p&gt;F# is a good compromise between machine and abstractions and might be a good
way to kill two birds with one stone.&lt;/p&gt;
&lt;p&gt;To be productive immediately and find (easily?) remote (low?) paying jobs as web developer:
* HTML (not really a language)
* CSS (not really a language)
* Javascript&lt;/p&gt;
&lt;p&gt;Bonus shout to Typescript.&lt;/p&gt;
&lt;p&gt;To work in the corporate world for an obscene amount of money: 
* C#
* Java&lt;/p&gt;
&lt;p&gt;Bonus shouts to Powershell and Bash for automation; Rust to look cool to the hiring manager.&lt;/p&gt;
&lt;p&gt;To work as a data scientist (AI AI AI &amp;hellip;):
* Python
* C++&lt;/p&gt;
&lt;p&gt;&amp;hellip; And a good math background. Bonus shouts to R and Julia.&lt;/p&gt;
&lt;p&gt;There are fantastic books on all these languages. Everyone has his favorite.&lt;/p&gt;
&lt;p&gt;I also have no idea what is best to teach young people as I have never done it.&lt;/p&gt;
&lt;p&gt;They probably prefer to build funny stuff (i.e., games) which is not trivial with my &amp;lsquo;fundamental choices&amp;rsquo;
of C and Haskell. Compromises need to be made.&lt;/p&gt;
&lt;p&gt;I know there is a good Racket &lt;a href="https://www.amazon.com/Realm-Racket-Learn-Program-Game/dp/1593274912"&gt;book&lt;/a&gt;
along those lines. Perhaps there are others. I have not investigated the matter.&lt;/p&gt;</description>
            <pubDate>Wed, 21 Feb 2024 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2024-02-21-best-programming-languages.html</guid>
        </item>
        
        <item>
            <title>I am speaking at GoTech World in Bucharest</title>
            <link>https://www.lucabol.com/posts/2023-10-26-i-am-speaking-at-gotecc-world.html</link>
            <description>&lt;p&gt;Come and watch me &lt;a href="https://www.gotech.world/net-stage-2023-agenda"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="banner" src="/img/gotech.png" /&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 23 Oct 2023 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2023-10-26-i-am-speaking-at-gotecc-world.html</guid>
        </item>
        
        <item>
            <title>Excel Financial Functions live on</title>
            <link>https://www.lucabol.com/posts/2022-08-05-excel-financial-functions-live-on.html</link>
            <description>&lt;p&gt;I have a sweet spot for &lt;a href="https://github.com/fsprojects/ExcelFinancialFunctions"&gt;this library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I coded it the summer my daughter was born in 2008, while back in Italy for three months. It is one of my first forays into functional programming.&lt;/p&gt;
&lt;p&gt;I coded most of them with the sea in front of me. I would bet that it is one of the most Excel-compliant libraries in existence across all languages.&lt;/p&gt;
&lt;p&gt;I am happy that the tests (all 199,252 of them) still pass! This is a testament to good backward compatibility in the language.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/jcoliz"&gt;James&lt;/a&gt; for keeping it alive.&lt;/p&gt;</description>
            <pubDate>Fri, 05 Aug 2022 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2022-08-05-excel-financial-functions-live-on.html</guid>
        </item>
        
        <item>
            <title>Using Zig comptime for conceptual dryness</title>
            <link>https://www.lucabol.com/posts/2022-03-09-using-zig-comptime-for-conceptual-dryness.html</link>
            <description>&lt;p&gt;On &lt;a href="https://github.com/lucabol/Zig-Forth/tree/blog"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;While writing my C# Forth, I grew unhappy about the conceptual repetition in the code.
 To add a new Forth word, you have to add a new value to the enumerator that represents the opcode,
 add a new member to a hashtable that maps it to a string (what the user types) and finally implement the action
 for the word. See &lt;a href="https://www.lucabol.com/posts/2022-03-07-implementing-forth-dotnet/#interpreting-words"&gt;here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Granted, by using a &lt;code&gt;struct&lt;/code&gt;, I could have kept these items geographically closer, but the repetition is there.
 Using reflection, I could have removed it, but then performance would suck in the inner loop
 of my interpreter.&lt;/p&gt;
&lt;p&gt;My familiarity with the &lt;code&gt;Zig&lt;/code&gt; language made me realize that I could remove the redundancy by using
 zig&amp;rsquo;s &lt;code&gt;comptime&lt;/code&gt;, without any loss in performance. This post describes a prototype of that.&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;The idea is to have functions on my main &lt;code&gt;struct&lt;/code&gt; in the form &lt;code&gt;op_WORDNAME&lt;/code&gt;. At compile time, I
 generate the enumerator with all the opcodes and the series of conditional statements to call the right
 function &lt;code&gt;op_WORDNAME&lt;/code&gt; when the user types &lt;code&gt;WORDNAME&lt;/code&gt;. By making the functions &lt;code&gt;inline&lt;/code&gt;, I don&amp;rsquo;t even pay
 the price of a function call. BTW: Zig gives a compile-time error if it can&amp;rsquo;t inline.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;Vm&lt;/code&gt; code below, if you want to support a new word, you add a new function.
 The rest of the code is unchanged.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-zig"&gt;
const std = @import(&amp;quot;std&amp;quot;);

const Vm = struct {
    state: i32 = 0,

    inline fn op_double(this: *Vm) void {
        this.state = this.state * 2;
    }
    inline fn op_plus1(this: *Vm) void {
        this.state = this.state + 1;
    }
    inline fn op_notFound(_: *Vm) void {
        std.log.info(&amp;quot;{s}&amp;quot;, .{&amp;quot;Word not found.&amp;quot;});
    }
    inline fn op_bye(_: *Vm) void {
        std.process.exit(0);
    }
};

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The Shell Loop&lt;/h2&gt;
&lt;p&gt;This is the shell main loop. It is pretty standard stuff until you get to the innermost while loop,
 marked with (*). Even if it looks like the code is calling two functions (&lt;code&gt;findToken&lt;/code&gt; and &lt;code&gt;execToken&lt;/code&gt;),
 it isn&amp;rsquo;t. The compiler replaces these two function calls with a series of &lt;code&gt;if&lt;/code&gt; statements to match
 a string with the corresponding opcode and to find the correct function to call.&lt;/p&gt;
&lt;p&gt;Even the enumerator &lt;code&gt;Token&lt;/code&gt; is not defined anywhere in the code. It is generated automatically at compile
 time and contains one value for each &lt;code&gt;op_XXX&lt;/code&gt; function defined on &lt;code&gt;Vm&lt;/code&gt;. Even if I have not defined it,
 I can still access the values normally (i.e., see &lt;code&gt;Token.ntFound&lt;/code&gt; below).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-zig"&gt;
fn shellLoop(stdin: std.fs.File.Reader, stdout: std.fs.File.Writer) !void {
    const max_input = 1024;
    var input_buffer: [max_input]u8 = undefined;
    var vm = Vm{};

    while (true) {
        try stdout.print(&amp;quot;&amp;gt; &amp;quot;, .{});

        var input_str = (try stdin.readUntilDelimiterOrEof(input_buffer[0..], '\n')) orelse {
            try stdout.print(&amp;quot;\n&amp;quot;, .{});
            return;
        };

        if (input_str.len == 0) continue;
        var words = std.mem.tokenize(u8, input_str, &amp;quot; &amp;quot;);

        while (words.next()) |word| { // (*)
            const token = findToken(word) orelse Token.notFound;
            execToken(&amp;amp;vm, token);
        }
        std.log.info(&amp;quot;{}&amp;quot;, .{vm.state});
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Finding Tokens&lt;/h2&gt;
&lt;p&gt;So, how do we do it? Let&amp;rsquo;s start with &lt;code&gt;findToken&lt;/code&gt;. The code is relatively simple because you are not
 writing a &amp;lsquo;macro&amp;rsquo;. You are just writing normal Zig code. For .NET programmers, this is like having
 &lt;code&gt;System.Reflection&lt;/code&gt; and &lt;code&gt;System.Reflection.Emit&lt;/code&gt; available at compile time.&lt;/p&gt;
&lt;p&gt;You could do something similar
 with &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview"&gt;C# source generators&lt;/a&gt;,
 but you would need to operate on a rather complex &amp;lsquo;AST&amp;rsquo; and generate code using string concatenation. It would
 probably be dozens of lines of very intricated code. Here, it is three simple lines.&lt;/p&gt;
&lt;p&gt;An &lt;code&gt;inline for&lt;/code&gt; tells Zig to unroll the loop. The compiler iterates overa all the field of the &lt;code&gt;Enum&lt;/code&gt;
 and generates a series of &lt;code&gt;if&lt;/code&gt; statements that return the value of the &lt;code&gt;Enum&lt;/code&gt; that matches the given string
 (what the user typed).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-zig"&gt;
inline fn findToken(word: []const u8) ?Token {
    inline for (@typeInfo(Token).Enum.fields) |enField| {
        if (std.mem.eql(u8, enField.name, word))
            return @field(Token, enField.name);
    }
    return null;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Token Execution&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Token&lt;/code&gt; execution is similar. Again we unroll the loop at compile time, generating a series of &lt;code&gt;if&lt;/code&gt;
 statements that execute the &lt;code&gt;Vm&lt;/code&gt; function corresponding to the given &lt;code&gt;Token&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-zig"&gt;
inline fn execToken(vm: *Vm, tok: Token) void {
    inline for (@typeInfo(Token).Enum.fields) |enField| {
        const enumValue = @field(Token, enField.name);
        if (enumValue == tok) {
            const empty = .{};
            _ = @call(empty, @field(Vm, &amp;quot;op_&amp;quot; ++ @tagName(enumValue)), .{vm});
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Token Generation&lt;/h2&gt;
&lt;p&gt;We generate the &lt;code&gt;Token&lt;/code&gt; enumerator by iterating over all the declarations on the &lt;code&gt;Vm&lt;/code&gt; struct and
 generating a set of declarations that are then use to compile time construct the correct &lt;code&gt;Enum&lt;/code&gt; using
 the &lt;code&gt;@Type&lt;/code&gt; builtin function.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-zig"&gt;
const Token = GenerateTokenEnumType(Vm);

fn GenerateTokenEnumType(comptime T: type) type {
    const fieldInfos = std.meta.declarations(T);
    var enumDecls: [fieldInfos.len]std.builtin.TypeInfo.EnumField = undefined;
    var decls = [_]std.builtin.TypeInfo.Declaration{};
    inline for (fieldInfos) |field, i| {
        const name = field.name;
        if (name[0] == 'o' and name[1] == 'p') {
            enumDecls[i] = .{ .name = field.name[3..], .value = i };
        }
    }
    return @Type(.{
        .Enum = .{
            .layout = .Auto,
            .tag_type = u8,
            .fields = &amp;amp;enumDecls,
            .decls = &amp;amp;decls,
            .is_exhaustive = true,
        },
    });
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Assembly Output&lt;/h2&gt;
&lt;p&gt;Ok, but does it really work? Well, you can run it with &lt;code&gt;zig build run&lt;/code&gt;, but it is really inlining
 correctly? Well, the assembly language says yes. No calls to external functions in the main loop.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-assembly"&gt; const token = findToken(word) orelse Token.notFound;
 2310db: f6 85 a1 fa ff ff 01 testb $0x1,-0x55f(%rbp)
 2310e2: 75 09 jne 2310ed &amp;lt;shellLoop+0x38d&amp;gt;
 2310e4: c6 85 9f fa ff ff 02 movb $0x2,-0x561(%rbp)
 2310eb: eb 0c jmp 2310f9 &amp;lt;shellLoop+0x399&amp;gt;
 2310ed: 8a 85 a0 fa ff ff mov -0x560(%rbp),%al
 2310f3: 88 85 9f fa ff ff mov %al,-0x561(%rbp)
 home/lucabol/dev/zig-forth/src/main.zig:65
 execToken(&amp;amp;vm, token);
 2310f9: 8a 85 9f fa ff ff mov -0x561(%rbp),%al
 2310ff: 48 8d 8d 58 fb ff ff lea -0x4a8(%rbp),%rcx
 231106: 48 89 4d d8 mov %rcx,-0x28(%rbp)
 23110a: 88 45 d7 mov %al,-0x29(%rbp)
 execToken():
 home/lucabol/dev/zig-forth/src/main.zig:32
 if (enumValue == tok) {
 23110d: 31 c0 xor %eax,%eax
 23110f: 3a 45 d7 cmp -0x29(%rbp),%al
 231112: 75 50 jne 231164 &amp;lt;shellLoop+0x404&amp;gt;
 home/lucabol/dev/zig-forth/src/main.zig:34
 _ = @call(empty, @field(Vm, &amp;quot;op_&amp;quot; ++ @tagName(enumValue)), .{vm});
 231114: 48 8b 45 d8 mov -0x28(%rbp),%rax
 231118: 48 89 45 e0 mov %rax,-0x20(%rbp)
 Vm.op_double():
 home/lucabol/dev/zig-forth/src/main.zig:7
 this.state = this.state * 2;
 23111c: 48 8b 45 e0 mov -0x20(%rbp),%rax
 231120: 48 89 85 58 fa ff ff mov %rax,-0x5a8(%rbp)
 231127: 48 8b 4d e0 mov -0x20(%rbp),%rcx
 23112b: b8 02 00 00 00 mov $0x2,%eax
 231130: 0f af 01 imul (%rcx),%eax
 231133: 89 85 60 fa ff ff mov %eax,-0x5a0(%rbp)
 231139: 0f 90 c0 seto %al
 23113c: 70 02 jo 231140 &amp;lt;shellLoop+0x3e0&amp;gt;
 23113e: eb 13 jmp 231153 &amp;lt;shellLoop+0x3f3&amp;gt;
 231140: 48 bf 68 1f 20 00 00 00 00 00 movabs $0x201f68,%rdi
 23114a: 31 c0 xor %eax,%eax
 23114c: 89 c6 mov %eax,%esi
 23114e: e8 fd 32 fd ff callq 204450 &amp;lt;std.builtin.default_panic&amp;gt;
 231153: 48 8b 85 58 fa ff ff mov -0x5a8(%rbp),%rax
 23115a: 8b 8d 60 fa ff ff mov -0x5a0(%rbp),%ecx
 231160: 89 08 mov %ecx,(%rax)
 execToken():
 home/lucabol/dev/zig-forth/src/main.zig:32
 if (enumValue == tok) {
 231162: eb 02 jmp 231166 &amp;lt;shellLoop+0x406&amp;gt;
 231164: eb 00 jmp 231166 &amp;lt;shellLoop+0x406&amp;gt;
 231166: b0 01 mov $0x1,%al
 231168: 3a 45 d7 cmp -0x29(%rbp),%al
 23116b: 75 4c jne 2311b9 &amp;lt;shellLoop+0x459&amp;gt;
 home/lucabol/dev/zig-forth/src/main.zig:34
 _ = @call(empty, @field(Vm, &amp;quot;op_&amp;quot; ++ @tagName(enumValue)), .{vm});
 23116d: 48 8b 45 d8 mov -0x28(%rbp),%rax
 231171: 48 89 45 e8 mov %rax,-0x18(%rbp)
 Vm.op_plus1():
 home/lucabol/dev/zig-forth/src/main.zig:10
 this.state = this.state + 1;
 231175: 48 8b 45 e8 mov -0x18(%rbp),%rax
 231179: 48 89 85 48 fa ff ff mov %rax,-0x5b8(%rbp)
 231180: 48 8b 45 e8 mov -0x18(%rbp),%rax
 231184: 8b 00 mov (%rax),%eax
 231186: ff c0 inc %eax
 231188: 89 85 54 fa ff ff mov %eax,-0x5ac(%rbp)
 23118e: 0f 90 c0 seto %al
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, more directly, see below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-asm"&gt; return @field(Token, enField.name);
 230ff0: c6 85 a1 fa ff ff 01 movb $0x1,-0x55f(%rbp)
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 230ff7: c6 85 a0 fa ff ff 00 movb $0x0,-0x560(%rbp)
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 230ffe: e9 d8 00 00 00 jmpq 2310db &amp;lt;shellLoop+0x37b&amp;gt;
 home/lucabol/dev/zig-forth/src/main.zig:24
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 if (std.mem.eql(u8, enField.name, word))
 231003: 48 8b 85 a8 fa ff ff mov -0x558(%rbp),%rax
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 23100a: 48 89 45 b0 mov %rax,-0x50(%rbp)
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 23100e: 48 8b 85 b0 fa ff ff mov -0x550(%rbp),%rax
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 231015: 48 89 45 b8 mov %rax,-0x48(%rbp)
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 231019: 48 bf e0 2a 20 00 00 00 00 00 movabs $0x202ae0,%rdi
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 231023: 48 8d b5 a8 fa ff ff lea -0x558(%rbp),%rsi
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 23102a: e8 61 ac fd ff callq 20bc90 &amp;lt;std.mem.eql&amp;gt;
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 23102f: a8 01 test $0x1,%al
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 231031: 75 02 jne 231035 &amp;lt;shellLoop+0x2d5&amp;gt;
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 231033: eb 13 jmp 231048 &amp;lt;shellLoop+0x2e8&amp;gt;
 home/lucabol/dev/zig-forth/src/main.zig:25
 inlined by /home/lucabol/dev/zig-forth/src/main.zig:64 (shellLoop)
 return @field(Token, enField.name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the driver is obvious.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-zig"&gt;
pub fn main() !u8 {
    const stdin = std.io.getStdIn().reader();
    const stdout = std.io.getStdOut().writer();
    try stdout.print(&amp;quot;*** Hello, I am a Forth shell! ***\n&amp;quot;, .{});

    try shellLoop(stdin, stdout);

    return 0; // We either crash or we are fine.
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Wed, 09 Mar 2022 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2022-03-09-using-zig-comptime-for-conceptual-dryness.html</guid>
        </item>
        
        <item>
            <title>Horchata</title>
            <link>https://www.lucabol.com/posts/2022-03-09-horchata.html</link>
            <description>&lt;p&gt;&lt;img src="/img/horchata.jpg" alt="house overlooking highway" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;Here is a house on a hill overlooking the highway. Behind that, the sea. The old couple sits on the terrace, watching the traffic snake by. In all these years, they have seen a lot. There have been accidents, a police chase, a shooting even. Once a horse wandered on the road.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I want a piece of all that life,&amp;rdquo; says the old man. His name is Pedro and he has the heart of a child. He goes down to the garage and builds a big wooden sign that says &amp;ldquo;Horchata.&amp;rdquo; His wife rolls her eyes. Her name is Maite and she is very patient.&lt;/p&gt;
&lt;p&gt;The next day, they wake up early. Maite grinds the almonds and mixes the sugar while Pedro puts up the sign. They wait.&lt;/p&gt;
&lt;p&gt;People come—first families, then the big trucks. Word goes around and lines start to form. They are longer every day.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not just the horchata. Maite sings sometimes. She has the voice of a hummingbird, but you have to coax it out of her. She is too shy. Pedro talks to the men about sports and politics. He has a lot of opinions.&lt;/p&gt;
&lt;p&gt;But it is mainly the horchata that does it. The sea air gives it flavor. A drop of whisky makes it unique.&lt;/p&gt;
&lt;p&gt;The day batch finishes in the early mornings. The customers don&amp;rsquo;t like that and honk their horns to tell the others back in the line. Pedro&amp;rsquo;s heart sinks. He goes back to the garage and builds another sign that says: &amp;ldquo;se acabo&amp;rdquo; - it is finished. They put the sign up every late morning to avoid people getting out of the highway for nothing.&lt;/p&gt;
&lt;p&gt;The line of customers starts forming earlier every day. Some sleep the night in line. Pedro brings them coffee in the morning. He feels guilty it has come to that.&lt;/p&gt;
&lt;p&gt;They need to increase production - he reasons. But Maite has just two hands and there is just one almond tree. So he puts more water in it. And then some more. He also lowers the price because he is an honest man. The lines get even longer. They still honk when the sign comes up.&lt;/p&gt;
&lt;p&gt;Now Maite wants a vacation. She is tired of all the grinding. She doesn&amp;rsquo;t even like almonds and she is getting addicted to sugar and whisky. Her voice slurs when she sings.&lt;/p&gt;
&lt;p&gt;Pedro has an idea. He gets a copyright on the name &amp;ldquo;Maite&amp;rsquo;s horchata&amp;rdquo; and goes and talks to all the bars in town. He lets them use the name and the recipe but takes a percentage of the sales. Maite is a brand.&lt;/p&gt;
&lt;p&gt;Sales skyrocket. Some bars don&amp;rsquo;t follow the recipe, but Pedro is on their case and makes sure quality is preserved. The couple still lives in the house on the hill, but now it is bigger. It got a sign that says: &amp;ldquo;The original Maite.&amp;rdquo; They have people making the horchata now. They get the almonds from Marocco. Pedro doesn&amp;rsquo;t talk to customers anymore. Maite doesn&amp;rsquo;t sing. Her voice is not what it used to be.&lt;/p&gt;
&lt;p&gt;And big money comes. They can go national, but they have to change the recipe. You see, almonds are too expensive and whiskey is a no-no. They use caramel and more sugar instead.&lt;/p&gt;
&lt;p&gt;Maite is a celebrity now. She got her face on all these cans. She is always on TV. She tries to sing, but her voice comes out funny. It is all these parties she has to go to. The music is too loud and the smoke gets in her lungs.&lt;/p&gt;
&lt;p&gt;Pedro enjoys the attention. He buys a fancy car and drives Maite around town to her appointments. He wears shoes made with crocodile skin and they are very pointy. He talks loud and drinks a lot. Sometimes he falls asleep in the car parked in the driveway to their new villa.&lt;/p&gt;
&lt;p&gt;The house on the hill is a museum. They have photos of how things were when it all started. The lines of trucks outside; Maite grinding almonds; Pedro building the big sign.&lt;/p&gt;
&lt;p&gt;One night they go to a movie premiere. In the car, they talk about their good luck. Sure there are problems: they are busy, always running around. They are tired. They drink too much. But look at what they have!&lt;/p&gt;
&lt;p&gt;And they look. And they look &amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;hellip; and find nothing of importance.&lt;/p&gt;
&lt;p&gt;If you come up the road to the house, you better come up quietly. Don&amp;rsquo;t make a fuss of it. When you are up on the terrace, don&amp;rsquo;t make a sound. You might catch Maite singing as she goes about her business. You might wake up Pedro. He will be happy to see you. He enjoys the occasional chat about sport and politics. He has lots of opinions.&lt;/p&gt;
&lt;p&gt;In the garden, here is the almond tree. Down below snakes the highway. Behind that, the sea.&lt;/p&gt;</description>
            <pubDate>Wed, 09 Mar 2022 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2022-03-09-horchata.html</guid>
        </item>
        
        <item>
            <title>Implementing Forth.Net</title>
            <link>https://www.lucabol.com/posts/2022-03-07-implementing-forth-dotnet.html</link>
            <description>&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;This is a Forth for the .NET framework in one cs file. It is a token threaded implementation that can save its status to a very concise binary format.
Feel free to reuse this code as you wish.&lt;br /&gt;
 ## How to use it
Simply copy this file or reference the nuget package &lt;code&gt;Forth.Net&lt;/code&gt; in your project. This is the public interface:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Vm {
    public Vm( ... sizes of memory areas ...);

    public Func&amp;lt;string&amp;gt;? NextLine;
    public void Quit();

    public void EvaluateSingleLine   (string forthLine);
    public void EvaluateMultipleLines(string forthLines);

    public bool Debug;
    public void Reset();

    public IEnumerable&amp;lt;string&amp;gt; Words;
    public string StackString();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You set &lt;code&gt;NextLine&lt;/code&gt; to tell Forth where to get the next line of input from. &lt;code&gt;Quit&lt;/code&gt; starts the interpretation. &lt;code&gt;EvaluateSingleLine&lt;/code&gt; and &lt;code&gt;EvaluateMultipleLines&lt;/code&gt; are utility functions.
You can write them yourself with &lt;code&gt;NextLine&lt;/code&gt; and &lt;code&gt;Quit&lt;/code&gt;. The rest should be self explanatory.&lt;/p&gt;
&lt;p&gt;## Preliminaries
The ambition was to write a Forth that can be recompiled for 32 or 64 bits. I just tested the 64 bits part.
The rest is just standard &lt;code&gt;using&lt;/code&gt; stuff that I can&amp;rsquo;t move to a &lt;code&gt;global.cs&lt;/code&gt; file because I want to be able to simply copy
this cs file to a project and have my Forth there.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;#if CELL32
using Cell      = System.Int32;
using Index     = System.Int32;
#else
using Cell      = System.Int64;
using Index     = System.Int32;
#endif

using Code    = System.Byte;
using AUnit   = System.Byte;
using AChar   = System.Byte;

using System.Text;
using System.Runtime.CompilerServices;
using System.Buffers.Binary;

using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using static Forth.Utils;

[assembly:InternalsVisibleTo(&amp;quot;Forth.Net.Tests&amp;quot;)]

namespace Forth;

public class Vm {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## The outer interpret
In Forth everything starts at &lt;code&gt;Quit&lt;/code&gt;. Yep. It is the line interpreter. It reads a line (with &lt;code&gt;Refill&lt;/code&gt;) and interprets it. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public void Quit()
    {
        rp = 0; Executing = true; ds[inp] = 0; // Don't reset the parameter stack as for ANS FORTH definition of QUIT.

        while(true)
        {
            Refill();
            if(Pop() != FORTH_TRUE) return;
            Interpret();
        }
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then comes the word interpret. It tries to interpret the text between spaces first as a word, then as a number &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void Interpret()
    {
        while(true)
        {
            Bl();
            Word(inKeyword: true);
            if(IsEmptyWord()) { Drop(); break;};

            // TODO: remove string allocation from main loop. It is not trivial to do, because some functions inside InterpretWord rely on it.
            Dup();
            var aword = ToDotNetStringC().ToLowerInvariant();

            if(InterpretWord(aword)) continue;

            if(TryParseNumber(aword, out Cell n))
                InterpretNumber(n);
            else
                Throw($&amp;quot;{aword} is not a recognized word or number.&amp;quot;);
        }
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## Interpreting numbers 
 Let&amp;rsquo;s tackle parsing the number first. In Forth you can express numbers in different basis. We use the standard .NET conversion
        functions here, but those support just a few basis and throw exceptions on failure (bad design). We could consider writing our own to support all basis.
        Also the code can be compiled for 32 bits cell size and maybe it works. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    bool TryParseNumber(string s, out Cell n)
    {
        var b = ds[basep];

        try {
#if CELL32
            n = Convert.ToInt32(s, b);
#else
            n = Convert.ToInt64(s, b);
#endif
            return true;
        } catch (FormatException )
        {
            // This is not actually an exception case in Forth.
            n = 0;    

        } catch(OverflowException)
        {
            throw;
        }
        return false;
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we can parse a number, we can interpret it. This is a token interpreter. Word as described as tokens of various kind. You are either executing
        a token, or compiling it inside of another word (i.e., when using the defining word &lt;code&gt;:&lt;/code&gt;). &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void InterpretNumber(Cell value)
    {
        if(Executing)
            Execute(Token.Numb, value);
        else
            PushOp(Token.Numb, value);
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Executing a token is a bit complicated. Let&amp;rsquo;s look first at compiling it. Compilation in this model means adding a token on top of the data stack.
        In Forth, the data stack is where user defined words live and we are in the middle of defining one. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void PushOp(Token op) {
        ds[herep] = (Code)op;
        herep++;
    }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes tokens have parameters. If they have a numeric one, we encode it so to minimize the overall size both in memory (for cache sake) and on disk.
        For that we use the &lt;a href="https://www.nuget.org/packages/GitVarInt/"&gt;GitVarInt&lt;/a&gt; library. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void PushOp(Token op, Cell value)
    {
        PushOp(op);
        Write7BitEncodedCell(ds, herep, value, out var howMany);
        herep += howMany;
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## Interpreting words &lt;/p&gt;
&lt;p&gt;Now that we know how to compile numbers and that it exists a magic function that executes tokens, we can go back and look at interpreting words.
In this implementation, words are separated in user defined words, primitives and immediate primitive. This is likely a bad design brought about
by a desire of optimize prematurely. There should be an unified representation.&lt;/p&gt;
&lt;p&gt;The logic is still relatively simple. If it is a user defined word, execute/compile a call token with its address. If it is a primitive,
execute/compile the corresponding token. If it is an immediate primitive, execute the code associated with it.&lt;/p&gt;
&lt;p&gt;It is awkward that finding the user defined word relies on parameters on the stack, while the other cases use a .net string representation to find
the token in an hash table. Apart from style, this is an irritating allocation in the main loop that could be optimized away with some work.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    bool InterpretWord(string aword)
    {
        LowerCase();
        FindUserDefinedWord();

        var found   = Pop();
        var xt      = (Index)Pop();

        // Manage user defined word.
        if(found != FORTH_FALSE)
        {
            var immediate = found == 1; // There can be user defined immediate functions.
            if(Executing || immediate)
                Execute(Token.Call, xt);
            else
                PushOp(Token.Call, xt);
            return true;
        }
        // Manage simple primitives.
        if(WordToSimpleOp.TryGetValue(aword, out var op))
        {
            if(Executing)
                Execute(op, null);
            else
                PushOp(op);
            return true;
        }
        // Manage immediate primitives.
        if(ImmediatePrimitives.TryGetValue(aword, out var immediateWord))
        {
            immediateWord.Item2();
            return true;
        }
        return false;
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Simple primitives map a word with the token defining it. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    readonly Dictionary&amp;lt;string, Token&amp;gt; WordToSimpleOp = new()
    {
        { &amp;quot;.&amp;quot;           , Token.Prin },
        { &amp;quot;count&amp;quot;       , Token.Count },
        { &amp;quot;words&amp;quot;       , Token.Words },
        { &amp;quot;testsys&amp;quot;     , Token.TestSys },
        { &amp;quot;cells&amp;quot;       , Token.Cells },
        { &amp;quot;allot&amp;quot;       , Token.Allot },
        { &amp;quot;and&amp;quot;         , Token.And },
        { &amp;quot;or&amp;quot;          , Token.Or },
        { &amp;quot;base&amp;quot;        , Token.Base },
        { &amp;quot;refill&amp;quot;      , Token.Refill },
        { &amp;quot;interpret&amp;quot;   , Token.Interpret },
        { &amp;quot;quit&amp;quot;        , Token.Quit },
        { &amp;quot;word&amp;quot;        , Token.Word },
        { &amp;quot;parse&amp;quot;       , Token.Parse },
        { &amp;quot;save&amp;quot;        , Token.Save },
        { &amp;quot;load&amp;quot;        , Token.Load },
        { &amp;quot;savesys&amp;quot;     , Token.SaveSys },
        { &amp;quot;loadsys&amp;quot;     , Token.LoadSys },
        { &amp;quot;included&amp;quot;    , Token.Included },
        { &amp;quot;,&amp;quot;           , Token.Comma },
        { &amp;quot;c,&amp;quot;          , Token.CComma },
        { &amp;quot;here&amp;quot;        , Token.Here },
        { &amp;quot;@&amp;quot;           , Token.At },
        { &amp;quot;c@&amp;quot;          , Token.CAt },
        { &amp;quot;pad&amp;quot;         , Token.Pad },
        { &amp;quot;!&amp;quot;           , Token.Store },
        { &amp;quot;state&amp;quot;       , Token.State },
        { &amp;quot;bl&amp;quot;          , Token.Bl },
        { &amp;quot;:&amp;quot;           , Token.Colo },
        { &amp;quot;bye&amp;quot;         , Token.Bye },
        { &amp;quot;.s&amp;quot;          , Token.DotS },
        { &amp;quot;+&amp;quot;           , Token.Plus },
        { &amp;quot;-&amp;quot;           , Token.Minu },
        { &amp;quot;*&amp;quot;           , Token.Mult },
        { &amp;quot;/&amp;quot;           , Token.Divi },
        { &amp;quot;&amp;lt;&amp;quot;           , Token.Less },
        { &amp;quot;&amp;gt;&amp;quot;           , Token.More },
        { &amp;quot;=&amp;quot;           , Token.Equal },
        { &amp;quot;&amp;lt;&amp;gt;&amp;quot;          , Token.NotEqual },
        { &amp;quot;create&amp;quot;      , Token.Create },
        { &amp;quot;does&amp;gt;&amp;quot;       , Token.Does },
        { &amp;quot;&amp;gt;body&amp;quot;       , Token.Body },
        { &amp;quot;rdepth&amp;quot;      , Token.RDepth },
        { &amp;quot;swap&amp;quot;        , Token.Swap },
        { &amp;quot;depth&amp;quot;       , Token.Depth },
        { &amp;quot;over&amp;quot;        , Token.Over },
        { &amp;quot;dup&amp;quot;         , Token.Dup },
        { &amp;quot;dup2&amp;quot;        , Token.Dup2 },
        { &amp;quot;drop&amp;quot;        , Token.Drop },
        { &amp;quot;drop2&amp;quot;       , Token.Drop2 },
        { &amp;quot;*/mod&amp;quot;       , Token.MulDivRem },
        { &amp;quot;invert&amp;quot;      , Token.Invert },
        { &amp;quot;exit&amp;quot;        , Token.Exit },
        { &amp;quot;i&amp;quot;           , Token.I },
        { &amp;quot;j&amp;quot;           , Token.J },
        { &amp;quot;&amp;gt;r&amp;quot;          , Token.ToR },
        { &amp;quot;r&amp;gt;&amp;quot;          , Token.FromR },
        { &amp;quot;leave&amp;quot;       , Token.Leave },
        { &amp;quot;immediate&amp;quot;   , Token.Immediate },
        { &amp;quot;source&amp;quot;      , Token.Source },
        { &amp;quot;type&amp;quot;        , Token.Type },
        { &amp;quot;emit&amp;quot;        , Token.Emit },
        { &amp;quot;cr&amp;quot;          , Token.Cr },
        { &amp;quot;char&amp;quot;        , Token.Char },
        { &amp;quot;&amp;gt;in&amp;quot;         , Token.In },
        { &amp;quot;find&amp;quot;        , Token.Find },
        { &amp;quot;execute&amp;quot;     , Token.Exec },
        { &amp;quot;.net&amp;gt;type&amp;quot;   , Token.DType },
        { &amp;quot;.net&amp;gt;method&amp;quot; , Token.DMethod },
        { &amp;quot;.net&amp;gt;call&amp;quot;   , Token.DCall },
    };


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other hand, immediate actions need to be executed at compile time when their token is encountered.
        This is indexed by the string word, which is what we see in the interpreter. But later I discovered the need
        to index it by operator as well, so I bolted it on as a tuple. We&amp;rsquo;ll look in more depth at how they work later. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    readonly Dictionary&amp;lt;string, (Token, Action)&amp;gt; ImmediatePrimitives = new();


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;User defined words are stored in the data space as a linked list. Each word is in the format:
        -&amp;gt; Cell   &amp;lt;-&amp;gt; One Byte &amp;lt;-&amp;gt; Bytes    &amp;lt;-&amp;gt; Bytes
        | Next Link|  Len Word  | Word chars | Tokens |
        This function follow the links, staring at &lt;code&gt;dictHead&lt;/code&gt;, until it finds the word on top of the parameter stack.
        As an optimization, the length field uses the higher bit to store if the word is an immediate one (save one byte, save the planet). &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    internal void FindUserDefinedWord()
    {
        var caddr = (Index)Pop();
        var clen  = ds[caddr];
        var cspan = new Span&amp;lt;AChar&amp;gt;(ds, caddr + 1 * CHAR_SIZE, clen);

        var dp = dictHead;

        while(true)
        {
            if(dp == 0) break;

            var wordNameStart = dp + CELL_SIZE;
            var wordLenRaw    = ds[wordNameStart];
            var wordLen       = Utils.ResetHighBit(wordLenRaw); // Resets the high bit, so we get the real length.
            var wordSpan      = new Span&amp;lt;AChar&amp;gt;(ds, wordNameStart + 1 * CHAR_SIZE, wordLen);
            var found         = cspan.SequenceEqual(wordSpan);
            if(found)
            {
                Push(LinkToCode(dp, wordLen));                
                var isImmediate = Utils.HighBitValue(wordLenRaw) == 1;
                Push( isImmediate ? 1 : -1);
                return;
            }
            dp = (Index)ReadCell(ds, dp);
        }
        // Not found
        Push(caddr);
        Push(0);
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These functions abstract out the details of the word structure. At least that was the idea. In practice that knowledge has leaked
        in other parts of the code base. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static Index LinkToCode(Index link, Index wordLen)
        // Addr + Link size + len size  + word chars
        =&amp;gt; link + CELL_SIZE + CHAR_SIZE + CHAR_SIZE * wordLen;

    static Index LinkToLen(Index link) =&amp;gt; link + CELL_SIZE;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## Memory organization 
 As we touched on the internal memory organization, it might now be time to describe it in more detail. Firstly the data space, parameter stack and
        return stack are represented as arrays of bytes. Some notes:
        * In Forth, you can access the stacks as Cells or bytes. I choose the lower denominator to simplify things.
        * I didn&amp;rsquo;t use the .NET &lt;code&gt;Stack&lt;/code&gt; class because it doesn&amp;rsquo;t let you easily index into it.
        * One could use &lt;code&gt;unsafe&lt;/code&gt; and pointers to avoid checking boundaries at each access, but then you could use the library just from unsafe code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    Index sp     = 0;                   // Top of parameter stack.
    Index rp     = 0;                   // Top for return stack.
    Index herep  = 0;                   // Top of data space.
    AUnit[] ps;                         // Parameter stack.
    AUnit[] rs;                         // Return stack.
    AUnit[] ds;                         // Data space.


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then come some pointers that map areas in the data space that are used by the system or point to some system cells.
        They get initialized in the Vm constructor. Also, some other random state used by the system. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    Index dictHead;                     // The last word added to the dictionary.

    readonly Index source;              // Input buffer.
    readonly Index inp;                 // Points char number (0...source_max_chars) to be read in the input buffer.
    readonly Index inputBufferSize;     // Size of the input buffer.
    readonly Index keyWord;             // Word read by the interpreter.
    readonly Index word;                // Text read by the Forth word `word`. It needs to be separated from keyWord, so as to not conflict.
    readonly Index wordBufferSize;      // Size of the `word` and `keyword` buffer.
    readonly Index pad;                 // Pad area. A temporary area usable by the user.
    readonly Index dotnetStrings;       // Area used to store string parameters passed from dotnet to Forth. 
    readonly Index code;                // Each token needs to be stored in the data space before execution, so that the instruction pointer can work.
    readonly Index basep;               // Store base for numbers.
    readonly Index state;               // Are we compiling or interpreting? See `Executing` below.
    readonly Index userStart;           // Start of the user part of the data space. `Save` starts saving from here.
    readonly Index savedDictHead;       // Used by `save` and `load` to fetch the index of the last word in the dictionary.

    Index input_len_chars = 0;          // How many chars in the input buffer.

    bool Executing { get =&amp;gt; ReadCell (ds, state) == FORTH_FALSE;
                     set =&amp;gt; WriteCell(ds, state, value ? FORTH_FALSE : FORTH_TRUE);}

    public bool Debug { get ; set; }    // Doesn't do much as of now, but we can extend it to print out a lot of useful thins (i.e., token disassembly).


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I decided for the system to use UTF8 internally to save space, despite .NET running on a &amp;lsquo;kind of&amp;rsquo; UTF16. I convert at the boundary.
        A cell can be either 64 bits or 32 bits. I have not tested the latter. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    internal const Index CHAR_SIZE = 1;
    internal const Index CELL_SIZE = sizeof(Cell);

    const Cell FORTH_TRUE  = -1;
    const Cell FORTH_FALSE = 0;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is very important. By setting this field you can get the interpret to read the next line of text from wherever (typically Console or file). &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public Func&amp;lt;string&amp;gt;? NextLine = null;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These cache the last dotnet type and method, so that you can call multiple methods on the same type ergonomically. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    Type lastType = typeof(Console);
    MethodInfo? lastMethod;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s see how the pointers are initialized. First some debatable defaults for the most important
        data source areas. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public Vm(
        Index parameterStackSize =  16 * 1_024,
        Index returnStackSize    =  16 * 1_024,
        Index dataStackSize      = 256 * 1_024,
        Index padSize            =       1_024,
        Index sourceSize         =       1_024,
        Index wordSize           =       1_024
        ) {


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are the arrays storing the three most important memory areas. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        ps   = new AUnit[parameterStackSize];
        rs   = new AUnit[returnStackSize];
        ds   = new AUnit[dataStackSize];


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we initialize all the pointers &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        inputBufferSize  = sourceSize;
        wordBufferSize   = wordSize;

        code             = herep;
        herep           += CHAR_SIZE + CELL_SIZE; // Maximum size of an instruction.

        keyWord          = herep;
        herep           += wordSize * CHAR_SIZE;
        source           = herep;
        herep           += sourceSize * CHAR_SIZE;

        word             = herep;
        herep           += wordSize * CHAR_SIZE;

        pad              = herep;
        herep           += padSize;

        basep            = herep;
        herep           += CELL_SIZE;
        ds[basep]        = 10;

        dotnetStrings    = herep;
        herep           += 256 * Vm.CHAR_SIZE;

        inp              = herep;
        herep           += CELL_SIZE;

        state            = herep;
        herep           += CELL_SIZE;

        userStart        = herep;
        savedDictHead    = herep;
        herep           += CELL_SIZE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This table contains the immediate primitive words. These words are executed at compile time.
The management of conditionals and loop constructs is messy.&lt;/p&gt;
&lt;p&gt;Take the &lt;code&gt;if&lt;/code&gt; statement, at the point where the interpret encounters it, it doesn&amp;rsquo;t yet know
where it has to jump to in case the condition is not satisfied.
It embeds a &amp;lsquo;conditional&amp;rsquo; branching instruction, leaving two bytes
empty for the branching target. It also pushes the address of the empty bytes.
When the interpret encounters &lt;code&gt;else&lt;/code&gt; or &lt;code&gt;then&lt;/code&gt;, it backfill those empty bytes with
the right value so that the branch instruction jumps to the correct point.&lt;/p&gt;
&lt;p&gt;Other flow control structures behave similarly. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        ImmediatePrimitives = new()
        {
            { &amp;quot;debug&amp;quot;,      (Token.IDebug,     () =&amp;gt; Debug = !Debug) },
            { &amp;quot;[char]&amp;quot;,     (Token.IChar,      () =&amp;gt; { Char(); PushOp(Token.Numb, Pop());}) },
            { &amp;quot;literal&amp;quot;,    (Token.ILiteral,   () =&amp;gt; { PushOp(Token.Numb, Pop());}) },
            { &amp;quot;sliteral&amp;quot;,   (Token.ISLit,      EmbedSString(Token.ISLit)) },
            { &amp;quot;[&amp;quot;,          (Token.IBrakO,     () =&amp;gt; Executing = true) },
            { &amp;quot;]&amp;quot;,          (Token.IBrakC,     () =&amp;gt; Executing = false) },
            { &amp;quot;;&amp;quot;,          (Token.ISemi,      () =&amp;gt; { PushOp(Token.Exit);  Executing = true; }) },
            { &amp;quot;postpone&amp;quot;,   (Token.IPostCall,  Postpone) },
            { &amp;quot;begin&amp;quot;,      (Token.IBegin,     () =&amp;gt; Push(herep)) },
            { &amp;quot;do&amp;quot;,         (Token.IDo,        () =&amp;gt; { PushOp(Token.Do); herep += CELL_SIZE; Push(herep); }) },
            { &amp;quot;loop&amp;quot;,       (Token.ILoop,      EmbedHereJmp0Bck)},
            { &amp;quot;+loop&amp;quot;,      (Token.ILoopP,     EmbedHereJmp0BckP)},
            { &amp;quot;again&amp;quot;,      (Token.IAgain,     EmbedHereJmpBck)},    
            { &amp;quot;if&amp;quot;,         (Token.IIf,        BranchAndMark) },
            { &amp;quot;else&amp;quot;,       (Token.IElse,      EmbedInPoppedJmpFwd)  },    
            { &amp;quot;then&amp;quot;,       (Token.IThen,      () =&amp;gt; {
                var mark = (Index)Pop();
                short delta = (short)(herep - mark);
                WriteInt16(ds, mark, delta);
            }) },
            { &amp;quot;while&amp;quot;,      (Token.IWhile,     BranchAndMark) },    
            { &amp;quot;repeat&amp;quot;,     (Token.IRepeat,    () =&amp;gt; {
                var whileMark = (Index)Pop();
                short delta   = (short)(herep + 3 - whileMark);
                WriteInt16(ds, whileMark, delta);
                EmbedHereJmpBck();
                }) },
            { &amp;quot;c\&amp;quot;&amp;quot;,         (Token.ICStr,     EmbedString(Token.ICStr)) },
            { &amp;quot;s\&amp;quot;&amp;quot;,         (Token.ISStr,     EmbedString(Token.ISStr)) },
        };


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After everything is set up, we can now load the initialization files. In Forth, normally 
a good part of the interpret is written in Forth itself. Implementations vary with regard to
how many instructions are primitives. The obvious trade-offs apply.&lt;/p&gt;
&lt;p&gt;Here we try to load from a binary file first, if present.&lt;/p&gt;
&lt;p&gt;So, that was the idea, at least. In practice I got tired of trying to figure out where such a file should live to be
included correctly by the dll in all scenarios. So embedded as a constant instead. It also good so that you can just
copy this single file in a project and be done.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        EvaluateMultipleLines(INIT_FORTH);
        /*
        if(File.Exists(&amp;quot;init.io&amp;quot;))
        {
            FromDotNetString(&amp;quot;init.io&amp;quot;);
            LoadSystem(true);
        } else if(File.Exists(&amp;quot;init.fth&amp;quot;)) {
            FromDotNetString(&amp;quot;init.fth&amp;quot;);
            Included();
        } else
        {
            Console.WriteLine(&amp;quot;No init file loaded.&amp;quot;);
        }
        */

        Reset();
    }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our token based interpret, loading and saving the system is a trivial operation. Just copy the bytes. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void SaveSystem(bool all = false)
    {
        var start = all ? 0 : userStart ;
        WriteCell(ds, savedDictHead, dictHead);

        var fileName = ToDotNetString();
        File.WriteAllBytes(fileName, ds[start .. herep]);
        Console.WriteLine($&amp;quot;Saved in file {Path.Join(Environment.CurrentDirectory, fileName)} .&amp;quot;);
    }
    void LoadSystem(bool all = false)
    {
        var start = all ? 0 : userStart ;
        var fileName = ToDotNetString();
        var buf      = File.ReadAllBytes(fileName);
        buf.CopyTo(ds, start);

        dictHead = (Index)ReadCell(ds, savedDictHead);
        herep = buf.Length;
        Console.WriteLine($&amp;quot;Loaded from file {Path.Join(Environment.CurrentDirectory, fileName)}&amp;quot;);
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## Executing words &lt;/p&gt;
&lt;p&gt;With all of that under our belt, we can now look at &lt;code&gt;Execute&lt;/code&gt;. This is &lt;code&gt;switch threaded&lt;/code&gt;.
It could be written as a table of &lt;code&gt;Token&lt;/code&gt; to &lt;code&gt;Action&lt;/code&gt;, but then I would lose possible
performance tricks that the compiler can play to speed it up (i.e., using function pointers).&lt;/p&gt;
&lt;p&gt;It is a giant &lt;code&gt;do ... while&lt;/code&gt; loop of getting the Token at the instruction pointer and performing
the associated action. The action might change the instruction pointer (i.e., jumps), so when
we get back to the top of the loop, we might be executing at a very different &lt;code&gt;ip&lt;/code&gt; from where started.&lt;/p&gt;
&lt;p&gt;We will comment on the most interesting cases.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    Index PushExecOp(Token op, Cell? value)
    {
        ds[code] = (Code)op;
        var howMany = 0;

        if(value is not null) Write7BitEncodedCell(ds, code + 1, (Cell)value, out howMany);
        return howMany + 1;
    }

    void Execute(Token op, Cell? data) {

        Index opLen = PushExecOp(op, data); // Store the token and data in the code area so IP can point to it.
        var ip      = code;

        do {
            var token = (Token)ds[ip];
            ip++;

            Cell n, flag, index, limit, incr ;
            Index count, idx;
            bool bflag;

            switch(token) {
                case Token.Words:
                    Console.WriteLine(string.Join(&amp;quot; &amp;quot;, Words()));
                    break;
                case Token.Source:
                    Source();
                    break;
                case Token.Base:
                    Push(basep);
                    break;
                case Token.Emit:
                    Console.Write((char)Pop());
                    break;
                case Token.Type:
                    Console.Write(ToDotNetString());
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A string literal gets stored immediately after the ip. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.ISLit:
                    count = ds[ip];
                    Push(ip + 1);
                    Push(count);
                    ip += count + 1;
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Postponing is a two step process. At compile time, we embed one of the two tokens below.
                    They allow postponing either user defined functions or primitives. For immediate primitives, 
                    postponing means embedding a token to execute the action. See description of &lt;code&gt;Postpone()&lt;/code&gt; later.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.IPostCall:
                    n = Read7BitEncodedCell(ds, ip, out count);
                    PushOp(Token.Call, n);
                    ip += count;
                    break;
                case Token.IPostponeOp:
                    PushOp((Token)ds[ip]);
                    ip += 2; // There is a noop here to classify this as 2 bytes operation.
                    break;
                case Token.ImmCall:
                    var act = ImmediateAction((Token)ds[ip]);
                    if(act is null) Throw($&amp;quot;ImmCall with a non existing op: {(Token)ds[ip]}&amp;quot;);
                    act();
                    ip++;
                    break;
                case Token.Allot:
                    herep += (Index)Pop();
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These three tokens enable my rudimentary (static methods) dotnet integration. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.DType:
                    var typeName = ToDotNetString();
                    var aType = Type.GetType(typeName);
                    if(aType is null) Throw($&amp;quot;Cannot find type {typeName}&amp;quot;);
                    lastType = aType;
                    break;
                case Token.DMethod:
                    var methodName = ToDotNetString();
                    lastMethod = lastType.GetMethod(methodName);
                    if(lastMethod is null) Throw($&amp;quot;No method {methodName} on type {lastType.Name}&amp;quot;);
                    break;
                case Token.DCall:
                    DCall();
                    break;
                case Token.Cells:
                    Push(Pop() * CELL_SIZE);
                    break;
                case Token.Find:
                    Find();
                    break;
                case Token.Exec:
                    idx = (Index)Pop();
                    RPush(ip);
                    ip = (Index)idx;
                    break;
                case Token.Cr:
                    Console.WriteLine();
                    break;
                case Token.In:
                    Push(inp);
                    break;
                case Token.Char:
                    Char();
                    break;
                case Token.ICStr:
                    Push(ip);
                    ip += ds[ip] + 1;
                    break;
                case Token.ISStr:
                    Push(ip + 1);
                    idx = ds[ip];
                    Push(idx);
                    ip += idx + 1;
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Numb and NumbEx are two ways to embed a number in the ip stream. The latter is needed 
                    because of the control structures (i.e., loop, if, &amp;hellip;). We need to use a full cell to store
                    the jumping point as we don&amp;rsquo;t know upfront where we are going to jump to, hence how many bytes
                    we are going to need to store the address. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Numb:
                    n = Read7BitEncodedCell(ds, ip, out count);
                    Push(n);
                    ip += count;
                    break;
                case Token.NumbEx:
                    n = ReadCell(ds, ip);
                    Push(n);
                    ip = (Index)RPop();
                    break;
                case Token.Prin:
                    n = Pop();
                    Console.Write($&amp;quot;{Convert.ToString(n, ds[basep])} &amp;quot;);
                    break;
                case Token.Count:
                    Count();
                    break;
                case Token.Refill:
                    Refill();
                    break;
                case Token.Word:
                    Word();
                    break;
                case Token.Parse:
                    Parse();
                    break;
                case Token.Comma:
                    Comma();
                    break;
                case Token.CComma:
                    ds[herep] = (byte) Pop();
                    herep++;
                    break;
                case Token.Save:
                    SaveSystem();
                    break;
                case Token.Load:
                    LoadSystem();
                    break;
                case Token.SaveSys:
                    SaveSystem(true);
                    break;
                case Token.LoadSys:
                    LoadSystem(true);
                    break;
                case Token.Included:
                    Included();
                    break;
                case Token.Here:
                    Here();
                    break;
                case Token.ToR:
                    PStoRS();
                    break;
                case Token.FromR:
                    FromR();
                    break;
                case Token.At:
                    At();
                    break;
                case Token.CAt:
                    CFetch();
                    break;
                case Token.Pad:
                    Push(pad);
                    break;
                case Token.Drop:
                    Drop();
                    break;
                case Token.Drop2:
                    Drop2();
                    break;
                case Token.MulDivRem:
                    MulDivRem();
                    break;
                case Token.Store:
                    Store();
                    break;
                case Token.State:
                    State();
                    break;
                case Token.Bl:
                    Bl();
                    break;
                case Token.Dup:
                    Dup();
                    break;
                case Token.Swap:
                    Swap();
                    break;
                case Token.Over:
                    Over();
                    break;
                case Token.Dup2:
                    Dup2();
                    break;
                case Token.Bye:
                    Environment.Exit(0);
                    break;
                case Token.TestSys:
                    EvaluateMultipleLines(PRELIM_TEST);
                    break;
                case Token.DotS:
                    Console.WriteLine(StackString());
                    break;
                case Token.Quit:
                    Quit();
                    break;
                case Token.Interpret:
                    Interpret();
                    break;
                case Token.And:
                    Push(Pop() &amp;amp; Pop());
                    break;
                case Token.Or:
                    Push(Pop() | Pop());
                    break;
                case Token.Plus:
                    Push(Pop() + Pop());
                    break;
                case Token.Minu:
                    Push(- Pop() + Pop());
                    break;
                case Token.Mult:
                    Push(Pop() * Pop());
                    break;
                case Token.Less:
                    Push(Pop() &amp;gt; Pop() ? FORTH_TRUE : FORTH_FALSE);
                    break;
                case Token.More:
                    Push(Pop() &amp;lt; Pop() ? FORTH_TRUE : FORTH_FALSE);
                    break;
                case Token.Equal:
                    Push(Pop() == Pop() ? FORTH_TRUE : FORTH_FALSE);
                    break;
                case Token.NotEqual:
                    Push(Pop() != Pop() ? FORTH_TRUE : FORTH_FALSE);
                    break;
                case Token.Depth:
                    Push(sp / CELL_SIZE);
                    break;
                case Token.RDepth:
                    Push(rp / CELL_SIZE);
                    break;
                case Token.Invert:
                    Push(~Pop());
                    break;
                case Token.Immediate:
                    Utils.SetHighBit(ref ds[LinkToLen(dictHead)]);
                    break;
                case Token.Divi:
                    var d = Pop();
                    var u = Pop();
                    Push(u / d);
                    break;
                case Token.Body:
                    Push(Pop() + 1 + CELL_SIZE); // See create below.
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;create ... does&amp;gt;&lt;/code&gt; is the pearl of Forth, but its implementation is complex. &lt;code&gt;create&lt;/code&gt;
                    gives a byte address in the data space a name adding it to the dictionary. It also embed
                    a token in the instruction stream to push the created address when executed, so that
                    this works &lt;code&gt;create bob 10 , bob ?&lt;/code&gt;. Here is a place when we need to use &lt;code&gt;NumbEx&lt;/code&gt;. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Create:
                    Push(' ');
                    Word();
                    if(ds[Peek()] == 0) Throw(&amp;quot;'create' needs a subsequent word in the stream.&amp;quot;);
                    LowerCase();
                    DictAdd();

                    PushOp(Token.NumbEx);
                    // Need to use full cell because it gets substituted by a jmp in does&amp;gt;
                    // and I don't know how many cells the number I need to jump to takes
                    WriteCell(ds, herep, herep + CELL_SIZE);
                    herep += CELL_SIZE;
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here stuff is tricky. First we get the address for the code of the last &lt;code&gt;created&lt;/code&gt; word
                    (where &lt;code&gt;create&lt;/code&gt; stored the &lt;code&gt;NumbEx addr&lt;/code&gt;). We then override it with a jump to the current
                    &lt;code&gt;ip&lt;/code&gt;. Then we store an instruction to push the address of the last created word. Finally,
                    we copy all the remaining tokens until we encounter Exit. This allows the following to
                    work and print &lt;code&gt;10&lt;/code&gt;: &lt;code&gt;: var create  , does&amp;gt; ? ;   10 var bob  bob&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Does:
                    // Allows adding code to the last `defined` word, not just last `created` one!!
                    // Even in gforth!!
                    idx = Lastxt();
                    var addrToPush = ReadCell(ds, idx + 1);

                    var currentIp = herep;
                    herep = idx;
                    PushOp(Token.Jmp, currentIp);
                    herep = currentIp;
                    PushOp(Token.Numb, addrToPush);
                    PushUntilExit(ref ip);
                    ip = (Index)RPop();
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Colon &lt;code&gt;:&lt;/code&gt;, despite its importance, is utterly simple. Get the next word from the input
                    buffer, add it to the dictionary and move the interpret to compile mode. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Colo:
                    Push(' ');
                    Word();
                    if(ds[Peek()] == 0) Throw(&amp;quot;Colon needs a subsequent word in the stream.&amp;quot;);
                    LowerCase();
                    DictAdd();
                    Executing = false;
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;call&lt;/code&gt; stores the ip on the return stack, while &lt;code&gt;jmp&lt;/code&gt; just moves the ip. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Call:
                    n = Read7BitEncodedCell(ds, ip, out count);
                    ip += count;
                    RPush(ip);
                    ip = (Index)n;
                    break;
                case Token.Jmp:
                    n = Read7BitEncodedCell(ds, ip, out _);
                    ip = (Index) n;
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;exit&lt;/code&gt; gets the ip from the return stack &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Exit:
                    ip = (Index)RPop();
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here come all the instructions for control flow control in a stack based Vm.
                    I recommend stepping through a &lt;code&gt;do ... loop&lt;/code&gt; to understand the tricky details.
                    Generally, the return stack contains &lt;code&gt;ip after the loop | limit | index&lt;/code&gt;.
                    &amp;lsquo;ip after the loop&lt;code&gt;is needed by the&lt;/code&gt;leave` instruction, which needs to know where
                    to go. There might be a way to pre-calculate this at compile time, but I didn&amp;rsquo;t find it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.Branch0:
                    flag = Pop();
                    ip += flag == FORTH_FALSE ? ReadInt16(ds, ip) : 2 ;
                    break;
                case Token.Do:
                    RPush(ReadCell(ds, ip));
                    ip += CELL_SIZE;
                    PStoRS();
                    PStoRS();
                    break;
                case Token.I:
                    Push(ReadCell(rs, rp - CELL_SIZE * 2));
                    break;
                case Token.J:
                    Push(ReadCell(rs, rp - CELL_SIZE * 5));
                    break;
                case Token.Leave:
                    RPop();
                    RPop();
                    ip = (Index)RPop();
                    break;
                case Token.Loop:
                    limit = RPop();
                    index = RPop();
                    index++;
                    bflag = index &amp;lt; limit; 
                    if(bflag) {
                        RPush(index);
                        RPush(limit);
                        ip += ReadInt16(ds, ip);
                    }  else {
                        RPop();
                        ip += 2;
                    }
                    break;
                case Token.LoopP:
                    incr  = Pop();
                    limit = RPop();
                    index = RPop();
                    index += incr;
                    bflag = incr &amp;gt; 0 ? index &amp;lt; limit : index &amp;gt;= limit; 
                    if(bflag) {
                        RPush(index);
                        RPush(limit);
                        ip += ReadInt16(ds, ip);
                    }  else {
                        RPop();
                        ip += 2;
                    }
                    break;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For control structures we use relative jumps of 2 bytes, not to waste a full cell for them.
                    If you have an &lt;code&gt;if&lt;/code&gt; statement longer than &lt;code&gt;FFFFFFFF&lt;/code&gt; bytes, you are screwed. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                case Token.RelJmp:
                    ip += ReadInt16(ds, ip);
                    break;
                default:

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can treat all the immediate primitives in a generic way, by just calling their
                        associated action. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;                    var a = ImmediateAction(token); 
                    if(a is not null)
                        a();
                    else 
                        Throw($&amp;quot;{(Token)op} bytecode not supported.&amp;quot;);
                    break;
            }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When do we stop looping? It took me a while to get this one right. The &lt;code&gt;ip&lt;/code&gt; wonders around the
            data space following all the &lt;code&gt;call&lt;/code&gt; and &lt;code&gt;jmp&lt;/code&gt;,but, eventually, it comes back where it started. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        } while (ip != code + opLen);
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some details 
 Now you should understand the how interpretation and compilation work. The rest is details.
        Let&amp;rsquo;s look at a few of them.
 Forth uses &lt;code&gt;included&lt;/code&gt; to interpret code in external files. Note the versatility of &lt;code&gt;NextLine&lt;/code&gt;.
        We used it before as part of the interpret loop. Now we use the same mechanism to read from 
        a file and keep track of line numbers for the sake of error messages. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void Included()
    {

        var lineNum  = 0;
        var lineText = &amp;quot;&amp;quot;;

        var fileName     = ToDotNetString();
        using var stream = File.OpenRead(fileName);
        using var reader = new StreamReader(stream);
        var backupNL     = NextLine;

        try {
            if (Debug) Console.Write($&amp;quot;Interpreting file {fileName} ...&amp;quot;);
            NextLine = () =&amp;gt; { lineNum++; lineText = reader.ReadLine()! ; return lineText; };

            Quit();

            if (Debug) Console.WriteLine(&amp;quot; done.\n&amp;quot;);
        } catch(Exception)
        {
            ColorLine(ConsoleColor.Red, $&amp;quot;File: {fileName} Line: {lineNum}\n{lineText}&amp;quot;);
            throw; 
        } finally
        {
            NextLine = backupNL;
        }
    }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is awkward. When processing &lt;code&gt;does&amp;gt;&lt;/code&gt;, I need to copy all the tokens until &lt;code&gt;Exit&lt;/code&gt;. But how do I
        recognize it? There could be a byte with &lt;code&gt;Exit&lt;/code&gt; value, which is part of some number. So I divide the
        tokens according to their lengths push each instruction one by one. There is certainly a better way,
        likely involving a more careful design of the token representation. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void PushUntilExit(ref Index ip)
    {
        while(true)
        {
            var token = ds[ip];
            var count = 0;

            if(Utils.HasCellSize(token))
                count = CELL_SIZE;
            else if(Utils.HasVarNumberSize(token))
                Read7BitEncodedCell(ds, ip + 1, out count);
            else if(Utils.HasStringSize(token))
                count += ds[ip + 1] + 1; // Size of string + 1 for the len byte.

            Array.Copy(ds, ip, ds, herep, 1 + count);

            ip    += 1 + count;
            herep += 1 + count;

            if((Token)token == Token.Exit)
                break;
        }
    }



&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This long and ugly beast navigates the dictionary linked list until it finds a word. If it doesn&amp;rsquo;t, it
        looks for one in the primitives table, otherwise in the immediate primitive table. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void Find()
    {
        // Look for user defined word
        var caddr = (Index)Peek();
        FindUserDefinedWord();

        if(Peek() != FORTH_FALSE) return;

        var clen  = ds[caddr];
        var cspan = new Span&amp;lt;AChar&amp;gt;(ds, caddr + 1 * CHAR_SIZE, clen);
        var sl    = Encoding.UTF8.GetString(cspan);

        // Look for simple statements
        if(WordToSimpleOp.TryGetValue(sl, out var op))
        {
            RetNewOp(op);
            return;
        }
        // Look for immediate words
        if(ImmediatePrimitives.TryGetValue(sl, out var imm))
        {
            RetNewImmediateOp(imm.Item1);
            return;
        }
        // Getting here, we return the result of FindUserDefinedWord. Below utility funcs.
        void RetNewImmediateOp(Token op)
        {
            var xt = herep;
            PushOp(Token.ImmCall);
            PushOp(op);
            PushOp(Token.Exit);
            Ret(xt, 1);
        }
        void RetNewOp(Token op)
        {
            var xt = herep;
            PushOp(op);
            PushOp(Token.Exit);
            Ret(xt, -1);
        }
        void Ret(Index xt, Cell f)
        {
            Drop(); Drop(); Push(xt); Push(f);
        }
    }
    Index Lastxt() =&amp;gt; LinkToCode(dictHead, ds[dictHead + CELL_SIZE]);


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding to the dictionary means adding to a linked list. Just bytes twiddling. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    internal void DictAdd()
    {
        // First put the link
        Push(dictHead);             // Push last index
        dictHead = herep;           // DH is now here
        Comma();                    // Store last index in new dictHead (here)

        // Copy word to here
        var len = ds[(Index)Peek()];
        Push(herep);
        Push(len + 1);
        CMove();
        herep += len + 1;
    }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Postpone&lt;/code&gt; gave me some grief. In summary, if it is a user defined word, postpone a call to its xt;
        if it is a primitive, postpone its token; if it is an immediate primitive, postpone its token. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void Postpone()
    {
        Bl();
        Word();
        LowerCase();
        Dup();
        var sl = ToDotNetStringC();

        FindUserDefinedWord();

        var res = Pop();
        var xt    = (Index)Pop();

        if(res != FORTH_FALSE) {
            PushOp(Token.IPostCall, xt);
            return;
        }

        if(WordToSimpleOp.TryGetValue(sl, out var op)) {
            PushOp(Token.IPostponeOp);
            PushOp(op);
            PushOp(Token.Noop); // Need that because we don't have tokens with 2 bytes operands.
            return;
        }

        // TODO: confirm that all immediate tokens are one byte long.
        if(ImmediatePrimitives.TryGetValue(sl, out var imm)) {
            PushOp(imm.Item1);
            return;
        }
        Throw($&amp;quot;{sl: don't know this word.}&amp;quot;);
    }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## List of Tokens 
 In each implementation, each instruction is (Token, Operand) where Token is one byte, while operand
        can be 1 byts, 2 bytes, Cell size, a variable number or a string. There is vast literature, but no agreement
        on the most optimal number of primitives for a Forth system. It is a trade off between easy of porting vs 
        performance and compactness. I stayed somewhere in the middle. Whatever seemed to be highly optimizable
        as a single instruction became one. Having said that, if I had to do it again, I would probably have less primitives. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    internal enum Token {
        Error , Colo,  Does, Plus, Minu, Mult, Divi, Prin, Base, Noop,
        Count, Word, Parse, Refill, Comma, CComma, Here, At, Store, State, Bl, Dup, Exit, Immediate,
        Swap, Dup2, Drop, Drop2, Find, Bye, DotS, Interpret, Quit, Create, Body, RDepth, Depth,
        Less, Words, TestSys, More, Equal, NotEqual, Do, Loop, LoopP, ToR, FromR, I, J, Leave, Cr,
        Source, Type, Emit, Char, In, Over, And, Or, Allot, Cells, Exec, Invert, MulDivRem,
        Save, Load, SaveSys, LoadSys, Included, DType, DCall, DMethod, CAt, Pad,
        IDebug, ISemi,  IBegin, IDo, ILoop, ILoopP, IAgain, IIf, IElse, IThen,
        IWhile, IRepeat, IBrakO, IBrakC,   // End of 1 byte
        Branch0, RelJmp, ImmCall, IPostponeOp,// End of 2 byte size
        NumbEx, // End of CELL Size 
        Jmp , Numb, Call, IPostCall, ILiteral, IChar,// End of Var number
        ICStr, ISStr, ISLit, // End of string words
        FirstHasVarNumb = Jmp, FirstHas2Size = Branch0, FirstHasCellSize = NumbEx,
        FirstStringWord = ICStr,
    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;## Forth defined primitives 
 Whatever is not a primitive, is implemented in Forth in the giant string below. Note that
        comments are implemented in Forth. What other language lets you do that? I guess Lisp, SmallTalk
        and derivatives &amp;hellip; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    const string INIT_FORTH = @&amp;quot;
: ( [char] ) parse drop drop ; immediate
: \ 0 word drop ; immediate

\ Some modified from https://theforth.net/package/minimal/current-view/README.md
: variable create 0 , ;
: constant create , does&amp;gt; @ ;

\ Arithmetic
: 1+ 1 + ;
: 2+ 2 + ;
: 1- 1 - ;
: 2- 2 - ;
: min ( n1 n2 -- n3 )  over over &amp;gt; if swap then drop ;
: max ( n1 n2 -- n3 )  over over &amp;lt; if swap then drop ;
: mod ( n n -- n )  1 swap */mod drop ;
: dec 10 base ! ;
: hex 16 base ! ;
: 2* 2 * ;
: negate -1 * ;
: d- - ;

\ Stack
: rot ( x1 x2 x3 -- x2 x3 x1 )  &amp;gt;r  swap r&amp;gt; swap ;
: -rot ( x1 x2 x3 -- x3 x2 x1 )  rot rot ;
: nip ( x1 x2 -- x2 )  swap drop ;
: tuck ( x1 x2 -- x2 x1 x2 )  swap over ;
: ?dup dup 0 &amp;lt;&amp;gt; if dup then ;
: bounds ( addr1 u -- addr2 addr3 )  over + swap ;
: 2dup ( d1 -- d1 d1 )  over over ;
: 2swap ( d1 d2 -- d2 d1 )  &amp;gt;r rot rot r&amp;gt; rot rot ;
: 2over ( d1 d2 -- d1 d2 d1 )  &amp;gt;r &amp;gt;r 2dup r&amp;gt; r&amp;gt; 2swap ;
: um/mod 2dup mod -rot / ;

\ Boolean
0 constant false
false invert constant true
: 0= 0 = ;
: 0&amp;lt; 0 &amp;lt; ;
: 0&amp;gt; 0 &amp;gt; ;
: or ( x x -- x )  invert swap invert and invert ; ( do morgan )
: xor ( x x -- x )  over over invert and &amp;gt;r swap invert and r&amp;gt; or ;
: lshift ( x1 u -- x2 )  begin dup while &amp;gt;r  2*  r&amp;gt; 1 - repeat drop ;
: endif postpone then ; immediate

\ Memory
: ? @ . ;
: +! ( x addr -- )  swap over @ + swap ! ;
: chars ;
: char+ ( c-addr1 -- c-addr2 )  1 chars + ;
: cell+ ( addr1 -- addr2 )  1 cells + ;
: aligned ( addr -- a-addr )  cell+ 1 -   1 cells 1 - invert  and ;
: 2! ( d addr -- )   SWAP OVER ! CELL+ ! ;
: 2@ ( addr -- d )  DUP CELL+ @ SWAP @ ;

\ Compiler
: ' bl word find drop ;
: ['] ' postpone literal ; immediate
: value ( -- )  create , does&amp;gt; @ ;
: defer ( &amp;quot;&amp;quot;&amp;lt;spaces&amp;gt;name&amp;quot;&amp;quot; -- )  create 0 , does&amp;gt; @ execute ;
: to ( x &amp;quot;&amp;quot;&amp;lt;spaces&amp;gt;name&amp;quot;&amp;quot; -- ) 
   state @ 
   if  postpone [']  postpone &amp;gt;body postpone !  
   else ' &amp;gt;body ! then ; immediate

: is ( x &amp;quot;&amp;quot;&amp;lt;spaces&amp;gt;name&amp;quot;&amp;quot; -- ) 
   state @ if  postpone to  else ['] to execute  then ; immediate

\ Strings
: space ( -- )  bl emit ;
: spaces ( u -- ) dup 0 &amp;gt; if  begin dup while  space 1 -  repeat  then  drop ;

\ .net inteop samples
: .net ( type-s-addr type-c methodName-s-addr method-name-c -- ** )
    2swap .net&amp;gt;type .net&amp;gt;method .net&amp;gt;call ;

: escape s&amp;quot;&amp;quot; System.Uri, System&amp;quot;&amp;quot; s&amp;quot;&amp;quot; EscapeDataString&amp;quot;&amp;quot; .net ;
: sqrt s&amp;quot;&amp;quot; System.Math&amp;quot;&amp;quot; s&amp;quot;&amp;quot; Sqrt&amp;quot;&amp;quot; .net ;
&amp;quot;;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rest is either byte fiddling or control structures details. You should be able to understand it
        on your own, given what explained before. If you are highly motivated.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void CFetch()
    {
        var c = (Index)Pop();
        var sl = new Span&amp;lt;AUnit&amp;gt;(ds, c, 1);
        Push(sl[0]);
    }

    internal void Count()
    {
        var start = (Index) Pop();
        Push(start + 1);
        Push(ds[start]);
    }
    void FromDotNetString(string s)
    {
        var bytes = Encoding.UTF8.GetBytes(s);
        bytes.CopyTo(ds, dotnetStrings);
        Push(dotnetStrings);
        Push(bytes.Length);
    }
    internal string ToDotNetStringC()
    {
        var a = (Index)Pop();
        var s = new Span&amp;lt;AChar&amp;gt;(ds, a + CHAR_SIZE, ds[a]);
        return Encoding.UTF8.GetString(s);
    }
    internal string ToDotNetString()
    {
        var c = (Index)Pop();
        var a = (Index)Pop();
        var s = new Span&amp;lt;AUnit&amp;gt;(ds, a, c);
        return Encoding.UTF8.GetString(s);
    }
    internal void Parse()
    {
        var delim = (byte) Pop();
        ref var off = ref ds[inp]; 
        var addr = source + off;
        var startOff = off;

        while(ds[source + off] != delim) off++;
        off++;

        Push(addr);
        Push(off - startOff - 1);
    }
    /* TODO: the delimiter in this implementation (and Forth) as to be one byte char, but UTF8 puts that into question */
    internal void Word(bool inKeyword = false)
    {
        var delim = (byte)Pop();
        var s = ToChars(source, input_len_chars);
        var toPtr = inKeyword ? keyWord : word;

        var w = ToChars(toPtr, wordBufferSize);

        var j = 1; // It is a counted string, the first byte contains the length

        ref var index = ref ds[this.inp];

        while (index &amp;lt; input_len_chars &amp;amp;&amp;amp; s[(Index)index] == delim) { index++; }

        // If all spaces to the end of the input, return a string with length 0. 
        if (index &amp;gt;= input_len_chars)
        {
            w[0] = (byte)0;
            Push(toPtr);
            return;
        }

        // Copy chars until end of space allocated, end of buffer or delim.
        while (j &amp;lt; wordBufferSize &amp;amp;&amp;amp; index &amp;lt; input_len_chars &amp;amp;&amp;amp; s[(Index)index] != delim)
        {
            var c = s[(Index)index];
            index++;
            w[j++] = c;
        }
        // Points past the delimiter. Otherwise it would stay on last &amp;quot; of a string.
        if(index &amp;lt; input_len_chars) index++;
        if (j &amp;gt;= wordBufferSize) throw new Exception($&amp;quot;Word longer than {wordBufferSize}: {Encoding.UTF8.GetString(s)}&amp;quot;);

        w[0] = (byte)(j - 1);  // len goes into the first char
        Push(toPtr);
    }
    Span&amp;lt;byte&amp;gt; ToChars(Index start, Index lenInBytes)
            =&amp;gt; new(ds, start, lenInBytes);
    const string PRELIM_TEST = @&amp;quot;
CR CR SOURCE TYPE ( Preliminary test ) CR
SOURCE ( These lines test SOURCE, TYPE, CR and parenthetic comments ) TYPE CR
( The next line of output should be blank to test CR ) SOURCE TYPE CR CR

( It is now assumed that SOURCE, TYPE, CR and comments work. SOURCE and      )
( TYPE will be used to report test passes until something better can be      )
( defined to report errors. Until then reporting failures will depend on the )
( system under test and will usually be via reporting an unrecognised word   )
( or possibly the system crashing. Tests will be numbered by #n from now on  )
( to assist fault finding. Test successes will be indicated by               )
( 'Pass: #n ...' and failures by 'Error: #n ...'                             )

( Initial tests of &amp;gt;IN +! and 1+ )
( Check that n &amp;gt;IN +! acts as an interpretive IF, where n &amp;gt;= 0 )
( Pass #1: testing 0 &amp;gt;IN +! ) 0 &amp;gt;IN +! SOURCE TYPE CR
( Pass #2: testing 1 &amp;gt;IN +! ) 1 &amp;gt;IN +! xSOURCE TYPE CR
( Pass #3: testing 1+ ) 1 1+ &amp;gt;IN +! xxSOURCE TYPE CR

( Test results can now be reported using the &amp;gt;IN +! trick to skip )
( 1 or more characters )

( The value of BASE is unknown so it is not safe to use digits &amp;gt; 1, therefore )
( it will be set it to binary and then decimal, this also tests @ and ! )

( Pass #4: testing @ ! BASE ) 0 1+ 1+ BASE ! BASE @ &amp;gt;IN +! xxSOURCE TYPE CR
( Set BASE to decimal ) 1010 BASE !
( Pass #5: testing decimal BASE ) BASE @ &amp;gt;IN +! xxxxxxxxxxSOURCE TYPE CR

( Now in decimal mode and digits &amp;gt;1 can be used )

( A better error reporting word is needed, much like .( which can't  )
( be used as it is in the Core Extension word set, similarly PARSE can't be )
( used either, only WORD is available to parse a message and must be used   )
( in a colon definition. Therefore a simple colon definition is tested next )

( Pass #6: testing : ; ) : .SRC SOURCE TYPE CR ; 6 &amp;gt;IN +! xxxxxx.SRC
( Pass #7: testing number input ) 19 &amp;gt;IN +! xxxxxxxxxxxxxxxxxxx.SRC

( VARIABLE is now tested as one will be used instead of DROP e.g. Y ! )

( Pass #8: testing VARIABLE ) VARIABLE Y 2 Y ! Y @ &amp;gt;IN +! xx.SRC

: MSG 41 WORD COUNT ;  ( 41 is the ASCII code for right parenthesis )
( The next tests MSG leaves 2 items on the data stack )
( Pass #9: testing WORD COUNT ) 5 MSG abcdef) Y ! Y ! &amp;gt;IN +! xxxxx.SRC
( Pass #10: testing WORD COUNT ) MSG ab) &amp;gt;IN +! xxY ! .SRC

( For reporting success .MSG( is now defined )
: .MSG( MSG TYPE ; .MSG( Pass #11: testing WORD COUNT .MSG) CR

( To define an error reporting word, = 2* AND will be needed, test them first )
( This assumes 2's complement arithmetic )
1 1 = 1+ 1+ &amp;gt;IN +! x.MSG( Pass #12: testing = returns all 1's for true) CR
1 0 = 1+ &amp;gt;IN +! x.MSG( Pass #13: testing = returns 0 for false) CR
1 1 = -1 = 1+ 1+ &amp;gt;IN +! x.MSG( Pass #14: testing -1 interpreted correctly) CR

1 2* &amp;gt;IN +! xx.MSG( Pass #15: testing 2*) CR
-1 2* 1+ 1+ 1+ &amp;gt;IN +! x.MSG( Pass #16: testing 2*) CR

-1 -1 AND 1+ 1+ &amp;gt;IN +! x.MSG( Pass #17: testing AND) CR
-1  0 AND 1+ &amp;gt;IN +! x.MSG( Pass #18: testing AND) CR
6  -1 AND &amp;gt;IN +! xxxxxx.MSG( Pass #19: testing AND) CR

( Define ~ to use as a 'to end of line' comment. \ cannot be used as it a )
( Core Extension word )
: ~  ( -- )  SOURCE &amp;gt;IN ! Y ! ;

( Rather than relying on a pass message test words can now be defined to )
( report errors in the event of a failure. For convenience words ?T~ and )
( ?F~ are defined together with a helper ?~~ to test for TRUE and FALSE  )
( Usage is: &amp;lt;test&amp;gt; ?T~ Error #n: &amp;lt;message&amp;gt;                               )
( Success makes &amp;gt;IN index the ~ in ?T~ or ?F~ to skip the error message. )
( Hence it is essential there is only 1 space between ?T~ and Error      )

: ?~~  ( -1 | 0 -- )  2* &amp;gt;IN +! ;
: ?F~ ( f -- )   0 = ?~~ ;
: ?T~ ( f -- )  -1 = ?~~ ;

( Errors will be counted )
VARIABLE #ERRS 0 #ERRS !
: Error  1 #ERRS +! -6 &amp;gt;IN +! .MSG( CR ;
: Pass  -1 #ERRS +! 1 &amp;gt;IN +! Error ;  ~ Pass is defined solely to test Error

-1 ?F~ Pass #20: testing ?F~ ?~~ Pass Error
-1 ?T~ Error #1: testing ?T~ ?~~ ~

0  0 = 0= ?F~ Error #2: testing 0=
1  0 = 0= ?T~ Error #3: testing 0=
-1 0 = 0= ?T~ Error #4: testing 0=

0  0 = ?T~ Error #5: testing =
0  1 = ?F~ Error #6: testing =
1  0 = ?F~ Error #7: testing =
-1 1 = ?F~ Error #8: testing =
1 -1 = ?F~ Error #9: testing =

-1 0&amp;lt; ?T~ Error #10: testing 0&amp;lt;
0  0&amp;lt; ?F~ Error #11: testing 0&amp;lt;
1  0&amp;lt; ?F~ Error #12: testing 0&amp;lt;

 DEPTH 1+ DEPTH = ?~~ Error #13: testing DEPTH
 ~ Up to now whether the data stack was empty or not hasn't mattered as
 ~ long as it didn't overflow. Now it will be emptied - also
 ~ removing any unreported underflow
 DEPTH 0&amp;lt; 0= 1+ &amp;gt;IN +! ~ 0 0 &amp;gt;IN ! Remove any underflow
 DEPTH 0= 1+ &amp;gt;IN +! ~ Y !  0 &amp;gt;IN ! Empty the stack
 DEPTH 0= ?T~ Error #14: data stack not emptied 

 4 -5 SWAP 4 = SWAP -5 = = ?T~ Error #15: testing SWAP
 111 222 333 444
 DEPTH 4 = ?T~ Error #16: testing DEPTH
 444 = SWAP 333 = = DEPTH 3 = = ?T~ Error #17: testing SWAP DEPTH
 222 = SWAP 111 = = DEPTH 1 = = ?T~ Error #18: testing SWAP DEPTH
 DEPTH 0= ?T~ Error #19: testing DEPTH = 0

~ From now on the stack is expected to be empty after a test so
~ ?~ will be defined to include a check on the stack depth. Note
~ that ?~~ was defined and used earlier instead of ?~ to avoid
~ (irritating) redefinition messages that many systems display had
~ ?~ simply been redefined

: ?~  ( -1 | 0 -- )  DEPTH 1 = AND ?~~ ; ~ -1 test success, 0 test failure

123 -1 ?~ Pass #21: testing ?~
Y !   ~ equivalent to DROP

~ Testing the remaining Core words used in the Hayes tester, with the above
~ definitions these are straightforward

1 DROP DEPTH 0= ?~ Error #20: testing DROP
123 DUP  = ?~ Error #21: testing DUP
123 ?DUP = ?~ Error #22: testing ?DUP
0  ?DUP 0= ?~ Error #23: testing ?DUP
123  111  + 234  = ?~ Error #24: testing +
123  -111 + 12   = ?~ Error #25: testing +
-123 111  + -12  = ?~ Error #26: testing +
-123 -111 + -234 = ?~ Error #27: testing +
-1 NEGATE 1 = ?~ Error #28: testing NEGATE
0  NEGATE 0=  ?~ Error #29: testing NEGATE
987 NEGATE -987 = ?~ Error #30: testing NEGATE
HERE DEPTH SWAP DROP 1 = ?~ Error #31: testing HERE
CREATE TST1 HERE TST1 = ?~ Error #32: testing CREATE HERE
16  ALLOT HERE TST1 NEGATE + 16 = ?~ Error #33: testing ALLOT
-16 ALLOT HERE TST1 = ?~ Error #34: testing ALLOT
0 CELLS 0= ?~ Error #35: testing CELLS
1 CELLS ALLOT HERE TST1 NEGATE + VARIABLE CSZ CSZ !
CSZ @ 0= 0= ?~ Error #36: testing CELLS
3 CELLS CSZ @ DUP 2* + = ?~ Error #37: testing CELLS
-3 CELLS CSZ @ DUP 2* + + 0= ?~ Error #38: testing CELLS
: TST2  ( f -- n )  DUP IF 1+ THEN ;
0 TST2 0=  ?~ Error #39: testing IF THEN
1 TST2 2 = ?~ Error #40: testing IF THEN
: TST3  ( n1 -- n2 )  IF 123 ELSE 234 THEN ;
0 TST3 234 = ?~ Error #41: testing IF ELSE THEN
1 TST3 123 = ?~ Error #42: testing IF ELSE THEN
: TST4  ( -- n )  0 5 0 DO 1+ LOOP ;
TST4 5 = ?~ Error #43: testing DO LOOP
: TST5  ( -- n )  0 10 0 DO I + LOOP ;
TST5 45 = ?~ Error #44: testing I
: TST6  ( -- n )  0 10 0 DO DUP 5 = IF LEAVE ELSE 1+ THEN LOOP ;
TST6 5 = ?~ Error #45: testing LEAVE
: TST7  ( -- n1 n2 ) 123 &amp;gt;R 234 R&amp;gt; ;
TST7 NEGATE + 111 = ?~ Error #46: testing &amp;gt;R R&amp;gt;
: TST8  ( -- ch )  [CHAR] A ;
TST8 65 = ?~ Error #47: testing [CHAR]
: TST9  ( -- )  [CHAR] s [CHAR] s [CHAR] a [CHAR] P 4 0 DO EMIT LOOP ;
TST9 .MSG(  #22: testing EMIT) CR
: TST10  ( -- )  S&amp;quot;&amp;quot; Pass #23: testing S&amp;quot;&amp;quot; TYPE [CHAR] &amp;quot;&amp;quot; EMIT CR ; TST10

~ The Hayes core test core.fr uses CONSTANT before it is tested therefore
~ we test CONSTANT here

1234 CONSTANT CTEST
CTEST 1234 = ?~ Error #48: testing CONSTANT

~ The Hayes tester uses some words from the Core extension word set
~ These will be conditionally defined following definition of a
~ word called ?DEFINED to determine whether these are already defined

VARIABLE TIMM1 0 TIMM1 !
: TIMM2  123 TIMM1 ! ; IMMEDIATE
: TIMM3 TIMM2 ; TIMM1 @ 123 = ?~ Error #49: testing IMMEDIATE

: ?DEFINED  ( &amp;quot;&amp;quot;name&amp;quot;&amp;quot; -- 0 | -1 )  32 WORD FIND SWAP DROP 0= 0= ;
?DEFINED SWAP 0= ?~ Error #50: testing FIND ?DEFINED
?DEFINED &amp;lt;&amp;lt;no-such-word-hopefully&amp;gt;&amp;gt; 0= ?~ Error #51 testing FIND ?DEFINED

?DEFINED \ ?~ : \ ~ ; IMMEDIATE 
\ Error #52: testing \
: TIMM4  \ Error #53: testing \ is IMMEDIATE
;

~ TRUE and FALSE are defined as colon definitions as they have been used
~ more than CONSTANT above

?DEFINED TRUE  ?~ : TRUE 1 NEGATE ;
?DEFINED FALSE ?~ : FALSE 0 ;
?DEFINED HEX   ?~ : HEX 16 BASE ! ;

TRUE -1 = ?~ Error #54: testing TRUE
FALSE 0=  ?~ Error #55: testing FALSE
10 HEX 0A = ?~ Error #56: testing HEX
AB 0A BASE ! 171 = ?~ Error #57: testing hex number

~ Delete the ~ on the next 2 lines to check the final error report
~ Error #998: testing a deliberate failure
~ Error #999: testing a deliberate failure

~ Describe the messages that should be seen. The previously defined .MSG(
~ can be used for text messages

CR .MSG( Results: ) CR
CR .MSG( Pass messages #1 to #23 should be displayed above)
CR .MSG( and no error messages) CR

~ Finally display a message giving the number of tests that failed.
~ This is complicated by the fact that untested words including .( .&amp;quot;&amp;quot; and .
~ cannot be used. Also more colon definitions shouldn't be defined than are
~ needed. To display a number, note that the number of errors will have
~ one or two digits at most and an interpretive loop can be used to
~ display those.

CR
0 #ERRS @
~ Loop to calculate the 10's digit (if any)
DUP NEGATE 9 + 0&amp;lt; NEGATE &amp;gt;IN +! ( -10 + SWAP 1+ SWAP 0 &amp;gt;IN ! )
~ Display the error count
SWAP ?DUP 0= 1+ &amp;gt;IN +! ( 48 + EMIT ( ) 48 + EMIT

.MSG(  test) #ERRS @ 1 = 1+ &amp;gt;IN +! ~ .MSG( s)
.MSG(  failed out of 57 additional tests) CR

CR CR .MSG( --- End of Preliminary Tests --- ) CR

&amp;quot;;
}

public class ForthException: Exception { public ForthException(string s): base(s) { } };

static class Utils {

    const AChar HighBit     = 0b10000000; 
    const AChar HighBitMask = 0b01111111;

    internal static bool  IsHighBitSet(AChar c)     =&amp;gt; (HighBit &amp;amp; c) != 0;
    internal static AChar ResetHighBit(AChar c)     =&amp;gt; (AChar)(HighBitMask &amp;amp; c);
    internal static void SetHighBit(ref AChar c)    =&amp;gt; c = (AChar)(HighBit | c);
    internal static AChar HighBitValue(AChar c)     =&amp;gt; (AChar) (c &amp;gt;&amp;gt; 7);

    internal static void WriteInt16(AUnit[] ar, Index i, Int16 c)
        =&amp;gt; BinaryPrimitives.WriteInt16LittleEndian(new Span&amp;lt;byte&amp;gt;(ar, i, 2), c);
    internal static Int16 ReadInt16(AUnit[] ar, Index i)
        =&amp;gt; BinaryPrimitives.ReadInt16LittleEndian(new Span&amp;lt;byte&amp;gt;(ar, i, 2));

    internal static void WriteCell(AUnit[] ar, Index i, Cell c)
#if CELL32
        =&amp;gt; BinaryPrimitives.WriteInt32LittleEndian(new Span&amp;lt;byte&amp;gt;(ar, i, Vm.CELL_SIZE), c);
#else
        =&amp;gt; BinaryPrimitives.WriteInt64LittleEndian(new Span&amp;lt;byte&amp;gt;(ar, i, Vm.CELL_SIZE), c);
#endif

    internal static Cell ReadCell(AUnit[] ar, Index i)
#if CELL32
        =&amp;gt; BinaryPrimitives.ReadInt32LittleEndian(new Span&amp;lt;byte&amp;gt;(ar, i, Vm.CELL_SIZE));
#else
        =&amp;gt; BinaryPrimitives.ReadInt64LittleEndian(new Span&amp;lt;byte&amp;gt;(ar, i, Vm.CELL_SIZE));
#endif

    internal static AUnit[] Add(AUnit[] a, ref Index i, Cell t) {
        if(i + Vm.CELL_SIZE &amp;gt;= a.Length) Array.Resize(ref a, i * 2);
        WriteCell(a, i, t);        
        i += Vm.CELL_SIZE;
        return a;
    }
    internal static Cell ReadBeforeIndex(AUnit[] a, ref Index i)
    {
        i -= Vm.CELL_SIZE;
        return ReadCell(a, i);
    }
    [DoesNotReturn]
    internal static void Throw(string message) =&amp;gt; throw new ForthException(message);

    internal static long Read7BitEncodedCell(Code[] codes, Index index, out Index howMany) {
        using var stream = new MemoryStream(codes, index, 10);
        howMany = (Index)stream.Position;
#if CELL32
        var result = stream.ReadVarInt32();
#else
        var result = stream.ReadVarInt64();
#endif
        howMany = (Index)stream.Position - howMany;
        return result;
    }

    internal static void Write7BitEncodedCell(Code[] codes, Index index, Cell value, out Index howMany) {
        //howMany = Write(codes, index, value);
        using var stream = new MemoryStream(codes, index, 10);
        howMany = (Index)stream.Position;
        stream.WriteVarInt(value);
        howMany = (Index)stream.Position - howMany;
    }

    internal static bool Has2NumberSize(byte b)
        =&amp;gt; b &amp;gt;= (int)Vm.Token.FirstHas2Size &amp;amp;&amp;amp; b &amp;lt; (int)Vm.Token.FirstHasCellSize;
    internal static bool HasCellSize(byte b)
        =&amp;gt; b &amp;gt;= (int)Vm.Token.FirstHasCellSize &amp;amp;&amp;amp; b &amp;lt; (int)Vm.Token.FirstHasVarNumb;
    internal static bool HasVarNumberSize(byte b)
        =&amp;gt; b &amp;gt;= (int)Vm.Token.FirstHasVarNumb &amp;amp;&amp;amp; b &amp;lt; (int) Vm.Token.FirstStringWord;
    internal static bool HasStringSize(byte b)
        =&amp;gt; b &amp;gt;= (int)Vm.Token.FirstStringWord;

    // Rewritten from https://github.com/pvginkel/GitVarInt/blob/master/GitVarInt/VarInt.cs
    // to remove unsafe code and use new C# feature with the goal of removing any dependencies and be able to copy the file to a project.
    static int ReadVarInt32(this Stream stream) =&amp;gt; ZigZagDecode(stream.ReadVarUInt32());

    static uint ReadVarUInt32(this Stream stream)
    {
        byte b = ReadByte(stream);
        uint value = (uint)(b &amp;amp; 127);

        while ((b &amp;amp; 128) != 0)
        {
            value += 1;
            if (value == 0 || (value &amp;amp; 0xfe000000u) != 0)
                Throw(&amp;quot;Decode overflow&amp;quot;);
            b = ReadByte(stream);
            value = (value &amp;lt;&amp;lt; 7) + (uint)(b &amp;amp; 127);
        }

        return value;
    }

    static long ReadVarInt64(this Stream stream) =&amp;gt; ZigZagDecode(stream.ReadVarUInt64());

    static ulong ReadVarUInt64(this Stream stream)
    {
        byte b = ReadByte(stream);
        ulong value = (ulong)(b &amp;amp; 127);

        while ((b &amp;amp; 128) != 0)
        {
            value += 1;
            if (value == 0 || (value &amp;amp; 0xfe00000000000000ul) != 0)
                Throw(&amp;quot;Decode overflow&amp;quot;);
            b = ReadByte(stream);
            value = (value &amp;lt;&amp;lt; 7) + (ulong)(b &amp;amp; 127);
        }

        return value;
    }

    static void WriteVarInt(this Stream stream, int value) =&amp;gt; stream.WriteVarInt(ZigZagEncode(value));

    static void WriteVarInt(this Stream stream, uint value)
    {
        Span&amp;lt;byte&amp;gt; buffer = stackalloc byte[5];
        int offset = 5;

        buffer[--offset] = (byte)(value &amp;amp; 0x7F);

        while ((value &amp;gt;&amp;gt;= 7) != 0)
            buffer[--offset] = (byte)(0x80 | (--value &amp;amp; 0x7F));

        while (offset &amp;lt; 5)
            stream.WriteByte(buffer[offset++]);
    }

    static void WriteVarInt(this Stream stream, long value) =&amp;gt; stream.WriteVarInt(ZigZagEncode(value));

    static void WriteVarInt(this Stream stream, ulong value)
    {
        Span&amp;lt;byte&amp;gt; buffer = stackalloc byte[10];
        int offset = 10;

        buffer[--offset] = (byte)(value &amp;amp; 0x7F);

        while ((value &amp;gt;&amp;gt;= 7) != 0)
            buffer[--offset] = (byte)(0x80 | (--value &amp;amp; 0x7F));

        while (offset &amp;lt; 10)
            stream.WriteByte(buffer[offset++]);
    }

    static uint  ZigZagEncode(int value)   =&amp;gt; ((uint) value &amp;lt;&amp;lt; 1) ^ (uint)-(int)((uint)value &amp;gt;&amp;gt; 31);
    static ulong ZigZagEncode(long value)  =&amp;gt; ((ulong)value &amp;lt;&amp;lt; 1) ^ (ulong)-(long)((ulong)value &amp;gt;&amp;gt; 63);
    static int   ZigZagDecode(uint value)  =&amp;gt; (int)  (value &amp;gt;&amp;gt; 1) ^ -((int)value &amp;amp; 0x1);
    static long  ZigZagDecode(ulong value) =&amp;gt; (long) (value &amp;gt;&amp;gt; 1) ^ -((long)value &amp;amp; 0x1);

    private static byte ReadByte(Stream stream)
    {
        int b = stream.ReadByte();
        if (b == -1)
            Throw(&amp;quot;Unexpected end&amp;quot;);

        return (byte)b;
    }
}

System.Char[]
    void CMove()
    {
        var u  = Pop();
        var a2 = Pop();
        var a1 = Pop();
        Array.Copy(ds, a1, ds, a2, u);
    }
    void BranchAndMark() { PushOp(Token.Branch0); Push(herep); herep += 2;}
    void EmbedInPoppedJmpFwd() {
            PushOp(Token.RelJmp);
            var mark = (Index)Pop();
            short delta = (short)((herep + 2) - mark);
            WriteInt16(ds, mark, delta);
            Push(herep);
            herep += 2;
    }
    void EmbedHereJmpBck() {
            PushOp(Token.RelJmp);
            var mark = (Index)Pop();
            var delta = (short)(mark - herep);
            WriteInt16(ds, herep, delta); 
            herep += 2;
    }
    void EmbedHereJmp0Bck() {
            PushOp(Token.Loop);
            var mark = (Index)Pop();
            var delta = (short)(mark - herep);
            WriteInt16(ds, herep, delta); 
            herep += 2;

            var leaveTarget = mark - CELL_SIZE;
            WriteCell(ds, leaveTarget, herep);
    }
    void EmbedHereJmp0BckP() {
            PushOp(Token.LoopP);
            var mark = (Index)Pop();
            var delta = (short)(mark - herep);
            WriteInt16(ds, herep, delta); 
            herep += 2;
    }
    Action EmbedString(Token op) { return () =&amp;gt;
    {
        PushOp(op);

        Push('&amp;quot;');
        Parse();
        var len = (Index)Peek();
        Push(herep + 1);
        Swap();
        CMove();
        if(Executing &amp;amp;&amp;amp; op == Token.ICStr) Push(herep);
        if(Executing &amp;amp;&amp;amp; op == Token.ISStr) { Push(herep + 1); Push(len); }
        ds[herep] = (byte)len;
        herep += len + 1;
    }; }

    Action EmbedSString(Token op) { return () =&amp;gt;
    {
        PushOp(op);
        var len = (Index)Pop();
        Push(herep + 1);
        Push(len);
        CMove();
        ds[herep] = (byte)len;
        herep += len + 1;
    };}
    public void Reset()
    {
        sp = 0; rp = 0; Executing = true; ds[inp] = 0;
    }
    public void EvaluateSingleLine(string forthLine)
    {
        var oldLine = NextLine;
        try { 
            NextLine = () =&amp;gt; forthLine;
            Refill();
            if(Pop() == FORTH_TRUE)
                Interpret();
        } finally
        {
            NextLine = oldLine;
        }
    }
    // Code duplication from EvaluateSingleLine on purpose for perf reason. TODO: Refactor EvaluateMultipleLines.
    public void EvaluateMultipleLines(string forthCode)
    {
        var oldLine = NextLine;
        try {
            var s = &amp;quot;&amp;quot;;
            var forthLines = forthCode.Split('\n');
            var sLine   = () =&amp;gt; s;
            NextLine = sLine;
            foreach (var l in forthLines)
            {
                s = l;
                Refill();
                if(Pop() == FORTH_TRUE)
                    Interpret();
            }
        } finally
        {
            NextLine = oldLine;
        }
    }
    public IEnumerable&amp;lt;string&amp;gt; Words()
    {
        List&amp;lt;string&amp;gt; userWords = new();

        var dp = dictHead;
        while(true)
        {
            if(dp == 0) break;

            var wordNameStart = dp + CELL_SIZE;
            var wordLenRaw    = ds[wordNameStart];
            var wordLen       = Utils.ResetHighBit(wordLenRaw);
            var wordSpan      = new Span&amp;lt;AChar&amp;gt;(ds, wordNameStart + 1 * CHAR_SIZE, wordLen);
            var wordName      = Encoding.UTF8.GetString(wordSpan);
            userWords.Add(wordName);

            dp = (Index)ReadCell(ds, dp);
        }
        return WordToSimpleOp.Keys.Concat(ImmediatePrimitives.Keys).Concat(userWords).OrderBy(s =&amp;gt; s);
    }

    // TODO: clean this up, it now works because the default value of Op is 0 -&amp;gt; Error. It should use some kind of multidictionary here.
    Action? ImmediateAction(Token op) {
        var result =
            ImmediatePrimitives.FirstOrDefault(e =&amp;gt; e.Value.Item1 == op);
        if(result.Value.Item1 != default)
            return result.Value.Item2;
        else
            return null;
    }

    void LowerCase()
    {
        var s  = (Index)Peek();
        var bs = new Span&amp;lt;byte&amp;gt;(ds, s + 1, ds[s]);
        foreach(ref byte b in bs)
            b = (byte) char.ToLowerInvariant((char)b); 
    }
    static void ColorLine(ConsoleColor color, string s) {
        var backupcolor = Console.ForegroundColor;
        Console.ForegroundColor = color;
        Console.WriteLine(s);
        Console.ForegroundColor = backupcolor;
    }
    internal bool IsEmptyWord() =&amp;gt; ds[Peek()] == 0;

    public string StackString()
    {
        StringBuilder sb = new(&amp;quot;\\ &amp;quot;);
        for (int i = 0; i &amp;lt; sp; i += CELL_SIZE)
        {
            sb.Append(ReadCell(ps, i)); sb.Append(' ');
        }
        if(sp == 0) sb.Append(&amp;quot;empty&amp;quot;);
        return sb.ToString();
    }
    internal void Bl()    =&amp;gt; Push(' ');
    void State() =&amp;gt; Push(state);

    /* These are internal to be able to test them. What a bother. */
    internal void Push(Cell n)  =&amp;gt; ps = Utils.Add(ps, ref sp, n);
    internal Cell Pop()         =&amp;gt; Utils.ReadBeforeIndex(ps, ref sp);
    internal Cell Peek()        =&amp;gt; Utils.ReadCell(ps, sp - CELL_SIZE);

    internal void RPush(Cell n) =&amp;gt; rs = Utils.Add(rs, ref rp, n);
    internal Cell RPop()        =&amp;gt; Utils.ReadBeforeIndex(rs, ref rp);
    void PStoRS()                  =&amp;gt; RPush(Pop());
    void FromR()                =&amp;gt; Push(RPop());

    internal void DPush(Cell n) =&amp;gt; ds = Utils.Add(ds, ref herep, n);

    internal void Comma()       =&amp;gt; ds = Utils.Add(ds, ref herep, Pop());
    internal void Store()       =&amp;gt; Utils.WriteCell(ds, (Index)Pop(), Pop());
    internal void At()          =&amp;gt; Push(Utils.ReadCell(ds, (Index)Pop()));
    internal void Here()        =&amp;gt; Push(herep);
    internal void Depth()       =&amp;gt; Push(sp / CELL_SIZE);
    internal void Over()        =&amp;gt; Push(ReadCell(ps, sp - CELL_SIZE * 2));
    internal void Swap()        { var a = Pop(); var b = Pop(); Push(a); Push(b); }

    void Char()
    {
        Bl();
        Word();
        var idx = (Index)Pop();
        if(ds[idx] == 0) Throw(&amp;quot;'char' need more input.&amp;quot;);
        Push(ds[idx + 1]);
    }
    internal void Refill()
    {
        if(NextLine == null) Throw(&amp;quot;Trying to Refill, without having passed a NextLine func&amp;quot;);

        var inputBuffer = NextLine();

        if (inputBuffer == null)
        {
            Push(FORTH_FALSE);
        }
        else
        {
            inputBuffer = inputBuffer.Trim();
            input_len_chars = Encoding.UTF8.GetByteCount(inputBuffer);
            if (input_len_chars &amp;gt; inputBufferSize)
                throw new Exception(
                $&amp;quot;Cannot parse a line longer than {inputBufferSize}. {inputBuffer} is {input_len_chars} chars long.&amp;quot;);
            var inputCharSpan = ToChars(source, input_len_chars);
            var bytes = new Span&amp;lt;byte&amp;gt;(Encoding.UTF8.GetBytes(inputBuffer));
            bytes.CopyTo(inputCharSpan);
            WriteCell(ds, inp, 0);
            Push(FORTH_TRUE);
        }
    }
    internal void Source()
    {
        Push(source);
        Push(input_len_chars);
    }

    internal void Compare()
    {
        var u2 = (Index)Pop();
        var a2 = (Index)Pop();
        var u1 = (Index)Pop();
        var a1 = (Index)Pop();

        var s1 = new Span&amp;lt;AChar&amp;gt;(ds, a1, u1);
        var s2 = new Span&amp;lt;AChar&amp;gt;(ds, a2, u2);
        var r  = MemoryExtensions.SequenceCompareTo(s1, s2);
        Push(r &amp;lt; 0 ? -1 : r &amp;gt; 0 ? +1 : 0);
    }
    internal void Drop()  =&amp;gt; sp -= CELL_SIZE;
    internal void Drop2() =&amp;gt; sp -= CELL_SIZE * 2; 
    internal void Dup()   =&amp;gt; Push(Peek());
    internal void Dup2()
    {
        var x2 = Pop();
        var x1 = Pop();
        Push(x1);
        Push(x2);
        Push(x1);
        Push(x2);
    }
    void MulDivRem()
    {
        var n3 = Pop();
        var n2 = Pop();
        var n1 = Pop();
        (var n5, var n4) = Math.DivRem(n1 * n2, n3);
        Push(n4);
        Push(n5);
    }

    void DCall()
    {
        if(lastMethod is null) Throw($&amp;quot;No method UNKNOWN on type {lastType.Name}&amp;quot;);
        var args = lastMethod.GetParameters().Reverse();
        var objs =
            args.Select&amp;lt;ParameterInfo, object&amp;gt;(p =&amp;gt; p.ParameterType == typeof(string) ? ToDotNetString() : (Cell) Pop());
        var res = lastMethod.Invoke(null, objs.Reverse().ToArray());
        if(res is null)
            Throw(&amp;quot;null returned from this invocation.&amp;quot;);
        else
            if(res.GetType() == typeof(string))
                FromDotNetString((string)res);
            else
                Push(Convert.ToInt64(res));
    }
    /* It is implemented like this to avoid endianess problems 
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Mon, 07 Mar 2022 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2022-03-07-implementing-forth-dotnet.html</guid>
        </item>
        
        <item>
            <title>Introducing Forth.Net</title>
            <link>https://www.lucabol.com/posts/2022-02-23-introducting-forth-dotnet.html</link>
            <description>&lt;p&gt;An implementation of the &lt;a href="https://en.wikipedia.org/wiki/Forth_(programming_language)"&gt;Forth&lt;/a&gt; programming language for the &lt;a href="https://en.wikipedia.org/wiki/.NET_Framework"&gt;.Net Framework&lt;/a&gt;.
You can use it as a C# library, interactively with a CLI or compile the code to a compact binary format.&lt;/p&gt;
&lt;p&gt;It is on &lt;a href="https://github.com/lucabol/Forth.Net/tree/main/Forth.Net"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;dotnet tool install -g forth.net.program
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;# Start the CLI.
nforth

# Interpret some files and exit.
nforth Test1.fth Test2.fth -e bye

# Compile files to binary
nforth Test1.fth Test2.fth -e 's\&amp;quot; myfile.io&amp;quot; save'

# Execute a binary file
nforth -e 's\&amp;quot; myfile.io&amp;quot; load aword'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Notes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Save the user portion of the dictionary with &lt;code&gt;S" myfile.io" save&lt;/code&gt;. You load it with &lt;code&gt;S" myfile.io" load&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save the whole dictionary, system included, with &lt;code&gt;S" myfile.io" savesys&lt;/code&gt;. You load it with &lt;code&gt;S" myfile.io" loadsys&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To use the library, copy the file &lt;code&gt;Vm.cs&lt;/code&gt; or reference the nuget package &lt;code&gt;Forth.Net&lt;/code&gt;. Go &lt;a href="Forth.Net"&gt;here&lt;/a&gt; for usage notes and implementation details.&lt;/li&gt;
&lt;li&gt;See all the supported words with &lt;code&gt;words&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Perform a system test with &lt;code&gt;testsys&lt;/code&gt;. Your results should look like the text at the bottom of this doc.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;debug&lt;/code&gt; if curious.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;nforth --help&lt;/code&gt; for less used options.&lt;/li&gt;
&lt;li&gt;Call the .NET APIs with these words. (FYI just static methods with strings or numbers for now).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-factor"&gt;: escape s&amp;quot; System.Uri, System&amp;quot; s&amp;quot; EscapeDataString&amp;quot; .net ;
: sqrt   s&amp;quot; System.Math&amp;quot;        s&amp;quot; Sqrt&amp;quot;             .net ;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Test output&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;CR CR SOURCE TYPE ( Preliminary test ) CR
SOURCE ( These lines test SOURCE, TYPE, CR and parenthetic comments ) TYPE CR
( The next line of output should be blank to test CR ) SOURCE TYPE CR CR

( Pass #1: testing 0 &amp;gt;IN +! ) 0 &amp;gt;IN +! SOURCE TYPE CR
( Pass #2: testing 1 &amp;gt;IN +! ) 1 &amp;gt;IN +! xSOURCE TYPE CR
( Pass #3: testing 1+ ) 1 1+ &amp;gt;IN +! xxSOURCE TYPE CR
( Pass #4: testing @ ! BASE ) 0 1+ 1+ BASE ! BASE @ &amp;gt;IN +! xxSOURCE TYPE CR
( Pass #5: testing decimal BASE ) BASE @ &amp;gt;IN +! xxxxxxxxxxSOURCE TYPE CR
( Pass #6: testing : ; ) : .SRC SOURCE TYPE CR ; 6 &amp;gt;IN +! xxxxxx.SRC
( Pass #7: testing number input ) 19 &amp;gt;IN +! xxxxxxxxxxxxxxxxxxx.SRC
( Pass #8: testing VARIABLE ) VARIABLE Y 2 Y ! Y @ &amp;gt;IN +! xx.SRC
( Pass #9: testing WORD COUNT ) 5 MSG abcdef) Y ! Y ! &amp;gt;IN +! xxxxx.SRC
( Pass #10: testing WORD COUNT ) MSG ab) &amp;gt;IN +! xxY ! .SRC
Pass #11: testing WORD COUNT .MSG
Pass #12: testing = returns all 1's for true
Pass #13: testing = returns 0 for false
Pass #14: testing -1 interpreted correctly
Pass #15: testing 2*
Pass #16: testing 2*
Pass #17: testing AND
Pass #18: testing AND
Pass #19: testing AND
Pass #20: testing ?F~ ?~~ Pass Error
Pass #21: testing ?~
Pass #22: testing EMIT
Pass #23: testing S&amp;quot;

Results:

Pass messages #1 to #23 should be displayed above
and no error messages

0 tests failed out of 57 additional tests
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Wed, 23 Feb 2022 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2022-02-23-introducting-forth-dotnet.html</guid>
        </item>
        
        <item>
            <title>Down by the seaside</title>
            <link>https://www.lucabol.com/posts/2022-02-22-down-by-the-seaside.html</link>
            <description>&lt;p&gt;&lt;img src="/img/lovers.jpg" alt="two lovers" width="100%" style="max-width: 100%; border-radius: 8px; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); padding: 4px;" /&gt;&lt;/p&gt;
&lt;p&gt;The wind batters their face; the sea sings in their ears. The night is yellow with hate. I look at them from my position behind the house. They are like shadows.&lt;/p&gt;
&lt;p&gt;She is my girlfriend. I don&amp;rsquo;t know him. They kiss, as I know they would: entwined like a grapevine. A dog barks in the distance. I jump, scared. The moon laughs at us all.&lt;/p&gt;
&lt;p&gt;Jenny and I got together a long time ago. We were very young: our hearts pure, our desires less so. We loved each other ferociously: entwined like a grapevine.&lt;/p&gt;
&lt;p&gt;She told me she loved me — many times. We talked about starting a family together: kids and all. We are engaged now. It is a big deal. And now this.&lt;/p&gt;
&lt;p&gt;The rifle shines in the moonlight. It sings my revenge - the joy of the kill - the thrill of the fall.&lt;/p&gt;
&lt;p&gt;I point the rifle.&lt;/p&gt;
&lt;p&gt;A cloud covers the moon. I lose my target - I lose my resolve. Rain starts to fall. It washes my anger away. I breathe salt in the wind - lower my weapon - head home.&lt;/p&gt;
&lt;p&gt;My train leaves tomorrow - a new city waits for me. Jenny is right. We are no more.&lt;/p&gt;
&lt;p&gt;The moon shines over the rifle by the side of the house - no clouds in the sky.&lt;/p&gt;</description>
            <pubDate>Tue, 22 Feb 2022 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2022-02-22-down-by-the-seaside.html</guid>
        </item>
        
        <item>
            <title>I have create a font - Italiko</title>
            <link>https://www.lucabol.com/posts/2021-06-23-i-have-created-a-font-italiko.html</link>
            <description>&lt;p&gt;Here it is. Buy buy buy: &lt;a href="https://www.myfonts.com/fonts/luca-bolognese/italiko/"&gt;https://www.myfonts.com/fonts/luca-bolognese/italiko/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;
&lt;img alt="Example of Italiko font" src="/img/Giulietta.webp" /&gt;&lt;/p&gt;</description>
            <pubDate>Wed, 23 Jun 2021 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2021-06-23-i-have-created-a-font-italiko.html</guid>
        </item>
        
        <item>
            <title>Introduction to Functional Programming in F#</title>
            <link>https://www.lucabol.com/posts/2021-05-20-functional-programming-introduction-with-fsharp.html</link>
            <description>&lt;p&gt;Here is a new presentation I did for Future Tech 2021. It is a gentle introduction to the core of functional programming using F# (at least the way I see it).&lt;/p&gt;
&lt;p&gt;It is likely too simplicistic for some, but hopefully useful to many.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4BfOpsx2rwI"&gt;https://www.youtube.com/watch?v=4BfOpsx2rwI&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Sun, 23 May 2021 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2021-05-20-functional-programming-introduction-with-fsharp.html</guid>
        </item>
        
        <item>
            <title>New C# Source Generator Samples</title>
            <link>https://www.lucabol.com/posts/2020-08-25-new-csharp-generator-samples.html</link>
            <description>&lt;p&gt;This is just a note to keep all my material in one place.&lt;/p&gt;
&lt;p&gt;I wrote &lt;a href="https://devblogs.microsoft.com/dotnet/new-c-source-generator-samples/"&gt;this blog post&lt;/a&gt; on the MSDN .NET Blog about my CSV and Mustache C# Source Generators samples.&lt;/p&gt;</description>
            <pubDate>Tue, 25 Aug 2020 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2020-08-25-new-csharp-generator-samples.html</guid>
        </item>
        
        <item>
            <title>Text for proofing fonts</title>
            <link>https://www.lucabol.com/posts/2020-06-10-text-for-proofing-fonts.html</link>
            <description>&lt;p&gt;This comes from &lt;a href="https://www.typography.com/blog/text-for-proofing-fonts"&gt;this article&lt;/a&gt;. It is useful to evaluate the kerning of a font. Switch the Theme at the top of the blog to see the results on the text below.&lt;/p&gt;
&lt;h2&gt;Latin Lowercase&lt;/h2&gt;
&lt;p&gt;Angel Adept Blind Bodice Clique Coast Dunce Docile Enact Eosin Furlong Focal Gnome Gondola Human Hoist Inlet Iodine Justin Jocose Knoll Koala Linden Loads Milliner Modal Number Nodule Onset Oddball Pneumo Poncho Quanta Qophs Rhone Roman Snout Sodium Tundra Tocsin Uncle Udder Vulcan Vocal Whale Woman Xmas Xenon Yunnan Young Zloty Zodiac. Angel angel adept for the nuance loads of the arena cocoa and quaalude. Blind blind bodice for the submit oboe of the club snob and abbot. Clique clique coast for the pouch loco of the franc assoc and accede. Dunce dunce docile for the loudness mastodon of the loud statehood and huddle. Enact enact eosin for the quench coed of the pique canoe and bleep. Furlong furlong focal for the genuflect profound of the motif aloof and offers. Gnome gnome gondola for the impugn logos of the unplug analog and smuggle. Human human hoist for the buddhist alcohol of the riyadh caliph and bathhouse. Inlet inlet iodine for the quince champion of the ennui scampi and shiite. Justin justin jocose for the djibouti sojourn of the oranj raj and hajjis. Knoll knoll koala for the banknote lookout of the dybbuk outlook and trekked. Linden linden loads for the ulna monolog of the consul menthol and shallot. Milliner milliner modal for the alumna solomon of the album custom and summon. Number number nodule for the unmade economic of the shotgun bison and tunnel. Onset onset oddball for the abandon podium of the antiquo tempo and moonlit. Pneumo pneumo poncho for the dauphin opossum of the holdup bishop and supplies. Quanta quanta qophs for the inquest sheqel of the cinq coq and suqqu. Rhone rhone roman for the burnt porous of the lemur clamor and carrot. Snout snout sodium for the ensnare bosom of the genus pathos and missing. Tundra tundra tocsin for the nutmeg isotope of the peasant ingot and ottoman. Uncle uncle udder for the dunes cloud of the hindu thou and continuum. Vulcan vulcan vocal for the alluvial ovoid of the yugoslav chekhov and revved. Whale whale woman for the meanwhile blowout of the forepaw meadow and glowworm. Xmas xmas xenon for the bauxite doxology of the tableaux equinox and exxon. Yunnan yunnan young for the dynamo coyote of the obloquy employ and sayyid. Zloty zloty zodiac for the gizmo ozone of the franz laissez and buzzing.&lt;/p&gt;
&lt;h2&gt;Latin Uppercase&lt;/h2&gt;
&lt;p&gt;ABIDE ACORN OF THE HABIT DACRON FOR THE BUDDHA GOUDA QUAALUDE. BENCH BOGUS OF THE SCRIBE ROBOT FOR THE APLOMB JACOB RIBBON. CENSUS CORAL OF THE SPICED JOCOSE FOR THE BASIC HAVOC SOCCER. DEMURE DOCILE OF THE TIDBIT LODGER FOR THE CUSPID PERIOD BIDDER. EBBING ECHOING OF THE BUSHED DECAL FOR THE APACHE ANODE NEEDS. FEEDER FOCUS OF THE LIFER BEDFORD FOR THE SERIF PROOF BUFFER. GENDER GOSPEL OF THE PIGEON DOGCART FOR THE SPRIG QUAHOG DIGGER. HERALD HONORS OF THE DIHEDRAL MADHOUSE FOR THE PENH RIYADH BATHHOUSE. IBSEN ICEMAN OF THE APHID NORDIC FOR THE SUSHI SAUDI SHIITE. JENNIES JOGGER OF THE TIJERA ADJOURN FOR THE ORANJ KOWBOJ HAJJIS. KEEPER KOSHER OF THE SHRIKE BOOKCASE FOR THE SHEIK LOGBOOK CHUKKAS. LENDER LOCKER OF THE CHILD GIGOLO FOR THE UNCOIL GAMBOL ENROLLED. MENACE MCCOY OF THE NIMBLE TOMCAT FOR THE DENIM RANDOM SUMMON. NEBULA NOSHED OF THE INBRED BRONCO FOR THE COUSIN CARBON KENNEL. OBSESS OCEAN OF THE PHOBIC DOCKSIDE FOR THE GAUCHO LIBIDO HOODED. PENNIES PODIUM OF THE SNIPER OPCODE FOR THE SCRIP BISHOP HOPPER. QUANTA QOPHS OF THE INQUEST OQOS FOR THE CINQ COQ SUQQU. REDUCE ROGUE OF THE GIRDLE ORCHID FOR THE MEMOIR SENSOR SORREL. SENIOR SCONCE OF THE DISBAR GODSON FOR THE HUBRIS AMENDS LESSEN. TENDON TORQUE OF THE UNITED SCOTCH FOR THE NOUGHT FORGOT BITTERS. UNDER UGLINESS OF THE RHUBARB SEDUCE FOR THE MANCHU HINDU CONTINUUM. VERSED VOUCH OF THE DIVER OVOID FOR THE TELAVIV KARPOV FLIVVER. WENCH WORKER OF THE UNWED SNOWCAP FOR THE ANDREW ESCROW GLOWWORM. XENON XOCHITL OF THE MIXED BOXCAR FOR THE SUFFIX ICEBOX EXXON. YEOMAN YONDER OF THE HYBRID ARROYO FOR THE DINGHY BRANDY SAYYID. ZEBRA ZOMBIE OF THE PRIZED OZONE FOR THE FRANZ ARROZ BUZZING.&lt;/p&gt;
&lt;h2&gt;Latin Small Caps&lt;/h2&gt;
&lt;p style="font-variant:small-caps"&gt;
Abide Acorn Anaheim. Bench Bogus Babcock. Census Coral Cocoon. Demure Docile Didion. Ebbing Echoing Energetic. Feeder Focus Fiftieth. Gender Gospel Gogol. Herald Honors Hohokus. Ibsen Iceman Isinglass. Jennies Jogger Jejune. Keeper Kosher Kokopelli. Lender Locker Liliput. Menace Mccoy Mimosa. Nebula Noshed Nonesuch. Obsess Ocean Onondaga. Pennies Podium Popcorn. Quanta Qophs Queque. Reduce Rogue Reread. Senior Sconce Sesame. Tendon Torque Totality. Under Ugliness Usually. Versed Vouch Vivacious. Wench Worker Wowed. Xenon Xochitl Xerxes. Yeoman Yonder Yoyo. Zebra Zombie Zizek.

&lt;p style="font-variant:small-caps"&gt;
Abide abide acorn of the habit dacron for the buddha gouda quaalude. Bench bench bogus of the scribe robot for the aplomb jacob ribbon. Census census coral of the spiced jocose for the basic havoc soccer. Demure demure docile of the tidbit lodger for the cuspid period bidder. Ebbing ebbing echoing of the bushed decal for the apache anode needs. Feeder feeder focus of the lifer bedford for the serif proof buffer. Gender gender gospel of the pigeon dogcart for the sprig quahog digger. Herald herald honors of the dihedral madhouse for the penh riyadh bathhouse. Ibsen ibsen iceman of the aphid nordic for the sushi saudi shiite. Jennies jennies jogger of the tijera adjourn for the oranj kowboj hajjis. Keeper keeper kosher of the shrike bookcase for the sheik logbook chukkas. Lender lender locker of the child gigolo for the uncoil gambol enrolled. Menace menace mccoy of the nimble tomcat for the denim random summon. Nebula nebula noshed of the inbred bronco for the cousin carbon kennel. Obsess obsess ocean of the phobic dockside for the gaucho libido hooded. Pennies pennies podium of the sniper opcode for the scrip bishop hopper. Quanta quanta qophs of the inquest oqos for the cinq coq suqqu. Reduce reduce rogue of the girdle orchid for the memoir sensor sorrel. Senior senior sconce of the disbar godson for the hubris amends lessen. Tendon tendon torque of the united scotch for the nought forgot bitters. Under under ugliness of the rhubarb seduce for the manchu hindu continuum. Versed versed vouch of the diver ovoid for the telaviv karpov flivver. Wench wench worker of the unwed snowcap for the andrew escrow glowworm. Xenon xenon xochitl of the mixed boxcar for the suffix icebox exxon. Yeoman yeoman yonder of the hybrid arroyo for the dinghy brandy sayyid. Zebra zebra zombie of the prized ozone for the franz arroz buzzing.
&lt;/p&gt;</description>
            <pubDate>Wed, 10 Jun 2020 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2020-06-10-text-for-proofing-fonts.html</guid>
        </item>
        
        <item>
            <title>Recursively extracting nested links from a webpage using Racket</title>
            <link>https://www.lucabol.com/posts/2020-05-11-recursively-extracting-sensted-links-from-a-webpage-using-Racket.html</link>
            <description>&lt;p&gt;This is my first attempt at writing Racket or LISP code. It might be ugly &amp;hellip;
  For now, let&amp;rsquo;s build a web crawler, next, I shall write myself a language.
  That&amp;rsquo;s where Racket really shine.&lt;/p&gt;
&lt;p&gt;The code is &lt;a href="https://github.com/lucabol/website-links"&gt;here&lt;/a&gt;. Thanks to &lt;a href="https://github.com/mjrousos"&gt;Mike&lt;/a&gt; for reviewing it.&lt;/p&gt;
&lt;h2&gt;Why&lt;/h2&gt;
&lt;p&gt;I want to translate a website, including recursively reached pages, to a pdf to read on my e-reader.
  This program does the first step: going from a URL to a list of URLs by recursively navigating the links
  on the page.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;PS1Script&lt;/code&gt; directory contains scripts to perfrom the other steps:
  1. Translate all the links to PDF pages (using Chrome headless).
  2. Combine all the PDFs to a single document (using &lt;code&gt;cpdf&lt;/code&gt;).&lt;/p&gt;
&lt;h2&gt;Prelude&lt;/h2&gt;
&lt;p&gt;First you declare which language you are using. Racket is a language to build
  languages and the language itself is just one of many (try rereading this phrase).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;#lang racket
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then expose the main functions of the library. Aka recursively getting all links from a webpage
  to a certain nesting level both as a Racket list and as a newline delimitated string.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;; Provides functions to extract links from web pages recursively

(provide
 ; uriString nestingLevels -&amp;gt; list of uriStrings
 ; Doesn't follow links to non-html resources or pointing to a different domain then uriString.
 uri-&amp;gt;nestedLinks
 ; uriSTring nestingLevels -&amp;gt; string of newline separated Uri Strings
 uri-&amp;gt;nestedLinksNl)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;This is similar, but not identical, to C# &lt;code&gt;using&lt;/code&gt; statement as you declare which packages are needed.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(require (planet neil/html-parsing:2:0)
         net/url
         xml
         html
         sxml/sxpath
         threading)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The program crawl just links to html files in the same domain as the first URI given to it. It is
  possible to extend this more by having the program take a regular expression (or * expression) to 
  identify which file sto leave out of the crawling.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define invalid-suffixes
  '(&amp;quot;./&amp;quot; &amp;quot;.xml&amp;quot; &amp;quot;.jpg&amp;quot; &amp;quot;.jpeg&amp;quot; &amp;quot;.png&amp;quot; &amp;quot;.gif&amp;quot; &amp;quot;.tiff&amp;quot; &amp;quot;.psd&amp;quot;
    &amp;quot;.eps&amp;quot; &amp;quot;.ai&amp;quot; &amp;quot;.indd&amp;quot; &amp;quot;.raw&amp;quot; &amp;quot;.svg&amp;quot;))

(define invalid-prefixes '(&amp;quot;#&amp;quot; &amp;quot;mailto:&amp;quot; &amp;quot;javascript:&amp;quot;))

(define (different-domain? baseUrl l)
  (define url (string-&amp;gt;url l))
  (and (url-host url) (not (equal? (url-host baseUrl) (url-host url)))))

(define (good-link? baseUrl l) (not (or (different-domain? baseUrl l)
                                (ormap (curry string-suffix? l) invalid-suffixes)
                                (ormap (curry string-prefix? l) invalid-prefixes))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next we have to parse the HTML. We use XPath for that. Racket is particularly good for XML parsing as
  it maps naturally to expressions which are the bread and butter of the language. I don&amp;rsquo;t enjoy
  the nesting of expressions that LISP like languages force onto you (as in the expression below). But
  see later for a partial solution.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define (xexp-&amp;gt;links xexp) (flatten (map cdr ((sxpath &amp;quot;//a/@href&amp;quot;) xexp))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The strange &lt;code&gt;~&amp;gt;&amp;gt;&lt;/code&gt; operator in the code below comes from the &lt;a href="https://docs.racket-lang.org/threading/index.html"&gt;&lt;code&gt;Threading&lt;/code&gt;&lt;/a&gt;
  package. This set of macros lets you build pipelines of computations similarly to the F# &lt;code&gt;|&amp;gt;&lt;/code&gt; operator.
  The initial value comes first and then the functions are applied in series each one to the result of 
  the previous. By doing that you &amp;lsquo;flatten&amp;rsquo; the nested expressions, making them more readable (at least to my eyes).&lt;/p&gt;
&lt;p&gt;This capability of changing the core behavior of the language is something very peculiar to the LISP family,
  and the reaason why I am attracted to Racket in the first place.&lt;/p&gt;
&lt;p&gt;This function extracts all the &amp;lsquo;good&amp;rsquo; links from a url. BTW: I love that you can use &lt;code&gt;-&amp;gt;&lt;/code&gt; to name symbols.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define (url-&amp;gt;links url)
  (~&amp;gt;&amp;gt; (call/input-url url get-pure-port html-&amp;gt;xexp)
       xexp-&amp;gt;links
       (filter (curry good-link? url))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;λ~&amp;gt; is the function composition operator in the &amp;lsquo;Threading&amp;rsquo; library. You got to love embedding lambdas in the code. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define uri-&amp;gt;links
  (λ~&amp;gt; string-&amp;gt;url url-&amp;gt;links))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the main recursive workhorse of the program. It works something like this (numbers marked in the code):&lt;/p&gt;
&lt;ol start="0"&gt;
&lt;li&gt;Treat links to subparts of a web page as if they were links to the webpage&lt;/li&gt;
&lt;li&gt;If it is not a good link, return the links already visited (&lt;code&gt;visited&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Same thing if the link is alread in &lt;code&gt;visited&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If we reached the nesting level specified, add the link to &lt;code&gt;visited&lt;/code&gt; and return &amp;lsquo;visited&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Otherwise add the link to &lt;code&gt;visited&lt;/code&gt; and call yourself on all sublinks on the page&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The function is not tail recursive, but that is not a huge deal in Racket as the stack is very large.
  It doesn&amp;rsquo;t blow up as easily as in most other languages.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define (uri-&amp;gt;nestedLinks-rec baseUrl uri visited levels)

  (define abs-url (if (string-contains? uri &amp;quot;#&amp;quot;) ; &amp;lt;0&amp;gt;
      (~&amp;gt; uri (string-split &amp;quot;#&amp;quot;) first (combine-url/relative baseUrl _))
      (~&amp;gt;&amp;gt; uri (combine-url/relative baseUrl))))

  (log-info &amp;quot;~a, ~a, ~a:~a~n&amp;quot; (url-&amp;gt;string baseUrl)
                              levels uri (url-&amp;gt;string abs-url))

  (cond [(not (good-link? baseUrl uri)) visited] ; &amp;lt;1&amp;gt;
        [(member abs-url visited)  visited]      ; &amp;lt;2&amp;gt;
        [(zero? levels)  (cons abs-url visited)] ; &amp;lt;3&amp;gt;
        [else  (for/fold ([acc (cons abs-url visited)]) ;&amp;lt;4&amp;gt;
                         ([l (in-list (url-&amp;gt;links abs-url))])
                 (uri-&amp;gt;nestedLinks-rec abs-url l acc (sub1 levels)))]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally we can trivially define the two main functions in the module. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define (uri-&amp;gt;nestedLinks uri levels)
  (reverse (uri-&amp;gt;nestedLinks-rec (string-&amp;gt;url uri) &amp;quot;&amp;quot; '() levels)))

(define (uri-&amp;gt;nestedLinksNl uri levels)
  (define links (uri-&amp;gt;nestedLinks uri levels))
  (string-join (map url-&amp;gt;string links) &amp;quot;\n&amp;quot; #:after-last &amp;quot;\n&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Test&lt;/h2&gt;
&lt;p&gt;To my great pleasure, Racket allows (encourages?) you to have tests in the same file as the code.
They just go into sub modules, that can be constructed piecewise with the &lt;code&gt;module+&lt;/code&gt; instruction.&lt;/p&gt;
&lt;p&gt;You could add the tests beside each function, but I decided to have a separate section in the file
instead. To run them you call &lt;code&gt;raco test FILENAME&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define (uri-&amp;gt;path test-uri)
        (build-path &amp;quot;./data&amp;quot; (~&amp;gt; test-uri first uri-&amp;gt;file string-&amp;gt;path)))
(define uri-&amp;gt;file (λ~&amp;gt; string-&amp;gt;url url-host))
(define test-uris '(
                    (&amp;quot;https://www.lucabol.com&amp;quot; 3)
                    (&amp;quot;https://beautifulracket.com/&amp;quot; 3)
                    (&amp;quot;https://en.wikipedia.org/wiki/Typeface&amp;quot; 1)
                    (&amp;quot;https://brieferhistoryoftime.com&amp;quot; 3)
                    (&amp;quot;https://mobydick.wales/&amp;quot; 3)
                    (&amp;quot;https://resilientwebdesign.com&amp;quot; 3)
                    (&amp;quot;https://www.c82.net/euclid/&amp;quot; 3)
                    ))

(module+ test
  (require rackunit)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I got a bit sloppy not naming my lambdas here &amp;hellip; But, doesn&amp;rsquo;t the lambda symbol look cool? &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;  (for-each (λ (test-uri)
              (with-input-from-file
                  (uri-&amp;gt;path test-uri)
                (λ () (begin
                        (define saved-result (port-&amp;gt;string))
                        (define calc-result
                          (uri-&amp;gt;nestedLinksNl (first test-uri) (second test-uri)))
                        (check-equal? calc-result saved-result test-uri)))
                #:mode 'text
                ))
            test-uris))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is used to regenerate the test data. You can then inspect it manually before running tests. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(define (refresh-test-data)
    (for-each (λ (test-uri)
                (with-output-to-file
                    (uri-&amp;gt;path test-uri)                  
                  (λ () (display (uri-&amp;gt;nestedLinksNl (first test-uri) (second test-uri))))
                  #:exists 'replace))
              test-uris))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Main&lt;/h2&gt;
&lt;p&gt;Main goes into its own submodule as well. Racket is not as pure as Haskell, so you can naturally 
  manage side effects like user input and such. You got to appreciate the concisivness of the command
  line parsing library.&lt;/p&gt;
&lt;p&gt;The code below looks a bit odd to me. It could probably be refactored
  so that the parser expression returns the values instead of filling out  parameters.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-racket"&gt;(module+ main

  (define levels (make-parameter &amp;quot;3&amp;quot;))
  (define uri (make-parameter #f))

  (define parser
    (command-line
     #:program &amp;quot;website-links&amp;quot;
     #:usage-help &amp;quot;Extracts links from a webpage recursively to a specified level.&amp;quot;
     #:once-each
     [(&amp;quot;-l&amp;quot; &amp;quot;--levels&amp;quot;) LEVELS &amp;quot;How many nested levels to process (default 3).&amp;quot; (levels LEVELS)]
     #:args (URI) (uri URI)))

  (display (uri-&amp;gt;nestedLinksNl (uri) (string-&amp;gt;number (levels)))))

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I liked Racket very much. It takes a little while to get use to the expression syntax, which is very
  different from the C-like one most of us are used to. It also takes a while to get used to the style 
  of the documentation, which is written very precisely for the careful reader. We are more used to the
  &amp;lsquo;here is an example, copy it&amp;rsquo; kind of documentation. For the distracted programmer &amp;hellip;&lt;/p&gt;</description>
            <pubDate>Mon, 11 May 2020 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2020-05-11-recursively-extracting-sensted-links-from-a-webpage-using-Racket.html</guid>
        </item>
        
        <item>
            <title>Confusing characters in text</title>
            <link>https://www.lucabol.com/posts/2020-03-19-confusing-characters-in-text.html</link>
            <description>&lt;p&gt;In the process of chosing fonts for my blog, I looked for lists of words containing characters that can be easily confused.&lt;/p&gt;
&lt;p&gt;I took this one from &lt;a href="https://typography.guru/journal/letters-symbols-misrecognition/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Henry III - Henry lII - Henry 111 - Henry tll - Henry t7I&lt;/p&gt;
&lt;p&gt;Henry l - Henry 1 - Henry I - Henry 7&lt;/p&gt;
&lt;p&gt;i j, B 8, D 0, O 0, o 0, k R, a o, &lt;em&gt;f&lt;/em&gt; &lt;em&gt;F&lt;/em&gt; , r v Y, B 8, g q, a g, J I, J L, l !, u v, U V, 5 S, B 8, a o, rn m, vv w, Z 2, C G, Q O, ISO 150, go 90, LJ IJ LI Ll L1 U, LU LLI UU W, LILI UU, CI O 0, &amp;lt;j (J (j (T&lt;/p&gt;
&lt;p&gt;clear dear, burn bum, skivvy skiwy, CS5 CSS, 105 IOS, z2 22, 5AM SAM, travel bavel, LJ U, MENSUR SULJOVIC, 6 9, ce œ, amazon.corn amazon.com mac.com rnac.com, Ox0 0OR &lt;/p&gt;
&lt;p&gt;minnimalistI1llI&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Henry III - Henry lII - Henry 111 - Henry tll - Henry t7I

Henry l - Henry 1 - Henry I - Henry 7

i j, B 8, D 0, O 0, o 0, k R, a o, _f_ _F_ , r v Y, B 8, g q, a g, J I, J L, l !, u v, U V, 5 S, B 8, a o, rn m, vv w, Z 2, C G, Q O, ISO 150, go 90, LJ IJ LI Ll L1 U, LU LLI UU W, LILI UU, CI O 0, &amp;lt;j (J (j (T

clear dear, burn bum, skivvy skiwy, CS5 CSS, 105 IOS, z2 22, 5AM SAM, travel bavel, LJ U, MENSUR SULJOVIC, 6 9, ce œ, amazon.corn amazon.com mac.com rnac.com, Ox0 0OR 

minnimalistI1llI
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Sun, 19 Jan 2020 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2020-03-19-confusing-characters-in-text.html</guid>
        </item>
        
        <item>
            <title>Introducing PS1 Libraries for Azure Lab Services and DevTest Labs</title>
            <link>https://www.lucabol.com/posts/2020-01-06-introducing-ps1-libraries-for-azure-lab-services-and-devtest-lab.html</link>
            <description>&lt;p&gt;I am not sure why I have not blogged about this. We have released some very nice PS1 libraries to automate the usage of Azure Lab Services and Azure DevTest Labs.&lt;/p&gt;
&lt;p&gt;The nicest thing about them is how they make use of the &lt;a href="https://docs.microsoft.com/en-us/powershell/scripting/learn/understanding-the-powershell-pipeline?view=powershell-7"&gt;PS1 Pipeline&lt;/a&gt; to give a nice user experience.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;Get-AzLabAccount | Get-AzLab | Get-AzLabVm -Status Running | Stop-AzLabVm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I intend to shoot some brief videos to describe how to use them. In the meantime, you can read tutorials &lt;a href="https://github.com/Azure/azure-devtestlab/blob/master/samples/ClassroomLabs/Modules/Library/HowTo.md"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/Azure/azure-devtestlab/blob/master/samples/DevTestLabs/Modules/Library/HowTo.md"&gt;here&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 06 Jan 2020 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2020-01-06-introducing-ps1-libraries-for-azure-lab-services-and-devtest-lab.html</guid>
        </item>
        
        <item>
            <title>Status of C# 8.0 functional features with a comparison to Haskell</title>
            <link>https://www.lucabol.com/posts/2019-12-06-status-of-csharp-8-functional-features-with-a-comparison-to-haskell.html</link>
            <description>&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Writing C# functional code has become easier with each new release of the language (i.e. nullable ref types, tuples, switch expr, &amp;hellip;).
This document presents a review of the current status of &lt;em&gt;basic&lt;/em&gt; functional features for C# 8.0.
It focuses mostly on syntax and aims to achieve its goal using code examples.
It doesn&amp;rsquo;t touches on more advanced topics as Monad, Functors, etc &amp;hellip;&lt;/p&gt;
&lt;p&gt;Haskell has been chosen as the &amp;lsquo;comparison&amp;rsquo; language (using few examples from &lt;a href="http://learnyouahaskell.com/"&gt;here&lt;/a&gt; and elsewhere).
This is not intended as a statement of value of one language vs the other.
The languages are profoundly  different in underlying philosophies.
They both do much more than what is presented here (i.e. C# supports OO and imperative style, while Haskell goes much deeper in type system power etc&amp;hellip;).&lt;/p&gt;
&lt;p&gt;I also present samples of usage of &lt;a href="https://github.com/louthy/language-ext"&gt;language-ext&lt;/a&gt; to show what can be achieved in C# using a functional library.&lt;/p&gt;
&lt;h2&gt;Using a library of functions&lt;/h2&gt;
&lt;p&gt;In C# you can use static functions as if they were &amp;lsquo;floating&amp;rsquo; by importing the static class they are defined to with the syntax &lt;code&gt;using static CLASSNAME&lt;/code&gt;. Below an example of both importing &lt;code&gt;Console.WriteLine&lt;/code&gt; and using it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.IO;

using LanguageExt;
using LanguageExt.TypeClasses;
using LanguageExt.ClassInstances;
using System.Collections.Generic;

using static System.Console;
using static System.Linq.Enumerable;
using static System.Math;
using static LanguageExt.Prelude;

public static class Core {

    static void UseFunc() =&amp;gt; WriteLine(&amp;quot;System.WriteLine as a floating function&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Writing simple functions&lt;/h2&gt;
&lt;p&gt;In Haskell, a simple function might be written as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;   square :: Num a =&amp;gt; a -&amp;gt; a
   square x = x * x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which in C# looks like the below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static int Square(int x) =&amp;gt; x * x; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As an aside, note that we lose the generality of the function (i.e. we need a different one for doubles).This is due to the lack of ad-hoc polymorphism in C#.
By using language-ext, you can fake it so that it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static A Square&amp;lt;NumA, A&amp;gt;(A x) where NumA : struct, Num&amp;lt;A&amp;gt; =&amp;gt; default(NumA).Product(x, x);

    static void SquarePoly() {
        WriteLine(Square&amp;lt;TInt, int&amp;gt;(2));
        WriteLine(Square&amp;lt;TDouble, double&amp;gt;(2.5));
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Haskell, it is conventional to write the type of a function before the function itself. In C# you can use &lt;code&gt;Func&lt;/code&gt; and &lt;code&gt;Action&lt;/code&gt; to
achieve a similar goal (aka seeing the types separately from the function implementation), despite with more verbose syntax, as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static Func&amp;lt;int, int&amp;gt; SquareF = x =&amp;gt; x * x;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Pattern matching&lt;/h2&gt;
&lt;p&gt;Here is an example in Haskell:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;    lucky :: (Integral a) =&amp;gt; a -&amp;gt; String  
    lucky 7 = &amp;quot;LUCKY NUMBER SEVEN!&amp;quot;  
    lucky x = show x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, you can write it in a few ways. Either as a function static property &amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static Func&amp;lt;int, string&amp;gt; Lucky = x =&amp;gt; x switch {
            7 =&amp;gt; &amp;quot;LUCKY NUMBER SEVEN!&amp;quot;,
            _ =&amp;gt; x.ToString()
        };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or with a normal function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static string Lucky1(int x) =&amp;gt; x switch {
            7 =&amp;gt; &amp;quot;LUCKY NUMBER SEVEN!&amp;quot;,
            _ =&amp;gt; x.ToString()
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or even using the ternary operator (a perennial favorite of mine).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static string Lucky2(int x) =&amp;gt; x == 7 ? &amp;quot;LUCKY NUMBER SEVEN!&amp;quot;
                                          : x.ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pattern matching on tuples works with similar syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static bool And(bool x, bool y) =&amp;gt;
        (x, y) switch
        {
            (true, true) =&amp;gt; true,
            _            =&amp;gt; false
        };


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Haskell you can match on lists as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;    sum :: Num a =&amp;gt; [a] -&amp;gt; a
    sum [] = 0
    sum (x:xs) = x + sum xs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Writing this in standard C# looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static int Sum(IEnumerable&amp;lt;int&amp;gt; l) =&amp;gt; l.Count() == 0
                                            ? 0
                                            : l.First() + Sum(l.Skip(1));

    static int Sum1(IEnumerable&amp;lt;int&amp;gt; l) =&amp;gt; l.Count() switch {
        0 =&amp;gt; 0,
        _ =&amp;gt; l.First() + Sum(l.Skip(1))
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Language-ext gives you a simpler syntax, with more flexibility on what you can match against:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static int Sum2(Seq&amp;lt;int&amp;gt; l) =&amp;gt;
        match(l,
               () =&amp;gt; 0,
               (x, xs) =&amp;gt; x + Sum1(xs));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously you always have to be careful with recursion in C# (&lt;a href="https://github.com/dotnet/csharplang/issues/2544"&gt;here&lt;/a&gt;).
Better use the various methods on &lt;code&gt;Enumerable&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Guards (and case expressions)&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s explore guards. Case expressions have an identical translation in C#.&lt;/p&gt;
&lt;p&gt;In Haskell guards are used as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;    bmiTell :: (RealFloat a) =&amp;gt; a -&amp;gt; a -&amp;gt; String  
    bmiTell weight height  
            | weight / height ^ 2 &amp;lt;= 18.5 = &amp;quot;Under&amp;quot;  
            | weight / height ^ 2 &amp;lt;= 25.0 = &amp;quot;Normal&amp;quot;  
            | weight / height ^ 2 &amp;lt;= 30.0 = &amp;quot;Over&amp;quot;  
            | otherwise                   = &amp;quot;Way over&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which can be coded in C# as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static string BmiTell(double weight, double height) =&amp;gt;
        (weight, height) switch
        {
            _ when Pow(weight / height, 2) &amp;lt;= 18.5 =&amp;gt; &amp;quot;Under&amp;quot;,
            _ when Pow(weight / height, 2) &amp;lt;= 25.0 =&amp;gt; &amp;quot;Normal&amp;quot;,
            _ when Pow(weight / height, 2) &amp;lt;= 30.0 =&amp;gt; &amp;quot;Over&amp;quot;,
            _                                      =&amp;gt; &amp;quot;Way over&amp;quot;
        };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously this is quite bad. You would like something more like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;    bmiTell :: (RealFloat a) =&amp;gt; a -&amp;gt; a -&amp;gt; String  
    bmiTell weight height  
            | bmi &amp;lt;= skinny = &amp;quot;Under&amp;quot;  
            | bmi &amp;lt;= normal = &amp;quot;Normal&amp;quot;  
            | bmi &amp;lt;= fat    = &amp;quot;Over&amp;quot;  
            | otherwise     = &amp;quot;Way Over&amp;quot;  
            where bmi = weight / height ^ 2  
                  skinny = 18.5  
                  normal = 25.0  
                  fat = 30.0 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But it is not trivial in C# to declare variables in expression bodied members.
You can either move it to a normal method or abuse the LINQ query syntax. Both shown below.
Notice that this is more similar to &lt;code&gt;let&lt;/code&gt; expressions in Haskell, as they come before the expression, not after.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static string BmiTell1(double weight, double height) {
        double bmi = Pow(weight / height, 2),
               skinny = 18.5,
               normal = 25.0,
               fat = 30;

        return bmi switch
        {
            _ when bmi &amp;lt;= skinny =&amp;gt; &amp;quot;Under&amp;quot;,
            _ when bmi &amp;lt;= normal =&amp;gt; &amp;quot;Normal&amp;quot;,
            _ when bmi &amp;lt;= fat    =&amp;gt; &amp;quot;Over&amp;quot;,
            _                    =&amp;gt; &amp;quot;Way over&amp;quot;
        };
    }

    static string BmiTell2(double weight, double height) =&amp;gt;
        (   from _ in &amp;quot;x&amp;quot;
            let bmi     = Pow(weight / height, 2)
            let skinny  = 18.5
            let normal  = 25.0
            let fat     = 30
            select   bmi &amp;lt;= skinny ? &amp;quot;Under&amp;quot;
                   : bmi &amp;lt;= normal ? &amp;quot;Normal&amp;quot;
                   : bmi &amp;lt;= fat    ? &amp;quot;Over&amp;quot;
                   :                 &amp;quot;Way over&amp;quot;).First();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Product types (aka Records)&lt;/h2&gt;
&lt;p&gt;In Haskell you define a product type as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;    data Person = Person { firstName :: String  
                             , lastName :: String  
                             , age :: Int
                             } deriving (Show)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, it is currently complicated to define an immutable product type with structural equality, structural ordering and efficient hashing.&lt;/p&gt;
&lt;p&gt;In essence, you have to implement a bunch of interfaces and operators, somehow similar to below (and I am not implementing ordering, and it is probably not too efficient either).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public readonly struct PersonData: IEquatable&amp;lt;PersonData&amp;gt; {
        public readonly string FirstName;
        public readonly string LastName;
        public readonly int Age;

        public PersonData(string first, string last, int age) =&amp;gt; (LastName, FirstName, Age) = (last, first, age);

        public override int GetHashCode() =&amp;gt; (FirstName, LastName, Age).GetHashCode();
        public override bool Equals(object other) =&amp;gt; other is PersonData l &amp;amp;&amp;amp; Equals(l);
        public bool Equals(PersonData oth) =&amp;gt; LastName == oth.LastName &amp;amp;&amp;amp; FirstName == oth.FirstName &amp;amp;&amp;amp; Age == oth.Age;
        public static bool operator ==(PersonData lhs, PersonData rhs) =&amp;gt; lhs.Equals(rhs);
        public static bool operator !=(PersonData lhs, PersonData rhs) =&amp;gt; !(lhs == rhs);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you use a &lt;code&gt;struct&lt;/code&gt;, you are still open to someone simply newing it using the default constructor, that you can&amp;rsquo;t make &lt;code&gt;private&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using a class (as below) avoids that, but loses the pass by value semantic.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public class PersonData1 : IEquatable&amp;lt;PersonData1&amp;gt; {
        public readonly string FirstName;
        public readonly string LastName;
        public readonly int Age;

        public PersonData1(string first, string last, int age) =&amp;gt; (LastName, FirstName, Age) = (last, first, age);

        public override int GetHashCode() =&amp;gt; (FirstName, LastName, Age).GetHashCode();
        public override bool Equals(object oth) =&amp;gt; oth is PersonData l &amp;amp;&amp;amp; Equals(l);
        public bool Equals(PersonData1 other) =&amp;gt; LastName == other.LastName &amp;amp;&amp;amp; FirstName == other.FirstName &amp;amp;&amp;amp; Age == other.Age;
        public static bool operator ==(PersonData1 lhs, PersonData1 rhs) =&amp;gt; lhs.Equals(rhs);
        public static bool operator !=(PersonData1 lhs, PersonData1 rhs) =&amp;gt; !(lhs == rhs);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, there is no easy fix. Using Language-ext you can do it much more simply, by inheritance.
But obviously it uses IL generation that is slow the first time around. Try running the code and notice the delay when IL generating.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public class PersonData2 : Record&amp;lt;PersonData2&amp;gt; {
        public readonly string FirstName;
        public readonly string LastName;
        public readonly int Age;

        public PersonData2(string first, string last, int age) =&amp;gt; (LastName, FirstName, Age) = (last, first, age);

    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Sum types (aka Discriminated Union)&lt;/h2&gt;
&lt;p&gt;In Haskell you write:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;    data Shape =
                Circle Float Float Float
            | Rectangle Float Float Float Float
            | NoShape
            deriving (Show)  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is no obvious equivalent in C#, and different libraries has sprung up to propose possible solutions (but not language-ext)
(i.e. &lt;a href="https://github.com/Galad/CSharpDiscriminatedUnion"&gt;here&lt;/a&gt; or &lt;a href="https://github.com/mcintyre321/OneOf"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;One possible &amp;lsquo;pure language&amp;rsquo; implementation, not considering structural equality/ordering/hash, follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    abstract class Shape {

        public sealed class NoShape : Shape { }
        public sealed class Circle : Shape {
            internal Circle(double r) =&amp;gt; Radius = r;
            public readonly double Radius;
        }
        public sealed class Rectangle : Shape {
            internal Rectangle(double height, double width) =&amp;gt; (Height, Width) = (height, width);
            public readonly double Height;
            public readonly double Width;
        }
    }

    static Shape.Circle Circle(double x)                 =&amp;gt; new Shape.Circle(x);
    static Shape.Rectangle Rectangle(double x, double y) =&amp;gt; new Shape.Rectangle(x,y);
    static Shape.NoShape NoShape()                       =&amp;gt; new Shape.NoShape();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then pattern match on it in various obvious ways:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static double Area(Shape s) =&amp;gt; s switch
    {
        Shape.NoShape _                  =&amp;gt; 0,
        Shape.Circle {Radius: var r }    =&amp;gt; Pow(r, 2) * PI,
        Shape.Rectangle r                =&amp;gt; r.Height * r.Width,
        _                                =&amp;gt; throw new Exception(&amp;quot;No known shape&amp;quot;)
    };

    static void CalcAreas() {
        var c = Circle(10);
        var r = Rectangle(10, 3);
        var n = NoShape();

        WriteLine(Area(c));
        WriteLine(Area(r));
        WriteLine(Area(n));
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Maybe (Or Option) type&lt;/h2&gt;
&lt;p&gt;In Haskell you write:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;     f::Int -&amp;gt; Maybe Int
     f 0 = Nothing
     f x = Just x

     g::Maybe Int -&amp;gt; Int
     g Nothing  = 0
     g (Just x) = x

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, this easily translates to &lt;code&gt;Nullable&lt;/code&gt; value and reference types. Assume you have &lt;code&gt;Nullable = enabled&lt;/code&gt; in your project&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static int? F(int i) =&amp;gt; i switch {
        0 =&amp;gt; new Nullable&amp;lt;int&amp;gt;(),
        _ =&amp;gt; i
    };

    static int G(int? i) =&amp;gt; i ?? 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Main Method&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s wrap all the samples with a &lt;code&gt;Main&lt;/code&gt; function and then write a full program.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    static void Main() {
        UseFunc();
        SquarePoly();
        WriteLine(Square(2) == SquareF(2));
        WriteLine(Sum(new[] { 1, 2, 3, 4 })  == Sum1(new[] { 1, 2, 3, 4 }));
        WriteLine(Sum1(new[] { 1, 2, 3, 4 }) == Sum2(new[] { 1, 2, 3, 4 }.ToSeq()));
        WriteLine(BmiTell(80, 100) == BmiTell1(80, 100));
        WriteLine(BmiTell(80, 100) == BmiTell2(80, 100));

        WriteLine(new PersonData(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40) == new PersonData(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40));
        WriteLine(new PersonData1(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40) == new PersonData1(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40));
        WriteLine(&amp;quot;Before IL gen&amp;quot;);
        WriteLine(new PersonData2(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40) == new PersonData2(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40));
        WriteLine(new PersonData2(&amp;quot;Alphie&amp;quot;, &amp;quot;Blake&amp;quot;, 40) &amp;lt;= new PersonData2(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40));
        WriteLine(&amp;quot;Already genned&amp;quot;);
        WriteLine(new PersonData2(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40) == new PersonData2(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40));
        WriteLine(new PersonData2(&amp;quot;Alphie&amp;quot;, &amp;quot;Blake&amp;quot;, 40) &amp;lt;= new PersonData2(&amp;quot;Bob&amp;quot;, &amp;quot;Blake&amp;quot;, 40));

        CalcAreas();

        Hangman.Core.MainHangman();

    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Full program&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s finish with a semi-working version of Hangman,
from an exercise in &lt;a href="http://haskellbook.com/"&gt;Haskell programming from first principles&lt;/a&gt;,
just to get an overall impression of how the two languages look for bigger things.&lt;/p&gt;
&lt;p&gt;The exercise was a fill-in-the-blanks kind of thing with the function names and types given,
so I don&amp;rsquo;t think I butcher it too badly, but maybe not.&lt;/p&gt;
&lt;p&gt;The Haskell code is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-haskell"&gt;module Main where

import Control.Monad (forever) -- [1]
import Data.Char (toLower) -- [2]
import Data.Maybe (isJust) -- [3]
import Data.List (intersperse) -- [4]
import System.Exit (exitSuccess) -- [5]
import System.Random (randomRIO) -- [6]

type WordList = [String]

allWords :: IO WordList
allWords = do
      dict &amp;lt;- readFile &amp;quot;data/dict.txt&amp;quot;
      return (lines dict)

minWordLength :: Int
minWordLength = 5

maxWordLength :: Int
maxWordLength = 9

gameWords :: IO WordList
gameWords = do
      aw &amp;lt;- allWords
      return (filter gameLength aw)
      where gameLength w =
              let l = length (w :: String)
              in l &amp;gt; minWordLength &amp;amp;&amp;amp; l &amp;lt; maxWordLength

randomWord :: WordList -&amp;gt; IO String
randomWord wl = do
      randomIndex &amp;lt;- randomRIO ( 0, length wl - 1)
      return $ wl !! randomIndex

randomWord' :: IO String
randomWord' = gameWords &amp;gt;&amp;gt;= randomWord

data Puzzle = Puzzle String [Maybe Char] [Char]

instance Show Puzzle where
      show (Puzzle _ discovered guessed) =
        (intersperse ' ' $ fmap renderPuzzleChar discovered)
        ++ &amp;quot; Guessed so far: &amp;quot; ++ guessed

freshPuzzle :: String -&amp;gt; Puzzle
freshPuzzle s = Puzzle s (map (const Nothing) s) []

charInWord :: Puzzle -&amp;gt; Char -&amp;gt; Bool
charInWord (Puzzle s _ _) c = c `elem` s

alreadyGuessed :: Puzzle -&amp;gt; Char -&amp;gt; Bool
alreadyGuessed (Puzzle _ _ s) c = c `elem` s

renderPuzzleChar :: Maybe Char -&amp;gt; Char
renderPuzzleChar Nothing  = '_'
renderPuzzleChar (Just c) = c

fillInCharacter :: Puzzle -&amp;gt; Char -&amp;gt; Puzzle
fillInCharacter (Puzzle word filledInSoFar s) c =
      Puzzle word newFilledInSoFar (c : s)
      where zipper guessed wordChar guessChar =
              if wordChar == guessed
                then Just wordChar
                else guessChar
            newFilledInSoFar =
              zipWith (zipper c) word filledInSoFar

handleGuess :: Puzzle -&amp;gt; Char -&amp;gt; IO Puzzle
handleGuess puzzle guess = do
      putStrLn $ &amp;quot;Your guess was: &amp;quot; ++ [guess]
      case (charInWord puzzle guess, alreadyGuessed puzzle guess) of
        (_, True) -&amp;gt; do
          putStrLn &amp;quot;You already guessed that character, pick something else!&amp;quot;
          return puzzle
        (True, _) -&amp;gt; do
          putStrLn &amp;quot;This character was in the word,filling in the word accordingly&amp;quot;
          return (fillInCharacter puzzle guess)
        (False, _) -&amp;gt; do
          putStrLn &amp;quot;This character wasn't in the word, try again.&amp;quot;
          return (fillInCharacter puzzle guess)

gameOver :: Puzzle -&amp;gt; IO ()
gameOver (Puzzle wordToGuess _ guessed) =
      if (length guessed) &amp;gt; 7 then do
          putStrLn &amp;quot;You lose!&amp;quot;
          putStrLn $ &amp;quot;The word was: &amp;quot; ++ wordToGuess
          exitSuccess
      else return ()

gameWin :: Puzzle -&amp;gt; IO ()
gameWin (Puzzle _ filledInSoFar _) =
      if all isJust filledInSoFar then do
        putStrLn &amp;quot;You win!&amp;quot;
        exitSuccess
      else return ()

runGame :: Puzzle -&amp;gt; IO ()
runGame puzzle = forever $ do
      gameOver puzzle
      gameWin puzzle
      putStrLn $ &amp;quot;Current puzzle is: &amp;quot; ++ show puzzle
      putStr &amp;quot;Guess a letter: &amp;quot;
      guess &amp;lt;- getLine
      case guess of
        [c] -&amp;gt; handleGuess puzzle c &amp;gt;&amp;gt;= runGame
        _ -&amp;gt; putStrLn &amp;quot;Your guess must be a single character&amp;quot;


main :: IO ()
main = do
      word &amp;lt;- randomWord'
      let puzzle = freshPuzzle (fmap toLower word)
      runGame puzzle
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which loosely translate to the code below (pure C#, no language-ext) . A few comments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I tried to keep the translation as 1:1 as possible.&lt;/li&gt;
&lt;li&gt;I used expression bodied members for everything except IO returning function. That&amp;rsquo;s a pleasing convention to me.&lt;/li&gt;
&lt;li&gt;Things translate rather straightforwardly except for:&lt;ol&gt;
&lt;li&gt;Cheated using a simple &lt;code&gt;struct&lt;/code&gt; instead of a &lt;code&gt;Record&lt;/code&gt;, but often it is ok to do so.&lt;/li&gt;
&lt;li&gt;Needed to use LINQ query syntax to translate more complex expressions, but cannot have lambadas in it.&lt;/li&gt;
&lt;li&gt;Needed to do manual currying (&lt;code&gt;language-ext&lt;/code&gt; would have beautified that).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;The line count for this example is roughly similar. I think that&amp;rsquo;s random. Also the C# code &amp;lsquo;extends to the right&amp;rsquo; more.&lt;/li&gt;
&lt;li&gt;Notably absent from the code are sum types, which would have been verbose to implement in C#.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;namespace Hangman {
    using WordList = IEnumerable&amp;lt;String&amp;gt;;
    using static System.Linq.Enumerable;

    static class Core {

        const int MinWordLength = 5;
        const int MaxWordLength = 9;

        static WordList AllWords =&amp;gt; File.ReadAllLines(&amp;quot;data/dict.txt&amp;quot;);

        static WordList GameWords =&amp;gt;
            AllWords.Where(w =&amp;gt; w.Length &amp;gt; MinWordLength &amp;amp;&amp;amp; w.Length &amp;lt; MaxWordLength);

        static Random r = new Random();

        static string RandomWord(WordList wl) =&amp;gt; GameWords.ElementAt(r.Next(0, wl.Length()));

        static string RandomWord1 =&amp;gt; RandomWord(GameWords);

        static char RenderPuzzleChar(char? c) =&amp;gt; c ?? '_';

        struct Puzzle { // Not implemented Eq and Ord because not needed in this program
            public string Word;
            public IEnumerable&amp;lt;char?&amp;gt; Discovered;
            public string Guessed;

            public override string ToString() =&amp;gt;
                $&amp;quot;{string.Join(&amp;quot; &amp;quot;, Discovered.Select(RenderPuzzleChar))}&amp;quot;
                    + &amp;quot; Guessed so far: &amp;quot; + Guessed;
        }

        static Puzzle FreshPuzzle(string s) =&amp;gt; new Puzzle {
            Word       = s,
            Discovered = s.Select(_ =&amp;gt; new Nullable&amp;lt;char&amp;gt;()),
            Guessed    = &amp;quot;&amp;quot;
        };

        static bool CharInWord(Puzzle p, char c)     =&amp;gt; p.Word.Contains(c);
        static bool AlreadyGuessed(Puzzle p, char c) =&amp;gt; p.Guessed.Contains(c);

        // Can't assign lambda expression to range variable with let, hence separate function
        static char? Zipper(char guessed, char wordChar, char? guessChar) =&amp;gt;
            wordChar == guessed ? wordChar : guessChar;

        // Manual curry. Could use language-ext to make it more beautiful.
        static Func&amp;lt;char, char?, char?&amp;gt; Zipper1(char c) =&amp;gt; (c1, c2) =&amp;gt; Zipper(c, c1, c2);

        static Puzzle FillInCharacter(Puzzle p, char c) =&amp;gt;
            (from _ in &amp;quot;x&amp;quot;
             let newFilledInSoFar = System.Linq.Enumerable.Zip&amp;lt;char, char?, char?&amp;gt;(p.Word, p.Discovered, Zipper1(c))
             select new Puzzle {
                Word = p.Word,
                Discovered = newFilledInSoFar,
                Guessed = c + p.Guessed
            }).First();

        static Puzzle HandleGuess(Puzzle puzzle, char guess) {// Braces means IO ...
            WriteLine($&amp;quot;Your guess was {guess}&amp;quot;);
            switch (CharInWord(puzzle, guess), AlreadyGuessed(puzzle, guess)) {
                case (_, true):
                    WriteLine(&amp;quot;You already guessed that character, pick something else!&amp;quot;);
                    return puzzle;
                case (true, _):
                    WriteLine(&amp;quot;This character was in the word,filling in the word accordingly&amp;quot;);
                    return FillInCharacter(puzzle, guess);
                case (false, _):
                    WriteLine(&amp;quot;This character wasn't in the word, try again.&amp;quot;);
                    return FillInCharacter(puzzle, guess);
            }
        }

        static void GameOver(Puzzle p) {
            if(p.Guessed.Length &amp;gt; 7) {
                WriteLine(&amp;quot;You lose!&amp;quot;);
                WriteLine($&amp;quot;The word was {p.Word}&amp;quot;);
                Environment.Exit(0);
            }
        }

        static void GameWin(Puzzle p) {
            if(p.Discovered.All(c =&amp;gt; c.HasValue)) {
                WriteLine(&amp;quot;You win!&amp;quot;);
                Environment.Exit(0);
            }
        }

        static void RunGame(Puzzle puzzle) {
            while(true) {
                GameOver(puzzle);
                GameWin(puzzle);
                WriteLine($&amp;quot;Current puzzle is: {puzzle}&amp;quot;);
                WriteLine(&amp;quot;Guess a letter: &amp;quot;);
                var guess = ReadLine();
                if(guess.Length == 1) RunGame(HandleGuess(puzzle, guess[0]));
                else WriteLine(&amp;quot;Your guess must be a single char&amp;quot;);
            }
        }

        public static void MainHangman() {
            var puzzle = FreshPuzzle(RandomWord1);
            RunGame(puzzle);
        }

    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Fri, 06 Dec 2019 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2019-12-06-status-of-csharp-8-functional-features-with-a-comparison-to-haskell.html</guid>
        </item>
        
        <item>
            <title>A single .NET Core project to rule them all</title>
            <link>https://www.lucabol.com/posts/2019-02-04-singleProject.html</link>
            <description>&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;The code is &lt;a href="https://github.com/lucabol/SingleSourceProject"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/mjrousos"&gt;Mike&lt;/a&gt; for reviewing this.&lt;/p&gt;
&lt;p&gt;I have always been mildly irritated by how many .net projects I need to create in my standard workflow.&lt;/p&gt;
&lt;p&gt;Usually I start with an idea for a library; I then want to test it with a simple executable; write some XUnit tests for it and finally benchmark some key scenarios. So I end up with at least four projects to manage.&lt;/p&gt;
&lt;p&gt;Sure, I can find ways to automatically generate those projects, but I have always been weary of codegen to solve complexity issues. It always ends up coming back to bite you. For those of you as old as I am, think &lt;a href="https://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library"&gt;MFC&lt;/a&gt; &amp;hellip;&lt;/p&gt;
&lt;p&gt;So what is my ideal world then? Well, let&amp;rsquo;s try this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;One single project for the library and related artifacts (i.e. test, benchmarks, etc&amp;hellip;).&lt;/li&gt;
&lt;li&gt;Distinguish the library code from the test code from the benchmark code by some convention (i.e. name scheme).&lt;/li&gt;
&lt;li&gt;Generate each artifact (i.e. library, tests, benchmarks, executable) by passing different options to &lt;code&gt;dotnet build&lt;/code&gt; and &lt;code&gt;dotnet run&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a new project by using the standard &lt;code&gt;dotnet new&lt;/code&gt; syntax.&lt;/li&gt;
&lt;li&gt;Have intellisense working normally in each file for my chosen editor (VSCode).&lt;/li&gt;
&lt;li&gt;Work with &lt;code&gt;dotnet watch&lt;/code&gt; so that one can automatically run tests when anything changes.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;What follows, despite working fine, is not the standard way .net tools are used. It is not in the &amp;lsquo;golden path&amp;rsquo;. That is problematic for production usage as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It might not work in your particular configuration.&lt;/li&gt;
&lt;li&gt;It might not work with other tools that rely on the presence of multiple projects (i.e. code coverage? &amp;hellip;).&lt;/li&gt;
&lt;li&gt;It might work now in all scenarios, but get broken in the future as you update to a new framework, sdk, editor.&lt;/li&gt;
&lt;li&gt;It might expose bugs in the tools, now or later, which aren&amp;rsquo;t going to be fixed, as you are not using the tools as intended.&lt;/li&gt;
&lt;li&gt;It might upset your coworkers that are used to a more standard setup.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I need to write a blog post about the concept of the &amp;lsquo;golden path&amp;rsquo; and the perils, mostly hidden, of getting away from it. The summary, it is a bad idea.&lt;/p&gt;
&lt;p&gt;Having said all of that, for the daring souls, here is one way to achieve most of the above. It also works out as a tutorial on how the different components of the .NET Core build system interacts.&lt;/p&gt;
&lt;h2&gt;How to use it&lt;/h2&gt;
&lt;p&gt;Here are the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Type &lt;code&gt;dotnet new -i Lucabol.SingleSourceProject&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a directory for your project and cd to it.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;dotnet new lsingleproject&lt;/code&gt; and optionally &lt;code&gt;--standardVersion &amp;lt;netstandardXX&amp;gt; --appVersion &amp;lt;netcoreappXX&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Either modify the &lt;code&gt;Library.cs&lt;/code&gt;, &lt;code&gt;Main.cs&lt;/code&gt;, &lt;code&gt;Test.cs&lt;/code&gt;, &lt;code&gt;Bench.cs&lt;/code&gt; files or create your own with this convention:&lt;ul&gt;
&lt;li&gt;Code for the executable goes in potentially multiple files named &lt;code&gt;XXXMain.cs&lt;/code&gt; (i.e. &lt;code&gt;MyLibrary.Main.cs&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Code for the tests goes into files named &lt;code&gt;XXXTest.cs&lt;/code&gt; (i.e. &lt;code&gt;MyLibrary.Test.cs&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Code for the benchmarks goes into files named &lt;code&gt;XXXBench.cs&lt;/code&gt; (i.e. &lt;code&gt;MyLibrary.Bench.cs&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Any &lt;code&gt;.cs&lt;/code&gt; file not following the above conventions is compiled into the dll.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Type:&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dotnet build&lt;/code&gt; or &lt;code&gt;dotnet build -c release&lt;/code&gt; to build &lt;code&gt;debug&lt;/code&gt; or &lt;code&gt;release&lt;/code&gt; version of your dll. This doesn&amp;rsquo;t include any of the main, test or bench code.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dotnet build -c main&lt;/code&gt; or &lt;code&gt;dotnet build -c main_release&lt;/code&gt; and the corresponding &lt;code&gt;dotnet run -c ..&lt;/code&gt; build and run the exe.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dotnet build -c test&lt;/code&gt;, &lt;code&gt;dotnet build -c test_release&lt;/code&gt; and &lt;code&gt;dotnet test -c test&lt;/code&gt; build and run the tests.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dotnet build -c bench&lt;/code&gt;, &lt;code&gt;dotnet run -c bench&lt;/code&gt; build and run the benchmark.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;How it all works&lt;/h2&gt;
&lt;p&gt;The various steps above are implemented as follows:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet new -i ...&lt;/code&gt; install a &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/custom-templates"&gt;custom template&lt;/a&gt; that I have created and pushed on NuGet.&lt;/p&gt;
&lt;p&gt;The custom template is composed of the following files:&lt;/p&gt;
&lt;h3&gt;Code files&lt;/h3&gt;
&lt;p&gt;There is one file for each kind of artifact that the project can generate: library, program, tests and benchmark. The files follow the name terminating conventions, as described above.&lt;/p&gt;
&lt;h3&gt;Project file&lt;/h3&gt;
&lt;p&gt;The project file is identical to any other project file generated by &lt;code&gt;dotnet new&lt;/code&gt; except that there is one additional line appended at the end:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;&amp;lt;Import Project=&amp;quot;Base.targets&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This instruct &lt;code&gt;msbuild&lt;/code&gt; to include the &lt;code&gt;Base.targets&lt;/code&gt; file. That file has most of the magick. I have separated it out so that you can use it unchanged in your own projects.&lt;/p&gt;
&lt;h3&gt;Base.targets&lt;/h3&gt;
&lt;p&gt;We start by removing all the file from compilation except the ones that are used to build the library.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;Compile Remove=&amp;quot;**/*Bench.cs;**/*Test.cs;**/*Main.cs&amp;quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then conditionally include the correct ones depending on which configuration is chosen. Please notice the last line, which instruct &lt;code&gt;dotnet watch&lt;/code&gt; to watch all the &lt;code&gt;.cs&lt;/code&gt; files. By default it just watches the ones in the &lt;code&gt;debug&lt;/code&gt; configuration.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;Compile Include=&amp;quot;**/*Test.cs&amp;quot;  Condition=&amp;quot;'$(Configuration)'=='Test'&amp;quot;/&amp;gt;
    &amp;lt;Compile Include=&amp;quot;**/*Test.cs&amp;quot;  Condition=&amp;quot;'$(Configuration)'=='Test_Release'&amp;quot;/&amp;gt;
    &amp;lt;Compile Include=&amp;quot;**/*Bench.cs&amp;quot; Condition=&amp;quot;'$(Configuration)'=='Bench'&amp;quot;/&amp;gt;
    &amp;lt;Compile Include=&amp;quot;**/*Main.cs&amp;quot;  Condition=&amp;quot;'$(Configuration)'=='Main'&amp;quot;/&amp;gt;
    &amp;lt;Compile Include=&amp;quot;**/*Main.cs&amp;quot;  Condition=&amp;quot;'$(Configuration)'=='Main_Release'&amp;quot;/&amp;gt;
    &amp;lt;Watch Include=&amp;quot;**\*.cs&amp;quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we need to define the references. Depending on what you are building you need to include references to the correct NuGet packages (i.e. if you are building &lt;code&gt;test&lt;/code&gt; you need the &lt;code&gt;xunit&lt;/code&gt; packages). This is done below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;  &amp;lt;ItemGroup  Condition=&amp;quot;'$(Configuration)'=='Bench' OR '$(Configuration)'=='Debug'&amp;quot;&amp;gt;
    &amp;lt;PackageReference Include=&amp;quot;BenchmarkDotNet&amp;quot; Version=&amp;quot;0.11.3&amp;quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;

  &amp;lt;ItemGroup Condition=&amp;quot;'$(Configuration)'=='Test' OR '$(Configuration)'=='Test_Release' OR '$(Configuration)'=='Debug'&amp;quot;&amp;gt;
    &amp;lt;PackageReference Include=&amp;quot;Microsoft.NET.Test.Sdk&amp;quot; Version=&amp;quot;15.9.0&amp;quot; /&amp;gt;
    &amp;lt;PackageReference Include=&amp;quot;xunit&amp;quot; Version=&amp;quot;2.4.0&amp;quot; /&amp;gt;
    &amp;lt;PackageReference Include=&amp;quot;xunit.runner.visualstudio&amp;quot; Version=&amp;quot;2.4.0&amp;quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One thing to notice is that most references are also included in the &lt;code&gt;debug&lt;/code&gt; configuration. This is not a good thing, but it is the only way to get VSCode Intellisense to work for all the files in the solution. Apparently, IntelliSense uses whatever reference are defined for the &lt;code&gt;debug&lt;/code&gt; build in &lt;code&gt;VsCode&lt;/code&gt;. So &lt;code&gt;debug&lt;/code&gt; is special, if you wish &amp;hellip;&lt;/p&gt;
&lt;p&gt;But that&amp;rsquo;s not enough. When you create your own &lt;code&gt;MsBuild&lt;/code&gt; configurations, you also have to replicate the properties and constants that are set in the &lt;code&gt;debug&lt;/code&gt; and &lt;code&gt;release&lt;/code&gt; configurations. You would like a way to inherit them, but I don&amp;rsquo;t think it is possible.&lt;/p&gt;
&lt;p&gt;It is particularly important to set the &lt;code&gt;TargetFramework&lt;/code&gt; property, as it needs to be set to &lt;code&gt;netcoreappXXX&lt;/code&gt; for the main, test and benchmark configurations. I give an example of the &lt;code&gt;Test&lt;/code&gt; and &lt;code&gt;Test_release&lt;/code&gt; configurations below. The rest is similar:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;  &amp;lt;PropertyGroup Condition=&amp;quot;'$(Configuration)'=='Test'&amp;quot;&amp;gt;
    &amp;lt;TargetFramework&amp;gt;netcoreapp2.1&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;DefineConstants&amp;gt;$(DefineConstants);DEBUG;TRACE;TEST&amp;lt;/DefineConstants&amp;gt;
    &amp;lt;DebugSymbols&amp;gt;true&amp;lt;/DebugSymbols&amp;gt;
    &amp;lt;DebugType&amp;gt;portable&amp;lt;/DebugType&amp;gt;
    &amp;lt;Optimize&amp;gt;false&amp;lt;/Optimize&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;PropertyGroup Condition=&amp;quot;'$(Configuration)'=='Test_Release'&amp;quot;&amp;gt;
    &amp;lt;TargetFramework&amp;gt;netcoreapp2.1&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;DefineConstants&amp;gt;$(DefineConstants);RELEASE;TRACE;TEST&amp;lt;/DefineConstants&amp;gt;
    &amp;lt;DebugSymbols&amp;gt;false&amp;lt;/DebugSymbols&amp;gt;
    &amp;lt;DebugType&amp;gt;portable&amp;lt;/DebugType&amp;gt;
    &amp;lt;Optimize&amp;gt;true&amp;lt;/Optimize&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The .template.config/template.json file&lt;/h3&gt;
&lt;p&gt;This is necessary to create a &lt;code&gt;dotnet new&lt;/code&gt; custom template. The only thing to notice is the two parameters &lt;code&gt;standardVersion&lt;/code&gt; and &lt;code&gt;appVersion&lt;/code&gt; that gives the user a way to indicate which version of the .NET Standard to use for the library and which version of the application framework to use for Main, Test and Bench.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;{
  &amp;quot;$schema&amp;quot;: &amp;quot;http://json.schemastore.org/template&amp;quot;,
  &amp;quot;author&amp;quot;: &amp;quot;Luca Bolognese&amp;quot;,
  &amp;quot;classifications&amp;quot;: [ &amp;quot;Classlib&amp;quot;, &amp;quot;Console&amp;quot;, &amp;quot;XUnit&amp;quot; ],
  &amp;quot;identity&amp;quot;: &amp;quot;Lucabol.SingleSourceProject&amp;quot;,
  &amp;quot;name&amp;quot;: &amp;quot;One single Project&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;One single Project for DLL, XUnit, Benchmark &amp;amp; Main, using configurations to decide what to compile&amp;quot;,
  &amp;quot;shortName&amp;quot;: &amp;quot;oneproject&amp;quot;,
  &amp;quot;tags&amp;quot;: {
    &amp;quot;language&amp;quot;: &amp;quot;C#&amp;quot;,
    &amp;quot;type&amp;quot;: &amp;quot;project&amp;quot;
  },
  &amp;quot;preferNameDirectory&amp;quot;: true,
  &amp;quot;sourceName&amp;quot;: &amp;quot;SingleSourceProject&amp;quot;,
  &amp;quot;symbols&amp;quot;:{
    &amp;quot;standardVersion&amp;quot;: {
      &amp;quot;type&amp;quot;: &amp;quot;parameter&amp;quot;,
      &amp;quot;defaultValue&amp;quot;: &amp;quot;netstandard2.0&amp;quot;,
      &amp;quot;replaces&amp;quot;:&amp;quot;netstandard2.0&amp;quot;
    },
    &amp;quot;appVersion&amp;quot;: {
      &amp;quot;type&amp;quot;: &amp;quot;parameter&amp;quot;,
      &amp;quot;defaultValue&amp;quot;: &amp;quot;netcoreapp2.1&amp;quot;,
      &amp;quot;replaces&amp;quot;:&amp;quot;netcoreapp2.1&amp;quot;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Now that you know how it all works, you can make an informed decision if to use it or not. As for me &amp;hellip;&lt;/p&gt;</description>
            <pubDate>Mon, 04 Feb 2019 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2019-02-04-singleProject.html</guid>
        </item>
        
        <item>
            <title>Meta-programming in C# with JIT dead code removal and inlining</title>
            <link>https://www.lucabol.com/posts/2019-01-29-meta-programming-and-policy-based-design.html</link>
            <description>&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/mjrousos"&gt;Mike&lt;/a&gt; for reviewing this.&lt;/p&gt;
&lt;p&gt;This is a way to enable compile time customization of classes/functions in the style of C++ template meta-programming as in &lt;a href="https://en.wikipedia.org/wiki/Modern_C%2B%2B_Design"&gt;Modern C++ Design&lt;/a&gt;.
In particular, we are going to implement the &lt;a href="https://en.wikipedia.org/wiki/Modern_C%2B%2B_Design#Policy-based_design"&gt;policy pattern&lt;/a&gt;, which is compile time version of the &lt;a href="https://en.wikipedia.org/wiki/Strategy_pattern"&gt;strategy pattern&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What do we gain by constraining ourselves to compile time customization, instead of run time one? High performance. Blazingly high performance. You gain an abstraction, without paying for it.&lt;/p&gt;
&lt;p&gt;Too good to be true? Read on!&lt;/p&gt;
&lt;p&gt;BTW1: none of this is new. It has been floating around in various forms. But I have never seen explained fully and associated to the policy pattern.
BTW2: it is also related to the uber cool &lt;a href="https://github.com/dotnet/csharplang/issues/164"&gt;Shape proposal for C#&lt;/a&gt;, where it becomes an implementation detail.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;First, the usual plethora of namespaces &amp;hellip; BenchmarkDotNet is really heavy into separating abstractions in different namespaces &amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Runtime.CompilerServices;
using System.Threading;

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Diagnostics.Windows.Configs;
using BenchmarkDotNet.Mathematics;
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Running;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at the strategy pattern, as more traditionally implemented. You got an interface &lt;code&gt;IIncrementer&lt;/code&gt; and two implementations, either thread safe or not.
Let&amp;rsquo;s also add a couple of struct implementations so that we can measure the performance difference of implementation by classes and by structs.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public interface IIncrementer { void Increment(ref int location); }

public sealed class CStandardIncrementer        : IIncrementer {[MethodImpl(MethodImplOptions.AggressiveInlining)] public void Increment(ref int location) =&amp;gt; location += 1; }
public sealed class CInterlockedIncrementer     : IIncrementer {[MethodImpl(MethodImplOptions.AggressiveInlining)] public void Increment(ref int location) =&amp;gt; Interlocked.Increment(ref location); }

public readonly struct SStandardIncrementer     : IIncrementer {[MethodImpl(MethodImplOptions.AggressiveInlining)] public void Increment(ref int location) =&amp;gt; location += 1; }
public readonly struct SInterlockedIncrementer  : IIncrementer {[MethodImpl(MethodImplOptions.AggressiveInlining)] public void Increment(ref int location) =&amp;gt; Interlocked.Increment(ref location); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then need a class that can be customized by an Incrementer. Think of it as: the policy of incrementing something is independent from the class in question.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a Counter and call it Dynamic as we want to be able to customize it at runtime. We need to keep things simple so that looking at ASM is doable.
Also we inline everything to try to squeeze the most performance out of our program.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class DynamicCounter&amp;lt;T&amp;gt; where T: IIncrementer
{
    int _count;
    T _incrementer;

    public DynamicCounter(T incrementer) =&amp;gt; _incrementer = incrementer;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void Increment() =&amp;gt; _incrementer.Increment(ref _count);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we look at how to implement the strategy pattern at compile time (transforming it magically into the policy pattern).&lt;/p&gt;
&lt;p&gt;(no-one every talks about the negative aspects of giving names to things, one of these days I&amp;rsquo;ll blog about it &amp;hellip;)&lt;/p&gt;
&lt;p&gt;There are many ways to go about it. They all rely on the fact that the JIT Compiler instantiates a different type for each struct used to customize the type (aka each &lt;code&gt;T&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;For each one of these types, the JIT knows at compile type what &lt;code&gt;T&lt;/code&gt; is, which brings about certain optimizations.&lt;/p&gt;
&lt;p&gt;The optimization exploited by &lt;code&gt;StaticCounterInterface&lt;/code&gt; is that the call to &lt;code&gt;Increment&lt;/code&gt; becomes a non-virtual call that can be inlined.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class StaticCounterInterface&amp;lt;T&amp;gt; where T : struct, IIncrementer
{
    int _count;
    T _incrementer = new T();

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void Increment() =&amp;gt; _incrementer.Increment(ref _count);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For &lt;code&gt;StaticCounterMatch&lt;/code&gt; the situation is even more obvious.&lt;/p&gt;
&lt;p&gt;The Jitter doesn&amp;rsquo;t generate code for any of the &lt;code&gt;if&lt;/code&gt; statements. It just puts the right code for the type &lt;code&gt;T&lt;/code&gt; directly in the body of the &lt;code&gt;Increment&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;It is as if the &lt;code&gt;if&lt;/code&gt; statement were executed at compile time, as with &lt;code&gt;C++&lt;/code&gt; templates. Also notice the &lt;code&gt;IncrementRaw&lt;/code&gt; method used for perf comparison.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class StaticCounterMatch&amp;lt;T&amp;gt;
{
    int _count;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void Increment() {
        if (typeof(T) == typeof(SStandardIncrementer))      _count += 1;
        if (typeof(T) == typeof(SInterlockedIncrementer))   Interlocked.Increment(ref _count);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void IncrementRaw() =&amp;gt; _count += 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are now ready for the performance testing. We create one class for each combination and benchmark their Increment method.&lt;/p&gt;
&lt;p&gt;A few comments on the attributes:
1. &lt;code&gt;DryCoreJob&lt;/code&gt; doesn&amp;rsquo;t do the benchmark, but just runs the diagnosers, in this case produces assembly code.
2. &lt;code&gt;InProcessAttribute&lt;/code&gt; makes everything go faster, but cannot be used to generate assembly.
3. &lt;code&gt;DisassemblyDiagnoser&lt;/code&gt; creates files with the assembly code.
4. &lt;code&gt;RankColumn&lt;/code&gt; generates a nicer table.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;//[DryCoreJob]
//[InProcessAttribute]
[DisassemblyDiagnoser(printAsm: true, printPrologAndEpilog: true, printIL: false, printSource: false, recursiveDepth: 3)]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn(NumeralSystem.Stars)]
public  class MainClass
{
    DynamicCounter&amp;lt;IIncrementer&amp;gt;         dynInterface           = new DynamicCounter&amp;lt;IIncrementer&amp;gt;(new CStandardIncrementer());
    DynamicCounter&amp;lt;CStandardIncrementer&amp;gt; dynConcrete            = new DynamicCounter&amp;lt;CStandardIncrementer&amp;gt;(new CStandardIncrementer());
    DynamicCounter&amp;lt;SStandardIncrementer&amp;gt; dynStruct              = new DynamicCounter&amp;lt;SStandardIncrementer&amp;gt;(new SStandardIncrementer());
    StaticCounterMatch&amp;lt;SStandardIncrementer&amp;gt; staticCounterM     = new StaticCounterMatch&amp;lt;SStandardIncrementer&amp;gt;();
    StaticCounterInterface&amp;lt;SStandardIncrementer&amp;gt; staticCounterI = new StaticCounterInterface&amp;lt;SStandardIncrementer&amp;gt;();

    [Benchmark] public void DynamicInterface()                      =&amp;gt; dynInterface.Increment();
    [Benchmark] public void DynamicConcrete()                       =&amp;gt; dynConcrete.Increment();
    [Benchmark] public void DynamicStruct()                         =&amp;gt; dynStruct.Increment();
    [Benchmark] public void StaticCounterInterface()                =&amp;gt; staticCounterI.Increment();
    [Benchmark] public void StaticCounterMatch()                    =&amp;gt; staticCounterM.Increment();
    [Benchmark(Baseline = true)] public void IncrementRaw()         =&amp;gt; staticCounterM.IncrementRaw();

    public static void Main() =&amp;gt; BenchmarkRunner.Run&amp;lt;MainClass&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;Please note that the results are valid just for the tested configuration.&lt;/p&gt;
&lt;p&gt;I have no reason to think that they would be different on other modern runtimes/OSs as the optimizations are quite well known.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-ini"&gt;BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17763.253 (1809/October2018Update/Redstone5)
Intel Core i7-6600U CPU 2.60GHz (Skylake), 1 CPU, 4 logical and 2 physical cores
.NET Core SDK=3.0.100-preview-009812
  [Host]     : .NET Core 2.0.9 (CoreCLR 4.6.26614.01, CoreFX 4.6.26614.01), 64bit RyuJIT
  DefaultJob : .NET Core 2.0.9 (CoreCLR 4.6.26614.01, CoreFX 4.6.26614.01), 64bit RyuJIT
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Median&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;th&gt;RatioSD&lt;/th&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;StaticCounterInterface&lt;/td&gt;
&lt;td&gt;0.0000 ns&lt;/td&gt;
&lt;td&gt;0.0000 ns&lt;/td&gt;
&lt;td&gt;0.0000 ns&lt;/td&gt;
&lt;td&gt;0.0000 ns&lt;/td&gt;
&lt;td&gt;0.000&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IncrementRaw&lt;/td&gt;
&lt;td&gt;0.1036 ns&lt;/td&gt;
&lt;td&gt;0.0515 ns&lt;/td&gt;
&lt;td&gt;0.0573 ns&lt;/td&gt;
&lt;td&gt;0.1071 ns&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;**&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StaticCounterMatch&lt;/td&gt;
&lt;td&gt;0.1122 ns&lt;/td&gt;
&lt;td&gt;0.0422 ns&lt;/td&gt;
&lt;td&gt;0.0943 ns&lt;/td&gt;
&lt;td&gt;0.1020 ns&lt;/td&gt;
&lt;td&gt;2.092&lt;/td&gt;
&lt;td&gt;1.95&lt;/td&gt;
&lt;td&gt;**&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DynamicStruct&lt;/td&gt;
&lt;td&gt;0.2707 ns&lt;/td&gt;
&lt;td&gt;0.0910 ns&lt;/td&gt;
&lt;td&gt;0.2683 ns&lt;/td&gt;
&lt;td&gt;0.1407 ns&lt;/td&gt;
&lt;td&gt;4.135&lt;/td&gt;
&lt;td&gt;6.28&lt;/td&gt;
&lt;td&gt;***&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DynamicConcrete&lt;/td&gt;
&lt;td&gt;1.9216 ns&lt;/td&gt;
&lt;td&gt;0.1506 ns&lt;/td&gt;
&lt;td&gt;0.4440 ns&lt;/td&gt;
&lt;td&gt;1.7883 ns&lt;/td&gt;
&lt;td&gt;23.417&lt;/td&gt;
&lt;td&gt;21.44&lt;/td&gt;
&lt;td&gt;****&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DynamicInterface&lt;/td&gt;
&lt;td&gt;2.2441 ns&lt;/td&gt;
&lt;td&gt;0.1170 ns&lt;/td&gt;
&lt;td&gt;0.3449 ns&lt;/td&gt;
&lt;td&gt;2.1470 ns&lt;/td&gt;
&lt;td&gt;32.783&lt;/td&gt;
&lt;td&gt;30.52&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As expected, you gain an order of magnitude in performance by foregoing run time customization, except when using a &lt;code&gt;struct&lt;/code&gt; as the optimizer manages to inline that one (as we&amp;rsquo;ll see).&lt;/p&gt;
&lt;p&gt;Notice that these numbers are really low. In fact the order of the first 4 lines might change when you run it. But they are always much faster than the rest.&lt;/p&gt;
&lt;p&gt;But why? Let&amp;rsquo;s look at the generated code.&lt;/p&gt;
&lt;h2&gt;IL and ASM&lt;/h2&gt;
&lt;p&gt;First let&amp;rsquo;s look at IL for a few of the methods&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-asm6502"&gt;MainClass.IncrementRaw()
       IL_0000: ldarg.0
       IL_0001: ldfld StaticCounterMatch`1&amp;lt;SStandardIncrementer&amp;gt; MainClass::staticCounterM
       IL_0006: callvirt System.Void StaticCounterMatch`1&amp;lt;SStandardIncrementer&amp;gt;::IncrementRaw()
       IL_000b: ret

; MainClass.StaticCounterInterface()
       IL_0000: ldarg.0
       IL_0001: ldfld StaticCounterInterface`1&amp;lt;SStandardIncrementer&amp;gt; MainClass::staticCounterI
       IL_0006: callvirt System.Void StaticCounterInterface`1&amp;lt;SStandardIncrementer&amp;gt;::Increment()
       IL_000b: ret

; MainClass.StaticCounterMatch()
       IL_0000: ldarg.0
       IL_0001: ldfld StaticCounterMatch`1&amp;lt;SStandardIncrementer&amp;gt; MainClass::staticCounterM
       IL_0006: callvirt System.Void StaticCounterMatch`1&amp;lt;SStandardIncrementer&amp;gt;::Increment()
       IL_000b: ret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, nothing interesting there apart from the use of &lt;code&gt;callvirt&lt;/code&gt; when you would think a standard &lt;code&gt;call&lt;/code&gt; would do (i.e. &lt;code&gt;IncrementRaw&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I vaguely remember from my C# compiler days that we do that as a way to short-circuit the test for null, as &lt;code&gt;callvirt&lt;/code&gt; does it automatically.&lt;/p&gt;
&lt;p&gt;The assembly code is more interesting. Let&amp;rsquo;s start from the three fast-resolved-at-compile-time methods.&lt;/p&gt;
&lt;p&gt;BTW: remember that looking at optimized ASM code is like peering into a muddy lake with foggy glasses. Let&amp;rsquo;s do it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-asm6502"&gt;; MainClass.IncrementRaw()
       mov     rax,qword ptr [rcx+20h]
       inc     dword ptr [rax+8]
       ret

; MainClass.StaticCounterInterface()
       mov     rax,qword ptr [rcx+28h]
       (*)mov     edx,dword ptr [rax]
       add     rax,8
       inc     dword ptr [rax]
       ret

; MainClass.StaticCounterMatch()
       mov     rax,qword ptr [rcx+20h]
       (*)mov     edx,dword ptr [rax]
       inc     dword ptr [rax+8]
       ret

; MainClass.DynamicStruct()
       mov     rax,qword ptr [rcx+18h]
       (*) mov     edx,dword ptr [rax]
       add     rax,8
       inc     dword ptr [rax]
       ret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yep, they are all the same (apart from the mysterious &lt;code&gt;*&lt;/code&gt; instruction)! Get the memory location of the field, increment it.&lt;/p&gt;
&lt;p&gt;The Jitter has completely inlined the code. It is as if you had written the incrementing code directly into the function, despite you composing the type using two independent abstractions.&lt;/p&gt;
&lt;p&gt;I think that is pretty cool! You can abstract your code properly and not pay the price for it (well, apart from one assembly instruction).&lt;/p&gt;
&lt;p&gt;For the sake of completeness, let&amp;rsquo;s look at the assembly code for the dynamic dispatching cases.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-asm6502"&gt;; MainClass.DynamicConcrete()
       mov     rcx,qword ptr [rcx+10h]
       cmp     dword ptr [rcx],ecx
       lea     rdx,[rcx+10h]
       mov     rcx,qword ptr [rcx+8]
       mov     r11,7FF8C2B30470h
       mov     rax,qword ptr [r11]
       cmp     dword ptr [rcx],ecx
       jmp     rax

; MainClass.DynamicInterface()
       mov     rcx,qword ptr [rcx+8]
       cmp     dword ptr [rcx],ecx
       lea     rdx,[rcx+10h]
       mov     rcx,qword ptr [rcx+8]
       mov     r11,7FF8C2B10470h
       mov     rax,qword ptr [r11]
       cmp     dword ptr [rcx],ecx
       jmp     rax
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first thing to notice is that the code is identical, despite their seemingly different declarations. The Jitter doesn&amp;rsquo;t care.&lt;/p&gt;
&lt;p&gt;Notice the machinations the Jitter performs, very likely related to dynamic dispatching, to calculate the address to finally jump to. That&amp;rsquo;s where our Increment method is located.&lt;/p&gt;
&lt;p&gt;No wonder it is slower.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;If you can afford to use the policy pattern instead of the more generic strategy pattern (i.e. compile time vs run time dispatch) and/or you need bare to the metal performance, consider the code above.&lt;/p&gt;
&lt;p&gt;As for me, I plan to use it in the near future for a few low level abstractions (i.e. memory allocators).&lt;/p&gt;</description>
            <pubDate>Tue, 29 Jan 2019 00:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2019-01-29-meta-programming-and-policy-based-design.html</guid>
        </item>
        
        <item>
            <title>Stopping Garbage Collection in .NET Core 3.0 (part II)</title>
            <link>https://www.lucabol.com/posts/2019-01-21-stopping-garbage-collection-in-net-core-3-0-part-ii.html</link>
            <description>&lt;p&gt;Let&amp;rsquo;s see how it&amp;rsquo;s implemented. For why it is implemented, see part I.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/mjrousos"&gt;Mike&lt;/a&gt; for reviewing this.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Diagnostics.Tracing;
using System.Runtime;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The FxCop code analyzers get upset if I don&amp;rsquo;t declare this, which also impede me from using unsigned numeral types in interfaces.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[assembly: CLSCompliant(true)]

namespace LNativeMemory
{
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first piece of the puzzle is to implement an event listener. It is a not-obvious (for me) class. I don&amp;rsquo;t fully
understand the lifetime semantics, but the code below seems to do the right thing.&lt;/p&gt;
&lt;p&gt;The interesting piece is &lt;code&gt;_started&lt;/code&gt; and the method &lt;code&gt;Start()&lt;/code&gt;. The constructor for &lt;code&gt;EventListener&lt;/code&gt; allocates plenty of stuff. I don&amp;rsquo;t want
to do those allocations after calling &lt;code&gt;TryStartNoGCRegion&lt;/code&gt; because they would use part of the GC Heap that I want for my program.
Instead, I create it before such call, but then I make it &amp;lsquo;switch on&amp;rsquo; just after the &lt;code&gt;Start()&lt;/code&gt; method is called.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    internal sealed class GcEventListener : EventListener
    {
        Action _action;
        EventSource _eventSource;
        bool _active = false;

        internal void Start() { _active = true; }
        internal void Stop() { _active = false; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As described in part one, you pass a delegate at creation time, which is called when garbage collection is restarted.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        internal GcEventListener(Action action) =&amp;gt; _action = action ?? throw new ArgumentNullException(nameof(action));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We register to all the events coming from .NET. We want to call the delegate at the exact point when garbage collection is turned on again.
We don&amp;rsquo;t have a clean way to do that (aka there is no runtime event we can hook up to, see &lt;a href="https://github.com/dotnet/coreclr/issues/21750"&gt;here&lt;/a&gt;,
so listening to every single GC event gives us the most chances of doing it right. Also it ties us the least to any pattern of events, which
might change in the future.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        // from https://docs.microsoft.com/en-us/dotnet/framework/performance/garbage-collection-etw-events
        private const int GC_KEYWORD = 0x0000001;
        private const int TYPE_KEYWORD = 0x0080000;
        private const int GCHEAPANDTYPENAMES_KEYWORD = 0x1000000;

        protected override void OnEventSourceCreated(EventSource eventSource)
        {
            if (eventSource.Name.Equals(&amp;quot;Microsoft-Windows-DotNETRuntime&amp;quot;, StringComparison.Ordinal))
            {
                _eventSource = eventSource;
                EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(GC_KEYWORD | GCHEAPANDTYPENAMES_KEYWORD | TYPE_KEYWORD));
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For each event, I check if the garbage collector has exited the NoGC region. If it has, then let&amp;rsquo;s invoke the delegate.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        protected override void OnEventWritten(EventWrittenEventArgs eventData)
        {
            var eventName = eventData.EventName;
            if(_active &amp;amp;&amp;amp; GCSettings.LatencyMode != GCLatencyMode.NoGCRegion)
            {
                _action?.Invoke();
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our event listener, we need to hook it up. The code below implements what I described earlier.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Do your allocations for the event listener&lt;/li&gt;
&lt;li&gt;Start the NoGc region&lt;/li&gt;
&lt;li&gt;Start monitoring the runtime for the start of the NoGC region&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public static class GC2
    {
        static private GcEventListener _evListener;

        public static bool TryStartNoGCRegion(long totalSize, Action actionWhenAllocatedMore)
        {

            _evListener = new GcEventListener(actionWhenAllocatedMore);
            var succeeded = GC.TryStartNoGCRegion(totalSize, disallowFullBlockingGC: false);
            _evListener.Start();

            return succeeded;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As puzzling as this might be, I provisionally believe it to be correct. Apparently, even if the GC is not in a NoGC region, you still need to call
&lt;code&gt;EndNoGCRegion&lt;/code&gt; if you have called &lt;code&gt;TryStartNoGCRegion&lt;/code&gt; earlier, otherwise your next call to &lt;code&gt;TryStartNoGCRegion&lt;/code&gt; will fail.
&lt;code&gt;EndNoGCRegion&lt;/code&gt; will throw an exception, but that&amp;rsquo;s OK. Your next call to &lt;code&gt;TryStartNoGCRegion&lt;/code&gt; will now succeed.&lt;/p&gt;
&lt;p&gt;Now read the above repeatedly until you got. Or just trust that it works somehow.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        public static void EndNoGCRegion()
        {
            _evListener.Stop();

            try
            {
                GC.EndNoGCRegion();
            } catch (Exception)
            {

            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is used as the default behavior for the delegate in the wrapper class below.
I was made aware by the code analyzer that I shouldn&amp;rsquo;t be throwing an OOF exception here. At first, I dismissed it, but then it hit me. It is right.&lt;/p&gt;
&lt;p&gt;We are not running out of memory here. We simply have allocated more memory than what we declared we would. There is likely plenty of memory left
on the machine. Thinking more about it, I grew ashamed of my initial reaction. Think about a support engineer getting an OOM exception at that point
and trying to figure out why. So, always listen to Lint &amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public class OutOfGCHeapMemoryException : OutOfMemoryException {
        public OutOfGCHeapMemoryException(string message) : base(message) { }
        public OutOfGCHeapMemoryException(string message, Exception innerException) : base(message, innerException) { }
        public OutOfGCHeapMemoryException() : base() { }

    }


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is an utility class that implements the &lt;code&gt;IDisposable&lt;/code&gt; pattern for this scenario. The size of the default ephemeral segment comes from
&lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#generations"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    public sealed class NoGCRegion: IDisposable
    {
        static readonly Action defaultErrorF = () =&amp;gt; throw new OutOfGCHeapMemoryException();
        const int safeEphemeralSegment = 16 * 1024 * 1024;

        public NoGCRegion(int totalSize, Action actionWhenAllocatedMore)
        {
            var succeeded = GC2.TryStartNoGCRegion(totalSize, actionWhenAllocatedMore);
            if (!succeeded)
                throw new InvalidOperationException(&amp;quot;Cannot enter NoGCRegion&amp;quot;);
        }

        public NoGCRegion(int totalSize) : this(totalSize, defaultErrorF) { }
        public NoGCRegion() : this(safeEphemeralSegment, defaultErrorF) { }

        public void Dispose() =&amp;gt; GC2.EndNoGCRegion();
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Mon, 21 Jan 2019 10:05:45 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2019-01-21-stopping-garbage-collection-in-net-core-3-0-part-ii.html</guid>
        </item>
        
        <item>
            <title>Stopping Garbage Collection in .NET Core 3.0 (part I)</title>
            <link>https://www.lucabol.com/posts/2019-01-14-stopping-garbage-collection-in-net-core-3-0-part-i.html</link>
            <description>&lt;h2&gt;Scenario&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/mjrousos"&gt;Mike&lt;/a&gt; for reviewing this.&lt;/p&gt;
&lt;p&gt;You have an application or a particular code path of your application that cannot take the pauses that GC creates.
Typical examples are real time systems, tick by tick financial apps, embedded systems, etc &amp;hellip;&lt;/p&gt;
&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;For any normal kind of applications, &lt;em&gt;YOU DON&amp;rsquo;T NEED TO DO THIS&lt;/em&gt;. You are likely to make your application run slower or blow up memory.
If you have an hot path in your application (i.e. you are creating an editor with Intellisense), use the GC latency modes.
Use the code below just under extreme circumstance as it is untested, error prone and wacky.
You are probably better off waiting for an official way of doing it (i.e. when &lt;a href="https://github.com/dotnet/coreclr/issues/21750"&gt;this&lt;/a&gt;
is implemented)&lt;/p&gt;
&lt;h2&gt;The problem with TryStartNoGCRegion&lt;/h2&gt;
&lt;p&gt;There is a GC.TryStartNoGCRegion in .NET. You can use it to stop garbage collection passing a totalBytes parameter that represents
the maximum amount of memory  that you plan to allocate from the managed heap. Matt describes it
&lt;a href="https://mattwarren.org/2016/08/16/Preventing-dotNET-Garbage-Collections-with-the-TryStartNoGCRegion-API/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The problem is that when/if you allocate more than that, garbage collection resumes silently. Your application continues to work,
but with different performance characteristics from what you expected.&lt;/p&gt;
&lt;h2&gt;The idea&lt;/h2&gt;
&lt;p&gt;The main idea is to use &lt;a href="https://docs.microsoft.com/en-us/windows/desktop/etw/about-event-tracing"&gt;ETW events&lt;/a&gt; to detect when a
GC occurs and to call an user provided delegate at that point. You can then do whatever you want in the delegate (i.e. shutdown the process,
send email to support, start another NoGC region, etc&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Also, I have wrapped the whole StartNoGCRegion/EndNoGCRegion in an IDisposable wrapper for easy of use.&lt;/p&gt;
&lt;h2&gt;The tests&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start by looking at how you use it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Xunit;
using System.Threading;

namespace LNativeMemory.Tests
{

    // XUnit executes all tests in a class sequentially, so no problem with multi-threading calls to GC
    public class GC2Tests
    {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to use a timer to maximize the chances that a GC happens in some of the tests. Also we allocate an amount that should
work in all GC configuration as per the article above. &lt;code&gt;trigger&lt;/code&gt; is a static field so as to stay zero-allocation
(otherwise the delegate will have to capture the a local &lt;code&gt;trigger&lt;/code&gt; variable creating a heap allocated closure).
Not that it matters any to be zero-allocation in this test, but I like to keep
&lt;a href="https://github.com/Microsoft/RoslynClrHeapAllocationAnalyzer"&gt;ClrHeapAllocationAnalyzer&lt;/a&gt; happy.&lt;/p&gt;
&lt;p&gt;BTW: XUnit executes all tests in a class sequentially, so no problem with multi-threading calls to GC.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        const int sleepTime = 200;
        const int totalBytes = 16 * 1024 * 1024;
        static bool triggered = false;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First we test that any allocation that doesn&amp;rsquo;t exceed the limit doesn&amp;rsquo;t trigger the call to action.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        [Fact]
        public void NoAllocationBeforeLimit()
        {
            try
            {
                triggered = false;
                var succeeded = GC2.TryStartNoGCRegion(totalBytes, () =&amp;gt; triggered = true);
                Assert.True(succeeded);
                Thread.Sleep(sleepTime);
                Assert.False(triggered);

                var bytes = new byte[99];
                Thread.Sleep(sleepTime);
                Assert.False(triggered);
            }
            finally
            {
                GC2.EndNoGCRegion();
                triggered = false;
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we test that allocating over the limit does trigger the action. To do so we need to trigger a garbage collection.
Out best attempt is with the goofy for loop. If you got a better idea, shout.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        [Fact]
        public void AllocatingOverLimitTriggersTheAction()
        {
            try
            {
                triggered = false;
                var succeeded = GC2.TryStartNoGCRegion(totalBytes, () =&amp;gt; triggered = true);
                Assert.True(succeeded);
                Assert.False(triggered);

                for (var i = 0; i &amp;lt; 3; i++) { var k = new byte[totalBytes]; }

                Thread.Sleep(sleepTime);
                Assert.True(triggered);
            }
            finally
            {
                GC2.EndNoGCRegion();
                triggered = false;
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also test that we can go back and forth between starting and stopping without messing things up.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        [Fact]
        public void CanCallMultipleTimes()
        {

            for (int i = 0; i &amp;lt; 3; i++)
            {
                NoAllocationBeforeLimit();
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And lastly, we make sure that we can use our little wrapper function, just to be sure everything works.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        [Fact]
        public void CanUseNoGCRegion()
        {
            triggered = false;
            using (new NoGCRegion(totalBytes, () =&amp;gt; triggered = true))
            {
                for (var i = 0; i &amp;lt; 3; i++) { var k = new byte[totalBytes]; }
                Thread.Sleep(sleepTime);
                Assert.True(triggered);
                triggered = false;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Mon, 14 Jan 2019 12:34:16 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2019-01-14-stopping-garbage-collection-in-net-core-3-0-part-i.html</guid>
        </item>
        
        <item>
            <title>A Stack data structure implementation using Span</title>
            <link>https://www.lucabol.com/posts/2018-06-04-a-stack-data-structure-implementation-using-span.html</link>
            <description>&lt;p&gt;I am back in Microsoft and today we talk about the code below, which is on github here:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public ref struct SpanStack&amp;lt;T&amp;gt;
{
    private Span memory;
    private int index;
    private int size;

    public SpanStack(Span mem) { memory = mem; index = 0; size = mem.Length; }

    public bool IsEmpty() =&amp;gt; index &amp;lt; 0;
    public bool IsFull() =&amp;gt; index &amp;gt; size - 1;

    public void Push(T item) =&amp;gt; memory[index++] = item;
    public T Pop() =&amp;gt; memory[--index];
}

public static class SpanExtensions
{
    public static SpanStack AsStack&amp;lt;T&amp;gt;(this Span span) =&amp;gt; new SpanStack(span);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Stack data structure can be used over memory that resides on the stack, heap or unmanaged heap. If you know about Span this should immediately make sense to you.&lt;/p&gt;
&lt;p&gt;This has to be a ref struct because it contains a Span. It can&amp;rsquo;t be used on the heap (i.e. in lambdas, async, class field, &amp;hellip;). You have to build it on top of Memory if you need that. Also, you can happily blow the stack with this guy &amp;hellip;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s micro-benchmark it with BenchmarkDotNet.  For example, a postfix calculator. Let&amp;rsquo;s first do it naively using inheritance and the generic Stack class in the framework.&lt;/p&gt;
&lt;p&gt;This is the naive object model:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;abstract class Token {}

sealed class Operand: Token
{
    public int Value { get; }
    public Operand(int v) { Value = v; }
}

abstract class Operator: Token {
    abstract public int Calc(int a, int b);
}

sealed class Add: Operator
{
    public override int Calc(int a, int b) =&amp;gt; a + b;
}

sealed class Mult : Operator
{
    public override int Calc(int a, int b) =&amp;gt; a * b;
}

sealed class Minus : Operator
{
    public override int Calc(int a, int b) =&amp;gt; a - b;
}
Let's then do it trying to be a bit more performance aware using a stack friendly representation:

public enum TokenType { Operand, Sum, Mult, Minus}

readonly struct SToken
{
    public TokenType Type { get; }
    public int Value { get; }
    public SToken(TokenType t, int v) { Type = t; Value = v; }
    public SToken(TokenType t) { Type = t; Value = 0; }

    public int Calc(int a, int b) =&amp;gt;
               Type == TokenType.Sum   ? a + b :
               Type == TokenType.Minus ? a - b :
               Type == TokenType.Minus ? a * b :
               throw new Exception(&amp;quot;I don't know that one&amp;quot;);

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Perhaps not overtly elegant, but not that terrible either. You got to love those expression bodied methods and throw-expression.&lt;/p&gt;
&lt;p&gt;We then setup things (I know I could/should parse a string here):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static Token[] tokens;
static SToken[] stokens;

[GlobalSetup]
public void Setup()
{
    tokens = new Token[] { new Operand(2), new Operand(3), new Operand(4), new Add(),
                           new Mult(), new Operand(5), new Minus() };
    stokens = new SToken[] { new SToken(TokenType.Operand, 2),
                             new SToken(TokenType.Operand, 3), new SToken(TokenType.Operand, 4),
                             new SToken(TokenType.Sum),  new SToken(TokenType.Mult),
                             new SToken(TokenType.Operand, 5), new SToken(TokenType.Minus)};
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And first test the naive object model with the standard Stack from System.Collections.Generic.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Benchmark]
public int PostfixEvalStack()
{
    var stack = new Stack(100);

    foreach (var token in tokens)
    {
        switch (token)
        {
            case Operand t:
                stack.Push(t);
                break;
            case Operator o:
                var a = stack.Pop() as Operand;
                var b = stack.Pop() as Operand;
                var result = o.Calc(a.Value, b.Value);
                stack.Push(new Operand(result));
                break;
        }
    }
    return (stack.Pop() as Operand).Value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then let&amp;rsquo;s just swap out our own lean-and-mean stack:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Benchmark]
public int PostfixEvalSpanStack()
{
    Span span = new Token[100];
    var stack = span.AsStack();

    foreach (var token in tokens)
    {
        switch (token)
        {
            case Operand t:
                stack.Push(t);
                break;
            case Operator o:
                var a = stack.Pop() as Operand;
                var b = stack.Pop() as Operand;
                var result = o.Calc(a.Value, b.Value);
                stack.Push(new Operand(result));
                break;
        }
    }
    return (stack.Pop() as Operand).Value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally let&amp;rsquo;s go the whole way, lean object model and lean data structure, everything on the stack:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Benchmark(Baseline = true)]
public int PostfixEvalSpanStackStructTypes()
{
    Span span = stackalloc SToken[100];
    var stack = span.AsStack();

    foreach (var token in stokens)
    {
        if (token.Type == TokenType.Operand)
        {
            stack.Push(token);
        } else {
            var a = stack.Pop();
            var b = stack.Pop();
            var result = token.Calc(a.Value, b.Value);
            stack.Push(new SToken(TokenType.Operand, result));
            break;
        }
    }
    return stack.Pop().Value;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also want to check that we didn&amp;rsquo;t code anything stupid and finally run the benchmark.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static void Test()
{
    var p = new Program();
    p.Setup();
    Trace.Assert(p.PostfixEvalStack() == p.PostfixEvalSpanStack() &amp;amp;&amp;amp;
                 p.PostfixEvalSpanStack() == p.PostfixEvalSpanStackStructTypes());
}
static void Main(string[] args)
{
    Test();
    var summary = BenchmarkRunner.Run();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On my machine I get these results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BenchmarkDotNet=v0.10.14, OS=Windows 10.0.16299.431 (1709/FallCreatorsUpdate/Redstone3)
Intel Core i7-6600U CPU 2.60GHz (Skylake), 1 CPU, 4 logical and 2 physical cores
Frequency=2742185 Hz, Resolution=364.6727 ns, Timer=TSC
.NET Core SDK=2.1.300-rc1-008673
  [Host]     : .NET Core 2.1.0-rc1 (CoreCLR 4.6.26426.02, CoreFX 4.6.26426.04), 64bit RyuJIT
  DefaultJob : .NET Core 2.1.0-rc1 (CoreCLR 4.6.26426.02, CoreFX 4.6.26426.04), 64bit RyuJIT
Method  Mean    Error   StdDev  Scaled  ScaledSD
PostfixEvalSpanStackStructTypes 76.24 ns    1.563 ns    2.857 ns    1.00    0.00
PostfixEvalSpanStack    168.65 ns   5.280 ns    15.319 ns   2.22    0.22
PostfixEvalStack    334.56 ns   7.387 ns    20.593 ns   4.39    0.31
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your mileage might vary. I want to emphasize that I am just playing with things. I haven&amp;rsquo;t done any deep analysis of this benchmark. There can be flaws, etc&amp;hellip; etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;Still, I find the idea of data structures which are memory-location-independent rather fascinating.&lt;/p&gt;</description>
            <pubDate>Mon, 04 Jun 2018 11:56:54 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2018-06-04-a-stack-data-structure-implementation-using-span.html</guid>
        </item>
        
        <item>
            <title>Building a stock alert system with Google Script</title>
            <link>https://www.lucabol.com/posts/2014-10-31-building-a-stock-alert-system-with-google-script.html</link>
            <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;This is obsolete as Yahoo stopped their quote service. I have a new spreadsheet &lt;a href="https://docs.google.com/spreadsheets/d/1OimxgxAgwY3GeCSvnzlEbQTPnWDU0-AnyvZMc3RfgdA/edit?usp=sharing"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I thought about it, I realized that my ideal system would be a spreadsheet where to add tickers and alert levels. Under the covers, the system would need to check the current price of a ticker, compare it with the alert level and send me email when triggered.&lt;/p&gt;
&lt;p&gt;Also the whole thing shouldn&amp;rsquo;t be running from my machine at home, but from somewhere on the internet.&lt;/p&gt;
&lt;p&gt;Google script fit the bill. Let&amp;rsquo;s see how it works.&lt;/p&gt;
&lt;p&gt;Script is here. Sheet is here.&lt;/p&gt;
&lt;p&gt;First a utility function to send errors via email, which will be used throughout the script.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function emailError(e) {
  MailApp.sendEmail(&amp;quot;lucabolg@gmail.com&amp;quot;, &amp;quot;Watchlist Error&amp;quot;,
                    &amp;quot;\r\nMessage: &amp;quot; + e.message
                    + &amp;quot;\r\nFile: &amp;quot; + e.fileName
                    + &amp;quot;\r\nLine: &amp;quot; + e.lineNumber
                    + &amp;quot;\r\nLOg: &amp;quot; + Logger.getLog())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then another one to check if the price downloaded from the internet is sensible.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function validPrice(price) {
 return price != 'undefined' &amp;amp;&amp;amp; price &amp;gt; 0.1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then need one to retrieve the current price of a ticker from the array of data returned from the internet:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;// Find the current price of a ticker in an array of data where the ticker is the first column
function getQuote(data, ticker) {
  var ticker = ticker.trim().toLowerCase()

  for(var i = 0; i = 22 &amp;amp;&amp;amp; hour &amp;lt;= 23) || value != &amp;quot;close&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With all of that in place, we can now look at the main function. First we load up the spreadsheet and get the values and headers we care about. This would be more robust if we looked up the sheet by name. Also the id of the sheet is burned in the code. You&amp;rsquo;ll need to change it if you want to make it point to your own.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;// Check spreadsheet with tickers and stop prices, send email when a stop is hit and mark the row as 'Executed'.
function checkQuotes() {
 try {

 // Get all data from spreadsheet in one web call.
 var ss = SpreadsheetApp.openById(&amp;quot;1WQf2AiBPQW5HLzCyGgsFlKN0f1HTOWAteJ5bJCXVnlc&amp;quot;)
 var range = ss.getSheets()[0].getDataRange()
 var values = range.getValues()
 var headers = values[0]
 var rows = ObjApp.rangeToObjects(values)
 var body = &amp;quot;&amp;quot;
 var now = new Date()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice &amp;lsquo;ObjApp&amp;rsquo; is part of the ObjService library to make the code a bit more maintainable, instead of scattering column numbers in the code.&lt;/p&gt;
&lt;p&gt;Now we get all the tickers and download the prices from Yahoo (we try three times as it occasionally fails.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;    // Fish out all tickers from col 0 where Status (col 4) is not executed
    var tickers = []
    for(var i = 1; i &amp;lt; rows.length; i++) {// dont' process the headers
      if((rows[i]).executed.toLowerCase() == 'active' &amp;amp;&amp;amp; isRightTime(rows[i], now)) tickers.push((rows[i]).ticker.trim().toLowerCase())
    }
    Logger.log(&amp;quot;Tickers:%s&amp;quot; ,tickers)

    if(tickers.length == 0) return // Nothing to process

    // Get ticker, real time bid, real time ask for all tickers in one web call
    var url = &amp;quot;http://finance.yahoo.com/d/quotes.csv?s=&amp;quot; + tickers.join(&amp;quot;+&amp;quot;) + &amp;quot;&amp;amp;f=sl1&amp;quot;//&amp;quot;&amp;amp;f=sb2b3&amp;quot;

    // Try 3 times before giving up
    for(var i = 0; i &amp;lt; 3; i++) {
      try {
        var response = UrlFetchApp.fetch(url)
        break;
      } catch(e) {
      }
    }

    Logger.log(&amp;quot;Response:\n%s&amp;quot;, response)
    var data = Utilities.parseCsv(response.getContentText())
    Logger.log(&amp;quot;Data:\n%s&amp;quot;, data)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once that is done, we enter the main loop. The concept is simple, for each row we check the price and, if the price is above/below the alert we add it to the body string and mark the row in the sheet so that we don&amp;rsquo;t process it again next time. A the end, we email the body variable if not null.&lt;/p&gt;
&lt;p&gt;First we check that we haven&amp;rsquo;t already executed this row:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;    for(var i = 1; i &amp;lt; rows.length; i++) {// dont' process the headers
      var current = rows[i]
      if(current.executed.trim().toLowerCase() == 'executed') continue // no need to process it as it is 'Executed'

      var symbol = current.operator
      var stop = current.stop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If it&amp;rsquo;s still active and if it is the right time, we check if the alert is triggered. If it is we add the text to the body variable.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;      if(isRightTime(current, now)) {
        var price = getQuote(data, current.ticker)
        if( (symbol.trim() == &amp;quot;&amp;gt;&amp;quot; &amp;amp;&amp;amp; price &amp;gt; stop) ||
           (symbol.trim() == &amp;quot;&amp;lt;&amp;quot; &amp;amp;&amp;amp; price &amp;lt; stop)) {

          current.executed = &amp;quot;Executed&amp;quot;
          current.price = price

          body += [current.kind, current.ticker, current.price, current.operator, current.stop, &amp;quot;\r\n&amp;quot;].join(&amp;quot; &amp;quot;)
          Logger.log(&amp;quot;Body in loop:\n%s&amp;quot;, body)
        }
      }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If body is not empty, that means that something was triggered, so we send the email.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;    if(body != &amp;quot;&amp;quot;) {
      Logger.log(&amp;quot;Body final:%s&amp;quot;, body)
      MailApp.sendEmail('lucabolg@gmail.com', 'Watchlist: stops triggered', body)
      var data = ObjApp.objectToArray(headers, rows)
      data.unshift(headers)
      range.setValues(data)
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If an error was generated, then we send the error email.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;  } catch (e) {
    Logger.log(e.lineNumber + &amp;quot;:&amp;quot; + e.message)
    emailError(e)
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My experience overall was remarkable. The learning curve was very quick and the web editor works remarkably well (well, stepping through code is rather slow).&lt;/p&gt;
&lt;p&gt;Overall, if Google has all your data (in Drive) and you can write code to manipulate it (in Google script), why do I need my home computer again? I can just have a small screen that connects to the internet and I&amp;rsquo;m done.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s probably true for me apart from two things that I haven&amp;rsquo;t found in web form: editing of images in the raw format and a sophisticated portfolio application. If I find these two, I&amp;rsquo;m ready to give up my life to Google &amp;hellip;&lt;/p&gt;</description>
            <pubDate>Fri, 31 Oct 2014 08:11:13 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2014-10-31-building-a-stock-alert-system-with-google-script.html</guid>
        </item>
        
        <item>
            <title>Funky C for literate programming</title>
            <link>https://www.lucabol.com/posts/2013-03-20-funky-c-for-literate-programming.html</link>
            <description>&lt;h2&gt;Main ideas&lt;/h2&gt;
&lt;p&gt;This is a port of &lt;a href="https://github.com/lucabol/LLite/blob/master/Program.fs"&gt;LLIte&lt;/a&gt; in C. The reason for it is to experiment with writing functional code in standard C and compare the experience with using a functional language like F#. It is in a way a continuation of my previous posts on the topic.&lt;/p&gt;
&lt;p&gt;I will be using glib and an header of convenient macros/functions to help me (lutils.h). I don’t think that is cheating. Any modern C praticoner has its bag of tricks …&lt;/p&gt;
&lt;p&gt;Don’t tell me this is not idiomatic C. I already know that.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;

#include &amp;lt;glib.h&amp;gt;
#include &amp;lt;glib/gprintf.h&amp;gt;

#ifdef ARENA
#include &amp;quot;arena.h&amp;quot;
#endif

#include &amp;quot;lutils.h&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Lack of tuples&lt;/h2&gt;
&lt;p&gt;In the snippet below I overcomed such deficiency by declaring a struct. Using the new constructor syntax makes initializing a static table simple.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;typedef struct LangSymbols { char language[40]; char start[10]; char end[10];} LangSymbols;

static
LangSymbols* s_lang_params_table[] = {
    &amp;amp;(LangSymbols) {.language = &amp;quot;fsharp&amp;quot;,   .start = &amp;quot;(*&amp;quot; &amp;quot;*&amp;quot;, .end = &amp;quot;*&amp;quot; &amp;quot;*)&amp;quot;},
    &amp;amp;(LangSymbols) {.language = &amp;quot;c&amp;quot;,        .start = &amp;quot;/*&amp;quot; &amp;quot;*&amp;quot;, .end = &amp;quot;*&amp;quot; &amp;quot;*/&amp;quot;},
    &amp;amp;(LangSymbols) {.language = &amp;quot;csharp&amp;quot;,   .start = &amp;quot;/*&amp;quot; &amp;quot;*&amp;quot;, .end = &amp;quot;*&amp;quot; &amp;quot;*/&amp;quot;},
    &amp;amp;(LangSymbols) {.language = &amp;quot;java&amp;quot;,     .start = &amp;quot;/*&amp;quot; &amp;quot;*&amp;quot;, .end = &amp;quot;*&amp;quot; &amp;quot;*/&amp;quot;},
    NULL
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Folding over arrays&lt;/h2&gt;
&lt;p&gt;I need to gather all the languages, aka perform a fold over the array. You might have noticed the propensity to add a NULL terminator marker to arrays (as for strings). This allows me to avoid passing a size to functions and makes simpler writing utility macros (as foreach below) more simply.&lt;/p&gt;
&lt;p&gt;In the rest of the program, every time I end a function with _z, it is because I consider it generally usable and I add a version of it without the _z to lutils.h.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define array_foreach_z(p) for(; *symbols != NULL; ++symbols)

static
char* summary(LangSymbols** symbols) {

    GString* langs = g_string_sized_new(20);
    array_foreach(symbols) g_string_append_printf(langs, &amp;quot;%s &amp;quot;, (*symbols)-&amp;gt;language);

    g_string_truncate(langs, strlen(langs-&amp;gt;str) - 1);

    GString* usage = g_string_sized_new(100);

    g_string_printf(usage,
        &amp;quot;You should specify:nt. either -l or -o and -pn&amp;quot;
        &amp;quot;t. either -indent or -P and -Cn&amp;quot;
        &amp;quot;t. -l supports: %s&amp;quot;
        ,langs-&amp;gt;str);

    return usage-&amp;gt;str;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Find an item in an array based on some expression. Returns NULL if not found. Again, this is a common task, hence I’ll abstract it out with a macro (that ends up being a cute use of gcc statment expressions).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define array_find_z(arr, ...)                          
    ({                                                  
        array_foreach(arr) if (__VA_ARGS__) break;      
        *arr;                                           
    })

static
LangSymbols* lang_find_symbols(LangSymbols** symbols, char* lang) {
    g_assert(symbols);
    g_assert(lang);

    return array_find(symbols, !strcmp((*symbols)-&amp;gt;language, lang));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Deallocating stuff&lt;/h2&gt;
&lt;p&gt;You might wonder why I don’t seem overly worried about deallocating the memory that I allocate. I haven’t gone crazy(yet). You’ll see.&lt;/p&gt;
&lt;h2&gt;Discriminated unions&lt;/h2&gt;
&lt;p&gt;Here are the discriminated unions macros from a previous blog post of mine. I’ll need a couple of these and pre-declare two functions.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;union_decl(CodeSymbols, Indented, Surrounded)
    union_type(Indented,    int indentation;)
    union_type(Surrounded,  char* start_code; char* end_code;)
union_end(CodeSymbols);

typedef struct Options {
    char*           start_narrative;
    char*           end_narrative;
    CodeSymbols*    code_symbols;
} Options;

static
gchar* translate(Options*, gchar*);

union_decl(Block, Code, Narrative)
    union_type(Code,        char* code)
    union_type(Narrative,   char* narrative)
union_end(Block);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Main data structure&lt;/h2&gt;
&lt;p&gt;We want to use higher level abstractions that standard C arrays, hence we’ll pick a convenient data structure to use in the rest of the code. A queue lets you to insert at the front and back, with just a one pointer overhead over a single linked list. Hence it is my data structure of choice for this program.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static
GQueue* blockize(Options*, char*);
There is already a function in glib to check if a string has a certain prefix (g_str_has_prefix). We need one that returns the remaining string after the prefix. We also define a g_slow_assert that is executed just if G_ENABLE_SLOW_ASSERT is defined

static
char* str_after_prefix(char* src, char* prefix) {
    g_assert(src);
    g_assert(prefix);
    g_slow_assert(g_str_has_prefix(src, prefix));

    while(*prefix != '0')
        if(*src == *prefix) ++src, ++prefix;
        else break;

    return src;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Tokenizer&lt;/h2&gt;
&lt;p&gt;The structure of the function is identical to the F# version. The big bread-winners are statement expressions and local functions …&lt;/p&gt;
&lt;p&gt;It is interesting how you can replicate the shape of an F# function by substituting ternary operators for match statements.&lt;/p&gt;
&lt;p&gt;It is nothing magic, just a way to have a case statment as an expression, but it is suggestive of its more functional counterpart.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define NL &amp;quot;n&amp;quot;

union_decl(Token, OpenComment, CloseComment, Text)
    union_type(OpenComment, int line)
    union_type(CloseComment,int line)
    union_type(Text,        char* text)
union_end(Token);

GQueue* tokenize(Options* options, char* source) {
    g_assert(options);
    g_assert(source);

    struct tuple { int line; GString* acc; char* rem;};

    bool is_opening(char* src)      { return g_str_has_prefix(src, options-&amp;gt;start_narrative);}
    bool is_closing(char* src)      { return g_str_has_prefix(src, options-&amp;gt;end_narrative);}
    char* remaining_open (char* src){ return str_after_prefix(src, options-&amp;gt;start_narrative);}
    char* remaining_close(char* src){ return str_after_prefix(src, options-&amp;gt;end_narrative);}

    struct tuple text(char* src, GString* acc, int line) {
        inline struct tuple stop_parse_text()
            { return (struct tuple) {.line = line, .acc = acc, .rem = src};}

        return  str_empty (src)? stop_parse_text() :
                is_opening(src)? stop_parse_text() :
                is_closing(src)? stop_parse_text() :
                                ({
                                  int line2         = g_str_has_prefix(src, NL) ? line + 1
                                                                                : line;
                                  GString* newAcc   = g_string_append_c(acc, *src);
                                  char* rem         = src + 1;
                                  text(rem, newAcc, line2);
                                });
    }

    GQueue* tokenize_rec(char* src, GQueue* acc, int line) {
        return  str_empty(src)  ?   acc                     :
                is_opening(src) ?   tokenize_rec(remaining_open(src),
                                        g_queue_push_back(acc, union_new(
                                                    Token, OpenComment, .line = line)),
                                        line)        :
                is_closing(src) ?   tokenize_rec(remaining_close(src),
                                               g_queue_push_back(acc, union_new(
                                                    Token, CloseComment, .line = line)),
                                        line)        :
                                ({
                                    struct tuple t = text(src, g_string_sized_new(200), line);
                                    tokenize_rec(t.rem,
                                        g_queue_push_back(acc, union_new(
                                                    Token, Text, .text = t.acc-&amp;gt;str)), t.line);
                                 });
    }

    return tokenize_rec(source, g_queue_new(), 1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Parser&lt;/h2&gt;
&lt;p&gt;This again has a similar structure to the F# version, just longer. It is very long because it contains 3 (nested) functions which are on the verbose side in C.&lt;/p&gt;
&lt;p&gt;The creation of a error macro is unfortunate. I just don’t know how to adapt g_assert_e so that it works for not pointer returning functions.&lt;/p&gt;
&lt;p&gt;I also need a simple function report_error to exit gracefully giving a message to the user. I didn’t found such thing in glib (?)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define report_error_z(...) G_STMT_START { g_print(__VA_ARGS__); exit(1); } G_STMT_END                                                            

union_decl(Chunk, NarrativeChunk, CodeChunk)
    union_type(NarrativeChunk,  GQueue* tokens)
    union_type(CodeChunk,       GQueue* tokens)
union_end(Chunk);

static
GQueue* parse(Options* options, GQueue* tokens) {
    g_assert(options);
    g_assert(tokens);

    struct tuple { GQueue* acc; GQueue* rem;};

    #define error(...) 
        ({ report_error(__VA_ARGS__); (struct tuple) {.acc = NULL, .rem = NULL}; })

    struct tuple parse_narrative(GQueue* acc, GQueue* rem) {

        bool isEmpty    = g_queue_is_empty(rem);
        Token* h        = g_queue_pop_head(rem);
        GQueue* t       = rem;

        return  isEmpty                 ?
                                    error(&amp;quot;You haven't closed your last narrative comment&amp;quot;) :
                h-&amp;gt;kind == OpenComment  ?
                    error(&amp;quot;Don't open narrative comments inside narrative comments at line %i&amp;quot;,
                          h-&amp;gt;OpenComment.line)                                              :
                h-&amp;gt;kind == CloseComment ? (struct tuple) {.acc = acc, .rem = t}             :
                h-&amp;gt;kind == Text         ? parse_narrative(g_queue_push_back(acc, h), t)     :
                                          error(&amp;quot;Should never get here&amp;quot;);
    };

    struct tuple parse_code(GQueue* acc, GQueue* rem) {

        bool isEmpty    = g_queue_is_empty(rem);
        Token* h    = g_queue_pop_head(rem);
        GQueue* t   = rem;

        return  isEmpty                 ? (struct tuple) {.acc = acc, .rem = t}         :
                h-&amp;gt;kind == OpenComment  ?
                    (struct tuple) {.acc = acc, .rem = g_queue_push_front(rem, h)}      :
                h-&amp;gt;kind == CloseComment ? parse_code(g_queue_push_back(acc, h), rem)    :
                h-&amp;gt;kind == Text         ? parse_code(g_queue_push_back(acc, h), rem)    :
                                          error(&amp;quot;Should never get here&amp;quot;);
    };
    #undef error

    GQueue* parse_rec(GQueue* acc, GQueue* rem) {

        bool isEmpty    = g_queue_is_empty(rem);
        Token* h    = g_queue_pop_head(rem);
        GQueue* t   = rem;

        return  isEmpty                 ? acc                                           :
                h-&amp;gt;kind == OpenComment  ? ({
                                           GQueue* emp = g_queue_new();
                                           struct tuple tu = parse_narrative(emp, t);
                                           Chunk* ch = union_new(
                                                Chunk, NarrativeChunk, .tokens = tu.acc );
                                           GQueue* newQ = g_queue_push_back(acc, ch);
                                           parse_rec(newQ, tu.rem);
                                           })                                            :
                h-&amp;gt;kind == CloseComment ?
                    report_error_e(
                        &amp;quot;Don't insert a close narrative comment at the start of your&amp;quot;
                        &amp;quot; program at line %i&amp;quot;,
                                            h-&amp;gt;OpenComment.line)                         :
                h-&amp;gt;kind == Text         ?
                                        ({
                                           GQueue* emp = g_queue_new();
                                           struct tuple tu =
                                                parse_code(g_queue_push_front(emp, h), t);
                                           parse_rec(g_queue_push_back
                                            (acc,
                                             union_new(Chunk, CodeChunk, .tokens = tu.acc)),
                                             tu.rem);
                                          })                                                               :
                                          g_assert_no_match;
    }

    return parse_rec(g_queue_new(), tokens);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Flattener&lt;/h2&gt;
&lt;p&gt;This follows the usual practice of representing fold as foreach statments (and maps to). Pheraps I shall build better abstractions for them at some point. I also introduce a little macro to simplify writing of GFunc lambdas, given how pervasive they are.&lt;/p&gt;
&lt;p&gt;Again, note how heavy ternary operated this is …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define g_func_z(type, name, ...) lambda(void,                                              
                                        (void* private_it, G_GNUC_UNUSED void* private_no){ 
                                       type name = private_it;                              
                                       __VA_ARGS__                                          
                                })

static
GQueue* flatten(Options* options, GQueue* chunks) {
    GString* token_to_string_narrative(Token* tok) {
        return  tok-&amp;gt;kind == OpenComment ||
                tok-&amp;gt;kind == CloseComment   ?
                    report_error_e(&amp;quot;Cannot nest narrative comments at line %i&amp;quot;,
                                   tok-&amp;gt;OpenComment.line)                                   :
                tok-&amp;gt;kind == Text           ? g_string_new(tok-&amp;gt;Text.text)                  :
                                              g_assert_no_match;
    }
    GString* token_to_string_code(Token* tok) {
        return  tok-&amp;gt;kind == OpenComment    ?
                report_error_e(
                    &amp;quot;Open narrative comment cannot be in code at line %i.&amp;quot;
                    &amp;quot; Pheraps you have an open comment &amp;quot;
                    &amp;quot;in a code string before this comment tag?&amp;quot;
                    , tok-&amp;gt;OpenComment.line)                                                :
                tok-&amp;gt;kind == CloseComment   ? g_string_new(options-&amp;gt;end_narrative)          :
                tok-&amp;gt;kind == Text           ? g_string_new(tok-&amp;gt;Text.text)                  :
                                              g_assert_no_match;
    }
    Block* flatten_chunk(Chunk* ch) {
        return  ch-&amp;gt;kind == NarrativeChunk  ? ({
                               GQueue* tokens = ch-&amp;gt;NarrativeChunk.tokens;
                               GString* res = g_string_sized_new(256);
                               g_queue_foreach(tokens, g_func(Token*, tok,
                                                g_string_append(
                                                    res,
                                                    token_to_string_narrative(tok)-&amp;gt;str);
                                                ), NULL);
                               union_new(Block, Narrative, .narrative = res-&amp;gt;str);
                                               })   :
                ch-&amp;gt;kind == CodeChunk       ? ({
                               GQueue* tokens = ch-&amp;gt;CodeChunk.tokens;
                               GString* res = g_string_sized_new(256);
                               g_queue_foreach(tokens, g_func(Token*, tok,
                                                        g_string_append(
                                                            res,
                                                            token_to_string_code(tok)-&amp;gt;str);
                                                        ), NULL);
                               union_new(Block, Code, .code = res-&amp;gt;str);
                                               })   :
                               g_assert_no_match;
    }

    GQueue* res = g_queue_new();
    g_queue_foreach(chunks, g_func(Chunk*, ch,
                                Block* b = flatten_chunk(ch);
                                g_queue_push_tail(res, b);
                                ) ,NULL);
    return res;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can tie everything together to build blockize, which is our parse tree.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static
GQueue* blockize(Options* options, char* source) {
    GQueue* tokens  = tokenize(options, source);
    GQueue* blocks  = parse(options, tokens);
    return flatten(options, blocks);
}
10 Define the phases
In C you can easily forward declare function, so you don’t have to come up with some clever escabotage like we had to do in F#.

static
GQueue* remove_empty_blocks(Options*, GQueue*);
static
GQueue* merge_blocks(Options*, GQueue*);
static
GQueue* add_code_tags(Options*, GQueue*);

static
GQueue* process_phases(Options* options, GQueue* blocks) {

    blocks          = remove_empty_blocks(options, blocks);
    blocks          = merge_blocks(options, blocks);
    blocks          = add_code_tags(options, blocks);
    return blocks;
}

static
char* extract(Block* b) {
    return  b-&amp;gt;kind == Code         ? b-&amp;gt;Code.code          :
            b-&amp;gt;kind == Narrative    ? b-&amp;gt;Narrative.narrative:
                                      g_assert_no_match;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There must be a higher level way to write this utility function …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static
bool is_str_all_spaces(const char* str) {
    g_assert(str);
    while(*str != '0') {
        if(!g_ascii_isspace(*str))
            return false;
        str++;
    }
    return true;
}

static
GQueue* remove_empty_blocks(G_GNUC_UNUSED Options* options, GQueue* blocks) {

    g_queue_foreach(blocks, g_func(Block*, b,
        if(is_str_all_spaces(extract(b)))
            g_queue_remove(blocks, b);
                                   ), NULL);
    return blocks;
}

static
GQueue* merge_blocks(G_GNUC_UNUSED Options*options, GQueue* blocks) {
    return  g_queue_is_empty(blocks)            ? blocks            :
            g_queue_get_length(blocks) == 1     ? blocks            :
                ({
                 Block* h1 = g_queue_pop_head(blocks);
                 Block* h2 = g_queue_pop_head(blocks);
                 h1-&amp;gt;kind == Code &amp;amp;&amp;amp; h2-&amp;gt;kind == Code ? ({
                     char* newCode =
                        g_strjoin(&amp;quot;&amp;quot;, h1-&amp;gt;Code.code, NL, h2-&amp;gt;Code.code, NULL);
                     Block* b = union_new(Block, Code, .code = newCode);
                     merge_blocks(options, g_queue_push_front(blocks, b));
                                                         })         :
                 h1-&amp;gt;kind == Narrative &amp;amp;&amp;amp; h2-&amp;gt;kind == Narrative ? ({
                     char* newNarr =
                        g_strjoin(
                            &amp;quot;&amp;quot;, h1-&amp;gt;Narrative.narrative, NL, h2-&amp;gt;Narrative.narrative, NULL);
                     Block* b = union_new(Block, Narrative, .narrative = newNarr);
                     merge_blocks(options, g_queue_push_front(blocks, b));
                                                         })         :
                                                         ({
                     GQueue* newBlocks =
                        merge_blocks(options, g_queue_push_front(blocks, h2));
                     g_queue_push_front(newBlocks, h1);
                                                         });
                 });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This really should be in glib …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;inline static
gint g_asprintf_z(gchar** string, gchar const *format, ...) {
    va_list argp;
    va_start(argp, format);
    gint bytes = g_vasprintf(string, format, argp);
    va_end(argp);
    return bytes;
}

static
char* indent(int n, char* s) {
    g_assert(s);

    char* ind       = g_strnfill(n, ' ');
    char* tmp;
    g_asprintf(&amp;amp;tmp, &amp;quot;%s%s&amp;quot;, ind, s);

    char* withNl;
    g_asprintf(&amp;amp;withNl, &amp;quot;n%s&amp;quot;, ind);

    return g_strjoinv(withNl, g_strsplit(tmp, NL, -1));
}
And finally I ended up defining map. See if you like how the usage looks in the function below.

#define g_queue_map_z(q, type, name, ...) ({                                
        GQueue* private_res = g_queue_new();                                
        g_queue_foreach(q, g_func(type, name,                               
            name = __VA_ARGS__;                                             
            g_queue_push_tail(private_res, name);                           
            ), NULL);                                                       
        private_res;                                                        
                                      })

static
GQueue* add_code_tags(Options* options, GQueue* blocks) {

    GQueue* indent_blocks(GQueue* blocks) {
        return g_queue_map(blocks, Block*, b,
                b-&amp;gt;kind == Narrative ? b                                                                                                    :
                b-&amp;gt;kind == Code      ?
                    union_new(Block, Code, .code =
                        indent(options-&amp;gt;code_symbols-&amp;gt;Indented.indentation, b-&amp;gt;Code.code))    :
                    g_assert_no_match;);
    }

    GQueue* surround_blocks(GQueue* blocks) {
        return g_queue_map(blocks, Block*, b,
                b-&amp;gt;kind == Narrative ?
                    union_new(Block, Narrative, .narrative =
                        g_strjoin(&amp;quot;&amp;quot;, NL, g_strstrip(b-&amp;gt;Narrative.narrative), NL, NULL))   :
                b-&amp;gt;kind == Code      ?
                    union_new(Block, Code, .code = g_strjoin(&amp;quot;&amp;quot;,
                                                 NL,
                                                 options-&amp;gt;code_symbols-&amp;gt;Surrounded.start_code,
                                                 NL,
                                                 g_strstrip(b-&amp;gt;Code.code),
                                                 NL,
                                                 options-&amp;gt;code_symbols-&amp;gt;Surrounded.end_code,
                                                 NL,
                                                 NULL))    :
                                       g_assert_no_match;);

    }

    return  options-&amp;gt;code_symbols-&amp;gt;kind == Indented     ?   indent_blocks(blocks)   :
            options-&amp;gt;code_symbols-&amp;gt;kind == Surrounded   ?   surround_blocks(blocks) :
                                                            g_assert_no_match;
}

char* stringify(GQueue* blocks) {
    GString* res = g_string_sized_new(2048);
    g_queue_foreach(blocks, g_func(Block*, b,
        g_string_append(res, extract(b));
    ), NULL);
    return g_strchug(res-&amp;gt;str);
}

void deb(GQueue* q);

static
char* translate(Options* options, char* source) {
    g_assert(options);
    g_assert(source);

    GQueue* blocks  = blockize(options, source);
    blocks          = process_phases(options, blocks);
    return stringify(blocks);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Parsing the command line&lt;/h2&gt;
&lt;p&gt;In glib there is a command line parser that accept options in unix-like format and automatically produces professional &amp;ndash;help messages and such. We shoudl really have something like this in .NET. Pheraps we do and I’m not aware of it?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;typedef struct CmdOptions { char* input_file; char* output_file; Options* options;} CmdOptions;

static
CmdOptions* parse_command_line(int argc, char* argv[]);

static char *no = NULL, *nc = NULL, *l = NULL, *co = NULL, *cc = NULL, *ou = NULL;
static char** in_file;

static int ind = 0;
static bool tests = false;

// this is a bug in gcc, fixed in 2.7.0 not to moan about the final NULL
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored &amp;quot;-Wmissing-field-initializers&amp;quot;

static GOptionEntry entries[] =
{
  { &amp;quot;language&amp;quot;          , 'l', 0, G_OPTION_ARG_STRING, &amp;amp;l ,
                                &amp;quot;Language used&amp;quot;, &amp;quot;L&amp;quot;  },
  { &amp;quot;output&amp;quot;            , 'o', 0, G_OPTION_ARG_FILENAME, &amp;amp;ou,
                                &amp;quot;Defaults to the input file name with mkd extension&amp;quot;, &amp;quot;FILE&amp;quot; },
  { &amp;quot;narrative-open&amp;quot;    , 'p', 0, G_OPTION_ARG_STRING, &amp;amp;no,
                                &amp;quot;String opening a narrative comment&amp;quot;,   &amp;quot;NO&amp;quot; },
  { &amp;quot;narrative-close&amp;quot;   , 'c', 0, G_OPTION_ARG_STRING, &amp;amp;nc,
                                &amp;quot;String closing a narrative comment&amp;quot;,   &amp;quot;NC&amp;quot; },
  { &amp;quot;code-open&amp;quot;         , 'P', 0, G_OPTION_ARG_STRING, &amp;amp;co,
                                &amp;quot;String opening a code block&amp;quot;,          &amp;quot;CO&amp;quot; },
  { &amp;quot;code-close&amp;quot;        , 'C', 0, G_OPTION_ARG_STRING, &amp;amp;cc,
                                &amp;quot;String closing a code block&amp;quot;,          &amp;quot;CC&amp;quot; },
  { &amp;quot;indent&amp;quot;            , 'i', 0, G_OPTION_ARG_INT,    &amp;amp;ind,
                                &amp;quot;Indent the code by N whitespaces&amp;quot;,    &amp;quot;N&amp;quot;  },
  { &amp;quot;run-tests&amp;quot;         , 't', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,   &amp;amp;tests,
                                &amp;quot;Run all the testcases&amp;quot;, NULL },
  { G_OPTION_REMAINING  ,   0, 0, G_OPTION_ARG_FILENAME_ARRAY, &amp;amp;in_file,
                                &amp;quot;Input file to process&amp;quot;,   &amp;quot;FILE&amp;quot; },
  { NULL }
};
#pragma GCC diagnostic pop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Brain damaged way to run tests with a -t hidden option. Not paying the code size price in release.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#ifndef NDEBUG
#include &amp;quot;tests.c&amp;quot;
#endif
Here is my big ass command parsing function. It could use a bit of refactoring …

void destroy_arena_allocator();

static
CmdOptions* parse_command_line(int argc, char* argv[]) {

    GError *error = NULL;
    GOptionContext *context;

    context =
        g_option_context_new (&amp;quot;- translate source code with comemnts to an annotated file&amp;quot;);
    g_option_context_add_main_entries (context, entries, NULL);
    g_option_context_set_summary(context, summary(s_lang_params_table));

    if (!g_option_context_parse (context, &amp;amp;argc, &amp;amp;argv, &amp;amp;error))
        report_error(&amp;quot;option parsing failed: %s&amp;quot;, error-&amp;gt;message);

    CmdOptions* opt = g_new(CmdOptions, 1);
    opt-&amp;gt;options = g_new(Options, 1);

    #ifndef NDEBUG
    if(tests) {
        int i = run_tests(argc, argv);
        exit(i);
    }
    #endif

    if(!in_file) report_error(&amp;quot;No input file&amp;quot;);
    opt-&amp;gt;input_file = *in_file;

    // Uses input file without extension, adding extension .mkd (assume markdown)
    opt-&amp;gt;output_file = ou ? ou :  ({
                                  char* output      = g_strdup(*in_file);
                                  char* extension   = g_strrstr(output, &amp;quot;.&amp;quot;);
                                  extension ? ({
                                               *extension = '0';
                                               g_strjoin(&amp;quot;&amp;quot;, output, &amp;quot;.mkd&amp;quot;, NULL);
                                                }) :
                                               g_strjoin(&amp;quot;&amp;quot;, output, &amp;quot;.mkd&amp;quot;, NULL);
                                  });

    if(l) { // user passed a language
        LangSymbols* lang = lang_find_symbols(s_lang_params_table, l);
        if(!lang) report_error(&amp;quot;%s is not a supported language&amp;quot;, l);

        opt-&amp;gt;options-&amp;gt;start_narrative  = lang-&amp;gt;start;
        opt-&amp;gt;options-&amp;gt;end_narrative    = lang-&amp;gt;end;

    } else {
        if(!no || !nc) report_error(&amp;quot;You need to specify either -l, or both -p and -c&amp;quot;);

        opt-&amp;gt;options-&amp;gt;start_narrative  = no;
        opt-&amp;gt;options-&amp;gt;end_narrative    = nc;
    }

    if(ind) { // user pass    g_option_context_free();
        opt-&amp;gt;options-&amp;gt;code_symbols = union_new(CodeSymbols, Indented, .indentation = ind);
    } else {
        if(!co || !cc) report_error(&amp;quot;You need to specify either -indent, or both -P and -C&amp;quot;);
        opt-&amp;gt;options-&amp;gt;code_symbols =
            union_new(CodeSymbols, Surrounded, .start_code = co, .end_code = cc);
    }

    return opt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some windows programs (i.e. notepad, VS, …) add a 3 bytes prelude to their utf-8 files, C doesn’t know anything about it, so you need to strip it. On this topic, I suspect the program works on UTF-8 files that contain non-ASCII chars, even if when I wrote it I didn’t know anything about localization.&lt;/p&gt;
&lt;p&gt;It should work because I’m just splitting the file when I see a certain ASCII string and in UTF-8 ASCII chars cannot appear anywhere else than in their ASCII position.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;char* skip_utf8_bom(char* str) {
    unsigned char* b = (unsigned char*) str;
    return  b[0] == 0xEF &amp;amp;&amp;amp; b[1] == 0xBB &amp;amp;&amp;amp; b[2] == 0xBF    ? (char*) &amp;amp;b[3]  : // UTF-8
                                                              (char*) b;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Not freeing memory (again)&lt;/h2&gt;
&lt;p&gt;The reason I haven’t been freeing memory all along is because I was planning on using an arena allocator (a kind of linear allocator).&lt;/p&gt;
&lt;p&gt;Memory management is fully hortogonal to the style of programming described in this post. You can do it whatever way you prefer, but there is a certain affinity between an arena allocator (or garbage collection) and functional programming because of the temporary objects created in expressions. You could create the temporary objects explicitely, but that would diminish the conciseness of the paradigm.&lt;/p&gt;
&lt;p&gt;I have an arena allocator implementation here. In the code below I comment it out so that you don’t have a dependency from that code if you want to try this. The program runs so quickly and it does so little that you can probably let the operating system reclame memory at the end of the process life.&lt;/p&gt;
&lt;p&gt;If you ended up integrating this with an editor (i.e. literate programming editing), you’d need to be more careful.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#ifdef ARENA

Arena_T the_arena;

inline static
gpointer arena_malloc(gsize n_bytes) {
    return Arena_alloc(the_arena, n_bytes, __FILE__, __LINE__);
}

inline static
gpointer arena_calloc(gsize n_blocks, gsize n_block_bytes) {
    return Arena_calloc(the_arena, n_blocks, n_block_bytes, __FILE__, __LINE__);
}

inline static
gpointer arena_realloc(gpointer mem, gsize n_bytes) {
    return Arena_realloc(the_arena, mem, n_bytes, __FILE__, __LINE__);
}

void arena_free(G_GNUC_UNUSED gpointer mem) {
    // NOP
}

void set_arena_allocator() {
    GMemVTable vt = (GMemVTable) { .malloc = arena_malloc,      .calloc = arena_calloc,
                                   .realloc = arena_realloc,    .free = arena_free,
                                   .try_malloc = arena_malloc,  .try_realloc = arena_realloc};
    g_mem_set_vtable(&amp;amp;vt);

    the_arena = Arena_new();
}

void destroy_arena_allocator() {
    Arena_dispose(&amp;amp;the_arena);
}

#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I have to say, it didn’t feel too cumbersome to structure C code in a functional way, assuming that you can use GLib and a couple of GCC extensions to the language. It certainly doesn’t have the problems that C++ has in terms of debugging STL failures.&lt;/p&gt;
&lt;p&gt;There are a couple of things I don’t like about GLib and I’m working on an hobby project to overcome them. Eventually I’ll post it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;int main(int argc, char* argv[])
{
#ifdef ARENA
    set_arena_allocator();
#endif

    CmdOptions* opt = parse_command_line(argc, argv);

    char* source    = NULL;
    GError* error   = NULL;

    if(!g_file_get_contents(opt-&amp;gt;input_file, &amp;amp;source, NULL, &amp;amp;error))
        report_error(error-&amp;gt;message);

    source = skip_utf8_bom(source);

    char* text              = translate(opt-&amp;gt;options, source);

    if(!g_file_set_contents(opt-&amp;gt;output_file, text, -1, &amp;amp;error))
        report_error(error-&amp;gt;message);

#ifdef ARENA
    destroy_arena_allocator();
#endif

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Wed, 20 Mar 2013 15:29:05 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2013-03-20-funky-c-for-literate-programming.html</guid>
        </item>
        
        <item>
            <title>Functional programming in C: Implementation</title>
            <link>https://www.lucabol.com/posts/2013-01-11-functional-programming-in-c-implementation.html</link>
            <description>&lt;h2&gt;Cleanup&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start simple with the cleanup function. First we need the usual barrage of includes. &lt;code&gt;G_BEGIN_DECLS&lt;/code&gt; allows the header to be linked in C++.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#ifndef L_UTILS_INCLUDED
#define L_UTILS_INCLUDED

#include &amp;quot;glib.h&amp;quot;

G_BEGIN_DECLS

#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
This feature is GCC specific. It uses __attribute((cleanup(f))) where f is the cleanup function. In this case the cleanup function just frees the memory.

#ifdef __GNUC__

 static inline void __autofree(void *p) {
     void **_p = (void**)p;
     free(*_p);
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;auto_clean is a building block that you can use to plug in your own cleanup function. In the common case of memory allocation, I created a wrapper macro auto_free to make it even easier.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define auto_clean(f)   __attribute((cleanup(f)))
#define auto_free       auto_clean(__autofree)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Lambdas&lt;/h2&gt;
&lt;p&gt;I took this one from here.&lt;/p&gt;
&lt;p&gt;If you think about it, a lambda is just an expression that returns a function. This macro creates a nested function, called fn, inside a statement expression and returns it. Unfortunately these features are gcc specific.&lt;/p&gt;
&lt;p&gt;Remember that lambdas are not allocated on the heap, so you have to be careful on how you used them.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define lambda(return_type, function_body)                                          
  ({                                                                                
    return_type __fn__ function_body                                                
    __fn__;                                                                         
  })

#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Unions&lt;/h2&gt;
&lt;p&gt;A union type is what you would expect: a struct that contains an unnamed union and a field to specify which type it is. We need the list of types in union_decl to create the kind enum. The usage of &lt;strong&gt;VA_ARGS&lt;/strong&gt; allows to use whatever syntax you want to go into the enum (i.e. specify int values).&lt;/p&gt;
&lt;p&gt;Having to specify the the types here is unfortunate as you are going to need to specify it in the union_case macros as well.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t found another way to do it. If you do, let me know.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define union_decl(alg, ...)                                                        
typedef struct alg {                                                                
    enum {  __VA_ARGS__ } kind;                                                     
    union {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You specify each type for the union with union_type. That looks pretty good to me.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define union_type(type, ...)                                                       
    struct type { __VA_ARGS__ } type;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ideally you shouldn&amp;rsquo;t need to specify alg here. Perhaps there is a way to avoid doing so.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define union_end(alg)                                                              
    };} alg;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then set the fields on the union type by using the below macro. Notice the usage of the new struct constructor here to allow optional named parameters.&lt;/p&gt;
&lt;p&gt;This is a statement, so it cannot go into an expression place. I think I could make it an expression that returns the existing (or a new) union. This is going to be a sceanrio if people are not using gcc statement expressions.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define union_set(instance, type, ...)                                              
    G_STMT_START {                                                                  
        (instance)-&amp;gt;kind     = (type);                                              
        (instance)-&amp;gt;type   = (struct type) { __VA_ARGS__ };                         
    } G_STMT_END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is an utility macro. It is a version of g_assert that you can use in an expression position.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define g_assert_e(expr) (                                                          
    (G_LIKELY (!expr) ?                                                             
   (void)g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 
                                             #expr)                             
    : (void) 1) )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this allows to fill the default case in a match statement implemented as a ternary operator. It prints out a text representation of the expression and returns it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#define union_fail(...) (g_assert_e(((void)(__VA_ARGS__) , false)), (__VA_ARGS__))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rest of the code is commented out. It is a macro way to do pattern matching. For me, the ternary operator is simpler, but I left it there in case you want to play with it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;/*
#define union_case_only_s(instance, type, ...)                                      
        G_STMT_START {                                                              
        if((instance)-&amp;gt;kind == (type)) {                                            
            G_GNUC_UNUSED struct type* it = &amp;amp;((instance)-&amp;gt;type); __VA_ARGS__; }     
        else g_assert_not_reached();                                                
        } G_STMT_END

#define union_case_first_s(alg, instance, type, ...)                                
    G_STMT_START {                                                                  
        alg* private_tmp = (instance);                                              
        if(private_tmp-&amp;gt;kind == type) {                                             
            G_GNUC_UNUSED struct type* it = &amp;amp;((private_tmp)-&amp;gt;type); __VA_ARGS__; }

#define union_case_s(type, ...)                                                     
        else if(private_tmp-&amp;gt;kind == type) {                                        
            G_GNUC_UNUSED struct type* it = &amp;amp;((private_tmp)-&amp;gt;type); __VA_ARGS__; }

#define union_case_last_s(type, ...)                                                
        else if(private_tmp-&amp;gt;kind == type) {                                        
            G_GNUC_UNUSED struct type* it = &amp;amp;((private_tmp)-&amp;gt;type); __VA_ARGS__; }  
            else g_assert_not_reached(); } G_STMT_END

#define union_case_default_s(...)                                                   
        else __VA_ARGS__; } G_STMT_END

// Need to use assert here because g_assert* cannot be used in expressions as it expands to do .. while(0)
#define union_case_only(instance, type, ...)                                        
        ( (instance)-&amp;gt;kind == (type) ? (__VA_ARGS__) : (assert(false), __VA_ARGS__) )

#define union_case_first(instance, type, ...)                                       
        ( (instance)-&amp;gt;kind == (type) ? (__VA_ARGS__) :

#define union_case(instance, type, ...)                                             
        (instance)-&amp;gt;kind == (type) ? (__VA_ARGS__) :

#define union_case_last(instance, type, ...)                                        
        (instance)-&amp;gt;kind == (type) ? (__VA_ARGS__) : (assert(false), (__VA_ARGS__)) )
#define union_case_default(...)                                                     
        (__VA_ARGS__) )

*/

G_BEGIN_DECLS

#endif // L_UTILS_INCLUDED
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Fri, 11 Jan 2013 16:37:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2013-01-11-functional-programming-in-c-implementation.html</guid>
        </item>
        
        <item>
            <title>Functional programming in C</title>
            <link>https://www.lucabol.com/posts/2013-01-04-functional-programming-in-c.html</link>
            <description>&lt;p&gt;This post/program (as I’m writing it in literate style) is a continuation of my previous posts about functional programming in C++. I promise I’m not going to post about doing it in assembly language (I think) ….&lt;/p&gt;
&lt;p&gt;I came to like the simplicity of C very much and got interested in how you could write functional code in it.&lt;/p&gt;
&lt;p&gt;There is one irritating thing about C as a viable programming language. Microsoft’s compiler support is not good. It just supports ANSI C, not C99 or C11. So, if you want to use more modern idyoms, you got to use gcc or clang. In this post I assume you use gcc. I will point out the gcc specific extensions.&lt;/p&gt;
&lt;p&gt;Also, the C standard library is pretty limited, so I decided to use GLib to complement it. I also created some macros to simplify the syntax. I never understood why people like templates and think macros are evil. It takes me all of 5 minutes to do a -E on GCC to debug the result of a macro expansion. With templates, well, that’s different.&lt;/p&gt;
&lt;p&gt;So, in summary, this post is about how you can write functional code in C, perhaps with some gcc extensions and certainly with some macro tricks. Let’s call it funkyC (thanks Ian ). I’m going to show how to use it first. Next post I’m going to show how it’s implemented.&lt;/p&gt;
&lt;h2&gt;Discriminated unions in C&lt;/h2&gt;
&lt;p&gt;With a bit of macro magic, you can get a decent looking discriminated union syntax. First we need to include the correct headers. lutils.h is where all the macros are defined.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#include &amp;lt;glib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;assert.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#include &amp;quot;lutils.h&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you can declare a discriminated union with the syntax below. It suffers from two problems: repeting the list of possible types in union_decl and repeating the name of the discriminated union in union_end. Perhaps there is a way to avoid that, but I haven’t found it.&lt;/p&gt;
&lt;p&gt;The syntax for the union_type call is the same as you would use inside a struct declaration. We’ll see how this works when we look at lutils.h.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;union_decl  (Car, Volvo, Fiat, Ferrari)
union_type      (Volvo,     int x; double y;)
union_type      (Fiat,      char* brand, *model;)
union_type      (Ferrari,   char* brand, *model;)
union_end   (Car)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can create a Car either on the stack, as below, or on the heap and we can set its value with union_set.&lt;/p&gt;
&lt;p&gt;Notice the usage of the new struct construction syntax to simulate optional named parameters in C. I would prefer not to have a dot at the start of the name, but overall it is beautiful (if I can say that myself).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static void printCar(Car*);

static void testUnion() {
    Car c;

    union_set   (&amp;amp;c, Volvo, .x = 3, .y = 4);
    printCar    (&amp;amp;c);
    union_set   (&amp;amp;c, Ferrari, .brand = &amp;quot;Ferrari&amp;quot;);
    printCar    (&amp;amp;c);
    union_set   (&amp;amp;c, Fiat, .brand = &amp;quot;Fiat&amp;quot;, .model = &amp;quot;234&amp;quot;);
    printCar    (&amp;amp;c);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then access values inside your discriminated union with normal if statements.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static void testCar(Car*, char const *);

static void printCar(Car* c) {

    if(c-&amp;gt;kind == Volvo) {
        int x = c-&amp;gt;Volvo.x;
        g_assert_cmpint(x, ==, 3);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or perhaps you want the equivalent of a match statement in F# (aka an expression that returns a value based on the type of the discriminated union). Notice that, as logical, all the expressions need to return the same type. That’s why union_fail takes a value of the expression type.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;    char temp[40];

    char* value =   c-&amp;gt;kind == Volvo    ?   itoa(c-&amp;gt;Volvo.x, temp, 10)
                  : c-&amp;gt;kind == Ferrari  ?   (void)c-&amp;gt;Ferrari.model, c-&amp;gt;Ferrari.brand
                  : c-&amp;gt;kind == Fiat     ?   c-&amp;gt;Fiat.model
                                        :   union_fail(&amp;quot;Not a valid car type&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are willing to be gcc specific, then your expression can be comprised of multiple statements, of which the last one returns the value of the expression. This allows a much more flexible syntax for your match clauses.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#ifdef __GNUC__

    value       =   c-&amp;gt;kind == Volvo    ? ({
                                            struct Volvo* it = &amp;amp;c-&amp;gt;Volvo;
                                            itoa(it-&amp;gt;x, temp, 10);
                                          })
                  : c-&amp;gt;kind == Ferrari  ?   (void)c-&amp;gt;Ferrari.model, c-&amp;gt;Ferrari.brand
                  : c-&amp;gt;kind == Fiat     ?   c-&amp;gt;Fiat.model
                                        :   union_fail(&amp;quot;Not a valid car type&amp;quot;);

    testCar(c, value);

#endif // __GNUC__
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then use the super simple test framework in GLib to make sure that it all works as expected …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static void testCar(Car* c, char const * value) {
    if(c-&amp;gt;kind == Volvo) g_assert_cmpstr(value, ==, &amp;quot;3&amp;quot;);
    else if (c-&amp;gt;kind == Fiat) g_assert_cmpstr(value, ==, &amp;quot;234&amp;quot;);
    else if (c-&amp;gt;kind == Ferrari) g_assert_cmpstr(value, ==, &amp;quot;Ferrari&amp;quot;);
    else g_assert_not_reached();

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Nested functions and lambda variables&lt;/h2&gt;
&lt;p&gt;GCC has many other cool extensions. A very simple one is nested functions. It allows you to nest functions :-) Look at the definition of doA and f2 in the function below. Putting together nested functions and block statement expressions allows you, with some macro magic, to define lambda functions in your code (from here ).&lt;/p&gt;
&lt;p&gt;Remember that lambdas (aka nested functions) are allocated on the stack. They are very fast, but you cannot store their pointer into a gloal table (unless such table is used while the stack for this function is alive).&lt;/p&gt;
&lt;p&gt;In such cases, you have to create a proper function. But for the other 90% of use cases, they work pretty well. They are lambdas in the spirit of C: very fast, but error prone …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;#ifdef __GNUC__

static void testLambda() {

    typedef int (*aFunc) (int);

    aFunc doA(aFunc f){

        int k(int i) {
            return f(i) + 3;
        }
        return k;
    }

    int clos = 2;

    int f2 (int i) {return i;}
    aFunc b = doA(lambda (int, (int p) {return p + clos;}));

    g_assert_cmpint(b(3), ==, 8);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Automatic cleanup of local variables&lt;/h2&gt;
&lt;p&gt;This is not a functional topic per se, but something that always annoyed me tremendously about C. The fact that you cannot define the equivalent of the using statement in C#, or destructors in C++. Well, now you can. Or not?&lt;/p&gt;
&lt;p&gt;Again, if you are willing to be GCC specific, you can use an attribute (more on this in the upcoming implementation post) to associate a cleanup function that gets called when your variable goes out of scope. In this case, I wrapped the free case in a nice looking macro.&lt;/p&gt;
&lt;p&gt;But that doesn’t really work. You would certainly want such function to be called on any kind of exit from the enclosing scope (aka via exit(), abort() or longjmp()). Alas, that doesn’t happen.&lt;/p&gt;
&lt;p&gt;This reduces the usefulness of this mechanism tremendously. Probably too much in that it lulls you into a false sense of security. You still need to free your resources in the error path of your application.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static void testAutomaticCleanup() {
    char* stack_alloc() {
        auto_free char* b = g_malloc(10000);
        memset(b, '#', 10000);
        return b;
    };

    char * c = stack_alloc();
    g_assert(*c != '#');
}

#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Data structures&lt;/h2&gt;
&lt;p&gt;GLib comes with a vast library of data structures to use, not too different from the .NET framework or Java. For example, below you have a single linked list …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;static void testGLib() {
     GSList* list = NULL;

     list = g_slist_append(list, &amp;quot;Three&amp;quot;);
     list = g_slist_prepend(list, &amp;quot;first&amp;quot;);
     g_assert_cmpint(g_slist_length(list), ==, 2);

     list = g_slist_remove(list, &amp;quot;first&amp;quot;);
     g_assert_cmpint(g_slist_length(list), ==, 1);

     g_slist_free(list);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;There you go, rising the level of abstraction of C, still keeping it very fast (if you are willing to be gcc bound).&lt;/p&gt;
&lt;p&gt;There are other features in functional programming languages that are not in this post. Maybe I’ll get around to macro my way into them eventually, maybe not.&lt;/p&gt;
&lt;p&gt;In the next post we’ll talk about how all of this is implemented. Below is the code for running the testcases.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;int runTests(int argc, char* argv[]) {
    g_test_init(&amp;amp;argc, &amp;amp;argv, NULL);

    if(g_test_quick()) {
        g_test_add_func(&amp;quot;/utils/automatic_cleanup&amp;quot;, testAutomaticCleanup);
        g_test_add_func(&amp;quot;/utils/lambda&amp;quot;, testLambda);
        g_test_add_func(&amp;quot;/utils/Union&amp;quot;, testUnion);
        g_test_add_func(&amp;quot;/utils/SList&amp;quot;, testGLib);
    }

    return g_test_run();
}

int main(int argc, char *argv[]) {
    return runTests(argc, argv);
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Fri, 04 Jan 2013 14:45:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2013-01-04-functional-programming-in-c.html</guid>
        </item>
        
        <item>
            <title>LLite : language friendly literate programming</title>
            <link>https://www.lucabol.com/posts/2012-12-14-llite-language-friendly-literate-programming.html</link>
            <description>&lt;h1&gt;Main ideas&lt;/h1&gt;
&lt;p&gt;My interest in &lt;a href="http://en.wikipedia.org/wiki/Literate_programming"&gt;literate programming&lt;/a&gt;
comes from some realizations on my part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When I go back to code that I have written some time ago, I don&amp;rsquo;t remember my reasoning&lt;/li&gt;
&lt;li&gt;When I write a blog post, my code seems to be better. Perhaps explaining things to people encourages
  me to be more precise&lt;/li&gt;
&lt;li&gt;I like to think top down, but the compiler forces me to write code bottom up, starting from details and
  going to higher level concepts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Unhappiness with existing tools&lt;/h2&gt;
&lt;p&gt;Many of the existing literate programming tools work similarly to the original &lt;a href="http://www-cs-faculty.stanford.edu/~uno/cweb.html"&gt;CWeb&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They have a tangle program that goes over your file and extract something that the compiler can understand&lt;/li&gt;
&lt;li&gt;They have a weave program that extracts from your file something that the document generator can understand&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This scheme has the unfortunate limitation of breaking your code editor. Given
that your file is not a valid code file anymore, the editor starts misbehaving (i.e. intellisense breaks).
The debugger starts to get confused (albeit people tried to remediate that with cleaver use of &lt;code&gt;#line&lt;/code&gt;.
If your language has an interactive console, that would not work either.&lt;/p&gt;
&lt;h2&gt;A different interpretation&lt;/h2&gt;
&lt;p&gt;The main idea of this program is to add your narrative to the comment part of a
code file by extending the comment tag (i.e. in C you could use /** ). This keeps editor, debugger and interactive console working.&lt;/p&gt;
&lt;p&gt;The weave phase as been retained and what you are reading is the program that goes over your code file and extracts
a nicely formatted (for this program in &amp;lsquo;markdown&amp;rsquo; format) file that can then be translated to HTML, PDF, latex, etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;You got that? &lt;em&gt;The document you are reading now &lt;/em&gt;&lt;em&gt;is&lt;/em&gt;&lt;em&gt; the program.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Multi-language, multi-document format&lt;/h2&gt;
&lt;p&gt;LLite works for any programming language, assuming it has open and close &lt;em&gt;comment&lt;/em&gt; character sequences, and any documentation format,
assuming it has open and close &lt;em&gt;code&lt;/em&gt; character sequences (aka allows you to delimitate your code somehow), or it needs the code to be indented.
This document uses &lt;a href="http://daringfireball.net/projects/markdown/"&gt;markdown&lt;/a&gt; (with &lt;a href="http://johnmacfarlane.net/pandoc/"&gt;Pandoc&lt;/a&gt;
extensions to generate table of contents and titles). &lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;You invoke the program as documented below. The first set of parameters lets you choose the symbols that delimitate your language comments (or the default symbols below).
The second set of parameters lets you choose how your target documentation language treats code. Either it delimits it with some symbols or it indents it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;module LLite

let langParamsTable     = [ &amp;quot;fsharp&amp;quot;, (&amp;quot;(*&amp;quot; + &amp;quot;*&amp;quot;, &amp;quot;*&amp;quot; + &amp;quot;*)&amp;quot;) // The + is not to confuse the parser
                            &amp;quot;c&amp;quot;, (&amp;quot;/**&amp;quot;, &amp;quot;**/&amp;quot;)
                            &amp;quot;csharp&amp;quot;, (&amp;quot;/**&amp;quot;, &amp;quot;**/&amp;quot;)
                            &amp;quot;java&amp;quot;, (&amp;quot;/**&amp;quot;, &amp;quot;**/&amp;quot;)] |&amp;gt; Map.ofList

let languages = langParamsTable |&amp;gt; Map.fold (fun state lang _ -&amp;gt; state + lang + &amp;quot; &amp;quot;) &amp;quot;&amp;quot;

let usage   = sprintf @&amp;quot;
Usage: llite inputFile parameters
where:
One of the following two sets of parameters is mandatory
    -no string : string opening a narrative comment
    -nc string : string closing a narrative comment
or
    -l language: where language is one of (%s)

One of the following two sets of parameters is mandatory
    -co string : string opening a code block
    -cc string : string closing a code block
or
    -indent N  : indent the code by N whitespaces

The following parameters are optional:
    -o outFile : defaults to the input file name with mkd extension&amp;quot; languages


let getLangNoNC lang    =
    match Map.tryFind lang langParamsTable with
    | Some(no, nc) -&amp;gt; no, nc
    | None -&amp;gt; failwith (lang + &amp;quot; is not a valid programming language&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Programming Languages limitations&lt;/h2&gt;
&lt;p&gt;One of the main tenets of literate programming is that the code should be written in the order that facilitates
exposition to a human reader, not in the order that makes the compiler happy. This is very important.&lt;/p&gt;
&lt;p&gt;If you have written a blog post or tried to explain a codebase to a new joiner, you must have noticed
that you don&amp;rsquo;t start from the top of the file and go down, but jump here and there trying to better explain
the main concepts. Literate programming says that you should write your code the same way.
But in our version of it, the compiler needs to be kept happy because the literate file &lt;em&gt;is&lt;/em&gt; the code file.&lt;/p&gt;
&lt;p&gt;Some ingenuity is required to achieve such goal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In C and C++ you can forward declare functions and classes, also class members can be in any order&lt;/li&gt;
&lt;li&gt;In C#, Java, VB.NET, F# (the object oriented part) you can write class members in any order&lt;/li&gt;
&lt;li&gt;In the functional part of F# you do have a problem (see &lt;a href="#an-aside-forward-declaring-functions-in-F"&gt;later in this doc&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The F# trick below is used in the rest of the program. You&amp;rsquo;ll understand its usage naturally by just reading the code&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let declare&amp;lt;'a&amp;gt;  = ref Unchecked.defaultof&amp;lt;'a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Implementation&lt;/h1&gt;
&lt;p&gt;At the core, this program is a simple translator that takes some code text and return a valid markdown/whatever text.
We need to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The strings that start and end a narrative comment (input symbols)&lt;/li&gt;
&lt;li&gt;How to translate a code block into a document. We support these variations:&lt;ul&gt;
&lt;li&gt;Indented: indent them by N spaces&lt;/li&gt;
&lt;li&gt;Surrounded by startCode/endCode strings&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type CodeSymbols =
    | Indent of int                 // indentation level in whitespaces
    | Surrounded of string * string // start code * end code

type Options = {
    startNarrative  : string
    endNarrative    : string
    codeSymbols     : CodeSymbols
}

let translate   = declare&amp;lt;Options -&amp;gt; string -&amp;gt; string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Going over the parse tree&lt;/h2&gt;
&lt;p&gt;We need a function that takes a string and returns a list with the various blocks. We can then go over each block,
perform some operations and, in the end, transform it back to text&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Block =
| Code      of string
| Narrative of string

let blockize = declare&amp;lt;Options -&amp;gt; string -&amp;gt; Block list&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I could have used regular expressions to parse the program, but it seemed ugly. I could also have used FsParsec,
but that brings with it an additional dll. So I decided to roll my own parser. This has several problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is probably very slow&lt;/li&gt;
&lt;li&gt;It doesn&amp;rsquo;t allow narrative comments inside comments, in particular it doesn&amp;rsquo;t allow the opening comment&lt;/li&gt;
&lt;li&gt;It doesn&amp;rsquo;t allow opening comments in the program code (not even inside a string)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The latter in particular is troublesome. You&amp;rsquo;ll need to use a trick in the code (i.e. concatenating strings)
to foul this program in not seeing an opening comment, but it is inconvenient.&lt;/p&gt;
&lt;p&gt;With all of that, it works.&lt;/p&gt;
&lt;p&gt;TODO: consider switching to FsParsec&lt;/p&gt;
&lt;h3&gt;Lexer&lt;/h3&gt;
&lt;p&gt;The lexer is going to process list of characters. We need functions to check if a list of characters starts
with certain chars and to return the remaining list after having removed such chars.&lt;/p&gt;
&lt;p&gt;BTW: these functions are polymorphic and tail recursive&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec startWith startItems listToCheck =
    match startItems, listToCheck with
    | [], _             -&amp;gt; true
    | _ , []            -&amp;gt; false
    | h1::t1, h2::t2  when h1 = h2  -&amp;gt; startWith t1 t2
    | _, _              -&amp;gt; false

let rec remove itemsToRemove listToModify =
    match itemsToRemove, listToModify with
    | [], l             -&amp;gt; l
    | _ , []            -&amp;gt; failwith &amp;quot;Remove not defined on an empty list&amp;quot;
    | h1::t1, h2::t2  when h1 = h2  -&amp;gt; remove t1 t2
    | _, _              -&amp;gt; failwith &amp;quot;itemsToRemove are not in the list&amp;quot;

let isOpening options       = startWith (List.ofSeq options.startNarrative) 
let isClosing options       = startWith (List.ofSeq options.endNarrative)
let remainingOpen options   = remove (List.ofSeq options.startNarrative)
let remainingClose options  = remove (List.ofSeq options.endNarrative)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a pretty basic tokenizer. It just analyzes the start of the text and returns what it finds.
It also keeps track of the line number for the sake of reporting it in the error message.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let NL = System.Environment.NewLine

type Token =
| OpenComment   of int
| CloseComment  of int
| Text          of string

let tokenize options source =

    let startWithNL = startWith (Seq.toList NL)

    let rec text line acc = function
        | t when isOpening options t    -&amp;gt; line, acc, t 
        | t when isClosing options t    -&amp;gt; line, acc, t
        | c :: t as full                -&amp;gt;
            let line' = if startWithNL full then line + 1 else line
            text line' (acc + c.ToString()) t
        | []                            -&amp;gt; line, acc, [] 
    let rec tokenize' line acc = function
        | []                            -&amp;gt; List.rev acc
        | t when isOpening options t    -&amp;gt; tokenize' line
                                            (OpenComment(line)::acc)  (remainingOpen options t)
        | t when isClosing options t    -&amp;gt; tokenize' line
                                            (CloseComment(line)::acc) (remainingClose options t)
        | t                             -&amp;gt;
            let line, s, t'= text line &amp;quot;&amp;quot; t
            tokenize' line (Text(s) :: acc) t'

    tokenize' 1 [] (List.ofSeq source)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Parser&lt;/h3&gt;
&lt;p&gt;The parse tree is just a list of Chunks, where a chunk can be a piece of narrative or a piece of code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Chunk =
| NarrativeChunk    of Token list
| CodeChunk         of Token list

let parse options source =

    let rec parseNarrative acc = function
        | OpenComment(l)::t         -&amp;gt;
            failwith (&amp;quot;Don't open narrative comments inside narrative comments at line &amp;quot;
                                                                                    + l.ToString())
        | CloseComment(_)::t        -&amp;gt; acc, t
        | Text(s)::t                -&amp;gt; parseNarrative (Text(s)::acc) t
        | []                        -&amp;gt; failwith &amp;quot;You haven't closed your last narrative comment&amp;quot;

    let rec parseCode acc = function
        | OpenComment(_)::t as t'   -&amp;gt; acc, t'
        | CloseComment(l)::t        -&amp;gt; parseCode (CloseComment(l)::acc) t
        | Text(s)::t                -&amp;gt; parseCode (Text(s)::acc) t
        | []                        -&amp;gt; acc, []
    let rec parse' acc = function
        | OpenComment(_)::t         -&amp;gt;
            let narrative, t' = parseNarrative [] t
            parse' (NarrativeChunk(narrative)::acc) t' 
        | Text(s)::t                -&amp;gt;
            let code, t' = parseCode [Text(s)] t
            parse' (CodeChunk(code)::acc) t'
        | CloseComment(l)::t           -&amp;gt;
            failwith (&amp;quot;Don't insert a close narrative comment at the start of your program at line &amp;quot;
                                                                                    + l.ToString())
        | []                -&amp;gt; List.rev acc

    parse' [] (List.ofSeq source)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Flattener&lt;/h3&gt;
&lt;p&gt;The flattening part of the algorithm is a bit unusual. At this point we have a parse tree that contains tokens, but we want
to reduce it to two simple node types containing all the text in string form.&lt;/p&gt;
&lt;p&gt;TODO: consider managing nested comments and comments in strings (the latter has to happen in earlier phases) &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let flatten options chunks =
    let tokenToStringNarrative = function
    | OpenComment(l) | CloseComment(l)  -&amp;gt; failwith (&amp;quot;Narrative comments cannot be nested at line &amp;quot;
                                                                                    + l.ToString())
    | Text(s)                           -&amp;gt; s

    let tokenToStringCode = function
    | OpenComment(l)                -&amp;gt; failwith (&amp;quot;Open narrative comment cannot be in code at line&amp;quot;
                                                                + l.ToString()) +
                                                 &amp;quot;. Perhaps you have an open comment in&amp;quot; +
                                                 &amp;quot; a code string before this comment tag?&amp;quot;
    | CloseComment(_)               -&amp;gt; string(options.endNarrative |&amp;gt; Seq.toArray)
    | Text(s)                       -&amp;gt; s

    let flattenChunk = function
    | NarrativeChunk(tokens)             -&amp;gt;
        Narrative(tokens |&amp;gt; List.fold (fun state token -&amp;gt; state + tokenToStringNarrative token) &amp;quot;&amp;quot;)
    | CodeChunk(tokens)                  -&amp;gt;
        Code(tokens |&amp;gt; List.fold (fun state token -&amp;gt; state + tokenToStringCode token) &amp;quot;&amp;quot;)

    chunks |&amp;gt; List.fold (fun state chunk -&amp;gt; flattenChunk chunk :: state) [] |&amp;gt; List.rev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are getting there, now we have a list of blocks we can operate upon&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;blockize := fun options source -&amp;gt; source |&amp;gt; tokenize options |&amp;gt; parse options |&amp;gt; flatten options

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Narrative comments phases&lt;/h2&gt;
&lt;p&gt;Each phase is a function that takes the options and a block list and returns a block list that has been &amp;lsquo;processed&amp;rsquo;
in some way.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Phase = Options -&amp;gt; Block List -&amp;gt; Block List

let removeEmptyBlocks   = declare&amp;lt;Phase&amp;gt;
let mergeBlocks         = declare&amp;lt;Phase&amp;gt;
let addCodeTags         = declare&amp;lt;Phase&amp;gt;

let processPhases options blockList = 
    blockList
    |&amp;gt; !removeEmptyBlocks   options
    |&amp;gt; !mergeBlocks         options
    |&amp;gt; !addCodeTags         options
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We want to manage how many newlines there are between different blocks, because we don&amp;rsquo;t trust the programmer
to have a good view of how many newline to keep from comment blocks and code blocks.
We&amp;rsquo;ll trim all newlines from the start and end of a block, and then add our own.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let newLines = [|'\n';'\r'|]

type System.String with
    member s.TrimNl () = s.Trim(newLines) 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Remove empty blocks&lt;/h3&gt;
&lt;p&gt;There might be empty blocks (i.e. between two consecutive comment blocks) in the file.
For the sake of formatting the file beautifully, we want to remove them.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let extract = function
    | Code(text)        -&amp;gt; text
    | Narrative(text)   -&amp;gt; text

removeEmptyBlocks := fun options blocks -&amp;gt;
                        blocks |&amp;gt; List.filter (fun b -&amp;gt; (extract b).TrimNl().Trim() &amp;lt;&amp;gt; &amp;quot;&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Merge blocks&lt;/h3&gt;
&lt;p&gt;Consecutive blocks of the same kind need to be merged, for the sake of formatting the overall text correctly.&lt;/p&gt;
&lt;p&gt;TODO: make tail recursive &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec mergeBlockList = function
    | []        -&amp;gt; []
    | [a]       -&amp;gt; [a]
    | h1::h2::t -&amp;gt; match h1, h2 with
                   | Code(t1), Code(t2)             -&amp;gt; mergeBlockList (Code(t1 + NL + t2)::t)
                   | Narrative(n1), Narrative(n2)   -&amp;gt; mergeBlockList(Narrative(n1 + NL + n2)::t)
                   | _, _                           -&amp;gt; h1::mergeBlockList(h2::t)

mergeBlocks := fun options blocks -&amp;gt; mergeBlockList blocks
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Adding code tags&lt;/h3&gt;
&lt;p&gt;Each code block needs a tag at the start and one at the end or it needs to be indented by N chars.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let indent n (s:string) =
    let pad = String.replicate n &amp;quot; &amp;quot;
    pad + s.Replace(NL, NL + pad)

addCodeTags := fun options blocks -&amp;gt;
    match options.codeSymbols with
    | Indent(n)         -&amp;gt;
        blocks |&amp;gt; List.map (function Narrative(s) as nar -&amp;gt; nar | Code(s) -&amp;gt; Code(indent n s))
    | Surrounded(s, e)  -&amp;gt; 
        blocks |&amp;gt; List.map (function
                            | Narrative(text)   -&amp;gt; Narrative(NL + text.TrimNl() + NL)
                            | Code(text)        -&amp;gt; Code(NL + s + NL + text.TrimNl() + NL + e + NL))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Flatten again&lt;/h3&gt;
&lt;p&gt;Once we have the array of blocks, we need to flatten them (transform them in a single string),
which is trivial, and then finally implement our original translate function.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let sumBlock s b2 = s + extract b2

let flattenB blocks = (blocks |&amp;gt; List.fold sumBlock &amp;quot;&amp;quot;).TrimStart(newLines)

translate := fun options text -&amp;gt; text |&amp;gt; !blockize options |&amp;gt; processPhases options |&amp;gt; flattenB
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Parsing command line arguments&lt;/h2&gt;
&lt;p&gt;Parsing command lines involves writing a function that goes from a sequence of strings
to an input file name, output file name and Options record&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseCommandLine = declare&amp;lt;string array -&amp;gt; string * string * Options&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To implement it, we are going to use a command line parser taken from &lt;a href="http://fssnip.net/8g"&gt;here&lt;/a&gt;. The parseArgs function takes a sequence of argument values
and map them into a (name,value) tuple. It scans the tuple sequence and put command name into all subsequent tuples without name and discard the initial (&amp;ldquo;&amp;rdquo;,&amp;rdquo;&amp;ldquo;) tuple.
It then groups tuples by name and converts the tuple sequence into a map of (name,value seq)&lt;/p&gt;
&lt;p&gt;For now, I don&amp;rsquo;t need the &amp;lsquo;value seq&amp;rsquo; part as all my parameters take a single argument, but I left it in there in case I will need to pass multiple args later on.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;open  System.Text.RegularExpressions

let (|Command|_|) (s:string) =
  let r = new Regex(@&amp;quot;^(?:-{1,2}|\/)(?&amp;lt;command&amp;gt;\w+)[=:]*(?&amp;lt;value&amp;gt;.*)$&amp;quot;,RegexOptions.IgnoreCase)
  let m = r.Match(s)
  if m.Success
  then 
    Some(m.Groups.[&amp;quot;command&amp;quot;].Value.ToLower(), m.Groups.[&amp;quot;value&amp;quot;].Value)
  else
    None


let parseArgs (args:string seq) =
  args 
  |&amp;gt; Seq.map (fun i -&amp;gt; 
                    match i with
                    | Command (n,v) -&amp;gt; (n,v) // command
                    | _ -&amp;gt; (&amp;quot;&amp;quot;,i)            // data
                  )
  |&amp;gt; Seq.scan (fun (sn,_) (n,v) -&amp;gt; if n.Length&amp;gt;0 then (n,v) else (sn,v)) (&amp;quot;&amp;quot;,&amp;quot;&amp;quot;)
  |&amp;gt; Seq.skip 1
  |&amp;gt; Seq.groupBy (fun (n,_) -&amp;gt; n)
  |&amp;gt; Seq.map (fun (n,s) -&amp;gt; (n, s |&amp;gt; Seq.map (fun (_,v) -&amp;gt; v) |&amp;gt; Seq.filter (fun i -&amp;gt; i.Length&amp;gt;0)))
  |&amp;gt; Map.ofSeq

let paramRetrieve (m:Map&amp;lt;string,_&amp;gt;) (p:string) = 
  if Map.containsKey p m
  then Some(m.[p])
  else None
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the main logic of parameter passing. Note that we give precedence to the -l and -indent parameters, if present.&lt;/p&gt;
&lt;p&gt;This is a function that goes from the map of command line parameters to the input file name, output file name and options. With that we
can finally define the original parseCommandLine.  &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let safeHead errMsg s = if s |&amp;gt; Seq.isEmpty then failwith errMsg else s |&amp;gt; Seq.head 

let paramsToInputs paramsMap =
    let single p er     = match paramRetrieve paramsMap p with | Some(k) -&amp;gt; Some(k |&amp;gt; safeHead er)
                                                               | None -&amp;gt; None
    let get p s         = match paramRetrieve paramsMap p with |Some(k) -&amp;gt; k |&amp;gt; safeHead s
                                                               | None -&amp;gt; failwith s
    let defaultP p q er = match paramRetrieve paramsMap p with | Some(k) -&amp;gt; k |&amp;gt; safeHead er
                                                               | None -&amp;gt; q

    let inputFile       = get &amp;quot;&amp;quot; &amp;quot;You need to pass an input file&amp;quot;
    let outputFile      = defaultP  &amp;quot;o&amp;quot;
                                    (System.IO.Path.GetFileNameWithoutExtension(inputFile:string) + &amp;quot;.mkd&amp;quot;)
                                    &amp;quot;You must pass a parameter to -o&amp;quot;

    let no, nc          = match single &amp;quot;l&amp;quot; &amp;quot;You must pass a language parameter to -l&amp;quot; with
                          | Some(l) -&amp;gt; getLangNoNC l
                          | None    -&amp;gt;
                                get &amp;quot;no&amp;quot; &amp;quot;The no (narrative open) parameter is mandatory, if no -l specified&amp;quot;,
                                get &amp;quot;nc&amp;quot; &amp;quot;The nc (narrative close) parameter is mandatory, if no -l specified&amp;quot;

    let codeSymbs       = match single &amp;quot;indent&amp;quot; &amp;quot;You must pass a whitespace indentation number to -indent&amp;quot; with
                          | Some(n)     -&amp;gt;
                                let success, value = System.Int32.TryParse n
                                if success
                                    then Indent(value)
                                    else failwith &amp;quot;-i accepts just an integer value as parameter&amp;quot;                          
                          | None        -&amp;gt;
                                match single &amp;quot;l&amp;quot; &amp;quot;You must pass a language parameter to -l&amp;quot; with
                                | Some(l) -&amp;gt; Surrounded(&amp;quot;~~~&amp;quot; + l,&amp;quot;~~~&amp;quot;)
                                | None    -&amp;gt;
                                    Surrounded(
                                        get &amp;quot;co&amp;quot; &amp;quot;The co (code open) parameter is mandatory, if no -indent specified&amp;quot;,
                                        get &amp;quot;cc&amp;quot; &amp;quot;The cc (code close) parameter is mandatory&amp;quot;)
    inputFile, outputFile, {
        startNarrative  = no
        endNarrative    = nc
        codeSymbols     = codeSymbs
        }

parseCommandLine := parseArgs &amp;gt;&amp;gt; paramsToInputs
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Main method&lt;/h2&gt;
&lt;p&gt;We can then write main as the only side effect function in the program. Here is where the IO monad would live &amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let banner  = &amp;quot;LLite : language friendly literate programming\n&amp;quot;

let printMemory () =
    let bytesInMeg = 1048576.
    let peak = System.Diagnostics.Process.GetCurrentProcess().PeakWorkingSet64
    let work = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64
    printfn &amp;quot;Peak working set: %A&amp;quot; ((float) peak / bytesInMeg)
    printfn &amp;quot;Working set: %A&amp;quot; ((float) peak / bytesInMeg)

let myMain args =
        try

            let inputFile, outputFile, options = !parseCommandLine args
            let input       = System.IO.File.ReadAllText inputFile
            let output      = !translate options input
            System.IO.File.WriteAllText (outputFile, output)

            //printMemory ()
            0
        with
        | e -&amp;gt;
            printfn &amp;quot;%s&amp;quot; &amp;quot;Failure&amp;quot;
            printfn &amp;quot;%s&amp;quot; e.Message 
            printfn &amp;quot;%s&amp;quot; usage
    #if DEBUG 
            printfn &amp;quot;\nDetailed Error Below:\n%A&amp;quot; e
    #endif
            -1
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;An aside: forward declaring functions in F#&lt;/h1&gt;
&lt;h2&gt;A simple solution&lt;/h2&gt;
&lt;p&gt;You can achieve something somehow similar to forward declaration by the &amp;lsquo;declare &amp;lsquo;dirty trick used in this program.
Whenever you want to do a forward declaration of a function , or variable, you can type:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let testDeclare() =

    let add = declare&amp;lt;float -&amp;gt; float&amp;gt;

    let ``function where I want to use add without having defined it`` nums = nums |&amp;gt; Seq.map !add
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a ref to a function from float to float. It looks a bit like an Haskell type declaration.
You can then use such function as if it were actually define and delay his definition to a later point
in time when you are ready to explain it.&lt;/p&gt;
&lt;p&gt;When you are ready to talk about it, you can then define it with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;    add := fun x -&amp;gt; x + 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The syntax is not too bad. You get that often-sought Haskell like explicit type declaration and you can
regex the codebase to create an index at the end of the program (maybe).&lt;/p&gt;
&lt;p&gt;But is it too slow? After all, there is one more indirection call for each function call.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s test it: enable #time in F# interactive and execute timeNormalF and timeIndirectF varying sleepTime
and howManyIter until you convince yourself that it is ok (or not).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;    let sleepTime   = 50
    let howManyIter = 100
    let normalF x   = System.Threading.Thread.Sleep sleepTime
    let indirectF   = declare&amp;lt;int -&amp;gt; unit&amp;gt;
    indirectF      := fun x -&amp;gt; System.Threading.Thread.Sleep sleepTime

    let timeNormalF     = [1..howManyIter] |&amp;gt; List.iter normalF
    let timeIndirectF   = [1..howManyIter] |&amp;gt; List.iter !indirectF
    ()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;A correct solution (but ugly)&lt;/h2&gt;
&lt;p&gt;Unfortunately, there is a big problem with all of the above: it doesn&amp;rsquo;t work with generic functions and curried function invocations.
The code below works in all cases, but it is ugly for the user to use. In this program I&amp;rsquo;ve used the beautiful, but incorrect, syntax.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Literate() =
    static member Declare&amp;lt;'a, 'b&amp;gt;  (ref : obj ref) (x : 'a) : 'b =
        unbox &amp;lt;| (unbox&amp;lt;obj -&amp;gt; obj&amp;gt; !ref) x
    static member Define&amp;lt;'a, 'b&amp;gt; (func : 'a -&amp;gt; 'b) (ref : obj ref) (f : 'a -&amp;gt; 'b) =
        ref := box (unbox&amp;lt;'a&amp;gt; &amp;gt;&amp;gt; f &amp;gt;&amp;gt; box)

// Declaration    
let rec id (x : 'a) : 'a = Literate.Declare idImpl x
and idImpl = ref null

// Usage
let f () = id 100 + id 200

// Definition
Literate.Define id idImpl (fun x -&amp;gt; x)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The traditional way&lt;/h2&gt;
&lt;p&gt;The traditional way of doing something like this is by passing the function as a parameter in a manner similar to the below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;// Declaration and usage intermingled
let calculate' (add: int -&amp;gt; int -&amp;gt; int) x y = add x y * add x y

// Definition
let add x y = x + y

let calculate = calculate' add
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To my way of seeing, this is the most cumbersome solution and conceptually dishonest because you are not parametrizing your function for technical
reasons, but just for the sake of explaining things. In a way, you are changing the signature of your functions for the sake of writing a book.
That can&amp;rsquo;t be right &amp;hellip; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;[&amp;lt;EntryPoint&amp;gt;]
let main args = myMain args
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Fri, 14 Dec 2012 12:29:26 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-12-14-llite-language-friendly-literate-programming.html</guid>
        </item>
        
        <item>
            <title>Exceptions vs. Return Values to represent errors (in F#) – IV – Implementation</title>
            <link>https://www.lucabol.com/posts/2012-12-07-exceptions-vs-return-values-to-represent-errors-in-f-iii-implementation.html</link>
            <description>&lt;p&gt;The Critical monad is defined as follows. First there is the type that propagates through the monad: &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Result&amp;lt;'a, 'b&amp;gt; =
| Success of 'a
| Failure of 'b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we define the usual computation expression methods.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Critical() =
       // a -&amp;gt; m a
        member o.Return x       = Success x
        // m a -&amp;gt; (a -&amp;gt; m b) -&amp;gt; m b
        member o.Bind (m, f)    = match m with
                                    | Failure e -&amp;gt; Failure e
                                    | Success x -&amp;gt; f x
        // m a -&amp;gt; m a
        member o.ReturnFrom m   = m
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Explaining how computational expressions work in F# is a blog onto itself. And several chapters in many books. Sufficient to say that conceptually this propagates the success value and returns the failure value.&lt;/p&gt;
&lt;p&gt;We then define an instance of this type, so that we can use the nice &amp;lsquo;critical { &amp;hellip; }&amp;rsquo; syntax.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let critical = Critical()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then go and define the functions that the user needs to use to annotate their function calls. The simplest one is the one to propagate any exception coming from the function &amp;lsquo;f&amp;rsquo;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let fault f = f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then it comes the one to manage contingencies. This will trap any exception for which &amp;lsquo;stopF ex&amp;rsquo; is &amp;lsquo;true&amp;rsquo;, call &amp;lsquo;errF ex&amp;rsquo; to construct the error return value and wrap it in a &amp;lsquo;Failure&amp;rsquo;. Otherwise it will rethrow the exception.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let contingentGen stopF errF f =
    try
        Success(f ())
    with
        | ex when stopF ex -&amp;gt; Failure(errF ex)
        | _                -&amp;gt; reraise ()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Albeit very simple, the above is the core of the system. Everything else is just details. Let&amp;rsquo;s look at them.&lt;/p&gt;
&lt;p&gt;First we want a function that takes as parameter a list of (Exception, ReturnValue) and gives back the correct stopF errF to plug into &amp;lsquo;contingentGen&amp;rsquo;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let exceptionMapToFuncs exMap =
    let tryFind ex = exMap |&amp;gt; List.tryFind (fun (k, _) -&amp;gt; k.GetType() = ex.GetType())
    (fun ex -&amp;gt;
        let found = tryFind ex
        match found with Some(_) -&amp;gt; true | None -&amp;gt; false),
    (fun ex -&amp;gt;
        let found = tryFind ex
        match found with
        | Some(k, v)    -&amp;gt; v ex
        | None          -&amp;gt; raise ex)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then ugliness comes. For the sake of getting a decent syntax (not great) on the calling site, we need to fake overloading of functions by the old trick of adding a number at the end. Thanks to &lt;a href="http://gotocon.com/amsterdam-2012/speaker/Tobias+Gedell"&gt;Tobias&lt;/a&gt; to point out this (my api was even worse earlier).&lt;/p&gt;
&lt;p&gt;I often wondered about the trade-off between currying and overloading for functions. I seem to always paint myself in a situation where I need overloading. In any case, here it goes:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let contingent1 exMap f x =
    let stopF, errF = exceptionMapToFuncs exMap
    contingentGen stopF errF (fun _ -&amp;gt; f x)
let contingent2 exMap f x y =
    let stopF, errF = exceptionMapToFuncs exMap
    contingentGen stopF errF (fun _ -&amp;gt; f x y)
let contingent3 exMap f x y z =
    let stopF, errF = exceptionMapToFuncs exMap
    contingentGen stopF errF (fun _ -&amp;gt; f x y z)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes you want to trap all exceptions from a function and return your own error value:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let neverThrow1 exc f x     = contingentGen (fun _ -&amp;gt; true) (fun ex -&amp;gt; exc ex) (fun _ -&amp;gt; f x)
let neverThrow2 exc f x y   = contingentGen (fun _ -&amp;gt; true) (fun ex -&amp;gt; exc ex) (fun _ -&amp;gt; f x y)
let neverThrow3 exc f x y z = contingentGen (fun _ -&amp;gt; true) (fun ex -&amp;gt; exc ex) (fun _ -&amp;gt; f x y z)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other times you need to go from a function that returns return values to one that throws exceptions. You need translating from contingencies to faults:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let alwaysThrow exc f x =
    match f x with
    | Success(ret)              -&amp;gt; ret
    | Failure(e)                -&amp;gt; raise (exc e)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;rsquo;s it. Hopefully we have bridged the gap between exceptions and return values without making the code too ugly (just a little bit). Or perhaps not.&lt;/p&gt;
&lt;p&gt;I need to add that I haven&amp;rsquo;t used this library myself (yet). I&amp;rsquo;m sure when I do I&amp;rsquo;ll discover many things to change.&lt;/p&gt;</description>
            <pubDate>Fri, 07 Dec 2012 09:44:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-12-07-exceptions-vs-return-values-to-represent-errors-in-f-iii-implementation.html</guid>
        </item>
        
        <item>
            <title>Exceptions vs. Return Values to represent errors (in F#) – III–The Critical monad</title>
            <link>https://www.lucabol.com/posts/2012-11-30-exceptions-vs-return-values-to-represent-errors-in-f-iiithe-critical-monad.html</link>
            <description>&lt;p&gt;Code for this post is &lt;a href="https://github.com/lucabol/ErrorExceptional"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the last post we looked at some Critical code and decided that, albeit correct, it is convoluted. The error management path obfuscates the underlying logic. Also we have no way of knowing if a developer had thought about the error path or not when invoking a function.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s tackle the latter concern first as it is easier. We want the developer to declaratively tag each method call with something that represents his intent about managing the Contingencies or Faults of the function. Moreover if the function has contingencies, we want to force the developer to manage them explicitly.&lt;/p&gt;
&lt;p&gt;We cannot use attributes for this as function calls happen in the middle of the code, so there is no place to stick attributes into. So we are going to use higher level functions to wrap the function calls. &lt;/p&gt;
&lt;p&gt;The first case is easy. If the developer thinks that the caller of his code has no way to recover from all the exceptions thrown by a function, he can prepend his function call with the &amp;lsquo;fault&amp;rsquo; word as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;fault parseUser userText
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That signals readers of the code that the developer is willing to propagate up all the exceptions thrown by the function parseUser. Embarrassingly, &amp;lsquo;fault&amp;rsquo; is implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let fault f = f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So it is just a tag. Things get trickier when the function has contingencies. We want to find a way to manage them without introducing undue complexity in the code. &lt;/p&gt;
&lt;p&gt;We&amp;rsquo;d like to catch some exceptions thrown by the function and convert them to return values and then either return such return values or manage the contingency immediately after the function call. On top of that, we&amp;rsquo;d want all of the code written after the function call to appear as clean as if no error management were taking place. Monads (computation values) can be used to achieve these goals.&lt;/p&gt;
&lt;p&gt;Last time we introduced a type to represent error return values:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Result&amp;lt;'a, 'b&amp;gt; =
| Success of 'a
| Failure of 'b
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type UserFetchError =
| UserNotFound  of exn
| NotAuthorized of int * exn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can then create a computation expression that &amp;lsquo;abstracts out&amp;rsquo; the Failure case and let you write the code as cleanly as if you were not handling errors. Let&amp;rsquo;s call such thing &amp;lsquo;critical&amp;rsquo;. Here is how the final code looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tryFetchUser3 userName =
    if String.IsNullOrEmpty userName then invalidArg &amp;quot;userName&amp;quot; &amp;quot;userName cannot be null/empty&amp;quot;
    critical {
        let Unauthorized (ex:exn) = NotAuthorized (ex.Message.Length, ex)
        let! userText = contingent1
                            [FileNotFoundException()        :&amp;gt; exn, UserNotFound;
                             UnauthorizedAccessException()  :&amp;gt; exn, Unauthorized]
                            dbQuery (userName + &amp;quot;.user&amp;quot;)
        return fault parseUser userText
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can compare this with the code you would have to write without the &amp;lsquo;critical&amp;rsquo; library (from last post):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tryFetchUser1 userName =
    if String.IsNullOrEmpty userName then invalidArg &amp;quot;userName&amp;quot; &amp;quot;userName cannot be null/empty&amp;quot;
    // Could check for file existence in this case, but often not (i.e. db)
    let userResult =    try
                            Success(dbQuery(userName + &amp;quot;.user&amp;quot;))
                        with
                        | FileNotFoundException as ex        -&amp;gt; Failure(UserNotFound ex)
                        | UnauthorizedAccessException as ex  -&amp;gt; Failure(NotAuthorized(2, ex))
                        | ex                                    -&amp;gt; reraise ()
    match userResult with
    | Success(userText) -&amp;gt;
        let user        = Success(parseUser(userText))
        user
    | Failure(ex)       -&amp;gt; Failure(ex)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And with the original (not critical) function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let fetchUser userName =
    let userText            = dbQuery (userName + &amp;quot;.user&amp;quot;)
    let user                = parseUser(userText)
    user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s go step by step and see how it works. First of all, you need to enclose the Critical parts of your code (perhaps your whole program) in a &amp;lsquo;critical&amp;rsquo; computation:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;critical {
   ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows you to call functions that return a Result and manage the return result as if it were the successful result. If an error were generated, it would be returned instead. We will show how to manage contingencies immediately after the function call later.&lt;/p&gt;
&lt;p&gt;The above is illustrated by the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let! userText = contingent1
                    [FileNotFoundException()        :&amp;gt; exn, UserNotFound;
                     UnauthorizedAccessException()  :&amp;gt; exn, Unauthorized]
                    dbQuery (userName + &amp;quot;.user&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here &amp;lsquo;contingent1&amp;rsquo; is a function that returns a Result, but userText has type string. The Critical monad, and in particular the usage of &amp;lsquo;let!&amp;rsquo; is what allows the magic to happen.&lt;/p&gt;
&lt;p&gt;&amp;lsquo;contingentN&amp;rsquo; is a function that you call when you want to manage certain exceptions thrown by a function as contingencies. The N part represents how many parameters the function takes.&lt;/p&gt;
&lt;p&gt;The first parameter to &amp;lsquo;contingent1&amp;rsquo; is a list of pairs (Exception, ErrorReturnConstructor). That means: when an exception of type Exception is thrown, return the result of calling &amp;lsquo;ErrorReturnConstructor(Exception)&amp;rsquo; wrapped inside a &amp;lsquo;Failure&amp;rsquo; object. The second parameter to &amp;lsquo;contingent1&amp;rsquo; is the function to invoke and the third is the argument to pass to it.&lt;/p&gt;
&lt;p&gt;Conceptually, &amp;lsquo;ContingentN&amp;rsquo; is a tag that says: if the function throws one of these exceptions, wrap them in these return values and propagate all the other exceptions. Notice that Unauthorized takes an integer and an exception as parameters while the ErrorReturnConstructor takes just an exception. So we need to add this line of code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let Unauthorized (ex:exn) = NotAuthorized (ex.Message.Length, ex)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the contingent1 call, we can then write code as if the function returned a normal string:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;return fault parseUser userText
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This achieves that we set up to do at the start of the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Contingencies are now explicit in the signature of tryFetchUser3 &lt;/li&gt;
&lt;li&gt;The developer needs to indicate for each function call how he intend to manage contingencies and faults &lt;/li&gt;
&lt;li&gt;The code is only slightly more complex than the non-critical one &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also decide to manage your contingencies immediately after calling a function. Perhaps there is a way to recover from the problem. For example, if the user is not in the database, you might want to add a standard one:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let createAndReturnUser userName = critical { return {Name = userName; Age = 43}}
let tryFetchUser4 userName =
    if String.IsNullOrEmpty userName then invalidArg &amp;quot;userName&amp;quot; &amp;quot;userName cannot be null/empty&amp;quot;
    critical {
        let Unauthorized (ex:exn) = NotAuthorized (ex.Message.Length, ex) // depends on ex
        let userFound = contingent1
                            [FileNotFoundException()        :&amp;gt; exn, UserNotFound;
                             UnauthorizedAccessException()  :&amp;gt; exn, Unauthorized]
                            dbQuery (userName + &amp;quot;.user&amp;quot;)
        match userFound with
        | Success(userText)         -&amp;gt; return  fault parseUser userText
        | Failure(UserNotFound(_))  -&amp;gt; return! createAndReturnUser(userName)
        | Failure(x)                -&amp;gt; return! Failure(x)
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only difference in this case is the usage of &amp;lsquo;let&amp;rsquo; instead of &amp;lsquo;let!&amp;rsquo;. This exposes the real return type of the function allowing you to pattern match against it.&lt;/p&gt;
&lt;p&gt;Sometimes a simple exception to return value mapping might not be enough and you want more control on which exceptions to catch and how to convert them to return values. In such cases you can use contingentGen:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tryFetchUser2 userName =
    if String.IsNullOrEmpty userName then invalidArg &amp;quot;userName&amp;quot; &amp;quot;userName cannot be null/empty&amp;quot;
    critical {
        let! userText = contingentGen
                            (fun ex -&amp;gt; ex FileNotFoundException || ex UnauthorizedAccessException)
                            (fun ex -&amp;gt;
                                match ex with
                                       | FileNotFoundException       -&amp;gt; UserNotFound(ex)
                                       | UnauthorizedAccessException -&amp;gt; NotAuthorized(3, ex)
                                       | _ -&amp;gt; raise ex)
                            (fun _ -&amp;gt; dbQuery (userName + &amp;quot;.user&amp;quot;))
        return fault parseUser userText
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first parameter is a lambda describing when to catch an exception. The second lambda translate between exceptions and return values. The third lambda represents which function to call.&lt;/p&gt;
&lt;p&gt;Sometimes you might want to catch all the exceptions that a function might throw and convert them to a single return value:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type GenericError = GenericError of exn
// 1. Wrapper that prevents exceptions for escaping the method by wrapping them in a generic critical result
let tryFetchUserNoThrow userName =
    if String.IsNullOrEmpty userName then invalidArg &amp;quot;userName&amp;quot; &amp;quot;userName cannot be null/empty&amp;quot;
    critical {
        let! userText = neverThrow1 GenericError dbQuery (userName + &amp;quot;.user&amp;quot;)
        return fault parseUser userText
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And sometimes you might want to go the opposite way. Given a function that exposes some contingencies, you want to translate them to faults because you don&amp;rsquo;t know how to recover from them.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let operateOnExistingUser userName =
    let user = alwaysThrow GenericException tryFetchUserNoThrow userName
    ()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next time we&amp;rsquo;ll look at how the Critical computation expression is implemented.&lt;/p&gt;</description>
            <pubDate>Fri, 30 Nov 2012 16:41:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-11-30-exceptions-vs-return-values-to-represent-errors-in-f-iiithe-critical-monad.html</guid>
        </item>
        
        <item>
            <title>Exceptions vs. Return Values to represent errors (in F#) – II– An example problem</title>
            <link>https://www.lucabol.com/posts/2012-11-23-exceptions-vs-return-values-to-represent-errors-in-f-iithe-critical-monad.html</link>
            <description>&lt;p&gt;In the previous post, we talked about the difference between Critical and Normal code. In this post we are going to talk about the Critical code part. Ideally, we want:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A way to indicate that a particular piece of code (potentially the whole program) is Critical &lt;/li&gt;
&lt;li&gt;A way to force/encourage the programmer to make an explicit decision on the call site of a function on how he wants to manage the error conditions (both contingencies and faults) &lt;/li&gt;
&lt;li&gt;A way to force/encourage the programmer to expose contingencies/faults that are appropriate for the conceptual level of the function the code is in (aka don&amp;rsquo;t expose implementation details for the function, i.e. don&amp;rsquo;t throw SQLException from a getUser method where the caller is supposed to catch it) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember that I can use the word &amp;lsquo;force&amp;rsquo; here because the programmer has already taken the decision to analyse each line of code for error conditions. As we discussed in the previous post, In many/most cases, such level of scrutiny is unwarranted.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s use the below scenario to unravel the design:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type User = {Name:string; Age:int}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let fetchUser userName =
    let userText            = dbQuery (userName + &amp;quot;.user&amp;quot;)
    let user                = parseUser(userText)
    user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks like a very reasonable .NET function and it is indeed reasonable in Normal code, but not in Critical code. Note that the caller likely needs to handle the user-not-in-repository case because there is no way for the caller to check such condition beforehand without incurring the performance cost of two network roundtrips.&lt;/p&gt;
&lt;p&gt;Albeit the beauty and simplicity, there are issues with this function in a Critical context: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The function throws implementation related exceptions, breaking encapsulation when the user needs to catch them &lt;/li&gt;
&lt;li&gt;It is not clear from the code if the developer thought about error management (do you think he did?) &lt;/li&gt;
&lt;li&gt;Preconditions are not checked, what about empty or null strings? &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To test our design let&amp;rsquo;s define a fake dbQuery:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let dbQuery     = function
    | &amp;quot;parseError.user&amp;quot;     -&amp;gt; &amp;quot;parseError&amp;quot;
    | &amp;quot;notFound.user&amp;quot;       -&amp;gt; raise (FileNotFoundException())
    | &amp;quot;notAuthorized.user&amp;quot;  -&amp;gt; raise (UnauthorizedAccessException())
    | &amp;quot;unknown.user&amp;quot;        -&amp;gt; failwith &amp;quot;Unknown error reading the file&amp;quot;
    | _                     -&amp;gt; &amp;quot;FoundUser&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first two exceptions are contingencies, the caller of fetchUser is supposed to manage them. The unknown.user exception is a fault in the implementation. parseError triggers a problem in the parseUser function.&lt;/p&gt;
&lt;p&gt;ParseUser looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseUser   = function
    | &amp;quot;parseError&amp;quot;          -&amp;gt; failwith &amp;quot;Error parsing the user text&amp;quot;
    | u                     -&amp;gt; {Name = u; Age = 43}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s now create a test function to test the different versions of fetchUser that we are going to create:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let test fetchUser =
    let p x                 = try printfn &amp;quot;%A&amp;quot; (fetchUser x) with ex -&amp;gt; printfn &amp;quot;%A %s&amp;quot; (ex.GetType()) ex.Message
    p &amp;quot;found&amp;quot;
    p &amp;quot;notFound&amp;quot;
    p &amp;quot;notAuthorized&amp;quot;
    p &amp;quot;parseError&amp;quot;
    p &amp;quot;unknown&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the function exposes the problems described above. From the point of view of the caller, there is no way to know what to expect by just inspecting the signature of the function. There is no differentiation between contingencies and faults. The only way to achieve that is to catch some implementation-specific exceptions.&lt;/p&gt;
&lt;p&gt;How would we translate this to Critical code?&lt;/p&gt;
&lt;p&gt;First, we would define a type to represent the result of a function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Result&amp;lt;'a, 'b&amp;gt; =
| Success of 'a
| Failure of 'b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is called the Either type, but the names have been customized to represent this scenario. We then need to define which kind of contingencies our function could return.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type UserFetchError =
| UserNotFound  of exn
| NotAuthorized of int * exn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we assume that the caller can manage the fact that the user is not found or not authorized. This type contains an Exception member. This is useful in cases where the caller doesn&amp;rsquo;t want to manage a contingency, but wants to treat it like a fault (for example when some Normal code is calling some Critical code).&lt;/p&gt;
&lt;p&gt;In such cases, we don&amp;rsquo;t lose important debugging information. But we still don&amp;rsquo;t break encapsulation because the caller is not supposed to &amp;lsquo;catch&amp;rsquo; a fault.&lt;/p&gt;
&lt;p&gt;Notice that NotAuthorized contains an int member. This is to show that contingencies can carry some more information than just their type. For example, a caller could match on both the type and the additional data.&lt;/p&gt;
&lt;p&gt;With that in place, let&amp;rsquo;s see how the previous function looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tryFetchUser1 userName =
    if String.IsNullOrEmpty userName then invalidArg &amp;quot;userName&amp;quot; &amp;quot;userName cannot be null/empty&amp;quot;
    // Could check for file existence in this case, but often not (i.e. db)
    let userResult =    try
                            Success(dbQuery(userName + &amp;quot;.user&amp;quot;))
                        with
                        | FileNotFoundException as ex        -&amp;gt; Failure(UserNotFound ex)
                        | UnauthorizedAccessException as ex  -&amp;gt; Failure(NotAuthorized(2, ex))
                        | ex                                    -&amp;gt; reraise ()
    match userResult with
    | Success(userText) -&amp;gt;
        let user        = Success(parseUser(userText))
        user
    | Failure(ex)       -&amp;gt; Failure(ex)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is what changed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changed name to tryXXX to convey the fact that the method has contingencies &lt;/li&gt;
&lt;li&gt;Added precondition test, which generates a fault &lt;/li&gt;
&lt;li&gt;The signature of the function now conveys the contingencies that the user is supposed to know about &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But still, there are problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The code became very long and convoluted obfuscating the success code path &lt;/li&gt;
&lt;li&gt;Still, has the developer thought about the error conditions in parseUser and decided to let exceptions get out, or did she forget about it? &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The return value crowd at this point is going to shout: &amp;ldquo;Get over it!! Your code doesn&amp;rsquo;t need to be elegant, it needs to be correct!&amp;rdquo;. But I disagree, obfuscating the success code path is a problem because it becomes harder to figure out if your business logic is correct. It is harder to know if you solved the problem you set out to solve in the first place.&lt;/p&gt;
&lt;p&gt;In the next post we&amp;rsquo;ll see what we can do about keeping beauty and being correct.&lt;/p&gt;</description>
            <pubDate>Fri, 23 Nov 2012 10:45:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-11-23-exceptions-vs-return-values-to-represent-errors-in-f-iithe-critical-monad.html</guid>
        </item>
        
        <item>
            <title>Exceptions vs. Return Values to represent errors (in F#) – Conceptual view</title>
            <link>https://www.lucabol.com/posts/2012-11-19-exceptions-vs-return-values-to-represent-errors-in-f-i-conceptual-view.html</link>
            <description>&lt;p&gt;Recently I’ve been reading numerous articles on the age old question of exceptions vs. return values. There is a vast literature on the topic with very passionate opinions on one side or the other. Below is my view on it.&lt;/p&gt;
&lt;p&gt;First of all, I’ll define my terms.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Success code path: chunk of code that is responsible to perform the main task of a function, without any regard for error conditions &lt;/li&gt;
&lt;li&gt;Contingency: an event that happens during the success code path execution that is of interest for the caller of the function. &lt;ul&gt;
&lt;li&gt;It happens rarely &lt;/li&gt;
&lt;li&gt;It can be described in terms that the caller understands, it doesn’t refer to the implementation of the function &lt;/li&gt;
&lt;li&gt;The caller stands a chance to recover from it &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fault: an event that happens during the success code path execution that is not expected by the caller of the function. &lt;ul&gt;
&lt;li&gt;It happens rarely &lt;/li&gt;
&lt;li&gt;It cannot be described in terms that the caller understands, it requires reference to the implementation of the function &lt;/li&gt;
&lt;li&gt;The caller has no way to recover from it &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples of the above for a FetchUser(userName) function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Success code path: the code that retrieves the user from the database &lt;/li&gt;
&lt;li&gt;Contingency: the fact that the requested user is not in the database &lt;/li&gt;
&lt;li&gt;Fault: userName = null, divide by zero, stack overflow, … &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The difference between Contingency and Fault is not sharp in practice and requires common sense, but it is useful none less. When in doubt, it would appear prudent to consider an event as a Contingency, so that the caller gets a chance to recover.&lt;/p&gt;
&lt;p&gt;Ideally, you would like a Contingency to be part of the signature of a function, so that the caller knows about it. On the other end, a Fault shouldn’t be part of the signature of a function for two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The user cannot recover from it &lt;/li&gt;
&lt;li&gt;Being part of the signature would break encapsulation by exposing implementation details of the function &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above seems to suggest that Contingencies should be represented as return values and Faults as exceptions. As an aside, in Java the former is represented as checked exceptions, which is part of the signature. We’ll tackle checked exceptions later on.&lt;/p&gt;
&lt;p&gt;An important point that is often neglected in the discussions on this topic is that there are two categories of applications: applications that care about Contingencies (Critical apps) and applications that don’t (Normal apps). I am of the opinion that the latter category is the largest.&lt;/p&gt;
&lt;p&gt;In many cases you can indeed write just the success code path and, if anything goes wrong, you just clean up after yourself and exit. That is a perfectly reasonable thing to do for very many applications. You are trading off speed of development with stability.&amp;#160; Your application can be anywhere on that continuum.&lt;/p&gt;
&lt;p&gt;Examples of Normal apps are: build scripts, utility applications, departmental applications where you can fix things quickly on the user machine, intranet web sites, internet web sites that are purely informative, etc …&lt;/p&gt;
&lt;p&gt;Examples of Critical apps are: servers, databases, operating systems, web site that sell stuff,&amp;#160; etc …&lt;/p&gt;
&lt;p&gt;For Normal apps, treating Contingencies as Fault is the right thing to do. You just slap a try … catch around your event loop/ thread/ process and you do your best to get the developer to fix the problem quickly. I think a lot of the angst of the ‘return value crowd’ is predicated on not having this distinction in mind. They are making very valid point regarding Critical apps to a crowd that is thinking about Normal apps. So the two sides are cross-talking.&lt;/p&gt;
&lt;p&gt;Also, in my opinion, the main problem with Java checked exceptions is that they make writing Normal apps as cumbersome as writing Critical apps. So, reasonably, people complain. &lt;/p&gt;
&lt;p&gt;The .NET framework decided to use Exceptions as the main way to convey both Faults and Contingencies. By doing so, it makes it easier to write Normal apps, but more difficult to write Critical apps.&lt;/p&gt;
&lt;p&gt;For a Critical app or section of code, you’d want to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Express contingencies in the function signature &lt;/li&gt;
&lt;li&gt;Force/Encourage people to take an explicit decision at the calling site on how they want to manage both Contingencies and Faults &lt;u&gt;for each function call&lt;/u&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the next post, let’s see how we can represent some of this in F#.&lt;/p&gt;</description>
            <pubDate>Mon, 19 Nov 2012 13:02:10 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-11-19-exceptions-vs-return-values-to-represent-errors-in-f-i-conceptual-view.html</guid>
        </item>
        
        <item>
            <title>Retrieving SQL Server data with type providers and exposing it with ASP.NET Web APIs in F#</title>
            <link>https://www.lucabol.com/posts/2012-09-04-retrieving-sql-server-data-with-type-providers-and-exposing-it-with-asp-net-web-apis-in-f.html</link>
            <description>&lt;p&gt;For a good introduction on how to use Web APIs in F#, read here. The starting point for type providers is here. This post is about how I solved a practical problem using these technologies.&lt;/p&gt;
&lt;p&gt;First, let’s discuss the scenario. In my company, we needed to log usage information for our various applications to a central repository and build a web site to access such information. I went through three different architectures for such a requirement, ending with the set of technologies described in the title.&lt;/p&gt;
&lt;p&gt;I found the intersection of the SQL type provider with the ASP.NET Web Api to be very sweet. Personally, I think this mix is much better than using the WFC Data Services, because the code you have to write and the infrastructure to maintain is significantly less.&lt;/p&gt;
&lt;p&gt;I suspect that the F# team and ASP.Net team didn’t talk to each other. It all happens because of a well defined interface (IQueryable) that both teams happen to work against.&lt;/p&gt;
&lt;h2&gt;1st version, heavy Javascript&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;SQL Server Express backend&lt;/li&gt;
&lt;li&gt;WFC Data Services middle tier in C# (autogenerated REST service from a table, you can query from the JS code)&lt;/li&gt;
&lt;li&gt;Plenty of Javascript in the browser, calling back to the REST web services through Ajax&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is an example of the kind of manipulation done in the JS layer:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function extractVersions(sessions) {
    var versions = {}
    $.each(sessions, function (i, s) {
        if (typeof versions[s.Version] == 'undefined') {
            versions[s.Version] = 0
        } else {
            versions[s.Version] = versions[s.Version] + 1
        }
    })

    var vs = []
    for (var prop in versions) {
        if (versions.hasOwnProperty(prop))
            vs.push({ Version: prop, Sessions: versions[prop] })
    }
    return vs;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pros:
1.          Back-end autogenerated
1.          I’ve learned JS pretty well&lt;/p&gt;
&lt;p&gt;Cons:
1.          Plenty of autogenerated code (crap) to debug into when things go wrong
1.          Difficult to customize the back-end
1.          Somehow slow, even if today’s JS engines are pretty good
1.          More time consuming to create and maintain JS code (compared to F# or C#)
1.          Aesthetically unsatisfying, as you really would like to do most manipulations on the server&lt;/p&gt;
&lt;h2&gt;2nd version, SOAP like web services&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;SQL Server Express backend&lt;/li&gt;
&lt;li&gt;SOAP like web services middle tier in C# (coded by hand), still using the WCF Data Services infrastructure&lt;/li&gt;
&lt;li&gt;Little Javascript in the browser exclusively for presentation, calling back to the REST web services through Ajax&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is how one of the web services would look like:
 &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;        [WebGet]
        public IEnumerable&amp;lt;VersionSessions&amp;gt; GetVersionsForMonth(string application, 
                                                                bool isQS, bool isAD)
        {
            var sessions = GetSessionsForMonth(application, isQS, isAD);
            var hash = new Dictionary&amp;lt;string, VersionSessions&amp;gt;();

            foreach (var s in sessions)
            {
                VersionSessions vs;
                var found = hash.TryGetValue(s.Version, out vs);

                if (!found)
                    hash[s.Version] = new VersionSessions { Version = s.Version, 
                                                                      Sessions = 0 };
                else
                    vs.Sessions += 1;
            }
            return hash.Values;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Maintainable business logic code (C# instead of JS)&lt;/li&gt;
&lt;li&gt;Somehow faster&lt;/li&gt;
&lt;li&gt;Easier to customize the back-end (just add another web service with the signature you want)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Still plenty of manipulation code (at least now on the back-end), not very RESTy&lt;/li&gt;
&lt;li&gt;Feels that the webservice are very ad-hoc for this particular presentation (i.e. a ViewModel, not a model)&lt;/li&gt;
&lt;li&gt;Still not trivial to customize the back-end logic, mostly because I was using WCF Data Services, which are opaque&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;3rd version, using SQL Views and F# type providers&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Moved the whole app to a dedicated VM&lt;/li&gt;
&lt;li&gt;SQL Server backend with a significant layer of Views and inline table-value functions&lt;/li&gt;
&lt;li&gt;Proper REST web services created through ASP.NET Web API and F# type providers&lt;/li&gt;
&lt;li&gt;Little Javascript in the browser exclusively for presentation, calling back to the REST web services through Ajax&lt;/li&gt;
&lt;li&gt;Moved all external ‘reference file’ (i.e. people in QS) to the DB. Before I was keeping business info in the database and config info in files.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is an example of an inline table value function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;ALTER FUNCTION [dbo].[FUsers] (@App nvarchar(40))
RETURNS TABLE
AS
RETURN
(
SELECT     UserAlias, MAX(Application) AS Application, MAX(Start) AS LastSessionStart, MAX(Finish) AS LastSessionFinish, DATEDIFF(MINUTE, MAX(Start), MAX(Finish)) AS LastSessionTotalTime, COUNT(*) AS Sessions, MAX(Machine) AS Machine, MAX(Version) AS Version, MAX(Qs) AS Qs
FROM         dbo.VTotalSessions AS s
WHERE     (TotalTime &amp;gt; 30) and (Application = @App)
GROUP BY UserAlias)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is an example of a type provider based web service. Most of my code works like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type usersController() =
    inherit ApiController()
 
    let db = dbSchema.GetDataContext()

    member x.Get() =
        query {
            for u in db.VUsers do
            select u
        }

    member x.Get(app) =
        query {
            for u in db.FUsers(app) do
            select u
        }

    member x.Post (value:string) = ()
    member x.Put (id:int) (value:string) = ()
    member x.Delete (id:int) = ()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is how a query is represented in JS (the whole query gets passed through to SQL, both the JS part and the F# part, IQueryable magick):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function loadOpenSessions(app, qs,  cont) {

    var query = new oQuery()
        .From(&amp;quot;/users/&amp;quot; + app)
        .Let(&amp;quot;lastMonth&amp;quot;, lastMonth)
        .Let(&amp;quot;twoMinutesAgo&amp;quot;, twoMinutesAgo)
        .Where(&amp;quot;item =&amp;gt; item.LastSessionFinish &amp;gt; $twoMinutesAgo&amp;quot;)
        .Orderby(&amp;quot;UserAlias&amp;quot;)
    commonCall(query, qs, cont)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Purely functional business logic code (SQL), very easy to debug problems by just running the query/view&lt;/li&gt;
&lt;li&gt;Maximum usage of SQL Server optimizer. As they say in the SQL Engine Team: “we’ve spent decades optimizing sql query engines. You are unlikely to do better with your ‘for’ loops …”&lt;/li&gt;
&lt;li&gt;Very easy to customize the back-end, just write F# code to implement GET/POST/PUT/DELETE etc…&lt;/li&gt;
&lt;li&gt;Moving all the state for the app (reference files included) in the DB, makes it much easier to integrate it into the business logic. It all becomes a big query for the optimizer to sort out.&lt;/li&gt;
&lt;li&gt;No autogenerated code anywhere in the architecture&lt;/li&gt;
&lt;li&gt;More separation between model and viewmodel. Tables are model, Views are ViewModel, F# is just a way to expose such view model to the world at large&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Routing algorithm for ASP.NET Web API is mysterious. It’s the only black box piece in the architecture (aka that I don’t understand it). &lt;/li&gt;
&lt;li&gt;Sometimes either SQL is not powerful enough (I abhor Stored procedures on religious grounds) or something doesn’t map well to a REST metaphor. In such cases I have diluted the metaphor as in the code below. The good thing is that, being just code, I can do that. I’m not blocked.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type statsController() =

    inherit ApiController()

    let db = dbSchema.GetDataContext()

    member x.Get(app:string, isQs:string, call:string) =
        match call with
        | &amp;quot;WeeklyUsers&amp;quot; -&amp;gt;
            let sessions = query {
                for s in db.VTotalSessionsAndWeeks do
                where (s.Application = app &amp;amp;&amp;amp; s.Qs = Nullable (Int32.Parse(isQs)))
                select s
            }
            weeklyUsers sessions
        | &amp;quot;WeeklyTime&amp;quot;  -&amp;gt;
            let sessions = query {
                for s in db.FTotalTime(app, Nullable (Int32.Parse(isQs))) do
                select s
            }
            weeklyTime sessions
        | &amp;quot;HourlyUsers&amp;quot;-&amp;gt;
            let users = query {
                for u in db.FHourlyUsers(app, Nullable (Int32.Parse(isQs))) do
                select u }
            hourlyUsers users

        | _ -&amp;gt; failwith &amp;quot;No call with that name&amp;quot;
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Tue, 04 Sep 2012 10:16:17 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-09-04-retrieving-sql-server-data-with-type-providers-and-exposing-it-with-asp-net-web-apis-in-f.html</guid>
        </item>
        
        <item>
            <title>And now Andy has a blog …</title>
            <link>https://www.lucabol.com/posts/2012-06-18-and-now-andy-has-a-blog.html</link>
            <description>&lt;p&gt;For those of you interested in C++, Andy Sawyer now has a blog &lt;a href="http://blog.pureabstract.org/"&gt;here&lt;/a&gt;. &lt;a href="http://blog.pureabstract.org/2012/06/09/choosing-an-stl-sequence-container/"&gt;Here&lt;/a&gt; is an extended discussion on how to choose an STL container. Enjoy !!&lt;/p&gt;</description>
            <pubDate>Mon, 18 Jun 2012 07:26:49 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-06-18-and-now-andy-has-a-blog.html</guid>
        </item>
        
        <item>
            <title>Writing functional code in C++ V – Miscellaneous and conclusions</title>
            <link>https://www.lucabol.com/posts/2012-06-01-writing-functional-code-in-c-v-miscellaneous-and-conclusions.html</link>
            <description>&lt;p&gt;Just a couple of trivialities and my parting thoughts.&lt;/p&gt;
&lt;h2&gt;Nested functions&lt;/h2&gt;
&lt;p&gt;If your language has lambdas, you don&amp;rsquo;t need nested functions support because you can implement them using it.&lt;/p&gt;
&lt;p&gt;I am a heavy user of nested functions, but I&amp;rsquo;m of two minds about it. On one side, I like that they sit close to where they are used, avoiding going outside the main function body to understand them. I also like that you don&amp;rsquo;t need to pass a lot of parameters to them, as they capture the function locals. On the other side, they end up creating the impression that your functions are very long and so, in my eyes, they occasionally reduce readability. The IDE helps you out there (at least VS 11) by allowing you to collapse the lambdas.&lt;/p&gt;
&lt;p&gt;An example of trivial case is below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;BOOST_AUTO_TEST_CASE(NestedFunctions)
{
    int x = 3;
    auto sumX = [&amp;amp;] (int y) { return x + y;};
    BOOST_CHECK_EQUAL(sumX(2), 3+2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is a more realistic one (not written in a functional style), where readability is reduced by the three nested functions (among many other things):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;bool condor(
            boost::gregorian::date now,  // date to evaluate
            double spot,                 // spot price underlying
            double v,                    // ATM volatility
            double r,                    // risk free rate
            double step,                 // % of spot price to keep as distance between wings
            int minCallShortDist,        // min distance from the short call strike in steps
            int minPutShortDist,         // min distance from the short put strike in steps
            int minDays,                 // min number of days to expiry
            int maxDays,                 // max number of days to expiry
            double maxDelta,             // max acceptable delta value for shorts in steps
            double minPremium,           // min accepted premium as % of step
            Condor&amp;amp; ret                  // return value
            )
{
    // convert params to dollar signs
    auto stepPr            = round(step * spot);
    auto toUSD             = [stepPr] (double x) { return round(stepPr * x);};
    auto minCpr            = toUSD( minCallShortDist );
    auto minPpr            = toUSD( minPutShortDist );
    auto premiumPr         = toUSD( minPremium );
    // calc strike values for short legs
    auto atm               = round(spot / stepPr) * (long) stepPr;
    auto callShort         = atm + minCpr;
    auto putShort          = atm - minPpr;
    auto addDays           = [](boost::gregorian::date d, int dys) -&amp;gt; boost::gregorian::date {
        using namespace boost::gregorian;
        auto toAdd         = days(dys);
        auto dTarget       = d + toAdd;
        return  dTarget;
    };
    // calc min &amp;amp; max allowed expiry dates
    auto minDate           = addDays(now, minDays);
    auto maxDate           = addDays(now, maxDays);
    auto expiry            = calcExpiry(now, 0);
    // find first good expiry
    while(expiry &amp;lt; minDate)
        expiry          = calcExpiry(expiry, +1);
    Greeks g;
    auto scholes           = [=, &amp;amp;g] (double strike, int days, bool CorP) {
        return blackScholesEuro(spot, strike, days, CorP, v, r, g, true);
    };
    // find a condor that works at this expiry
    auto findCondor        = [=, &amp;amp;g, &amp;amp;ret] (int days) -&amp;gt; bool {
        ret.shortCallStrike                = callShort;
        ret.shortPutStrike                 = putShort;
        auto shCallPremium                 = 0.0;
        auto shPutPremium                  = 0.0;
        // find short call strike price &amp;lt; maxDelta
        while(true) {
            shCallPremium                  = scholes(ret.shortCallStrike, days, true);
            if(g.delta &amp;lt;= maxDelta)
                break;
            else
                ret.shortCallStrike        += stepPr;
        }
        // find short put strike price &amp;lt; maxDelta
        while(true) {
            shPutPremium                   = scholes(ret.shortPutStrike, days, false);
            if( (- g.delta) &amp;lt;= maxDelta)
                break;
            else
                ret.shortPutStrike         -= stepPr;
        }
        // check premium is adeguate
        ret.longCallStrike                = ret.shortCallStrike + stepPr;
        ret.longPutStrike                 = ret.shortPutStrike  - stepPr;
        auto lgCall                       = scholes(ret.longCallStrike, days, true);
        auto lgPut                        = scholes(ret.longPutStrike,  days, false);
        ret.netPremium                    = shCallPremium + shPutPremium - lgCall - lgPut;
        return ret.netPremium &amp;gt; premiumPr;
    };
    // increases the expiry until it finds a condor or the expiry is too far out
    while (expiry &amp;lt; maxDate) {
        auto days        = (expiry - now).days();
        if(findCondor(days)) {
            ret.year     = expiry.year();
            ret.month    = expiry.month();
            ret.day      = expiry.day();
            return true;
        }
        expiry           = calcExpiry(expiry, +1);
    }
    return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is quite a mouthful, isn&amp;rsquo;t it? But really the function is not that long. It is all these nested functions that makes it seems so.&lt;/p&gt;
&lt;h2&gt;Tuples&lt;/h2&gt;
&lt;p&gt;Tuples are another feature toward which I have mixed feelings. They are really useful to return multiple results from a function and for rapid prototyping of concepts. But they are easy to abuse. Creating Records is almost always a better, safer way to craft your code, albeit more verbose.&lt;/p&gt;
&lt;p&gt;The standard C++ has an excellent tuple library that makes working with them almost as easy as in mainstream functional languages. The below function shows creating them, getting their value, passing them to functions and deconstructing them:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;BOOST_AUTO_TEST_CASE(Tuples)
{
    auto t = make_tuple(&amp;quot;bob&amp;quot;, &amp;quot;john&amp;quot;, 3, 2.3);
    BOOST_CHECK_EQUAL(get&amp;lt;0&amp;gt;(t), &amp;quot;bob&amp;quot;);
    BOOST_CHECK_EQUAL(get&amp;lt;2&amp;gt;(t), 3);
    // yep, compiler error
    //auto k = get&amp;lt;10&amp;gt;(t);
    auto t2(t);
    BOOST_CHECK(t2 == t);
    // passing as argument, returning it
    auto f = [] (tuple&amp;lt;string, string, int, double&amp;gt; t) { return t;};
    auto t1 = f(t);
    BOOST_CHECK(t == t1);
    // automatic deconstruction
    string s1; string s2; int i; double d;
    std::tie(s1, s2, i, d) = f(t);
    BOOST_CHECK_EQUAL(s1, &amp;quot;bob&amp;quot;);
    // partial reconstruction
    string s11;
    std::tie(s11, ignore, ignore, ignore) = f(t);
    BOOST_CHECK_EQUAL(s11, &amp;quot;bob&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m sure there are some fundamental functional features that I haven&amp;rsquo;t touched on (i.e. currying, more powerful function composition, etc…).  Despite that, I think we have enough material here to start drawing some conclusions. To start with, where is C++ deficient compared to mainstream functional languages &lt;em&gt;&lt;u&gt;for the sake of writing functional code&lt;/u&gt;&lt;/em&gt; ?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Compiler errors&lt;/u&gt;: if you make a well natured error, you often get back from the compiler a long page of rubbish if you are using templates (and you are). You put your goggles on and start swimming through it to find the nugget of gold that is the root cause of your problem. &lt;br /&gt;
    I can hear you C++ gurus screaming: come on, come on, it&amp;rsquo;s not that bad. After a while you get used to it. You become proficient in rubbish swimming. That makes me think of the story of that guy who lived in a strange neighbourhood where, as soon as you open the door of you house, someone kicks you in the nuts. His wife suggested that they moved to a better part of town, but the man replied: &amp;ldquo;no worries, I got used to it&amp;rdquo;. &lt;/li&gt;
&lt;li&gt;&lt;u&gt;Syntax oddity:&lt;/u&gt; we did our best to make the gods of syntax happy in this series of articles, but we are still far removed from Haskell, F#, etc beauty… &lt;/li&gt;
&lt;li&gt;&lt;u&gt;Advanced features&lt;/u&gt;: if you go beyond the basics of functional languages, there is a plethora of interesting features that just make your life so much easier and bring your code to an higher level of abstraction. Things like monads (i.e. f# async workflow), type providers, Haskell&amp;rsquo;s lazy execution, Haskell&amp;rsquo;s super strong type system, Closure&amp;rsquo;s transactional memory etc… Boost is trying to bring many of these things to C++, but there is still a big gap to be filled. &lt;/li&gt;
&lt;li&gt;&lt;u&gt;Temptation to cheat&lt;/u&gt;: you can cheat in many functional programming languages (i.e. having mutable variables), but nowhere the temptation is as strong as in C++. You need an iron discipline not to do it. The fact that sometimes cheating is the right thing to do makes it even worse. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, am I going to use C++ now as my main programming language? Not really. I don&amp;rsquo;t have one of those. My general view is to always use the best language for the job at hand (yes, I even use Javascript for web pages).&lt;/p&gt;
&lt;p&gt;C++ has some unique characteristics (i.e. speed, cross compilation &amp;amp; simple C interfacing). I&amp;rsquo;m going to use it whenever I need these characteristics, but now I&amp;rsquo;ll be a happier user knowing that I can write decent functional code in it.&lt;/p&gt;</description>
            <pubDate>Fri, 01 Jun 2012 06:45:26 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-06-01-writing-functional-code-in-c-v-miscellaneous-and-conclusions.html</guid>
        </item>
        
        <item>
            <title>Writing functional code in C++ IV – Algebraic datatypes</title>
            <link>https://www.lucabol.com/posts/2012-04-27-writing-functional-code-in-c-iv-algebraic-datatypes.html</link>
            <description>&lt;p&gt;And here comes the guilt bit. I have the strong suspicion (but not certainty) that what I am doing here can be done with templates, but didn&amp;rsquo;t take the time to do it. With that out of the way, let&amp;rsquo;s go.&lt;/p&gt;
&lt;p&gt;Code for this post is &lt;a href="https://github.com/lucabol/FunctionalCpp/blob/master/discriminated_union.cpp"&gt;here&lt;/a&gt;. Thanks to Steve Bower and Andy Sawyer for reviewing it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.google.co.uk/url?sa=t&amp;amp;rct=j&amp;amp;q=algebraic%20datatypes&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CDIQFjAA&amp;amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FAlgebraic_data_type&amp;amp;ei=UmZ9T8fGOoK2hQeRk6i-DA&amp;amp;usg=AFQjCNGG2oS5s9Ir1NvaX-RRcarkvVAoig"&gt;Algebraic datatypes&lt;/a&gt; (discriminated unions in F#) are a powerful concept in functional programming. They are the main way to represent type variation in your program. Very roughly, where object orientation uses derivation, functional programming uses algebraic datatypes. An entire book could be written on the theory of this, but the goal of this post is to see how we can map them to C++ without loosing C++ness.&lt;/p&gt;
&lt;p&gt;When talking about this with C++ programmers, they always point me to boost variant. That doesn&amp;rsquo;t do it for me for several reasons.&lt;/p&gt;
&lt;p&gt;First of all, boost variants represent one of a fixed collection of types. Algebraic datatypes represent one of a fixed collection of &lt;u&gt;named&lt;/u&gt; types. That means that a simple thing like the code below cannot be represented as variant:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type LivingEntity =
| Person of string  // name
| Dog of string     // name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, ok maybe you could represent it by &amp;lsquo;typifing&amp;rsquo; things using &lt;a href="http://www.boost.org/doc/libs/1_37_0/boost/strong_typedef.hpp"&gt;boost strong typedef&lt;/a&gt;, but things get ugly syntactically. Moreover, a lot of time the name is all you care about …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Switch = On | Off
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Are we going to strong typedef for such a simple thing? Oh boy. Even accepting the syntactic weight of all this, there are other issues in play. Discriminated unions are used extensively in functional programs. So you want a nice syntax to work with them Something like the below F# syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let print living =
    match living with
    | Person(name) -&amp;gt; printfn &amp;quot;I'm a per named %s&amp;quot; name
    | Dog(name)    -&amp;gt; printfn &amp;quot;I'm a dog named %s&amp;quot; name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which could be made even sweeter by using the &amp;lsquo;function&amp;rsquo; keyword as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let print = function
    | Person(name) -&amp;gt; printfn &amp;quot;I'm a per named %s&amp;quot; name
    | Dog(name)    -&amp;gt; printfn &amp;quot;I'm a dog named %s&amp;quot; name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In boost variant, you either use the get&lt;type&gt; functions or you write a visitor function. In the first case you are probably going to write a chain of &amp;lsquo;if&amp;rsquo; statements or a &amp;lsquo;switch&amp;rsquo; statement. Both are confusing and come with plenty of syntactic weight. I don&amp;rsquo;t really want to write a visitor like the one below for each &amp;lsquo;match&amp;rsquo; in my code. The magic is gone.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;class times_two_visitor
    : public boost::static_visitor&amp;lt;&amp;gt;
{
public:
    void operator()(int &amp;amp; i) const
    {
        i *= 2;
    }
    void operator()(std::string &amp;amp; str) const
    {
        str += str;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, so boost variant doesn&amp;rsquo;t really work for this. Remember that our overarching goal was to stay close to C++. The language itself has something that comes pretty close to what we want in the form of a union, or better a &lt;a href="http://en.wikipedia.org/wiki/Tagged_union"&gt;tagged union&lt;/a&gt;. Again, the types are not named, but maybe we can work that in.&lt;/p&gt;
&lt;p&gt;It turns out that Jared &lt;a href="http://blogs.msdn.com/b/jaredpar/archive/2010/11/18/discriminated-unions-in-c.aspx"&gt;here&lt;/a&gt; did all the hard work. The general idea is to use macros to hide the construction of a tagged union with methods to test the type and return the contained value. &lt;/p&gt;
&lt;p&gt;For example this code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;DU_DECLARE(LivingEntity)
    DU_VALUE(Person,    string)
    DU_VALUE(Dog,       string)
DU_END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Becomes something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct LivingEntity {
    private:
        LivingEntity() {}
        unsigned int m_kind;
    public:
        static LivingEntity Person(const string&amp;amp; value) {
            LivingEntity unionValue;
            unionValue.m_kind = 19;
            unionValue.m_Person = value;
            return unionValue; }
        bool IsPerson() const {
            return m_kind == 19;
        }
        const string&amp;amp; GetPerson() const {
            (void)( (!!(m_kind == 19)) || (_wassert(L&amp;quot;m_kind == __LINE__&amp;quot;, L&amp;quot;c:discriminated_union.cpp&amp;quot;, 19), 0) );
            return m_Person; }
        string GetPerson() {
            (void)( (!!(m_kind == 19)) || (_wassert(L&amp;quot;m_kind == __LINE__&amp;quot;, L&amp;quot;c:discriminated_union.cpp&amp;quot;, 19), 0) );
            return m_Person; }
   private:
        string m_Person;

   …
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see the outline of a tagged union (i.e. m_kind) with a constructor for each type (i.e. Person) and methods to test for at type and return its value. You can also see the storage for the value (i.e. m_Person).&lt;/p&gt;
&lt;p&gt;The only thing in DU_DECLARE that is different from Jared&amp;rsquo;s solution is the typedef below that allows not repeating the LivingEntity name in each DU_VALUE.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define DU_DECLARE(name)                        \
    struct name {                               \
    private:                                    \
        typedef name unionName;                 \
        name() {}                               \
        unsigned int m_kind;                    \
    public:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define DU_VALUE(entryName, entryType)                                                                      \
        static unionName entryName(const entryType&amp;amp; value) {                                                \
            unionName unionValue;                                                                           \
            unionValue.m_kind = __LINE__;                                                                   \
            unionValue.m_##entryName = value;                                                               \
            return unionValue;  }                                                                           \
        bool Is##entryName() const { return m_kind == __LINE__;}                                            \
        const entryType&amp;amp; Get##entryName() const { assert(m_kind == __LINE__); return m_##entryName; }       \
        entryType Get##entryName() { assert(m_kind == __LINE__); return m_##entryName; }                    \
    private:                                                                                                \
        entryType m_##entryName;                                                                            \
    public:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With all of that at your disposal it becomes easy to write:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;auto entity = LivingEntity::Dog(&amp;quot;Bob&amp;quot;);
DU_MATCH(entity)
    DU_CASE(Dog,   BOOST_CHECK_EQUAL(value, &amp;quot;Bob&amp;quot;);)
    DU_CASE(Person,BOOST_CHECK(false);)
DU_MATCH_END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are some beautiful things about this. First of all, the construction of any of such types is super simple. You even get intellisense!&lt;/p&gt;
&lt;p&gt;Moreover the &amp;lsquo;value&amp;rsquo; variable contains whatever was passed in the constructor for the object. So this is semantically equivalent, if not syntactically, to the match statement in F#.&lt;/p&gt;
&lt;p&gt;Obviously the code part is not limited to a single instruction:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;DU_MATCH(entity)
    DU_CASE(Dog,
        cout &amp;lt;&amp;lt; &amp;quot;I should be here&amp;quot;;
        BOOST_CHECK_EQUAL(value, &amp;quot;Bob&amp;quot;);
    )
    DU_CASE(Person,
        BOOST_CHECK(false);
    )
DU_MATCH_END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for those of you addicted to braces, I venture:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;DU_MATCH(entity)
    DU_CASE(Dog,
    {
        cout &amp;lt;&amp;lt; &amp;quot;I should be here&amp;quot;;
        BOOST_CHECK_EQUAL(value, &amp;quot;Bob&amp;quot;);
    })
    DU_CASE(Person,
    {
        BOOST_CHECK(false);
    })
DU_MATCH_END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They all work with the same macro definition. They expand to something along the line of:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;if(false) {}
    else if(entity.IsDog()) {
        auto value = entity.GetDog();
        BOOST_CHECK_EQUAL(value, &amp;quot;Bob&amp;quot;);
    }
    else if(entity.IsPerson()) {
        auto value = entity.GetPerson();
        BOOST_CHECK(false);
    }
    else {
        throw match_exception();
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;ve not reached the pinnacle of macro naming mastering with this one. Making them lowercase and risking a bit more on the conflict side would make the syntax much more palatable. I call it, as it is, not too bad.&lt;/p&gt;
&lt;p&gt;The last &amp;lsquo;else&amp;rsquo; clause assures you then if you add a new type to the discriminated union and forget to update one of the &amp;lsquo;MATCH&amp;rsquo; clauses at least you get a run time error. That is not good. Functional languages would give you a compile time error, which is much better. Maybe with judicious use of templates you can bring the error at compile time.&lt;/p&gt;
&lt;p&gt;The macros are trivial:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;class match_exception: std::exception {};
#define DU_MATCH(unionName) { auto du_match_var = unionName; if(false) {}
#define DU_CASE_TAG(entry, ...)                        \
    else if(du_match_var.Is##entry()) {                \
        __VA_ARGS__                                    \
    }
#define DU_CASE(entry, ...)                            \
    else if(du_match_var.Is##entry()) {                \
        auto value = du_match_var.Get##entry();        \
        __VA_ARGS__                                    \
    }
#define DU_DEFAULT(...)                                \
    else if(true) { __VA_ARGS__}
#define DU_MATCH_END else {throw new match_exception();} }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s now go back to our initial goal and see how far off we are. We were trying to do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type LivingEntity =
| Person of string
| Dog of string
let print = function
    | Person(name) -&amp;gt; printfn &amp;quot;I'm a per named %s&amp;quot; name
    | Dog(name)    -&amp;gt; printfn &amp;quot;I'm a dog named %s&amp;quot; name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is what we ended up with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;DU_DECLARE(LivingEntity)
    DU_VALUE(Person,    string)
    DU_VALUE(Dog,        string)
DU_END
auto print(LivingEntity en) -&amp;gt; void {
    DU_MATCH(entity)
        DU_CASE(Dog,    cout &amp;lt;&amp;lt; &amp;quot;I'm a dog named &amp;quot; &amp;lt;&amp;lt; value;)
        DU_CASE(Person, cout &amp;lt;&amp;lt; &amp;quot;I'm a per named &amp;quot; &amp;lt;&amp;lt; value;)
    DU_MATCH_END
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our Switch case:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Switch = On | Off
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You get the good looking:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;DU_DECLARE(Switch)
    DU_FLAG(On)
    DU_FLAG(Off)
DU_END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And along the way we lost compile time type safety in the very common case of adding new types to the discriminated union. That&amp;rsquo;s bad.&lt;/p&gt;
&lt;p&gt;Also some of you would strongly dislike the (ab)use of macros. As for me, it looks workable.&lt;/p&gt;</description>
            <pubDate>Fri, 27 Apr 2012 09:29:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-04-27-writing-functional-code-in-c-iv-algebraic-datatypes.html</guid>
        </item>
        
        <item>
            <title>Writing functional code in C++ III – Performance of different allocation schemes</title>
            <link>https://www.lucabol.com/posts/2012-04-16-writing-functional-code-in-c-iii-performance-of-different-allocation-schemes.html</link>
            <description>&lt;p&gt;In this post we are going to look at the performance characteristics of different ways to allocate objects in C++. The goal is to understand what is the best way to allocate objects in a functional style. Code for this post is &lt;a href="https://github.com/lucabol/FunctionalCpp/blob/master/allocation_perf.cpp"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First of all, let&amp;rsquo;s define what we are going to allocate:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct Record {
    int Id;
    int Value1;
    int Value2;
    int Value3;
    int Value4;
    int Value5;
    int Value6;
    int Value7;
    int Value8;
    int Value9;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a function to initialize it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;void record_init(Record&amp;amp; r, int i) {
    r.Id = i;
    r.Value1 = i;
    r.Value2 = i;
    r.Value3 = i;
    r.Value4 = i;
    r.Value5 = i;
    r.Value6 = i;
    r.Value7 = i;
    r.Value8 = i;
    r.Value9 = i;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a function to convert it to an int (so that the compiler doesn&amp;rsquo;t optimize away our code):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct to_int {
    typedef int result_type;
    int operator() (const Record&amp;amp; r) const { return r.Id;}
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s also define some constants:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;const int repetitions = 1000;
const int bigBlock = 1000;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a timer class to measure performance:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;typedef boost::chrono::process_cpu_clock the_clock;
struct timer {
    timer() : start(the_clock::now()) {}
    ~timer() {
        auto stop = the_clock::now();
        auto diff = stop - start;
        std::cout &amp;lt;&amp;lt; diff &amp;lt;&amp;lt; std::endl;
    }
    the_clock::time_point start;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&amp;rsquo;s look at different ways to allocate objects. First the normal way:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int normal() {
    vector&amp;lt;Record&amp;gt; v;
    for(int i = 0; i &amp;lt; repetitions; ++i) {
        v.clear();
        for(int j = 0; j &amp;lt; bigBlock; ++j) {
            Record r;
            record_init(r, j);
            v.push_back(r);
        }
    }
    return boost::accumulate(v, 0, [](int i, const Record&amp;amp; r) { return i + r.Id;});
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then using a pod_vector (a vector that doesn&amp;rsquo;t initialize its elements):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int podVector() {
    pod_vector&amp;lt;Record, size&amp;gt; v;
    for(int i = 0; i &amp;lt; repetitions; ++i) {
        v.clear();
        for(int j = 0; j &amp;lt; bigBlock; ++j) {
            Record r;
            record_init(r, j);
            v.push_back(r);
        }
    }
    return boost::accumulate(v, 0, [](int i, const Record&amp;amp; r) { return i + r.Id;});
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then using boost pool allocator:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int boostallocator(WhichOne which) {
    boost::pool&amp;lt;&amp;gt; p(sizeof(Record));
    vector&amp;lt;Record, boost::pool_allocator&amp;lt;Record&amp;gt;&amp;gt; v;
    for(int i = 0; i &amp;lt; repetitions; ++i) {
        v.clear();
        for(int j = 0; j &amp;lt; bigBlock; ++j) {
            Record r;
            record_init(r, j);
            v.push_back(r);
        }
    }
    return boost::accumulate(v, 0, [](int i, const Record&amp;amp; r) { return i + r.Id;});
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then using shared pointers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int pointers(WhichOne which) {
    vector&amp;lt;shared_ptr&amp;lt;Record&amp;gt;&amp;gt; v;
    for(int i = 0; i &amp;lt; repetitions; ++i) {
        v.clear();
        for(int j = 0; j &amp;lt; bigBlock; ++j) {
            auto r = make_shared&amp;lt;Record&amp;gt;();
            record_init(*r, j);
            v.push_back(r);
        }
    }
    return boost::accumulate(v, 0, [](int i, const shared_ptr&amp;lt;Record&amp;gt;&amp;amp; r) { return i + r-&amp;gt;Id;});
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then using Loki smart pointers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;typedef Loki::SmartPtr&amp;lt;Record,
                 Loki::RefCounted,
                 Loki::DisallowConversion,
                 Loki::AssertCheck,
                 Loki::DefaultSPStorage&amp;gt; RecordPtr;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int lokipointers(WhichOne) {
    vector&amp;lt;RecordPtr&amp;gt; v;
    for(int i = 0; i &amp;lt; repetitions; ++i) {
        v.clear();
        for(int j = 0; j &amp;lt; bigBlock; ++j) {
            auto r = RecordPtr(new Record());
            record_init(*r, j);
            v.push_back(r);
        }
    }
    return boost::accumulate(v, 0, [](int i, const RecordPtr&amp;amp; r) { return i + r-&amp;gt;Id;});
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The results are quite interesting. The pod_vector is the fastest, followed by the normal vector, followed by the boost pool allocator, followed by the shared pointers, followed by the Loki pointers.&lt;/p&gt;
&lt;p&gt;The pod_vector is faster than the normal vector because it doesn&amp;rsquo;t initialize its elements. The normal vector is faster than the boost pool allocator because the boost pool allocator has to maintain a pool of memory. The shared pointers are slower than the boost pool allocator because they have to maintain reference counts. The Loki pointers are slower than the shared pointers because they have to maintain reference counts and they have to check for null pointers.&lt;/p&gt;
&lt;p&gt;The conclusion is that if you want to write functional code in C++, you should use pod_vector or normal vector. If you need to share objects between different parts of your code, you should use shared pointers. If you need to share objects between different parts of your code and you need to check for null pointers, you should use Loki pointers.&lt;/p&gt;</description>
            <pubDate>Mon, 16 Apr 2012 09:11:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-04-16-writing-functional-code-in-c-iii-performance-of-different-allocation-schemes.html</guid>
        </item>
        
        <item>
            <title>Letter on investing</title>
            <link>https://www.lucabol.com/posts/2012-04-05-letter-on-investing.html</link>
            <description>&lt;p&gt;&lt;a name="_GoBack"&gt;&lt;/a&gt;In 2007 I wrote a &lt;a href="/2007/04/20/a-financial-education-my-ideas"&gt;blog post&lt;/a&gt; on investing. During the last five years, my view evolved a bit. People often ask me how to get a financial education. This is the latest email I sent on the topic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;From:&lt;/strong&gt; Bolognese, Luca&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sent:&lt;/strong&gt; 04 April 2012 16:52&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To:&lt;/strong&gt; XXX&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Subject:&lt;/strong&gt; RE: A financial education&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Disclaimer&lt;/span&gt;: this are just my personal opinions drawn from my 10+ years of investing, reading books and academic papers about it. I can justify most statements below with some academic reference, but that would make this email too long.&lt;/p&gt;
&lt;p&gt;Also someone else might read the same material and come up with a different opinion. It is a field that is probabilistic in nature and doesn’t lend itself to certainties. For example, you can make a lot of money out of an investment and still be wrong to have made it. And conversely.&lt;/p&gt;
&lt;p&gt;Our brains don’t work well in such fields.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The most important thing in investing is not investing, it is saving the money to invest. If you save enough and are mildly reasonable in your investments (aka you diversify), you are going to be ok. Saving is not mechanically difficult, it is motivationally difficult. The best book I found on the topic is &lt;a href="http://www.amazon.co.uk/Your-Money-Life-Transforming-Relationship/dp/0143115766/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333525302&amp;amp;sr=1-1"&gt;this one&lt;/a&gt;. I read earlier editions, this is a new one. I don’t like the investment chapters.&lt;/li&gt;
&lt;li&gt;After that, you need to make sure that your financial matters are in order (i.e. you are ensured against catastrophes, you maximize your tax deductions, etc..). This is the field of personal finance. I’ve been suggesting &lt;a href="http://www.amazon.co.uk/Personal-Finance-Dummies-Lifestyles-Paperback/dp/0470506938/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333525481&amp;amp;sr=1-1"&gt;this book&lt;/a&gt; to American audiences. It is on Amazon.co.uk, so it might be the UK version.&lt;/li&gt;
&lt;li&gt;Now that you have saved money and your finances are in order, you can start thinking about investing. The most important things in investing are: deciding what you believe in, what your risk tolerance is, how important is for your performance to track the market, what your time horizon is and how much time you want to dedicate to investing. &lt;ul&gt;
&lt;li&gt;My risk tolerance is high. I’ve spent a lot of time learning about investing. I’m willing to see the value of my portfolio go down without experiencing emotional distress (I’ve tried it)&lt;/li&gt;
&lt;li&gt;I don’t care about my investment performance tracking the market. I don’t watch financial programs.&lt;/li&gt;
&lt;li&gt;My time horizon is long. These are money I invest for my retirement.&lt;/li&gt;
&lt;li&gt;I’m willing to invest time to keep myself up to date on investment topics and manage my portfolio&lt;/li&gt;
&lt;li&gt;I believe the following (these are the biases that colour my view):&lt;/li&gt;
&lt;li&gt;Diversification among different sources of returns is to be sought aggressively&lt;/li&gt;
&lt;li&gt;Most asset classes are not efficient because of: &lt;ul&gt;
&lt;li&gt;Predictable flaws in human brain’s processing machinery&lt;/li&gt;
&lt;li&gt;Institutional constraints on most professional investor (aka they have to track the market they invest in closely)&lt;/li&gt;
&lt;li&gt;Short term performance incentive for professional investors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Some asset classes are intrinsically more inefficient than others (i.e. emerging markets micro stocks compared to US large stock) because that’s where the causes of inefficiencies are strongest&lt;/li&gt;
&lt;li&gt;The biggest inefficiencies are among asset classes (i.e. stocks vs bonds vs commodities)&lt;/li&gt;
&lt;li&gt;Most people (myself included) don’t have the time to do the research necessary to invest in individual stocks using the two ways that I believe are ‘right’: quant models or/and fundamental value analysis.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Some books to get you started: &lt;ul&gt;
&lt;li&gt;A good perspective on how to think about the market and the work you need to do if you want to invest in stocks&lt;a href="http://www.amazon.co.uk/Intelligent-Investor-Collins-Business-Essentials/dp/0060555661/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333546104&amp;amp;sr=1-1"&gt;. The intelligent investor&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Why diversification is important. The &lt;a href="http://www.amazon.co.uk/The-Intelligent-Asset-Allocator-Portfolio/dp/0071362363/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333546343&amp;amp;sr=1-1"&gt;intelligent asset allocator&lt;/a&gt;. I don’t believe in static asset allocation, but you need to know what it is to believe (or not) in it.&lt;/li&gt;
&lt;li&gt;Moving beyond a static asset allocation with a quant based highly diversified, but simple to implement system. &lt;a href="http://www.amazon.co.uk/The-Ivy-Portfolio-Endowments-Markets/dp/1118008855/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333546515&amp;amp;sr=1-1"&gt;The Ivy Portfolio.&lt;/a&gt; I am very tempted to use this one myself&lt;/li&gt;
&lt;li&gt;Why asset classes are often mispriced. Probably the premier quant shop around. Read most &lt;a href="https://www.gmo.com/America/MyHome/"&gt;quarterly letters&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Systems to take advantage of such mispricing are described &lt;a href="http://www.amazon.co.uk/The-Hedge-Fund-Edge-Strategies/dp/0471185388/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333547311&amp;amp;sr=1-1"&gt;here&lt;/a&gt;. I have obtained copies of all the newsletters sent by the author going back to 1991 and backtested some of the systems. These are the system I use. But the newsletter is relatively expensive and complex to follow.&lt;/li&gt;
&lt;li&gt;If you decide to branch out into value analysis of companies. &lt;a href="http://www.amazon.co.uk/The-Essays-Warren-Buffett-Investors/dp/0470820780/ref=sr_1_6?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333546836&amp;amp;sr=1-6"&gt;Essays of warren buffett&lt;/a&gt;. You would also need to read an introductory and an advanced accounting text. I don’t know UK accounting, so cannot suggest good candidates.&lt;/li&gt;
&lt;li&gt;If you are very conservative and want to just invest in Inflation Linked Bonds (or fearful of markets in general), there is a book for that: &lt;a href="http://www.amazon.co.uk/Worry-free-Investing-Approach-Achieving-Financial/dp/0130499277/ref=sr_1_10?s=books&amp;amp;ie=UTF8&amp;amp;qid=1333546962&amp;amp;sr=1-10"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;With all of that out of the way, here is some practical counsel &lt;ul&gt;
&lt;li&gt;if you have less than 20,000 pounds to invest try to find a fund or etf that invest in a diversified array of asset classes for a small price. I don’t know the UK market, so cannot suggest one.&lt;/li&gt;
&lt;li&gt;If you have more than that and are willing to dedicate a few hours a month, you can start implementing some of the systems in the Ivy Portfolio book. Maybe you integrate it with the GMO 7 years asset class forecasts to push a bit of value bias in your system.&lt;/li&gt;
&lt;li&gt;For most people that’s it. If it becomes a lifelong interest / mania as it is for me, there is a bit more that can be done, but it is unclear to me that the results are necessarily better than the simple systems described above.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cheers,&lt;/p&gt;
&lt;p&gt;.luca&lt;/p&gt;</description>
            <pubDate>Thu, 05 Apr 2012 07:57:59 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-04-05-letter-on-investing.html</guid>
        </item>
        
        <item>
            <title>Writing functional code in C++ II – Function composition</title>
            <link>https://www.lucabol.com/posts/2012-03-30-writing-functional-code-in-c-ii-function-composition.html</link>
            <description>&lt;p&gt;Function composition is at the core of functional programming. You start by being very confident that certain very small functions are correct, you compose them in well known ways and you end up being very confident that your final program is correct.&lt;/p&gt;
&lt;p&gt;You are very confident that the initial functions are correct because they are very small and side effect free. You are very confident that your program is correct because the means of composition are well known and generate functions that are themselves side effect free.&lt;/p&gt;
&lt;p&gt;Such &amp;lsquo;almost primitive&amp;rsquo; functions operate on data structures. Each functional language has its own set of data structures and &amp;lsquo;almost primitive&amp;rsquo; functions. Probably the most famous ones are contained in the &lt;a href="http://www.haskell.org/onlinereport/standard-prelude.html"&gt;haskell prelude&lt;/a&gt;, but F# has similar ones. LINQ in C# is just such a set.&lt;/p&gt;
&lt;p&gt;In this article I use the term functional composition in a broad sense as &amp;lsquo;putting functions together&amp;rsquo;, not in the more technical sense of f(g(x)): dot operator in Haskell or &amp;lsquo;&amp;gt;&amp;gt;&amp;rsquo; operator in F#.&lt;/p&gt;
&lt;p&gt;Code for this post is &lt;a href="https://github.com/lucabol/FunctionalCpp"&gt;here&lt;/a&gt;. Thanks to Steve Bower and Andy Sawyer for review and comments.&lt;/p&gt;
&lt;p&gt;Here is an example. The F# code below filters in the odd numbers from an array and doubles them. You have two logical operations, filtering and doubling.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let v = [|1;2;3;4;5;6;7;8;9;0|]
let transformed =
    v
    |&amp;gt; Seq.filter(fun i -&amp;gt; i % 2 = 0)
    |&amp;gt; Seq.map ((*) 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How would the code look in C++? There are many ways. One is the &amp;lsquo;big fat for loop&amp;rsquo;, or in C++ 11, for each:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;const int tmp[] = {1,2,3,4,5,6,7,8,9,0};
const vector&amp;lt;int&amp;gt; v(&amp;amp;tmp[0], &amp;amp;tmp[10]);
vector&amp;lt;int&amp;gt; filtered;
for(auto i: v)
{
    if(i % 2 == 0)
        filtered.push_back(i * 2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks simple enough, apart from the initialization syntax that gets better with C++ 11. But it&amp;rsquo;s simplicity is misleading. We have now lost the information that our computation is composed by a filter and a map. It&amp;rsquo;s all intermingled. Obviously, the info is still there in some sense, but you need to read each line in your head and figure out the structure on your own. It is not readily apparent to the reader.&lt;/p&gt;
&lt;p&gt;Obviously, things get much worse in a large program composed of several loops where each one does not trivial stuff. As for me, every time I indulge into the &amp;lsquo;big fat for loop pattern&amp;rsquo;, I end up regretting it either immediately or after some time when I have to make changes to the code. So I try to avoid it.&lt;/p&gt;
&lt;p&gt;Wait a minute, you might say, what about STL algorithms? Aren&amp;rsquo;t you supposed to use those?&lt;/p&gt;
&lt;p&gt;The syntax to call them is not very compositional. You cannot take the result of an algorithm and pass it to another easily. It is difficult to chain them that way. Everything takes two iterators, even if 99% of the times you are just using begin and end. Moreover, you have to create all sort of temporary data structures for the sake of not modifying your original one. Once you have done all of that, the syntactic weight of your code overwhelm the simplicity of what you are trying to do.&lt;/p&gt;
&lt;p&gt;For example, here is the same code using &amp;lsquo;transform&amp;rsquo; for the &amp;lsquo;map&amp;rsquo; part of the algorithm:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;vector&amp;lt;int&amp;gt; filtered;
copy_if(begin(v), end(v), back_inserter(filtered), [](int x) { return x % 2 == 0;});
vector&amp;lt;int&amp;gt; transformed;
transform(begin(filtered), end(filtered), back_inserter(transformed), [](int x) { return x * 2;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;m not arguing that STL is a bad library, I think it is a great one. It&amp;rsquo;s just that its syntax is not very compositional. And that breaks the magic.&lt;/p&gt;
&lt;p&gt;Luckily, help is on the way in the form of the &lt;a href="http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/index.html"&gt;Range&lt;/a&gt; library and &lt;a href="https://github.com/faithandbrave/OvenToBoost"&gt;OvenToBoost&lt;/a&gt;. These libraries &amp;lsquo;pack&amp;rsquo; the two iterators in a single structure and override the &amp;lsquo;|&amp;rsquo; operator to come up with something as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;auto result =
    v
    | filtered(   [] (int i) { return i % 2 == 0;})
    | transformed([] (int i) { return i * 2;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you use Boost lambdas (not sure I&amp;rsquo;d do that), the syntax gets even better:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;auto result =
    v
    | filtered(_1 % 2 == 0)
    | transformed(_1 * 2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, so we regained compositionality and clarity, but what price are we paying? Apart from the dependency from Boost::Range and OvenToBoost, you might think that this code would be slower than a normal for loop. And you would be right. But maybe not by as much as you would think.&lt;/p&gt;
&lt;p&gt;The code for my test is &lt;a href="https://github.com/lucabol/FunctionalCpp/blob/master/range_performance.cpp"&gt;here&lt;/a&gt;. I&amp;rsquo;m testing the perf difference between the following code engineered to put in a bad light the most pleasing syntax. A for loop:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int sum = 0;
for(vector&amp;lt;int&amp;gt;::const_iterator it = v.begin(); it != v.end(); ++it)
    if(*it &amp;lt; 50)
        sum += *it * 2;
return sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A Range based code using language lambdas (transformedF is a variation of &lt;a href="http://smellegantcode.wordpress.com/2011/10/31/linq-to-c-or-something-much-better/"&gt;this&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;auto lessThan50 = v | filtered(    [](int i) { return i &amp;lt; 50;})
                    | transformedF([] (int i) { return i * 2;});
return boost::accumulate (lessThan50, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A Range based code using two functors:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;auto lessThan50 = v | filtered(Filterer())
                    | transformed(Doubler());
return boost::accumulate (lessThan50, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct Doubler {
    typedef int result_type;
    int operator() (int i) const { return i * 2;}
};
struct Filterer {
    typedef int result_type;
    bool operator() (int i) const { return i &amp;lt; 50;}
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;a Range based code using Boost lambdas:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;auto lessThan50 = v | filtered(_1 &amp;lt; 50)
                    | transformed(_1 * 2);
return boost::accumulate (lessThan50, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally, some code using the STL for_each function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int sum = 0;
std::for_each( v.cbegin(), v.cend(),
    [&amp;amp;](int i){
        if( i &amp;lt; 50 ) sum += i*2;
    });
return sum;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that I need to run the test an humongous number of times (10000000) on a 100 integers array to start seeing some consistency in results.&lt;br /&gt;
And the differences that I see (in nanosecs below) are not huge:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-text"&gt;1&amp;gt;                         Language lambda: {1775645516;1778411400;0}
1&amp;gt;                          Functor lambda: {1433377701;1435209200;0}
1&amp;gt;                            Boost lambda: {1327829199;1326008500;0}
1&amp;gt;                                For loop: {1338268336;1341608600;0}
1&amp;gt;                             STL foreach: {1338268336;1341608600;0}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;True to be told, by changing the code a bit these numbers vary and, in some configurations, the Range code takes twice as long.&lt;/p&gt;
&lt;p&gt;But given how many repetitions of the test I need to run to notice the difference, I&amp;rsquo;d say that in most scenarios you should be ok.&lt;/p&gt;
&lt;p&gt;The &amp;lsquo;|&amp;gt;&amp;rsquo; operator over collections is the kind of functional composition, broadly defined, that I use the most, but you certainly can use it over other things as well. You&amp;rsquo;d like to write something like the below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;BOOST_CHECK_EQUAL(pipe(&amp;quot;bobby&amp;quot;, strlen, boost::lexical_cast&amp;lt;string, int&amp;gt;), &amp;quot;5&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you can, once you define the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;template&amp;lt; class A, class F1, class F2 &amp;gt;
inline auto pipe(const A &amp;amp; a, const F1 &amp;amp; f1, const F2 &amp;amp; f2)
    -&amp;gt; decltype(REMOVE_REF_BUG(f2(f1(a)))) {
    return f2(f1(a));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where REMOVE_REF_BUG is a workaround for a bug in the decltype implementation under msvc (it should be fixed in VS 11):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#ifdef _MSC_VER
    #define REMOVE_REF_BUG(...) remove_reference&amp;lt;decltype(__VA_ARGS__)&amp;gt;::type()
#else
    #define REMOVE_REF_BUG(...) __VA_ARGS__
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I didn&amp;rsquo;t do the work of creating &amp;lsquo;&amp;gt;&amp;gt;&amp;rsquo; , &amp;lsquo;&amp;lt;&amp;lt;&amp;rsquo; and &amp;lsquo;&amp;lt;|&amp;rsquo; F# operators or wrapping the whole lot with better syntax (i.e. operator overloading?), but it certainly can be done.&lt;/p&gt;
&lt;p&gt;Now that we have a good syntax for records and a good syntax for operating over collections, the next instalment will put them together and try to answer the question: how should I create collections of records and operate over them?&lt;/p&gt;</description>
            <pubDate>Fri, 30 Mar 2012 10:11:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-03-30-writing-functional-code-in-c-ii-function-composition.html</guid>
        </item>
        
        <item>
            <title>Writing functional code in C++ – Records</title>
            <link>https://www.lucabol.com/posts/2012-03-23-writing-functional-code-in-c-records.html</link>
            <description>&lt;p&gt;This is the first of a series of posts about writing functional code in C++.  My goal is different from &lt;a href="http://www.cc.gatech.edu/~yannis/fc++/"&gt;FC++&lt;/a&gt;, which is a full fledged &amp;lsquo;environment&amp;rsquo; to write functional code. Instead, I want to experiment with some of the new C++ 11 language features and see if one can build reasonably looking functional code and stay pretty close to the language. The idea is to judiciously use macros and external libraries to build a thin layer on top of the language that doesn&amp;rsquo;t change the performance characteristics of it (aka it doesn&amp;rsquo;t slow it down) and integrates fine with existing C++ code.&lt;/p&gt;
&lt;p&gt;Think of it as an attempt to answer the question: is there a way to write C++ code in a functional style without loosing its &amp;lsquo;C++sness&amp;rsquo;? We won&amp;rsquo;t attempt to be as type safe or syntactically pleasing as Haskell or F# , but we&amp;rsquo;ll attempt to stay as fast and flexible as C++ and make it functional enough to be interesting.&lt;/p&gt;
&lt;p&gt;Thanks to Steve Bower and Ganesh Sittampalam for reviewing and to Andy Sawyer for giving me so much feedback that this post can be considered a co-authorship. Code for this post is &lt;a href="https://github.com/lucabol/BlogCppFunctional"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s first talk about the data types that you typically find in a functional language. Let&amp;rsquo;s start with Records. They are not part of the functional model per se. You can do without them and just use algebraic data types and tuples. But they are damn convenient, and  most functional languages (i.e. Haskell, Clojure, etc…) have them now. We start from them because they map naturally to C++. Records are just like structs, but immutable and having structural equality.&lt;/p&gt;
&lt;p&gt;In F# your vanilla record looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Person = {
    Name: string
    Id: int
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice and simple. With C++, you become more verbose. A first attempt would be:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct Person {
    const string Name;
    const int Salary;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which looks nice and easy, but doesn&amp;rsquo;t quite work because more often than not you need to be able to compare two records for structural equality (which means the value of their fields, not the pointer in memory, defines equality). Records in functional languages automatically support that. But the syntax gets on the ugly side:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct Person {
    const string Name;
    const int Salary;
    bool operator==(const Person&amp;amp; other) const { return Salary == other.Salary &amp;amp;&amp;amp; Name == other.Name;}
    bool operator!=(const Person&amp;amp; other) const { return !(*this == other);}
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ll see how to simplify the syntax later. The syntax on the creation side is not too bad:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;Person p = {&amp;quot;Bobby&amp;quot;, 2};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s call the above representation, the obvious one. Let&amp;rsquo;s consider two variations on this scheme. The first one is useful if you want to make your records interoperable with C or with other C++ compilers. &lt;/p&gt;
&lt;p&gt;A full discussion of how to achieve these goals would be very long. It will go about discussing what &lt;a href="http://stackoverflow.com/questions/146452/what-are-pod-types-in-c"&gt;POD&lt;/a&gt; types are and how their definition &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm"&gt;got more precise&lt;/a&gt; in C++ 11.&lt;/p&gt;
&lt;p&gt;You can look at my experimentations on pod, standard layout and trivially constructible types &lt;a href="https://github.com/lucabol/FunctionalCpp/blob/master/records.cpp"&gt;here&lt;/a&gt;. My summary is pretty simple, if you want to achieve all the goals above, you got to use C structs that contain C-compatible types. No const, strings or STL libraries allowed.&lt;/p&gt;
&lt;p&gt;The above class would then become:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct Person {
    char Name[20];
    int Salary;
    bool operator==(const Person&amp;amp; other) const { return Salary == other.Salary &amp;amp;&amp;amp; !strcmp(Name,other.Name);}
    bool operator!=(const Person&amp;amp; other) const { return !(*this == other);}
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously, not being able to use strings or STL collections in your record is a big limitation, but in certain cases you might be able to live with it.  Let&amp;rsquo;s call this representation, the pod one.&lt;/p&gt;
&lt;p&gt;You would think you can make the syntax better by doing something like the below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;struct _Person {
    int id;
    char name[20];
    pod_equality(_Person);
};    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where pod_equality is defined as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define pod_equality(Record)                                                                 \
       bool operator==(const Record&amp;amp; other) const {                                          \
              static_assert(std::is_trivial&amp;lt;Record&amp;gt;::value, &amp;quot;Not trivially copyable&amp;quot;);       \
              return memcmp(this, &amp;amp;other, sizeof(Record)) == 0;}                             \
       bool operator!=(const Record&amp;amp; other) const { return !(*this == other);}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But you would be wrong (as I was for a while), as comparing memory values doesn&amp;rsquo;t work in this case because of the padding that the compiler can insert between fields. Such padding can contain random value (whatever was on the stack, for example) which would make the equality return false for structurally equal objects. Also this scheme fails for floating point types (i.e. NaN and signed zeros).&lt;/p&gt;
&lt;p&gt;An alternative representation for records, which nicely separates constness from the structure of your record is below. It does have some some advantages that we&amp;rsquo;ll look at, but in its raw form it is yet more syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;namespace Mutable {
    struct Person {
        string Name;
        int Salary;
        bool operator==(const Person&amp;amp; other) const { return Salary == other.Salary &amp;amp;&amp;amp; Name == other.Name;}
        bool operator!=(const Person&amp;amp; other) const { return !(*this == other);}
    };
}
typedef const Mutable::Person Person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s call this representation, the immutable one. Let&amp;rsquo;s give these guys some usage and talk about their trade-offs. If you want to write a function that increase someone salary, you would write it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;template&amp;lt;class T&amp;gt;
T rise_salary1(const T&amp;amp; p) {
    T ret = { p.Name, p.Salary + 1000 };
    return ret;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks nice and clean, unless your record has a lot of fields. Let me tell you, in real application it probably does. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;namespace Mutable {
    struct foo {
        int value1;
        int value2;
        int value3;
        int value4;
        int value5;
        int value7;
        int value6;
        int value8;
        int value9;
    };
}
typedef const Mutable::foo foo;
foo increment_value7( const foo&amp;amp; f )
{
     foo tmp = { f.value1, f.value2, f.value3, f.value4, f.value5, f.value6, f.value7+1, f.value8 };
     return tmp;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thanks to Andy for this example. BTW: did you spot the bug at first sight? What about the other one?&lt;/p&gt;
&lt;p&gt;So this syntax is problematic. True to be told, part of the problem is in the sub-optimal initialization syntax in C++. If you could use named parameters, it would be more difficult to introduce bugs, but the syntax would still be ugly. You really need something like the F# syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let r1 = {f = 0.2; k = 3}
let r2 = {r1 with f = 0.1}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Can we do something like that? Well, if we are willing to pass the Mutable one around, we can write this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;template&amp;lt;class T&amp;gt;
T rise_salary2(const T&amp;amp; p) {
    T ret(p);
    ret.Salary += 1000;
    return ret;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or even this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;template&amp;lt;class T&amp;gt;
T rise_salary3(T p) {
    p.Salary += 1000;
    return p;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But that doesn&amp;rsquo;t make us happy, does it? The whole point of making things const is that you want them to be const.  If you pass around mutable ones, who knows what&amp;rsquo;s going to happen inside the method?&lt;/p&gt;
&lt;p&gt;There is a middle ground that might be acceptable, which is to write functions so that their interface takes immutable records, but inside the function they operate on mutable ones. This is not a bad pattern in general, as having mutable versions of your immutable records might come useful for optimizing certain algorithms. Luckily the casting rules of C++ favour the bold, so the below works:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;Person rise_salary_m(const Person&amp;amp; p) {
    Mutable::Person ret(p);
    ret.Salary += 1000;
    return ret;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And doesn&amp;rsquo;t look too bad either.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s talk syntax. Defining a record is still a lot of typing (and a lot of reading if you are maintaining the code). F# does it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Person = {
    Name: string
    Id: int
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The best I came up with looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;RECORD2(Person,
          string, Name,
          int,    Salary);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you need a lot of those macros depending on how many fields your record has. You can write this macro to expand to either the Obvious or Immutable representation trivially. It is a bit more complex for the Pod one because of the interesting C++ array declaration syntax with the number of elements after the name of the field.&lt;/p&gt;
&lt;p&gt;For the Obvious one it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define RECORD2(n, t1, f1, t2, f2)                                                            \
    struct n {                                                                                \
        const t1 f1;                                                                          \
        const t2 f2;                                                                          \
                                                                                              \
        bool operator==(const n&amp;amp; other) const { return f1 == other.f1 &amp;amp;&amp;amp; f2 == other.f2;}     \
        bool operator!=(const n&amp;amp; other) const { return !(*this == other);}                    \
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the usual concerns about macros apply. Moreover all your fields need to have a meaningful == operator.&lt;/p&gt;
&lt;p&gt;To summarize, we have found three different representations of records in C++ and tried to alleviate the syntax burden with some macro magick. We&amp;rsquo;ll go wild in macro-land when we talk about discriminated unions.&lt;/p&gt;</description>
            <pubDate>Fri, 23 Mar 2012 08:11:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-03-23-writing-functional-code-in-c-records.html</guid>
        </item>
        
        <item>
            <title>A simple scheme to implement Design by Contract in C++</title>
            <link>https://www.lucabol.com/posts/2012-03-06-a-simple-scheme-to-implement-design-by-contract-in-c.html</link>
            <description>&lt;p&gt;Recently I got interested in C++ again. The new lambda functions in C++ 11 open up a world of opportunities for C++ programmers. I&amp;rsquo;ll talk more about how you can write functional code in C++ 11 in upcoming posts. For now let&amp;rsquo;s look at design by contract.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Design_by_contract"&gt;Design by contract&lt;/a&gt; is a development style promoted by&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Bertrand_Meyer"&gt;Bertrand Meyer&lt;/a&gt; and it is implemented in his own &lt;a href="http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29"&gt;Eiffel programming language&lt;/a&gt;. At core, it advocates using preconditions, postconditions and invariants.&lt;/p&gt;
&lt;p&gt;An invariant is an assertion that always holds true for a class after the class has been fully constructed and if the code is not executing inside a method. As a user of the class, you always observe the invariant to be true. As an implementer of the class, you can be assured that the invariant is true before a method is entered and you need to make the invariant true again by the time your method exits.&lt;/p&gt;
&lt;p&gt;A preconditions is an assertion that needs to hold true at the start of a function, for the postcondition to be true at the end of it. Taken together, invariant, precondition and postcondition define the contract between the implementer and the user of a class.&lt;/p&gt;
&lt;p&gt;Code for this post is &lt;a href="https://github.com/lucabol/FunctionalCpp/blob/master/dbc.hpp"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/lucabol/FunctionalCpp/blob/master/dbc.cpp"&gt;here&lt;/a&gt;. Thanks to Andy Sawyer, Steve Bower and Ganesh Sittampalam for reviewing my code and suggesting improvements.&lt;/p&gt;
&lt;p&gt;Preconditions are simple and everyone uses them. They are those little &lt;em&gt;if&lt;/em&gt; statements that you put at the start of your functions to make sure that the caller has given you the right parameters.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;double divide(double x, double y) {
    if(y == 0) throw new exception(&amp;quot;y cannot be 0&amp;quot;);
    …
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These little &amp;lsquo;if&amp;rsquo; statements don&amp;rsquo;t really make the precondition stand out. They can be confused with other, unrelated, &amp;lsquo;if&amp;rsquo; statements that do completely different semantic things. A more readable alternative is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;double divide(double x, double y) {
    requires(y != 0);
    …
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not an impressive difference, for sure, but kind of nice. The evil macro looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#ifndef ___PRECOND
#define requires(F) {if((!(F))) throw preexception(__FILE__, __LINE__,&amp;quot;Pre-condition failure: &amp;quot; #F);};
#else
#define requires(F)
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the exception maintains information not just about the file and line number of the failure, but also a textual representation of the failed condition. Such things you can do with macro magick.&lt;/p&gt;
&lt;p&gt;Postconditions are trickier. In the case of a side-effect free (pure) function, a postcondition asserts something of interest about the return value. In the case of a class, it asserts something of interest about the state of the class before and after the execution of the method.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with a pure function. I like to have all my assertion at the start of the function to allow reasoning about it without looking at implementation details. But that poses the problem that the result is available just at the end of the function.&amp;#160; My solution is to enforce this idiom:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;double divide(double x, double y) {
    double result;
    requires(y != 0);
    ensures(result &amp;lt; x); // Silly, just to falsify it in tests
    …
    return result;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So you need to declare your result upfront. That is the biggest limitation of the overall solution in my opinion.&amp;#160; If that is acceptable to you, the trick now is how to execute the postcondition test before the method exits. We can do that by storing a lambda and executing it in the destructor:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;typedef std::function&amp;lt;bool ()&amp;gt; ___dbcLambda;
class ___post {
public:
    ___post(const char *file, long line, const char *expr, const ___dbcLambda&amp;amp; postF)
        : _f(postF),
          _file(file),
          _line(line),
          _expr(expr)
    {}
    ~___post()
    {
        if( !std::uncaught_exception() &amp;amp;&amp;amp; !_f() )
        {
            throw postexception(_file,_line,_expr);
        }
    }
private:
    const ___dbcLambda _f;
    const char * const _file;
    const long _line;
    const char * const _expr;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might think that you shouldn&amp;rsquo;t throw exceptions in a destructor. That is something I never understood about the &lt;a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization"&gt;RAII&lt;/a&gt; pattern in C++. If I choose to use exceptions as my error notification method, how am I supposed to get notified if there is a problem releasing a resource in RAII, other than by throwing an exception in the destructor?&lt;/p&gt;
&lt;p&gt;Maybe because of this, the standard has an uncaught_exception() function that allows you to check if an exception has been thrown, so that you don&amp;rsquo;t throw another one during stack unwinding. If you really don&amp;rsquo;t like throwing in the destructor, feel free to assert.&lt;/p&gt;
&lt;p&gt;You might be worried about performance, but you really shouldn&amp;rsquo;t as you can disable all these macros in Release.&lt;/p&gt;
&lt;p&gt;The macro then creates a ___post class on the stack.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define ensures(F) \
    int ___UNIQUE_LINE = __LINE__;  \
    auto ___UNIQUE_POST = ___post( __FILE__, __LINE__, &amp;quot;Post-condition failure:&amp;quot; #F, [&amp;amp;](){return (F);});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The UNIQUE stuff is messy business. Part of it is by design and it is used to make sure that each __post variable has a unique name to have multiple &amp;lsquo;ensures&amp;rsquo; in a function. The other part is a workaround for &lt;a href="http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/2c4698e1-8159-44fc-a64c-d15220acedb8"&gt;this&lt;/a&gt; msvc bug. Let me know if you want more details. I suspect there is a better way to do it.&lt;/p&gt;
&lt;p&gt;Here is the full enchilada …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define ___MERGE(a, b) a##b
#define ___POST(a) ___MERGE(___postcond,a)
#define ___UNIQUE_POST ___POST(__LINE__)
#define ___LINE(a) ___MERGE(___line, a)
#define ___UNIQUE_LINE ___LINE(__LINE__)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The case in which a postcondition is used inside a method of a class is even trickier because the postcondition must be able to compare the state of the class at the entrance of the method to the state of the class at its exit. Assuming a Counter object with an Add method and assuming &amp;lsquo;___pre&amp;rsquo; captures the state of the counter at the start of the method, you&amp;rsquo;d like to write something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;void Add(int x) {
    ensuresClass(this-&amp;gt;c_ == ___pre.c_ + x);
    …
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, this is tricky. The only way to capture the &amp;lsquo;old&amp;rsquo; state in &amp;lsquo;___pre&amp;rsquo; is by making a copy of it and store it there. This is what the code below does:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define ensuresClass(F) \
    auto ___pre(*this); \
    auto ___UNIQUE_POST = ___post( __FILE__, __LINE__, &amp;quot;Post-condition failure: &amp;quot; #F, [&amp;amp;](){return (F);});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More troubling is the possibility that the class doesn&amp;rsquo;t have a copy constructor. In that case you explicitly need to associate a value with &amp;lsquo;___pre2&amp;rsquo; by passing it as the first parameter to the appropriate macro as in the code below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;void Add(int x) {
    ensuresClass2(this-&amp;gt;c_, c_ == ___pre2 + x);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which is implemented as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define ensuresClass2(ASS,F) \
    auto ___pre2(ASS); \
    auto ___UNIQUE_POST = ___post( __FILE__, __LINE__, &amp;quot;Post-condition failure: &amp;quot; #ASS &amp;quot; is ___pre2 in &amp;quot; #F, [&amp;amp;](){return (F);});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And I know about the giant ass …&lt;/p&gt;
&lt;p&gt;Now for invariants. The user should implement an isValid() method on his class as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;bool isValid() { return c_ &amp;gt;= 0;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then he should add an &amp;lsquo;invariant()&amp;rsquo; call at the start of each method, at the end of each constructor and at the start of each destructor:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;void Add(int x) {
    invariant();
    requires(x &amp;lt; 10);
    ensures(this-&amp;gt;c_ == ___pre.c_ + x);
    …
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This calls the &amp;lsquo;isValid&amp;rsquo; function at the start of the method and at the end of it using the same destructor trick:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;#define invariant() \
    if(!(this-&amp;gt;isValid())) throw preexception(__FILE__, __LINE__,&amp;quot;Invariant failure&amp;quot;); \
    auto ___UNIQUE_INV = ___post( __FILE__, __LINE__, &amp;quot;Invariant failure&amp;quot;, [&amp;amp;](){return this-&amp;gt;isValid();});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the above machinery is not at all equivalent to having such constructs in the language, but it is simple enough and with a decent enough syntax to be interesting.&lt;/p&gt;
&lt;p&gt;Now a caveat: I have no idea if any of this works. It does work in my examples and its behaviour seems reasonably safe to me, but I haven&amp;rsquo;t tried it out on any big codebase and haven&amp;rsquo;t stressed it enough for me to be confident recommending its usage. So, use it at your own risk, let me know how it goes.&lt;/p&gt;</description>
            <pubDate>Tue, 06 Mar 2012 16:42:58 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2012-03-06-a-simple-scheme-to-implement-design-by-contract-in-c.html</guid>
        </item>
        
        <item>
            <title>Adventure in parserland – parsing lambda expressions in F# – Part V</title>
            <link>https://www.lucabol.com/posts/2011-09-16-adventure-in-parserland-parsing-lambda-expressions-in-f-part-v.html</link>
            <description>&lt;p&gt;We are now going to look at a solution which is concise, efficient and gives sophisticated error messages. It is also less than 20 lines of code. We&amp;rsquo;ll be using &lt;a href="http://www.quanttec.com/fparsec/"&gt;FParsec&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;FParsec is a port of an Haskell library. It is a parser combinator library or, as I like to think of it, an internal &lt;a href="http://www.google.co.uk/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CC0QFjAA&amp;amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FDomain-specific_language&amp;amp;ei=2uInTsvgG4LDhAfxrIzvCQ&amp;amp;usg=AFQjCNFeEXnlId4QmC-faKR_2dF1paxZMA&amp;amp;sig2=aCu7doIcVL0yFVlg3uA-pA"&gt;DSL&lt;/a&gt; to build parsers in F#. My usual disclaimer: I&amp;rsquo;m not an expert in FParsec. It is likely that, if you are an expert, you can come up with more maintainable/efficient/elegant version of this parser.&lt;/p&gt;
&lt;p&gt;The whole code is below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let ws = &amp;quot; \t\n&amp;quot;
let specialChars = &amp;quot;.)(\\\n&amp;quot;
let pWs = spaces
let pName = manyChars (noneOf (ws + specialChars)) |&amp;gt;&amp;gt; EName
let pExpr, pExprRef = createParserForwardedToRef&amp;lt;Expression, Unit&amp;gt;()
let curry2 f a b = f(a,b)
let pFunction = pchar '\\' &amp;gt;&amp;gt;. pipe2 pName (pchar '.' &amp;gt;&amp;gt;. pExpr) (curry2 Function)
let pApplication = pchar '(' &amp;gt;&amp;gt;. pipe2 pExpr (pWs &amp;gt;&amp;gt;. pExpr) (curry2 Application)
                          .&amp;gt;&amp;gt; pWs .&amp;gt;&amp;gt; pchar ')'
do pExprRef := pFunction &amp;lt;|&amp;gt; pApplication &amp;lt;|&amp;gt; pName
let pExpressions = sepBy pExpr spaces1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This mirrors pretty closely the grammar we are trying to parse. A program is a bunch of expressions separated by whitespaces.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let pExpressions = sepBy pExpr spaces1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;sepBy is a combinator that takes a parser that defines what to parse and a parser that defines what the separator should be. And the separator should be one or more spaces …&lt;/p&gt;
&lt;p&gt;&lt;em&gt;pExpr&lt;/em&gt; is either a function, an application or a name. the operator &amp;lt;|&amp;gt; is a choice combinator that tries each parser in order. It tries the right parser just if the left parser fails and it doesn&amp;rsquo;t consume input. So it doesn&amp;rsquo;t backtrack. If you need a backtracking parser, you&amp;rsquo;ll need to get acquainted with the &lt;em&gt;attempt&lt;/em&gt; combinator.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;do pExprRef := pFunction &amp;lt;|&amp;gt; pApplication &amp;lt;|&amp;gt; pName
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A function starts with a &amp;lsquo;', then comes a name, a dot and an expression. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let pFunction = pchar '\\' &amp;gt;&amp;gt;. pipe2 pName (pchar '.' &amp;gt;&amp;gt;. pExpr) (curry2 Function)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I know that might look crazy (and maybe it is), but just bear with me. Someone , who I&amp;rsquo;m not sure I can name, once told me that functional programming is great to write code, but terrible to read it and debug it. The phrase stayed with me as containing a grain of truth. In any case, in the code above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;. is a combinator that says &amp;ldquo;use the left parser, discard its value and then use the right one, returning its value&amp;rdquo;. Try to guess what .&amp;gt;&amp;gt; does … &lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;pipe2 is a combinator that says &amp;ldquo;apply the first parser, the second parser and then call a function passing as parameters the values returned by the two parsers &lt;/li&gt;
&lt;li&gt;curry2 is a function combinator that transform a function that takes a tuple to a function that takes the parameters as untupled &lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let curry2 f a b = f(a,b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An application works similarly, but differently …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let pApplication = pchar '(' &amp;gt;&amp;gt;. pipe2 pExpr (pWs &amp;gt;&amp;gt;. pExpr) (curry2 Application)
                          .&amp;gt;&amp;gt; pWs .&amp;gt;&amp;gt; pchar ')'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only difference is that now we have to consume the optional whitespaces and the &amp;lsquo;)&amp;rsquo; at the end. A rule of thumb that I use is to use &amp;gt;&amp;gt;.&amp;#160; to flow the result through and pipeX when I need more than one result.&lt;/p&gt;
&lt;p&gt;The last thing is pName, which consume chars until it finds either a whitespace or a special char.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let ws = &amp;quot; \t\n&amp;quot;
let specialChars = &amp;quot;.)(\\\n&amp;quot;
let pWs = spaces
let pName = manyChars (noneOf (ws + specialChars)) |&amp;gt;&amp;gt; EName
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there you have it, a lexer, a parser all in 20 lines of code. I don&amp;rsquo;t like the code that I wrote above much. I&amp;rsquo;m sure I could refine it plenty and it probably contains some bugs, but it gives an idea of what is possible with FParsec.&lt;/p&gt;</description>
            <pubDate>Fri, 16 Sep 2011 06:57:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-09-16-adventure-in-parserland-parsing-lambda-expressions-in-f-part-v.html</guid>
        </item>
        
        <item>
            <title>Adventure in parserland – parsing lambda expressions in F# – Part IV</title>
            <link>https://www.lucabol.com/posts/2011-09-09-adventure-in-parserland-parsing-lambda-expressions-in-f-part-iv.html</link>
            <description>&lt;p&gt;Let&amp;rsquo; now look at the parser. First let&amp;rsquo;s review the grammar:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;(*
        &amp;lt;expression&amp;gt; ::= &amp;lt;name&amp;gt; | &amp;lt;function&amp;gt; | &amp;lt;application&amp;gt;
        &amp;lt;name&amp;gt; ::= non­blank character sequence
        &amp;lt;function&amp;gt; ::= \ &amp;lt;name&amp;gt; . &amp;lt;body&amp;gt;
        &amp;lt;body&amp;gt; ::= &amp;lt;expression&amp;gt;
        &amp;lt;application&amp;gt; ::= ( &amp;lt;function expression&amp;gt; &amp;lt;argument expression&amp;gt; )
        &amp;lt;function expression&amp;gt; ::= &amp;lt;expression&amp;gt;
        &amp;lt;argument expression&amp;gt; ::= &amp;lt;expression&amp;gt;
    *)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the data type to represent it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Name = string
and Body = Expression
and Function = Name * Expression
and FunctionExpression = Expression
and ArgumentExpression = Expression
and Expression =
| EName of string
| Function of Expression * Body
| Application of FunctionExpression * ArgumentExpression
| EOT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In essence, the data type need to store all the information needed for subsequent stages of computation (i.e. beta reductions and such). The closer it is to the grammar, the better. In this case it looks pretty close.&lt;/p&gt;
&lt;p&gt;Remember what is the main goal of our parser:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseTextReader: TextReader -&amp;gt; seq&amp;lt;Expression&amp;gt; =
                    textReaderToLazyList &amp;gt;&amp;gt; tokenStream &amp;gt;&amp;gt; parseExpressions
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have already looked at &lt;em&gt;TextReaderToLazyList&lt;/em&gt; and &lt;em&gt;tokenStream&lt;/em&gt;. Now it is the time to look at &lt;em&gt;parseExpressions&lt;/em&gt;. It&amp;rsquo;s goal is to&amp;#160; parse the &lt;em&gt;LazyList&lt;Token&gt;&lt;/em&gt; and return a sequence of expressions. The choice of returning a sequence at this point is to make the &lt;em&gt;parseTextReader&lt;/em&gt;, which is the main function in the program, return a more &amp;lsquo;standard&amp;rsquo; type.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and parseExpressions tokens = seq {
   let tokens = parseOptionalWs tokens
   let expr, tokens = parseExpr tokens
   let tokens = parseOptionalWs tokens
   match expr with
    | EOT   -&amp;gt; yield EOT
    | exp   -&amp;gt; yield exp; yield! parseExpressions tokens }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;parseOtionalWs&lt;/em&gt; simply skips ahead whatever whitespaces it finds.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and parseOptionalWs tokens = match tokens with
                                | LazyList.Nil -&amp;gt; LazyList.empty
                                | LazyList.Cons(h, t) -&amp;gt;
                                    match h with
                                       | Ws _ -&amp;gt; parseOptionalWs t
                                       | _ -&amp;gt; tokens
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;parseExpr&lt;/em&gt; is more interesting. It is the main switch that creates expression kinds.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec parseExpr tokens = match tokens with
                            | LazyList.Nil -&amp;gt; EOT, LazyList.empty
                            | LazyList.Cons(h, t) -&amp;gt;
                                match h with
                                    | EOF -&amp;gt; parseEOF tokens
                                    | Name _ -&amp;gt; parseName  tokens
                                    | Lambda -&amp;gt; parseFunction tokens
                                    | OpenParens -&amp;gt; parseApplication tokens
                                    | token -&amp;gt; errorAtStart &amp;quot;Expression&amp;quot; token
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;parseEOF&lt;/em&gt; is not.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and parseEOF tokens = EOT, LazyList.empty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;parseName&lt;/em&gt; just returns a &lt;em&gt;EName&lt;/em&gt;, unwrapping it from Name.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and parseName tokens = EName (head tokens |&amp;gt; unwrapName), tail tokens
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unwrap just unwraps it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let unwrapName = function
    | Name(s) -&amp;gt; s
    | tok -&amp;gt; errorExpecting &amp;quot;a Name&amp;quot; &amp;lt;| writeToken tok
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;parseFunction&lt;/em&gt; just conumes a Lambda, a name, a Dot token, a body (i.e. \x.x)and assembles them in a Function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and parseFunction tokens =
    let tokens = consumeToken Lambda tokens
    let name, tokens = parseName tokens
    let tokens = consumeToken Dot tokens
    let body, tokens = parseExpr tokens
    Function(name, body), tokens
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;consumeToken&lt;/em&gt; tries to consume a token generating an error if it doesn&amp;rsquo;t find it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let consumeToken token =
    genericConsumeToken (fun token' _ -&amp;gt; errorExpecting (writeToken token') (writeToken token)) token
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;genericConsumeToken&lt;/em&gt; is just a generalization of the function above:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let genericConsumeToken noMatch token = function
    | LazyList.Nil -&amp;gt; LazyList.empty
    | LazyList.Cons(h, t) as originalTokens -&amp;gt;
        match h with
        | tok when tok = token -&amp;gt; t
        | tok -&amp;gt; noMatch token originalTokens
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last thing left to consume is an application which is in this form (func args):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and parseApplication tokens =
    let tokens = consumeToken OpenParens tokens
    let funExpr, tokens = parseExpr tokens
    let tokens = parseOptionalWs tokens
    let argExpr, tokens = parseExpr tokens
    let tokens = consumeToken CloseParens tokens
    Application(funExpr, argExpr), tokens
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Various error and utility functions are defined below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let errorEOF expecting = failwith  (&amp;quot;Expected &amp;quot; + expecting + &amp;quot;, got EOF&amp;quot;)
let errorExpecting expecting gotToken = failwith (&amp;quot;Expected &amp;quot; + expecting + &amp;quot;, got&amp;quot; + gotToken)
let errorAtStart expecting gotToken = failwith (&amp;quot;Expected &amp;quot; + expecting + &amp;quot; which cannot start with&amp;quot; + writeToken gotToken)
let tail = LazyList.tail
let head = LazyList.head
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that is the parser. All 100+ lines of it. As you can tell it is rather formulaic to go from a grammar to a lexer and a parser, which is why you shouldn&amp;rsquo;t do it, but instead let a tool generate the code for you given the grammar or use FParsec.&lt;/p&gt;
&lt;p&gt;We have written 200+ code and I don&amp;rsquo;t think we can be too proud of our achievement. It is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Certainly buggy&lt;/li&gt;
&lt;li&gt;Primitive in error handling&lt;/li&gt;
&lt;li&gt;Not tail recursive (big text is likely to blow up our stack)&lt;/li&gt;
&lt;li&gt;Probably inefficient&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So let&amp;rsquo;s look next at a better way to do it.&lt;/p&gt;</description>
            <pubDate>Fri, 09 Sep 2011 06:09:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-09-09-adventure-in-parserland-parsing-lambda-expressions-in-f-part-iv.html</guid>
        </item>
        
        <item>
            <title>Adventure in parserland – parsing lambda expressions in F# – Part III</title>
            <link>https://www.lucabol.com/posts/2011-09-02-adventure-in-parserland-parsing-lambda-expressions-in-f-part-iii.html</link>
            <description>&lt;p&gt;Let&amp;rsquo;s start from the lexer. Remember, I wrote this code based on my memory of how a lexer ought to look like. I didn&amp;rsquo;t read again the relevant chapters in &lt;a href="http://en.wikipedia.org/wiki/Principles_of_Compiler_Design"&gt;the Dragon book&lt;/a&gt;. But I think it came out all right after all.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;tokenStream&lt;/em&gt; function we looked at last time takes a &lt;em&gt;LazyList&lt;char&gt;&lt;/em&gt; and returns a &lt;em&gt;LazyList&lt;Token&gt;&lt;/em&gt;. It uses the unfold method on &lt;em&gt;LazyList&lt;/em&gt; to call &lt;em&gt;matchToken&lt;/em&gt; on each char until the stream is empty.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec tokenStream chars =
    LazyList.unfold
        (fun chList -&amp;gt;
            match chList with
            | LazyList.Nil -&amp;gt; None
            | chList -&amp;gt;
                let token, chList' = matchToken chList
                Some(token, chList')
        )
        chars 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A token is what gets passed up to the parser to do syntactic analysis on. It is the vocabulary of our language. The lexer divide a phrase in words, the parser put together the words in a phrase. So, these are the words.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Token =
    | Name of string
    | Dot
    | OpenParens
    | CloseParens
    | Lambda
    | Def
    | Ws of string
    | NewLine
    | EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Matching is a process whereas you try to return the token that you have read plus the list of characters yet to be read. Matching a Token is defined below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let matchToken = function
    | LazyList.Nil                 -&amp;gt; EOF, LazyList.empty
    | LazyList.Cons(h, t) as chars -&amp;gt;
        match h with
        | ch when isWs ch -&amp;gt; matchWs chars
        | ch when isSpecialChar ch -&amp;gt; matchSpecialChar ch t
        | _ -&amp;gt; matchString chars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A token is either nothing, a whitespace, a special char or anything else.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at what matching each one of them means.&amp;#160; Matching whitespaces means consuming them and remembering what was consumed.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let matchWs chars =
    let value, remainingChars = matchSeriesOfChars isWs chars
    Ws value, remainingChars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;matchSeriesOfChars&lt;/em&gt; takes a predicate and a &lt;em&gt;LazyList&lt;/em&gt; of chars and returns the string composed of all the consecutive chars for which the predicate is true, plus, as always, the remaining chars to be matched. In this case the predicate returns true if the char is a whitespace.&lt;/p&gt;
&lt;p&gt;To write &lt;em&gt;matchSeriesOfChars&lt;/em&gt; I need a function that reverses a LazyList. Not having found such thing, I wrote it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let reversell l =
    let rec go l' a = match l', a with
                        | LazyList.Nil, a -&amp;gt; a
                        | LazyList.Cons(h, t), a -&amp;gt; go t (LazyList.cons h a)
    go l LazyList.empty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I wrote &lt;em&gt;matchSeriesOfChars&lt;/em&gt;. The function uses an accumulator. It adds to the front whenever the predicate is true, it reverses it and translates it to a string (I could have reversed the string instead, it might have been better).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let matchSeriesOfChars comparer chars =
    let rec go result = function
        | LazyList.Nil    -&amp;gt; charListToString(reversell result), LazyList.empty
        | LazyList.Cons(h, t) -&amp;gt; if comparer h then go (LazyList.cons h result) t
                                 else charListToString (reversell result), LazyList.cons h t
    go LazyList.empty chars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are&amp;#160; predicates we&amp;rsquo;ll use later on to recognize characters:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let isInString (ch: char) (s: string) = s.IndexOf(ch) &amp;lt;&amp;gt; -1
let isWs (chr: char) = isInString chr wsChars
let isNameChar (chr: char) = not (isInString chr (wsChars + specialChars))
let isSpecialChar ch = isInString ch specialChars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;wsChar&lt;/em&gt; and &lt;em&gt;specialChars&lt;/em&gt; are defined below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let wsChars = &amp;quot; \t&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let charTokens =
    Map.ofList [
        '.', Dot
        '(', OpenParens
        ')', CloseParens
        '\\', Lambda
        '\n', NewLine
     ]
let specialChars = charTokens |&amp;gt; Map.fold (fun s k v -&amp;gt; s + k.ToString()) &amp;quot;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Getting back to the more important matching functions, matching a special character is defined as a simple lookup in the &lt;em&gt;charToken&lt;/em&gt; map:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let matchSpecialChar ch chars = Map.find ch charTokens, chars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are left with matchString, this simply matches the characters until it finds a char that cannot be part of a name. It then looks it up in a list of special strings. If it finds it, it returns it, otherwise it just returns the name.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let stringTokens =
    Map.ofList [
        &amp;quot;Def&amp;quot;, Def
    ]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let matchString chars =
    let value, remainingChars = matchSeriesOfChars isNameChar chars
    let specialString = Map.tryFind value stringTokens
    if specialString.IsSome
        then specialString.Value, remainingChars
        else Name(value), remainingChars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we are done with the lexer, all of 100+ lines of it …&lt;/p&gt;</description>
            <pubDate>Fri, 02 Sep 2011 15:25:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-09-02-adventure-in-parserland-parsing-lambda-expressions-in-f-part-iii.html</guid>
        </item>
        
        <item>
            <title>Adventure in parserland – parsing lambda expressions in F# – Part II</title>
            <link>https://www.lucabol.com/posts/2011-08-26-adventure-in-parserland-parsing-lambda-expressions-in-f-part-ii.html</link>
            <description>&lt;p&gt;The parser starts simple with the following two functions to parse either a string or a file. I use the XXX_Readers_ because I want to lazy read character by character.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseString s =
    let reader = new StringReader(s)
    parseTextReader reader
let parseFile fileName =
    let reader = new StreamReader(fileName: string)
    parseTextReader reader
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The whole parser is in the following two lines:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseTextReader: TextReader -&amp;gt; seq&amp;lt;Expression&amp;gt; =
                    textReaderToLazyList &amp;gt;&amp;gt; tokenStream &amp;gt;&amp;gt; parseExpressions
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I need to specify the signature otherwise the compiler gets confused : wait, does it take a StringReader or a StreamReader? You better tell me!&lt;/p&gt;
&lt;p&gt;The function is a composite of three functions applied in sequence:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Translate a TextReader to a LazyList&lt;char&gt; &lt;/li&gt;
&lt;li&gt;Translate a LazyList&lt;char&gt; to a LazyList&lt;Token&gt; (lexer) &lt;/li&gt;
&lt;li&gt;Translate a LazyList&lt;Token&gt; to a LazyList&lt;Expression&gt; (parser) &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My usage of &lt;em&gt;LazyList&lt;/em&gt; as the workhorse for the program is because I want to match on the head of the stream of chars/tokens in a lazy way.&lt;/p&gt;
&lt;p&gt;I love it when a program naturally decomposes in such simple understandable pieces. I impute some of that to functional programming. For one reason or another, in my 15+ years of object oriented programming, I&amp;rsquo;ve rarely got to the core of a problem with such immediacy.&lt;/p&gt;
&lt;p&gt;A sequence of operations likes the above would be lost in a protected overridden implementation of a base class somewhere (or something else equally long to pronounce). The beauty would be lost somewhere in the vast machinery required to support it.&lt;/p&gt;
&lt;p&gt;In any case, &lt;em&gt;TextReaderToLazyList&lt;/em&gt; is a trivial generator function that uses the unfold function of LazyList to read a character at the time.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let textReaderToLazyList textReader = LazyList.unfold (fun (ts:TextReader) -&amp;gt;
    let ch = ts.Read()
    if ch = -1 then None else Some(char ch, ts)) textReader
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next step is to look at either the lexer, going bottom up, or the parser, going top down.&lt;/p&gt;</description>
            <pubDate>Fri, 26 Aug 2011 14:25:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-08-26-adventure-in-parserland-parsing-lambda-expressions-in-f-part-ii.html</guid>
        </item>
        
        <item>
            <title>Adventure in parserland – parsing lambda expressions in F# – Part I</title>
            <link>https://www.lucabol.com/posts/2011-08-19-adventure-in-parserland-parsing-lambda-expressions-in-f-part-i.html</link>
            <description>&lt;p&gt;This is part of my &amp;lsquo;things that I do in the empty spaces between one meeting and the next one, which might end up being vaguely interesting&amp;rsquo;. It is a lambda expression parser.&lt;/p&gt;
&lt;p&gt;The full source code is &lt;a href="http://code.msdn.microsoft.com/Parsing-Lambda-Expressions-7ad5271f"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I actually have two versions of it: one written longhand and the other one written with &lt;a href="http://www.quanttec.com/fparsec/about/fparsec-vs-alternatives.html"&gt;FParsec&lt;/a&gt;. Just to be clear: I&amp;rsquo;m no expert of either.&lt;/p&gt;
&lt;p&gt;And just to be more clear: I think writing most parsers longhand in the way I am about to show is crazy. You either use FParsec or&amp;#160; &lt;a href="http://blogs.msdn.com/b/jomo_fisher/archive/2010/06/15/use-fslex-and-fsyacc-to-make-a-parser-in-f.aspx"&gt;fslex / fsyacc&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I have a strong distaste for additional compilation steps. I think it lingers on from MFC project types of 15/20 years ago. I was one of these crazy folks that would generate the project, wrap the generated code (with some generalizations) in my own library and use that one from then on.&lt;/p&gt;
&lt;p&gt;So I prefer FParsec. I&amp;rsquo;m ok rewriting &lt;a href="http://en.wikipedia.org/wiki/Left_recursion"&gt;left recursive&lt;/a&gt; rules and its performance has never been a problem for me. &lt;a href="http://www.quanttec.com/fparsec/about/fparsec-vs-alternatives.html"&gt;Here&lt;/a&gt; is a table that compares the different approaches.&lt;/p&gt;
&lt;p&gt;But I started wondering about coding a a recursive descent parser for a simple grammar by hand, fully knowing the foolishness of the idea. Thanks to &lt;a href="http://www.haskellers.com/user/pepeiborra"&gt;Jose&lt;/a&gt; for code reviewing it.&lt;/p&gt;
&lt;p&gt;The inspiration for the grammar comes from &lt;a href="http://www.google.co.uk/url?sa=t&amp;amp;source=web&amp;amp;cd=4&amp;amp;ved=0CDgQFjAD&amp;amp;url=http%3A%2F%2Fwww.amazon.com%2FIntroduction-Functional-Programming-Calculus-International%2Fdp%2F0201178125&amp;amp;ei=KoklTqzjF4GWhQf-w5XlCQ&amp;amp;usg=AFQjCNGPzv_27nSNwctaEykBivq3N-I7Dg&amp;amp;sig2=4iLu_nZnd8GlwPXpt8crMg"&gt;this book&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-text"&gt;(*
        &amp;lt;expression&amp;gt; ::= &amp;lt;name&amp;gt; | &amp;lt;function&amp;gt; | &amp;lt;application&amp;gt;
        &amp;lt;name&amp;gt; ::= non­blank character sequence
        &amp;lt;function&amp;gt; ::= \ &amp;lt;name&amp;gt; . &amp;lt;body&amp;gt;
        &amp;lt;body&amp;gt; ::= &amp;lt;expression&amp;gt;
        &amp;lt;application&amp;gt; ::= ( &amp;lt;function expression&amp;gt; &amp;lt;argument expression&amp;gt; )
        &amp;lt;function expression&amp;gt; ::= &amp;lt;expression&amp;gt;
        &amp;lt;argument expression&amp;gt; ::= &amp;lt;expression&amp;gt;
    *)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In English, an expression is either a name, a function or an application. A name is a bunch of characters (better defined in the code). A function is &amp;lsquo;', a name, &amp;lsquo;.&amp;rsquo; and an expression. An application is &amp;lsquo;(&amp;lsquo;, an expression, whitespaces, an expression and &amp;lsquo;)&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;Some testcases for the above grammar and the parsers written to parse it are below. It should be intuitive what this code does just by the name of the functions. Even it isn&amp;rsquo;t, check that the expressions symbol contains valid productions from the grammar above.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;module Test
open Microsoft.FSharp.Collections
open Xunit
open LambdaEngine
open Parser
open Lexer
open FParser

let writeTokenStream stream = Seq.fold (fun acc token -&amp;gt; acc + writeToken token) &amp;quot;&amp;quot; stream

let rec writeExpr = function
        | EName(s) -&amp;gt; s
        | Function(expr, body) -&amp;gt; writeToken Lambda + writeExpr expr + writeToken Dot + writeExpr body
        | Application(funExpr, argExpr) -&amp;gt; writeToken OpenParens + writeExpr funExpr + writeToken (Ws(&amp;quot; &amp;quot;))
                                            + writeExpr argExpr + writeToken CloseParens
        | EOT -&amp;gt; &amp;quot;&amp;quot;

let tokenStreams = [
    &amp;quot;&amp;quot;
    &amp;quot;(\xs.xs \y.(y \x.y))&amp;quot;
    &amp;quot;(\xst.xst \y.(y  \x.y))&amp;quot;
    &amp;quot; &amp;quot;
    &amp;quot;x&amp;quot;
    &amp;quot;(x y)&amp;quot;
    ]

let expressions = [
    &amp;quot;&amp;quot;
    &amp;quot;(\x.x \y.(y \x.y))&amp;quot;
    &amp;quot;x&amp;quot;
    &amp;quot;(x y)&amp;quot;
    ]

let stringToCharList s =
    let textReader = new System.IO.StringReader(s)
    textReaderToLazyList textReader

[&amp;lt;Fact&amp;gt;]
let testTokenizer () =
    let testTokenStream s =
        let stream = tokenStream &amp;lt;| stringToCharList s
        let s1 = writeTokenStream stream
        Assert.Equal(s, s1)
    tokenStreams |&amp;gt; List.iter testTokenStream

let testExpr parseFunction s =
    let exprs = parseFunction s
    let s1 = exprs |&amp;gt; Seq.fold (fun s expr -&amp;gt; s + writeExpr expr) &amp;quot;&amp;quot;
    Assert.Equal(s, s1)

[&amp;lt;Fact&amp;gt;]
let testParser () = expressions |&amp;gt; List.iter (testExpr parseString)

[&amp;lt;Fact&amp;gt;]
let testFParser () = expressions |&amp;gt; List.iter (testExpr fparseString)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the next instalment, we&amp;rsquo;ll start looking at the real code for the parser.&lt;/p&gt;</description>
            <pubDate>Fri, 19 Aug 2011 06:53:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-08-19-adventure-in-parserland-parsing-lambda-expressions-in-f-part-i.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part VII</title>
            <link>https://www.lucabol.com/posts/2011-08-12-write-yourself-a-scheme-in-48-hours-in-f-part-vii.html</link>
            <description>&lt;p&gt;Let&amp;rsquo;s talk about the environment now.&amp;#160; This is the part of the interpreter that I like the least. It is a global variable and it contains a list of&amp;#160; (string, LispVal) where the LispVal is mutable.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Env = (string * LispVal ref) list ref
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is pretty bad. First of all, it immediately cuts off any option of running interpreters in different threads. Moreover, it makes a lot of functions in the evaluator to have side effects. That makes it much harder to reason about them.&lt;/p&gt;
&lt;p&gt;In a world where I am provided with infinite time and energy, I would change it. In this world, I won&amp;rsquo;t. If you try your hand at doing it, make sure that you pass all the testcases before declaring victory. The scope rules of Scheme are not all that obvious. A code reviewer called them the Italian scoping rules because he thought I got them wrong …&lt;/p&gt;
&lt;p&gt;In any case, there isn&amp;rsquo;t much to the symbol table management.&amp;#160; You can create an empty one:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let nullEnv (): Env = ref List.empty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check if a variable is bound:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let keyEq name (k, _) = name = k
let isBound var (env: Env) = !env |&amp;gt; List.exists (keyEq var)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Get a variable out:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let getVar var (env: Env) =
    let result = !env |&amp;gt; List.tryFind (keyEq var)
    match result with
    | None -&amp;gt; throw (UnboundVar(&amp;quot;Getting an unbound variable: &amp;quot; , var))
    | Some(_, r) -&amp;gt; !r
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set the value of an existing variable:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let setVar var value (env:Env) =
    let result = !env |&amp;gt; List.tryFind (keyEq var)
    match result with
    | Some(_, v) -&amp;gt; v := value ; value
    | None -&amp;gt; throw (UnboundVar(&amp;quot;Setting an unbound variable: &amp;quot; , var))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or define a new variable in the environment. Note that if the variable already exist, its value gets set.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let define (env:Env) var value =
    let result = !env |&amp;gt; List.tryFind (keyEq var)
    match result with
    | Some(_, v) -&amp;gt; v := value ; value
    | None -&amp;gt;
        env := [var, ref value] @ !env; value
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also bind a list of (string, LispVal) to the environment by prepending it to the existing ones:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let bindVars bindings (env:Env) =
   ref ((bindings |&amp;gt; List.map (fun (n, v) -&amp;gt; n , ref v)) @ !env)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you accept the evil of the global mutable variable scheme, these functions are easy enough.&lt;/p&gt;
&lt;p&gt;The only piece left is error management. This is where my implementation differs from the Haskell version the most. In essence, I throw exception and catch them to report errors, while the Haskell version uses a monad to propagate the error information.&lt;/p&gt;
&lt;p&gt;I have a &lt;em&gt;LispError&lt;/em&gt; that represents everything that can go wrong:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type LispError =
    | NumArgs of int * LispVal list
    | TypeMismatch of string * LispVal
    | ParseError of string * FParsec.Error.ParserError
    | BadSpecialForm of string * LispVal
    | NotFunction of string * string
    | UnboundVar of string * string
    | Default of string
    | IOError of string
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I wrap it in an exception:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;exception LispException of LispError
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is what I throw in various places in the code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let throw le = raise (LispException(le))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I then catch it at the outer layer:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let evalString env expr =
    try
        expr |&amp;gt; readExpr |&amp;gt; eval env
    with
    | LispException(error) -&amp;gt; String (showError error)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And display the error by using the below function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let showError = function
    | NumArgs(expected, found) -&amp;gt; &amp;quot;Expected &amp;quot; + expected.ToString() + &amp;quot; args; found values &amp;quot; + unwordsList found
    | TypeMismatch(expected, found) -&amp;gt; &amp;quot;Invalid type: expected &amp;quot; + expected + &amp;quot;, found &amp;quot; + showVal found
    | ParseError(msg, _) -&amp;gt; &amp;quot;Parse Errror&amp;quot; + msg
    | BadSpecialForm(message, form) -&amp;gt; message + showVal form
    | NotFunction(message, func) -&amp;gt; message + func
    | UnboundVar(message, varName) -&amp;gt; message + varName
    | Default(message) -&amp;gt; message
    | IOError(message) -&amp;gt; message
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;rsquo;s all there is to it. I hope you guys and gals enjoyed this seven part extravagance. Cheers.&lt;/p&gt;</description>
            <pubDate>Fri, 12 Aug 2011 07:11:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-08-12-write-yourself-a-scheme-in-48-hours-in-f-part-vii.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part VI</title>
            <link>https://www.lucabol.com/posts/2011-08-05-write-yourself-a-scheme-in-48-hours-in-f-part-vi.html</link>
            <description>&lt;p&gt;The evaluator takes as an input a &lt;em&gt;LispVal&lt;/em&gt;. Where does it come from? There must be something that converts your textual input into it. That is the job of the parser.&lt;/p&gt;
&lt;p&gt;I have used &lt;a href="http://www.quanttec.com/fparsec/"&gt;FParsec&lt;/a&gt; to build my parser. FParsec is a fantastic library to build parsers. It is a perfect showcase of the composition potential that functional code yields.&amp;#160; &lt;/p&gt;
&lt;p&gt;When you write an FParsec parser you compose many little parsers to create the one parser that works for your language.&amp;#160; The resulting code looks very much like your language grammar, but you don&amp;rsquo;t need&amp;#160; a separate code generation compilation step to produce it.&lt;/p&gt;
&lt;p&gt;There is one element of ugliness in the syntax to create recursive parsers. You need to define two global variables that can be referred to before they are constructed. This is an artefact of how F# works. So you need a line in your code that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseExpr, parseExprRef : LispParser * LispParser ref = createParserForwardedToRef()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that piece of machinery out of the way, we can focus on the parser itself. Our goal here is to parse expressions and generate &lt;em&gt;LispVal&lt;/em&gt;. We need a &lt;em&gt;LispParser&lt;/em&gt; like the below (the second generic parameter is for advanced usage).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type LispParser = Parser&amp;lt;LispVal, unit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to parse all the kind of expressions that the user can type. Notice in the below the use of a computation expression to simplify the syntax. Also note that lists and dotted lists look very much the same until you encounter the &amp;lsquo;.&amp;rsquo; character. You could disambiguate the situation by extracting out the commonality in a separate kind of expression. I decided instead to instruct the parser to backtrack if it gets it wrong (&lt;em&gt;attempt&lt;/em&gt;). This is slower, but keeps the code identical to our conceptual model. I value that greatly. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;do parseExprRef := parseAtom
                   &amp;lt;|&amp;gt; parseString
                   &amp;lt;|&amp;gt; parseNumber
                   &amp;lt;|&amp;gt; parseQuoted
                   &amp;lt;|&amp;gt; parse {
                           do! chr '('
                           let! x = (attempt parseList) &amp;lt;|&amp;gt; parseDottedList
                           do! chr ')'
                           return x
                       }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s start from the top. Parsing an atom means parsing something that starts with a letter or symbol and continues with letters, symbols or digits. Also &amp;ldquo;#t&amp;rdquo; and &amp;ldquo;#f&amp;rdquo; can be resolved at parsing time.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseAtom : LispParser = parse {
        let! first = letter &amp;lt;|&amp;gt; symbol
        let! rest = manyChars (letter &amp;lt;|&amp;gt; symbol &amp;lt;|&amp;gt; digit)
        return match first.ToString() + rest with
               | &amp;quot;#t&amp;quot; -&amp;gt; Bool true
               | &amp;quot;#f&amp;quot; -&amp;gt; Bool false
               | atom -&amp;gt; Atom atom
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A string is just a bunch of chars (except &amp;lsquo;') surrounded by &amp;rsquo; &amp;rdquo; &amp;lsquo;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseString : LispParser = parse {
    do! chr '&amp;quot;'
    let! xs = manyChars (noneOf &amp;quot;\&amp;quot;&amp;quot;)
    do! chr '&amp;quot;'
    return String(xs)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A number is just one or more digits. I am afraid we just support integers at this stage …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseNumber : LispParser = many1Chars digit |&amp;gt;&amp;gt; (System.Int32.Parse &amp;gt;&amp;gt; Number)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A quoted expression is jut a &amp;lsquo;' followed by an expression.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseQuoted : LispParser = chr '\'' &amp;gt;&amp;gt;. parseExpr |&amp;gt;&amp;gt; fun expr -&amp;gt; List [Atom &amp;quot;quote&amp;quot;; expr]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A list is just a bunch of expressions separate by at least one space.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseList : LispParser = sepBy parseExpr spaces1 |&amp;gt;&amp;gt; List
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A dotted list starts in the same way (hence the backtracking above), but then has a dot, one or more spaces and an expression.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseDottedList : LispParser = parse {
    let! head = endBy parseExpr spaces1
    let! tail = chr '.' &amp;gt;&amp;gt;. spaces1 &amp;gt;&amp;gt;. parseExpr
    return DottedList (head, tail)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here are a bunch of functions used throughout the code, presented here for completeness.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let spaces1 : LispParser&amp;lt;unit&amp;gt; = skipMany1 whitespace
    let chr c = skipChar c
    let endBy  p sep = many  (p .&amp;gt;&amp;gt; sep)
    let symbol : LispParser&amp;lt;char&amp;gt; = anyOf &amp;quot;!$%&amp;amp;|*+-/:&amp;lt;=?&amp;gt;@^_~#&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is all the code you need to translate text to a &lt;em&gt;LispVal&lt;/em&gt; to feed the evaluator. That is pretty impressive.&lt;/p&gt;
&lt;p&gt;There is also a function to go the other way, from a LispVal to text. It is used in implementing the testcases and to print out diagnostics.&lt;/p&gt;
&lt;p&gt;```fsharp
let rec showVal = function
        | String contents -&amp;gt; &amp;ldquo;"&amp;rdquo; + contents + &amp;ldquo;"&amp;rdquo;
        | Atom name -&amp;gt; name
        | Number num -&amp;gt; num.ToString()
        | Bool t -&amp;gt; if t then &amp;ldquo;#t&amp;rdquo; else &amp;ldquo;#f&amp;rdquo;
        | List l -&amp;gt; &amp;ldquo;(&amp;rdquo; + unwordsList l + &amp;ldquo;)&amp;rdquo;
        | DottedList (head, tail) -&amp;gt; &amp;ldquo;(&amp;rdquo; + unwordsList head + &amp;rdquo; . &amp;rdquo; + showVal tail + &amp;ldquo;)&amp;rdquo;
        | PrimitiveFunc(&lt;em&gt;) -&amp;gt; &amp;ldquo;&lt;primitive&gt;&amp;rdquo;
        | Port (&lt;/em&gt;) -&amp;gt; &amp;ldquo;&lt;IO port&gt;&amp;rdquo;
        | Func({ parms = parms; varargs = varargs; body = body; closure = closure }) -&amp;gt;
                                                &amp;ldquo;(lambda (&amp;rdquo; + unwordsList (parms |&amp;gt; List.map (String)) +
                                                    (match varargs with
                                                        | None -&amp;gt; &amp;ldquo;&amp;rdquo;
                                                        | Some(arg) -&amp;gt; &amp;rdquo; . &amp;rdquo; + arg) + &amp;ldquo;) &amp;hellip;)&amp;rdquo;
    and
        unwordsList = List.map showVal &amp;gt;&amp;gt; String.concat &amp;rdquo; &amp;ldquo;&lt;/p&gt;</description>
            <pubDate>Fri, 05 Aug 2011 07:08:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-08-05-write-yourself-a-scheme-in-48-hours-in-f-part-vi.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part V</title>
            <link>https://www.lucabol.com/posts/2011-07-29-write-yourself-a-scheme-in-48-hours-part-iv-2.html</link>
            <description>&lt;p&gt;We have one loose end to tie in the evaluator: the primitive operators. These are things that the interpreter knows intrinsically. There is a list of them below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec primitives =
     [
        &amp;quot;+&amp;quot;,    numericBinop (+)
        &amp;quot;-&amp;quot;,    numericBinop (-)
        &amp;quot;*&amp;quot;,    numericBinop (*)
        &amp;quot;/&amp;quot;,    numericBinop (/)
        &amp;quot;mod&amp;quot;,  numericBinop (%)
        &amp;quot;=&amp;quot;,    numBoolBinop (=)
        &amp;quot;&amp;lt;&amp;quot;,    numBoolBinop (&amp;lt;)
        &amp;quot;&amp;gt;&amp;quot;,    numBoolBinop (&amp;gt;)
        &amp;quot;/=&amp;quot;,   numBoolBinop (&amp;lt;&amp;gt;)
        &amp;quot;&amp;gt;=&amp;quot;,   numBoolBinop (&amp;gt;=)
        &amp;quot;&amp;lt;=&amp;quot;,   numBoolBinop (&amp;lt;=)
        &amp;quot;&amp;amp;&amp;amp;&amp;quot;,   boolBoolBinop (&amp;amp;&amp;amp;)
        &amp;quot;||&amp;quot;,   boolBoolBinop (||)
        &amp;quot;string=?&amp;quot;,     strBoolBinop (=)
        &amp;quot;string&amp;gt;?&amp;quot;,      strBoolBinop (&amp;gt;)
        &amp;quot;string&amp;lt;?&amp;quot;,      strBoolBinop (&amp;lt;)
        &amp;quot;string&amp;lt;=?&amp;quot;,    strBoolBinop (&amp;lt;=)
        &amp;quot;string&amp;gt;=?&amp;quot;,    strBoolBinop (&amp;gt;=)
        &amp;quot;car&amp;quot;,  car
        &amp;quot;cdr&amp;quot;,  cdr
        &amp;quot;cons&amp;quot;, cons
        &amp;quot;eq?&amp;quot;, eqv
        &amp;quot;eqv?&amp;quot;, eqv
        &amp;quot;equal?&amp;quot;, equal
        // IO primitives
        &amp;quot;apply&amp;quot;, applyProc
        &amp;quot;open-input-file&amp;quot;, makePort FileAccess.Read
        &amp;quot;open-output-file&amp;quot;, makePort FileAccess.Write
        &amp;quot;close-input-port&amp;quot;, closePort
        &amp;quot;close-output-port&amp;quot;, closePort
        &amp;quot;read&amp;quot;, readProc
        &amp;quot;write&amp;quot;, writeProc
        &amp;quot;read-contents&amp;quot;, readContents
        &amp;quot;read-all&amp;quot;, readAll
     ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Having seen the above list, it now becomes clearer why the &lt;em&gt;primitiveBindings&lt;/em&gt; function was defined as such. It just binds these pairs into the environment.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let primitiveBindings () =
    (nullEnv ()) |&amp;gt; bindVars [ for v, f in primitives -&amp;gt; v, PrimitiveFunc f ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;numericBinop&lt;/em&gt; unpacks the numbers, applies the provided operator and packs the result back in the Number.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let numericBinop op parms =
    if List.length parms &amp;lt; 2
        then throw &amp;lt;| NumArgs(2, parms)
        else parms |&amp;gt; List.map unpackNum |&amp;gt; foldl1 op |&amp;gt; Number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While we are at it, we can define _fold1 (_it tends to be&amp;#160; useful)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let foldl1 op = function
    | h::t -&amp;gt; List.fold op h t
    | [] -&amp;gt; throw (Default(&amp;quot;Expected a not empty list, got an empty list&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other XBinops work similarly …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let boolBinop unpacker op args =
    match args with
    | [ left; right ] -&amp;gt; Bool (op (unpacker left) (unpacker right))
    | _ -&amp;gt; throw (NumArgs(2,args))
let numBoolBinop = boolBinop unpackNum
let strBoolBinop = boolBinop unpackStr
let boolBoolBinop = boolBinop unpackBool
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now have to look at the family of unpackers. They all work rather similarly. Notice Scheme making an effort to get a number out of a string and to get anything out of a list. Strong type folks won&amp;rsquo;t like that. Oh well, just remove these lines …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec unpackNum = function
    | Number n  -&amp;gt; n
    | String n  -&amp;gt; let success, result = System.Int32.TryParse n
                   if success
                       then result
                       else throw (TypeMismatch(&amp;quot;number&amp;quot;, String n))
    | List [n]  -&amp;gt; unpackNum n
    | notNumber -&amp;gt; throw (TypeMismatch(&amp;quot;number&amp;quot;, notNumber))
let rec unpackStr = function
    | String s -&amp;gt; s
    | Number n -&amp;gt; n.ToString()
    | Bool b   -&amp;gt; b.ToString()
    | List [s]  -&amp;gt; unpackStr s
    | noString -&amp;gt; throw (TypeMismatch(&amp;quot;string&amp;quot;, noString))
let rec unpackBool = function
    | Bool b -&amp;gt; b
    | List [b]  -&amp;gt; unpackBool b
    | noBool -&amp;gt; throw (TypeMismatch(&amp;quot;boolean&amp;quot;, noBool))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now back to the list of primitive operators, there are the signature LISP operators &lt;em&gt;car&lt;/em&gt;, &lt;em&gt;cdr&lt;/em&gt; and &lt;em&gt;cons&lt;/em&gt;. Just understanding the first line for each function should be enough to get an idea of what they do.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let car = function
    | [List (x :: _)] -&amp;gt; x
    | [DottedList (x :: _, _)] -&amp;gt; x
    | [badArg] -&amp;gt; throw (TypeMismatch(&amp;quot;pair&amp;quot;, badArg))
    | badArgList -&amp;gt; throw (NumArgs(1, badArgList))
let cdr = function
    | [List (x :: xs)] -&amp;gt; List xs
    | [DottedList ([xs], x)] -&amp;gt; x
    | [DottedList ((_ :: xs), x)] -&amp;gt; DottedList (xs, x)
    | [badArg] -&amp;gt; throw (TypeMismatch(&amp;quot;pair&amp;quot;, badArg))
    | badArgList -&amp;gt; throw (NumArgs(1, badArgList))
let cons = function
    | [x; List xs] -&amp;gt; List (x :: xs)
    | [x; DottedList (xs, xlast)] -&amp;gt; DottedList (x :: xs, xlast)
    | [x1; x2] -&amp;gt; DottedList([x1], x2)
    | badArgList -&amp;gt; throw (NumArgs(2, badArgList))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then need to work our way to implement &lt;em&gt;eqv&lt;/em&gt; (aka &lt;em&gt;eq?&lt;/em&gt; in Scheme). We first define a function that tests that two LispVal are the same. It should be pretty self explanatory (the list piece is kind of cute).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec eqvPrim e1 e2 =
        match e1, e2 with
        | (Bool b1, Bool b2) -&amp;gt; b1 = b2
        | (Number n1, Number n2) -&amp;gt; n1 = n2
        | (String s1, String s2) -&amp;gt; s1 = s2
        | (Atom a1, Atom a2) -&amp;gt; a1 = a2
        | (DottedList (xs, x), DottedList(ys, y)) -&amp;gt; eqvPrim (List (xs @ [x])) (List (ys @ [y]))
        | (List l1, List l2) -&amp;gt; l1.Length = l2.Length &amp;amp;&amp;amp; List.forall2 eqvPrim l1 l2
        | _ -&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we wrap the result in a &lt;em&gt;Bool&lt;/em&gt;. Doing it this way avoid repeating the wrapping in each single line of &lt;em&gt;eqvPrim&lt;/em&gt; (thanks to Tobias for spotting this refactoring).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let eqv = function
          | [e1; e2] -&amp;gt; Bool (eqvPrim e1 e2)
          | badArgList -&amp;gt; throw (NumArgs (2, badArgList))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Equal?&lt;/em&gt; checks if there is any unpacking scheme that can be used to test equality of the two elements of a two element list.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let equal = function
    | [arg1; arg2] -&amp;gt;
        let unpackEqual = numUnpackEq arg1 arg2 ||
                          strUnpackEq arg1 arg2 ||
                          boolUnpackEq arg1 arg2
        Bool (eqvPrim arg1 arg2 || unpackEqual)
    | argsList -&amp;gt; throw (NumArgs(2, argsList))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to define equality of packed primitive types. We do it nicely below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tryUnpacker (unpack : LispVal -&amp;gt; 'a) (op : 'a -&amp;gt; 'a -&amp;gt; bool) arg1 arg2 =
    try op (unpack arg1) (unpack arg2) with _ -&amp;gt; false
let numUnpackEq = tryUnpacker unpackNum (=)
let strUnpackEq = tryUnpacker unpackStr (=)
let boolUnpackEq = tryUnpacker unpackBool (=)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;em&gt;apply&lt;/em&gt; statement maps more or less directly to our &lt;em&gt;apply&lt;/em&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;applyProc = function
            | [func; List args] -&amp;gt; apply func args
            | func :: args -&amp;gt; apply func args
            | [] -&amp;gt; throw (Default(&amp;quot;Expecting a function, got an empty list&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we are left with the I/O processing functions. We are simply wrapping a FileStream in a Port.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let makePort fileAccess = fileIOFunction (fun fileName -&amp;gt;
                                File.Open(fileName,FileMode.OpenOrCreate, fileAccess) |&amp;gt; Port)
    let closePort = function
                    | [Port(port)] -&amp;gt; port.Close() ; Bool true
                    | _ -&amp;gt; Bool false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then can read and write from it. Notice how the lack of arguments makes us do it from the standard Console.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec readProc port =
    let parseReader (reader:TextReader) = reader.ReadLine() |&amp;gt; readExpr
    match port with
       | [] -&amp;gt; parseReader(System.Console.In)
       | [Port(port)] -&amp;gt;
            use reader = new StreamReader(port)
            parseReader (reader)
       | args -&amp;gt; throw (NumArgs(1, args))
let writeProc objPort =
    let write obj (writer: TextWriter) = writer.Write(showVal obj) ; Bool true
    match objPort with
    | [obj] -&amp;gt; write obj (System.Console.Out)
    | [obj ; Port(port)] -&amp;gt;
        use writer = new StreamWriter(port)
        write obj writer
    | args -&amp;gt; throw (NumArgs(1, args))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There you go. A full evaluator in two blog posts!! Next up, the parser.&lt;/p&gt;</description>
            <pubDate>Fri, 29 Jul 2011 07:26:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-07-29-write-yourself-a-scheme-in-48-hours-part-iv-2.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part IV</title>
            <link>https://www.lucabol.com/posts/2011-07-22-write-yourself-a-scheme-in-48-hours-part-iv.html</link>
            <description>&lt;p&gt;It is the evaluator turn. It is a big file, let&amp;rsquo;s see if I can fit it in a single post.&lt;/p&gt;
&lt;p&gt;Aptly enough, the most important function is called &lt;em&gt;eval&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;eval env = function
| String _ as v -&amp;gt; v
| Number _ as v -&amp;gt; v
| Bool _ as v -&amp;gt; v
| Atom var -&amp;gt; getVar var env
| List [Atom &amp;quot;quote&amp;quot;; v] -&amp;gt; v
| List [Atom &amp;quot;if&amp;quot;; pred; conseq; alt] -&amp;gt; evalIf env pred conseq alt
| List [Atom &amp;quot;load&amp;quot;; fileName] -&amp;gt; load [fileName] |&amp;gt; List.map (eval env) |&amp;gt; last
| List [Atom &amp;quot;set!&amp;quot; ; Atom var ; form] -&amp;gt; env |&amp;gt; setVar var (eval env form)
| List [Atom &amp;quot;define&amp;quot;; Atom var; form] -&amp;gt; define env var (eval env form)
| List (Atom &amp;quot;define&amp;quot; :: (List (Atom var :: parms) :: body)) -&amp;gt;
    makeNormalFunc env parms body |&amp;gt; define env var
| List (Atom &amp;quot;define&amp;quot; :: (DottedList ((Atom var :: parms), varargs) :: body)) -&amp;gt;
    makeVarargs varargs env parms body |&amp;gt; define env var
| List (Atom &amp;quot;lambda&amp;quot; :: (List parms :: body)) -&amp;gt; makeNormalFunc env parms body
| List (Atom &amp;quot;lambda&amp;quot; :: (DottedList(parms, varargs) :: body)) -&amp;gt; makeVarargs varargs env parms body
| List (Atom &amp;quot;lambda&amp;quot; :: ((Atom _) as varargs :: body)) -&amp;gt; makeVarargs varargs env [] body
| List (func :: args) -&amp;gt;
    let f = eval env func
    let argVals = List.map (eval env) args
    apply f argVals
| badForm -&amp;gt; throw (BadSpecialForm(&amp;quot;Unrecognized special form&amp;quot;, badForm))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the core of the evaluator. It takes as an input the LispVal generated by the parser and an environment and returns a LispVal that is the result of the reduction. As a side effect, it occasionally modify the environment. I carefully crafted the previous phrase to maximize the discomfort&amp;#160; of the functional programmers tuned in. Such fun 🙂&lt;/p&gt;
&lt;p&gt;More seriously (?), here is what it does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If it is a String, Number of Bool, just return it &lt;/li&gt;
&lt;li&gt;If it is an Atom, return its value &lt;/li&gt;
&lt;li&gt;If it is a &lt;em&gt;quote&lt;/em&gt;&amp;#160; statement, return what is quoted (read your little schemer manual) &lt;/li&gt;
&lt;li&gt;If it is an &lt;em&gt;if&lt;/em&gt; statement, evaluate it (see below) &lt;/li&gt;
&lt;li&gt;If it is a &lt;em&gt;load&lt;/em&gt; statement, load the file (see below) and evaluate each expression using the current environment. Return the last expression in the file &lt;/li&gt;
&lt;li&gt;If it is a &lt;em&gt;set!&lt;/em&gt;, set the value of the passed variable to the evaluated form &lt;/li&gt;
&lt;li&gt;If it is a &lt;em&gt;define&lt;/em&gt;, do almost the same as above (except that you don&amp;rsquo;t throw if the variable doesn&amp;rsquo;t exist, but you create it) &lt;/li&gt;
&lt;li&gt;If it is a &lt;em&gt;define&lt;/em&gt;&amp;#160; that defines a function (it has that shape), create a &amp;lsquo;function slot&amp;rsquo; in the environment. That is a (functionName,&amp;#160; FuncRecord) pair (see below) &lt;/li&gt;
&lt;li&gt;If it is a &lt;em&gt;lambda&lt;/em&gt;, return the FuncRecord that describe the inline function &lt;/li&gt;
&lt;li&gt;If it is a function call, evaluate the expression that describe the function (yes, you can do that in Lisp!!), evaluate the arguments, and apply the function to the arguments &lt;/li&gt;
&lt;li&gt;Otherwise, it must be a bad form, throw it back to the calling function to do something meaningful with it &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We have a bunch of &amp;lsquo;see below&amp;rsquo; to take care of. We&amp;rsquo;ll look at them in order.&lt;/p&gt;
&lt;p&gt;First the &amp;lsquo;if&amp;rsquo; statement. If the evaluated predicate is Bool(True) evaluate the consequent, otherwise evaluate the alternative. For some reason, I wrote it the other way around.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and
    // 1a. If the evaluation of the pred is false evaluate alt, else evaluate cons
    evalIf env pred conseq alt =
        match eval env pred with
        | Bool(false) -&amp;gt; eval env alt
        | _ -&amp;gt; eval env conseq
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then there is the &lt;em&gt;load&lt;/em&gt; function. It reads all the test and gets out the list of LispVal contained in it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let load = fileIOFunction (fun fileName -&amp;gt; File.ReadAllText(fileName)
                                           |&amp;gt; readExprList)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;ReadExprList&lt;/em&gt; is part of the parser. We&amp;rsquo;ll look at it then. Sufficient here to say that it takes a &lt;em&gt;string&lt;/em&gt; and returns a list of &lt;em&gt;LispVal&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;FileIOFunction&lt;/em&gt; just encapsulates a common pattern in all the file access functions. I don&amp;rsquo;t like such mechanical factorization of methods, without any real reusability outside the immediate surroundings of the code. But I like repetition even less.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let fileIOFunction func = function
    | [String fileName] -&amp;gt; func (fileName)
    | [] -&amp;gt; throw (IOError(&amp;quot;No file name&amp;quot;))
    | args -&amp;gt; throw (NumArgs(1, args))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A family of functions create FuncRecord given appropriate parameters. I seem to have lost memory of the contortions related to the last one. If I end up having to work again on this code, I&amp;rsquo;ll need to figure it out again. Note to myself, please comment this kind of code next time.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let makeFunc varargs env parms body =
            Func ({parms = (List.map showVal parms); varargs = varargs; body = body; closure = env})
let makeNormalFunc = makeFunc None
let makeVarargs = showVal &amp;gt;&amp;gt; Some &amp;gt;&amp;gt; makeFunc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;apply&lt;/em&gt; is the other workhorse function in the evaluator.&amp;#160; The best way to understand it is to start from the bottom (where &lt;em&gt;bindVars&lt;/em&gt; starts the line). We are binding the arguments and the variable arguments in the closure that has been passed in. We then evaluate the body. But the body is just a list of &lt;em&gt;LispVal&lt;/em&gt;, so we just need to evaluate them in sequence and return the result of the last one.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;and apply func args =
    match func with
    | PrimitiveFunc(f) -&amp;gt; f args
    | Func ({parms = parms; varargs = varargs; body = body; closure = closure}) -&amp;gt;
        let invalidNonVarargs = args.Length &amp;lt;&amp;gt; parms.Length &amp;amp;&amp;amp; varargs.IsNone
        let invalidVarargs = args.Length &amp;lt; parms.Length &amp;amp;&amp;amp; varargs.IsSome
        if invalidVarargs || invalidNonVarargs
        then
            throw (NumArgs(parms.Length, args))
        else
            let remainingArgs = args |&amp;gt; Seq.skip parms.Length |&amp;gt; Seq.toList
            let evalBody env = body |&amp;gt; List.map (eval env) |&amp;gt; last
            let rec zip xs1 xs2 acc =
                match xs1, xs2 with
                | x1::xs1, x2::xs2 -&amp;gt; zip xs1 xs2 ((x1, x2)::acc)
                | _ -&amp;gt; acc
            let bindVarArgs arg env =
                match arg with
                | Some(argName) -&amp;gt; bindVars [argName, (List remainingArgs)] env
                | None -&amp;gt; env
            bindVars (zip parms args []) closure
                |&amp;gt; bindVarArgs varargs
                |&amp;gt; evalBody
    | funcName -&amp;gt; throw (NotFunction(&amp;quot;Expecting a function, getting &amp;quot;, showVal funcName))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is enough for one post. Next time we&amp;rsquo;ll finish the evaluator.&lt;/p&gt;</description>
            <pubDate>Fri, 22 Jul 2011 07:52:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-07-22-write-yourself-a-scheme-in-48-hours-part-iv.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part III</title>
            <link>https://www.lucabol.com/posts/2011-07-15-write-yourself-a-scheme-in-48-hours-in-f-part-iii.html</link>
            <description>&lt;p&gt;Very often my code ends up having the following form: parse an input to create an intermediate data structure and evaluate the structure to produce an output. Strangely, many years ago, when my code was object oriented, that wasn&amp;rsquo;t the case. Or at least I wasn&amp;rsquo;t explicitly aware of it.&lt;/p&gt;
&lt;p&gt;When you write an interpreter or a compiler, things always work out like that, but I see the same pattern in almost everything I produce: from financial backtesting to chart libraries. Sometimes when, out of laziness or stupidity, I forego the intermediate structure, I end up in the end having to retrofit it in. Simply processing input and generating output at the same time rarely cuts it. But it is tempting because you get going pretty fast and I&amp;rsquo;m tricked into it occasionally.&lt;/p&gt;
&lt;p&gt;Hence the first thing that I find myself reasoning about is often the particular form of such intermediate structure. In this case it looks like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Env = (string * LispVal ref) list ref
and FuncRecord = { parms: string list; varargs: string option; body: LispVal list; closure: Env}
and LispVal =
    | Atom of string
    | List of LispVal list
    | DottedList of LispVal list * LispVal
    | Number of int
    | String of string
    | Bool of bool
    | PrimitiveFunc of (LispVal list -&amp;gt; LispVal)
    | Func of FuncRecord
    | Port of System.IO.FileStream
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;em&gt;LispVal&lt;/em&gt; structure has one constructor for each kind of expression (production) that is allowed in Scheme. Or at least that ones I support …&lt;/p&gt;
&lt;p&gt;It is important that each one stores all the information that is necessary for the evaluator to evaluate the expression. No more, no less. Here is a brief description:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Atom&lt;/strong&gt;: it is a kind of a constant in Scheme. This is probably the worst definition ever given for it. Please read about it in your little schemer book.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;List&lt;/strong&gt;: is the main Scheme type. It represents a list of expressions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DottedList&lt;/strong&gt;: this is the bizarre Scheme way to pass optional parameters&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Number&lt;/strong&gt;: is a number 🙂 You will discover which kind of number when we talk about the parser&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;String&lt;/strong&gt; : is a string&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bool&lt;/strong&gt;: #t, #f&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PrimitiveFunc&lt;/strong&gt;: is the representation for the primitive operators/functions that are burned into the interpreter. It is just a function that takes a list of LispVal and returns a LispVal&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Func&lt;/strong&gt;: is a user defined function. Notice that the body of it is simply a list of LispVal. This is why LISP is so powerful. Also notice that a closure gets passed to it for the &amp;lsquo;captured&amp;rsquo; variables.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Port&lt;/strong&gt;: is a slightly goofy representation of an in/out stream&lt;/li&gt;
&lt;li&gt;Anything else (i.e. macros) is not supported, but this would be the first piece to change if they were.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only remaining code to address is: &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Env = (string * LispVal ref) list ref
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the symbol table and it is ugly. It is not multithread safe either. But it works and it is close enough to the Haskell version so I decided to retain it. A proper code review would &amp;lsquo;strongly suggest&amp;rsquo; rewriting the code to pass it around to each function instead of using &amp;lsquo;ref&amp;rsquo; or using the state monad encapsulated in a computation expression. Any of these solutions is left as an exercise to the reader (use the testcases to validate that you get it right).&lt;/p&gt;
&lt;p&gt;We could go in many different direction from here. We could talk about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The evaluator&lt;/li&gt;
&lt;li&gt;The parser&lt;/li&gt;
&lt;li&gt;The symbol table&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To keep with the top – down approach I&amp;rsquo;ve been espousing. I&amp;rsquo;ll probably talk about the evaluator next.&lt;/p&gt;</description>
            <pubDate>Fri, 15 Jul 2011 07:12:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-07-15-write-yourself-a-scheme-in-48-hours-in-f-part-iii.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part II</title>
            <link>https://www.lucabol.com/posts/2011-07-08-write-yourself-a-scheme-in-48-hours-in-f-part-ii.html</link>
            <description>&lt;p&gt;Usually, when I do blog posts that are all about code, I write them &amp;lsquo;bottom up&amp;rsquo;. I start talking about the most primitive types and functions and build up from there toward higher abstractions. I think this is a pretty common way of doing it.&lt;/p&gt;
&lt;p&gt;For this series I&amp;rsquo;m going to try the opposite. I start with the code that creates the REPL window and move down from there toward the guts of the interpreter. I hold the opinion that, if the code is written right, this should be ok. The naming scheme and general structure of it should allow understanding it at different levels.&lt;/p&gt;
&lt;p&gt;Or at least I hope so.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start from the &lt;em&gt;main&lt;/em&gt; function. Depending on the number of arguments it either runs the REPL window or executes whatever is in the file passed in as the first argument using the other arguments as parameters.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;[&amp;lt;EntryPoint&amp;gt;]
let main(args: string[]) =
    match Array.toList args with
    | [] -&amp;gt; runRepl ()
    | filename :: args -&amp;gt; runOne filename args
    0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The latter case is coded in the below function. It first load all the primitive operators (i.e. &amp;lsquo;+&amp;rsquo;, &amp;lsquo;-&amp;rsquo; etc…) and the standard library. The word &amp;lsquo;load&amp;rsquo; above is a little misleading. In reality it adds them to the environment. It then proceeds to add the arguments that were passed on. As the last step, it evaluates the &amp;lsquo;load&amp;rsquo; command by using the newly created environment, it transforms the returned token to a string and prints it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let runOne (filename : string) (args : list&amp;lt;string&amp;gt;) =
    let env = primitiveBindings ()
                |&amp;gt; loadStdLib
                |&amp;gt; bindVars [ &amp;quot;args&amp;quot;, List (List.map String args) ]
    List [Atom &amp;quot;load&amp;quot;; String filename] |&amp;gt; eval env |&amp;gt; showVal |&amp;gt; printStr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the REPL windows is equally simple. Load the primitive operators and the standard library, show a prompt and evaluate the input until the input is &amp;lsquo;Quit&amp;rsquo;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let runRepl () =
    let env = primitiveBindings () |&amp;gt; loadStdLib
    until (fun s -&amp;gt; s = &amp;quot;Quit&amp;quot; || s = &amp;quot;quit&amp;quot;) (fun () -&amp;gt; readPrompt &amp;quot;Lisp&amp;gt;&amp;gt;&amp;gt; &amp;quot;) (evalAndPrint env)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;readPrompt&lt;/em&gt; is pretty simple:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let printStr (s: string) = Console.Write(s)
let readPrompt (s: string) = printStr s ; Console.ReadLine ()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;EvalAndPrint&lt;/em&gt; is written as a chain of functions (lookup the &amp;lsquo;&amp;gt;&amp;gt;&amp;rsquo; operator in F#) and just evaluate the string, transform the result to a string, prints it and newline it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let newLine () = Console.WriteLine()
let evalAndPrint env = evalString env &amp;gt;&amp;gt; showVal &amp;gt;&amp;gt; printStr &amp;gt;&amp;gt; newLine
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;evalString&lt;/em&gt; parses the string and evaluates the expression. Note the exception management. This is a result of my decision of throwing an exception every time something goes wrong instead of using a monad to pass the state around. I think it is pretty clear, but haskellers might disagre. This is one of the main differences from the Haskell version.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let evalString env expr =
    try
        expr |&amp;gt; readExpr |&amp;gt; eval env
    with
    | LispException(error) -&amp;gt; String (showError error)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the sake of completeness, here is &lt;em&gt;until&lt;/em&gt;. Maybe there is a library function somewhere that I could have used?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec until pred prompter evaluator =
    let result = prompter ()
    if not (pred result) then
        evaluator result
        until pred prompter evaluator
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Back on the main flow of the code, &lt;em&gt;loadStdLib&lt;/em&gt; just loads the standard file and returns the populated environment.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadStdLib env =
    eval env (List [Atom &amp;quot;load&amp;quot;; String &amp;quot;stdlib.scm&amp;quot;]) |&amp;gt; ignore
    env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;primitiveBindings creates a new empty environment and adds a bunch of pairs (primitiveName, LispVal –&amp;gt; LispVal). LispVal is a representation of a Scheme expression, so the second part of the tuple is simply a reduction from one expression to another (hopefully simpler in some sense). We&amp;rsquo;ll talk more about LispVal in upcoming posts.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let primitiveBindings () =
    (nullEnv ()) |&amp;gt; bindVars [ for v, f in primitives -&amp;gt; v, PrimitiveFunc f ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There you have it. That&amp;rsquo;s the full implementation for the REPL window. Next post, we&amp;rsquo;ll look at LispEval and the evaluator.&lt;/p&gt;</description>
            <pubDate>Fri, 08 Jul 2011 07:01:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-07-08-write-yourself-a-scheme-in-48-hours-in-f-part-ii.html</guid>
        </item>
        
        <item>
            <title>Write Yourself a Scheme in 48 Hours in F# – Part I</title>
            <link>https://www.lucabol.com/posts/2011-06-30-write-yourself-a-scheme-in-48-hours-in-f-part-i.html</link>
            <description>&lt;p&gt;Hi, I&amp;rsquo;m back. I&amp;rsquo;ve finally sorted out the guidelines for blogging in Credit Suisse. &lt;/p&gt;
&lt;p&gt;Here is something I have been playing around with in the spare time between one meeting and the next one.&amp;#160; It is a Scheme interpreter that includes a REPL window. The full code is &lt;a href="http://code.msdn.microsoft.com/Write-Yourself-a-Scheme-in-d50ae449"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All the smarts for it come from &lt;a href="http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours"&gt;this Wiki Book&lt;/a&gt;. I just ported the code to F# (and modified it a bit). I thought the comparison might be interesting, so here we go. Thanks to &lt;a href="http://gedell.net/"&gt;Tobias&lt;/a&gt; and &lt;a href="http://www.haskellers.com/user/pepeiborra"&gt;Jose&lt;/a&gt; for reviewing the code, find one bug and suggest improvements.&lt;/p&gt;
&lt;p&gt;Before we start looking at the real code, here is what we are trying to accomplish in form of test cases. If you are a bit rusty on LISP syntax, you might want to try and see if you understand what it does.&lt;/p&gt;
&lt;p&gt;Our goal is to make all this XUnit test cases pass. Each of the lists below contains the Scheme statement and the result to display in the REPL window.&lt;/p&gt;
&lt;p&gt;```fsharp
open Xunit
open Lisp.Repl
open Lisp.Parser
open Lisp.SymbolTable
let eval env = evalString env &amp;gt;&amp;gt; showVal
let initEnv () = primitiveBindings () |&amp;gt; loadStdLib
let test tests =
    let env = initEnv ()
    tests |&amp;gt; List.iter (fun (expr, result) -&amp;gt; Assert.Equal(result, eval env expr))
[&lt;Fact&gt;]
let simpleEval() =
    let tests = [
        &amp;ldquo;(+ 2 2)&amp;rdquo;, &amp;ldquo;4&amp;rdquo;
        &amp;ldquo;(+ 2 (- 4 1))&amp;rdquo;, &amp;ldquo;5&amp;rdquo;
        &amp;ldquo;(- (+ 4 6 3) 3 5 2)&amp;rdquo;, &amp;ldquo;3&amp;rdquo;
    ]
    test tests
[&lt;Fact&gt;]
let errorCheck() =
    let tests = [
         &amp;ldquo;(+ 2 "two")&amp;rdquo;, &amp;ldquo;"Invalid type: expected number, found "two""&amp;rdquo;
         &amp;ldquo;(+ 2)&amp;rdquo;, &amp;ldquo;"Expected 2 args; found values 2"&amp;rdquo;
         &amp;ldquo;(what? 2)&amp;rdquo;, &amp;ldquo;"Getting an unbound variable: what?"&amp;rdquo;
         ]
    test tests
[&lt;Fact&gt;]
let moreEval() =
    let tests = [
         &amp;ldquo;(&amp;lt; 2 3)&amp;rdquo;, &amp;ldquo;#t&amp;rdquo;
         &amp;ldquo;(&amp;gt; 2 3)&amp;rdquo;, &amp;ldquo;#f&amp;rdquo;
         &amp;ldquo;(&amp;gt;= 3 3)&amp;rdquo;, &amp;ldquo;#t&amp;rdquo;
         &amp;ldquo;(string=? "test" "test")&amp;rdquo;, &amp;ldquo;#t&amp;rdquo;
         &amp;ldquo;(string=? "abcd" "dsft")&amp;rdquo;, &amp;ldquo;#f&amp;rdquo;
         &amp;ldquo;(if (&amp;gt; 2 3) "no" "yes")&amp;rdquo;, &amp;ldquo;"yes"&amp;rdquo;
         &amp;ldquo;(if (= 3 3) (+ 2 3 (- 5 1)) "unequal")&amp;rdquo;, &amp;ldquo;9&amp;rdquo;
         &amp;ldquo;(cdr &amp;lsquo;(a simple test))&amp;rdquo;, &amp;ldquo;(simple test)&amp;rdquo;
         &amp;ldquo;(car (cdr &amp;lsquo;(a simple test)))&amp;rdquo;, &amp;ldquo;simple&amp;rdquo;
         &amp;ldquo;(car &amp;lsquo;((this is) a test))&amp;rdquo;, &amp;ldquo;(this is)&amp;rdquo;
         &amp;ldquo;(cons &amp;lsquo;(this is) &amp;lsquo;test)&amp;rdquo;, &amp;ldquo;((this is) . test)&amp;rdquo;
         &amp;ldquo;(cons &amp;lsquo;(this is) &amp;lsquo;())&amp;rdquo;, &amp;ldquo;((this is))&amp;rdquo;
         &amp;ldquo;(eqv? 1 3)&amp;rdquo;, &amp;ldquo;#f&amp;rdquo;
         &amp;ldquo;(eqv? 3 3)&amp;rdquo;, &amp;ldquo;#t&amp;rdquo;
         &amp;ldquo;(eqv? &amp;lsquo;atom &amp;lsquo;atom)&amp;rdquo;, &amp;ldquo;#t&amp;rdquo;
         ]
    test tests
[&lt;Fact&gt;]
let assignement() =
    let tests = [
        &amp;ldquo;(define x 3)&amp;rdquo;, &amp;ldquo;3&amp;rdquo;
        &amp;ldquo;(+ x 2)&amp;rdquo;, &amp;ldquo;5&amp;rdquo;
        &amp;ldquo;(+ y 2)&amp;rdquo;, &amp;ldquo;"Getting an unbound variable: y"&amp;rdquo;
        &amp;ldquo;(define y 5)&amp;rdquo;, &amp;ldquo;5&amp;rdquo;
        &amp;ldquo;(+ x (- y 2))&amp;rdquo;, &amp;ldquo;6&amp;rdquo;
        &amp;ldquo;(define str "A string")&amp;rdquo;, &amp;ldquo;"A string"&amp;rdquo;
        &amp;ldquo;(&amp;lt; str "The string")&amp;rdquo;, &amp;ldquo;"Invalid type: expected number, found "A string""&amp;rdquo;
        &amp;ldquo;(string&amp;lt;? str "The string")&amp;rdquo;, &amp;ldquo;#t&amp;rdquo;
         ]
    test tests
[&lt;Fact&gt;]
let closure() =
    let tests = [
        &amp;ldquo;(define (f x y) (+ x y))&amp;rdquo;, &amp;ldquo;(lambda ("x" "y") &amp;hellip;)&amp;rdquo;
        &amp;ldquo;(f 1 2)&amp;rdquo;, &amp;ldquo;3&amp;rdquo;
        &amp;ldquo;(f 1 2 3)&amp;rdquo;, &amp;ldquo;"Expected 2 args; found values 1 2 3"&amp;rdquo;
        &amp;ldquo;(define (factorial x) (if (= x 1) 1 (&lt;em&gt; x (factorial (- x 1)))))&amp;rdquo;, &amp;ldquo;(lambda ("x") &amp;hellip;)&amp;rdquo;
        &amp;ldquo;(factorial 10)&amp;rdquo;, &amp;ldquo;3628800&amp;rdquo;
        &amp;ldquo;(define (counter inc) (lambda (x) (set! inc (+ x inc)) inc))&amp;rdquo;, &amp;ldquo;(lambda ("inc") &amp;hellip;)&amp;rdquo;
        &amp;ldquo;(define my-count (counter 5))&amp;rdquo;, &amp;ldquo;(lambda ("x") &amp;hellip;)&amp;rdquo;
        &amp;ldquo;(my-count 3)&amp;rdquo;, &amp;ldquo;8&amp;rdquo;
        &amp;ldquo;(my-count 6)&amp;rdquo;, &amp;ldquo;14&amp;rdquo;
        &amp;ldquo;(my-count 5)&amp;rdquo;, &amp;ldquo;19&amp;rdquo;
         ]
    test tests
[&lt;Fact&gt;]
let predefinedFunctions() =
    let tests = [
        &amp;ldquo;(map (curry + 2) &amp;lsquo;(1 2 3 4))&amp;rdquo;, &amp;ldquo;(3 4 5 6)&amp;rdquo;
        &amp;ldquo;(filter even? &amp;lsquo;(1 2 3 4))&amp;rdquo;, &amp;ldquo;(2 4)&amp;rdquo;
        ]
    test tests
[&lt;Fact&gt;]
let varargsCountCheck() =
    let tests = [
        &amp;ldquo;(define (sum x y . lst) (fold + (&lt;/em&gt; x y) lst))&amp;rdquo;, &amp;ldquo;(lambda ("x" "y" . lst) &amp;hellip;)&amp;rdquo;
        &amp;ldquo;(sum 1 2 3)&amp;rdquo;, &amp;ldquo;5&amp;rdquo;
        &amp;ldquo;(sum 1 1 1)&amp;rdquo;, &amp;ldquo;2&amp;rdquo;
        &amp;ldquo;(sum 1 2)&amp;rdquo;, &amp;ldquo;2&amp;rdquo;
        &amp;ldquo;(sum 1)&amp;rdquo;, &amp;ldquo;"Expected 2 args; found values 1"&amp;rdquo;
         ]
    test tests&lt;/p&gt;</description>
            <pubDate>Thu, 30 Jun 2011 15:41:12 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2011-06-30-write-yourself-a-scheme-in-48-hours-in-f-part-i.html</guid>
        </item>
        
        <item>
            <title>I have been DEEP FRIED!</title>
            <link>https://www.lucabol.com/posts/2010-03-31-i-have-been-deep-fried.html</link>
            <description>&lt;p&gt;&lt;img class="alignleft" title="Deep Fried Bytes logo" src="https://deepfriedbytes.com/files/media/image/WindowsLiveWriter/Media_8AE9/image_12.png" alt="Logo" width="250" height="102" /&gt;Yep, &lt;a href="https://deepfriedbytes.com/podcast/episode-50-behind-the-scenes-of-the-net-languages-with-luca-bolognese/" target="_self"&gt;here &lt;/a&gt;is my interview with the Deep Fried Bytes guys on various software topics. Enjoy.&lt;/p&gt;</description>
            <pubDate>Wed, 31 Mar 2010 20:50:32 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-03-31-i-have-been-deep-fried.html</guid>
        </item>
        
        <item>
            <title>Tracking spread trades in F# (and WPF MVVM) – Part II</title>
            <link>https://www.lucabol.com/posts/2010-03-19-tracking-spread-trades-in-f-and-wpf-mvvm-part-ii.html</link>
            <description>&lt;p&gt;I wanted to experiment with MVVM and WPF in F#, so I decided to create a little graphical interface for the csv file that drives the spread tracking application. When I started I thought I needed some kind of a grid with Submit/Cancel buttons, but the more I thought about it, the more I realized that I wouldn&amp;rsquo;t need them.&lt;/p&gt;
&lt;p&gt;See, I&amp;rsquo;ve always be one to complain about our current paradigm of Open File / Close File / Save File arguing that the user shouldn&amp;rsquo;t know about an entity called &amp;lsquo;file&amp;rsquo;. He shouldn&amp;rsquo;t be exposed to the fact that the application is just an in-memory copy of an hard disk artifact. His mental model should simply be: I open a document, I work on it, I close it, if needed I can make a copy; if I have problems I can revert to a previous version of the same document; If I make an error I can use &amp;lsquo;undo&amp;rsquo; to revert it. There are no files/save/submit/cancel in such paradigm. There is no file system.&lt;/p&gt;
&lt;p&gt;On the technical side I wanted to experiment with MVVM, even if in this case, the paradigm is overkilled (can really use this word?), given the simplicity of the application.&lt;/p&gt;
&lt;p&gt;In any case, the ViewModel is in F#. It uses two utility classes:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;// TODO: refactor to remove code repetition below
[&amp;lt;AbstractClass&amp;gt;]
type ViewModelBase () =
    let propertyChanged = new Event&amp;lt;PropertyChangedEventHandler, PropertyChangedEventArgs&amp;gt;()
    interface INotifyPropertyChanged with
        [&amp;lt;CLIEvent&amp;gt;]
        member this.PropertyChanged = propertyChanged.Publish
    member internal this.RaisePropertyChangedEvent(propertyName:string) =
        if not(propertyName = null) then
            let e = new PropertyChangedEventArgs(propertyName)
            let i = this :&amp;gt; INotifyPropertyChanged
            propertyChanged.Trigger(this, e)
type ObservableCollectionWithChanges&amp;lt;'a when 'a :&amp;gt; INotifyPropertyChanged&amp;gt; () =
    inherit ObservableCollection&amp;lt;'a&amp;gt; ()
    let propertyChanged = new Event&amp;lt;PropertyChangedEventHandler, PropertyChangedEventArgs&amp;gt;()
    member c.PropertyChanged = propertyChanged.Publish
    member private c.RaisePropertyChangedEvent(propertyName:string) =
        if not(propertyName = null) then
            let e = new PropertyChangedEventArgs(propertyName)
            let i = c :&amp;gt; INotifyPropertyChanged
            propertyChanged.Trigger(c, e)
    member c.Add(o) =
        base.Add(o)
        o.PropertyChanged.Add(fun x -&amp;gt; c.RaisePropertyChangedEvent(&amp;quot;&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first one is used as a base for all the viewmodel entities in the application, the second one serves as the base for all the collections. They both define the customary &lt;em&gt;PropertyChanged&lt;/em&gt; event. The latter adds itself as an observer to each object added to the collection so that, whenever one changes, it gets notified and can notify its own observers. Look at the &lt;em&gt;c.Add&lt;/em&gt; method. A lot of repetitive code here, I would heed the advice of the comment on top if this were production code.&lt;/p&gt;
&lt;p&gt;Each line in the csv file is represented as a ResultViewModel, hence the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type ResultViewModel (d:DateTime, sLong, sShort, tStop) =
    inherit ViewModelBase ()
    let mutable date = d
    let mutable stockLong = sLong
    let mutable stockShort = sShort
    let mutable trailingStop = tStop
    new () = new ResultViewModel(DateTime.Today, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, 0)
    member r.Date with get() = date
                       and set newValue =
                            date &amp;lt;- newValue
                            base.RaisePropertyChangedEvent(&amp;quot;Date&amp;quot;)
    member r.StockLong with get() = stockLong
                       and set newValue =
                            stockLong &amp;lt;- newValue
                            base.RaisePropertyChangedEvent(&amp;quot;StockLong&amp;quot;)
    member r.StockShort with get() = stockShort
                        and set newValue =
                            stockShort &amp;lt;- newValue
                            base.RaisePropertyChangedEvent(&amp;quot;StockShort&amp;quot;)
    member r.TrailingStop with get() =
                                trailingStop
                          and set newValue =
                                trailingStop &amp;lt;- newValue
                                base.RaisePropertyChangedEvent(&amp;quot;TrailingStop&amp;quot;)
    member r.IsThereAnError = r.TrailingStop &amp;lt; 0 || r.TrailingStop &amp;gt; 100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I need the empty constructor to be able to hook up to the DataGrid add-new capability. There might be an event I could use instead, but this is simple enough (even if a bit goofy).&lt;/p&gt;
&lt;p&gt;The main view model class then looks like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type MainViewModel (fileName:string) as self =
    inherit ViewModelBase ()
    let mutable results = new ObservableCollectionWithChanges&amp;lt;ResultViewModel&amp;gt;()
    let loadResults () =
        parseFile fileName
        |&amp;gt; Array.iter (fun (d,sl, ss, ts) -&amp;gt;
                        results.Add(new ResultViewModel(d, sl, ss, ts)))
    do
        loadResults ()
        results.CollectionChanged.Add(fun e -&amp;gt; self.WriteResults())
        results.PropertyChanged.Add(fun e -&amp;gt; self.WriteResults())
    member m.Results with get() = results
                     and set newValue =
                        results &amp;lt;- newValue
                        base.RaisePropertyChangedEvent(&amp;quot;Results&amp;quot;)
    member m.WriteResults () =
        let rs = results
                 |&amp;gt; Seq.map (fun r -&amp;gt; r.Date, r.StockLong, r.StockShort, r.TrailingStop)
        let thereAreErrors = results |&amp;gt; Seq.exists (fun r -&amp;gt; r.IsThereAnError)
        if not thereAreErrors then
            writeFile fileName rs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Things here are more interesting. First of all, in the constructor I load the results calling my model (which I created in &lt;a href="http://lucabolognese.wordpress.com/2010/03/13/tracking-spread-trades-in-f-and-hooking-up-xunit-and-fscheck-part-1/"&gt;Part I&lt;/a&gt; of this series). I then subscribe to both the events fired by the collection of results. The former is triggered when an object is added/removed, the latter is triggered when an object changes one of its properties. When one of them fires, I simply write the new state back to the file. This allows me to get rid of Submit/Cancel buttons. What the user sees on the screen is synchronized with the disk at all times. The user doesn&amp;rsquo;t need to know about the file system.&lt;/p&gt;
&lt;p&gt;If this were real, I would also implement an undo/redo mechanism. In such case, my reliance on object events might be unwise. I would probably route all the user changes through a command mechanism, so that they can be undo more easily.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it for the modelview. The View itself is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;Window x:Class=&amp;quot;SpreadTradingWPF.MainWindow&amp;quot;
        xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
        xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
        xmlns:spreadTrading=&amp;quot;clr-namespace:SpreadTradingWPF&amp;quot;
        Title=&amp;quot;Spread Trading&amp;quot; Height=&amp;quot;350&amp;quot; Width=&amp;quot;525&amp;quot; SizeToContent=&amp;quot;WidthAndHeight&amp;quot;&amp;gt;
        &amp;lt;Window.Resources&amp;gt;
            &amp;lt;spreadTrading:DateToShortStringConverter x:Key=&amp;quot;DateToShortStringC&amp;quot; /&amp;gt;
            &amp;lt;LinearGradientBrush x:Key=&amp;quot;BlueLightGradientBrush&amp;quot; StartPoint=&amp;quot;0,0&amp;quot; EndPoint=&amp;quot;0,1&amp;quot;&amp;gt;
                    &amp;lt;GradientStop Offset=&amp;quot;0&amp;quot; Color=&amp;quot;#FFEAF3FF&amp;quot;/&amp;gt;
                    &amp;lt;GradientStop Offset=&amp;quot;0.654&amp;quot; Color=&amp;quot;#FFC0DEFF&amp;quot;/&amp;gt;
                    &amp;lt;GradientStop Offset=&amp;quot;1&amp;quot; Color=&amp;quot;#FFC0D9FB&amp;quot;/&amp;gt;
            &amp;lt;/LinearGradientBrush&amp;gt;
            &amp;lt;Style TargetType=&amp;quot;{x:Type DataGrid}&amp;quot;&amp;gt;
                &amp;lt;Setter Property=&amp;quot;Margin&amp;quot; Value=&amp;quot;5&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;Background&amp;quot; Value=&amp;quot;{StaticResource BlueLightGradientBrush}&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;BorderBrush&amp;quot; Value=&amp;quot;#FFA6CCF2&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;RowBackground&amp;quot; Value=&amp;quot;White&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;AlternatingRowBackground&amp;quot; Value=&amp;quot;#FDFFD0&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;HorizontalGridLinesBrush&amp;quot; Value=&amp;quot;Transparent&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;VerticalGridLinesBrush&amp;quot; Value=&amp;quot;#FFD3D0&amp;quot; /&amp;gt;
                &amp;lt;Setter Property=&amp;quot;RowHeaderWidth&amp;quot; Value=&amp;quot;20&amp;quot; /&amp;gt;
            &amp;lt;/Style&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
        &amp;lt;StackPanel HorizontalAlignment=&amp;quot;Center&amp;quot; Name=&amp;quot;stackPanel1&amp;quot; VerticalAlignment=&amp;quot;Top&amp;quot; Margin=&amp;quot;20&amp;quot;&amp;gt;
            &amp;lt;TextBlock Text=&amp;quot;Spread Trading&amp;quot; Width=&amp;quot;135&amp;quot; HorizontalAlignment=&amp;quot;Center&amp;quot; FontSize=&amp;quot;18&amp;quot; FontWeight=&amp;quot;Bold&amp;quot; FontStretch=&amp;quot;ExtraExpanded&amp;quot; /&amp;gt;
            &amp;lt;DataGrid Height=&amp;quot;Auto&amp;quot; Width=&amp;quot;Auto&amp;quot; Margin=&amp;quot;5&amp;quot; ItemsSource=&amp;quot;{Binding Results}&amp;quot; CanUserAddRows =&amp;quot;True&amp;quot; CanUserDeleteRows=&amp;quot;True&amp;quot; AutoGenerateColumns=&amp;quot;False&amp;quot;&amp;gt;
                &amp;lt;DataGrid.RowValidationRules&amp;gt;
                    &amp;lt;spreadTrading:ResultValidationRule ValidationStep=&amp;quot;UpdatedValue&amp;quot;/&amp;gt;
                &amp;lt;/DataGrid.RowValidationRules&amp;gt;
                &amp;lt;DataGrid.RowValidationErrorTemplate&amp;gt;
                    &amp;lt;ControlTemplate&amp;gt;
                        &amp;lt;Grid Margin=&amp;quot;0,-2,0,-2&amp;quot;
                              ToolTip=&amp;quot;{Binding RelativeSource={RelativeSource
                              FindAncestor, AncestorType={x:Type DataGridRow}},
                              Path=(Validation.Errors)[].ErrorContent}&amp;quot;&amp;gt;
                            &amp;lt;Ellipse StrokeThickness=&amp;quot;0&amp;quot; Fill=&amp;quot;Red&amp;quot;
                                Width=&amp;quot;{TemplateBinding FontSize}&amp;quot;
                                Height=&amp;quot;{TemplateBinding FontSize}&amp;quot; /&amp;gt;
                            &amp;lt;TextBlock Text=&amp;quot;!&amp;quot; FontSize=&amp;quot;{TemplateBinding FontSize}&amp;quot;
                                FontWeight=&amp;quot;Bold&amp;quot; Foreground=&amp;quot;White&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot;  /&amp;gt;
                        &amp;lt;/Grid&amp;gt;
                    &amp;lt;/ControlTemplate&amp;gt;
                &amp;lt;/DataGrid.RowValidationErrorTemplate&amp;gt;
            &amp;lt;DataGrid.Columns&amp;gt;
                    &amp;lt;DataGridTextColumn Header=&amp;quot;Date&amp;quot; Binding=&amp;quot;{Binding Date, Converter= {StaticResource DateToShortStringC}}&amp;quot;  IsReadOnly=&amp;quot;false&amp;quot;/&amp;gt;
                    &amp;lt;DataGridTextColumn Header=&amp;quot;Long&amp;quot; Binding=&amp;quot;{Binding StockLong}&amp;quot;/&amp;gt;
                    &amp;lt;DataGridTextColumn Header=&amp;quot;Short&amp;quot; Binding=&amp;quot;{Binding StockShort}&amp;quot; /&amp;gt;
                    &amp;lt;DataGridTextColumn Header=&amp;quot;Stop&amp;quot; Binding=&amp;quot;{Binding TrailingStop}&amp;quot; /&amp;gt;
            &amp;lt;/DataGrid.Columns&amp;gt;
            &amp;lt;/DataGrid&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that I styled the grid and I used the right incantations to get validation errors and to bind things properly. The &lt;em&gt;DateToShortString&lt;/em&gt; converter used for the date field might be mildly interesting. It&amp;rsquo;s in the &lt;em&gt;Utilities.cs&lt;/em&gt; file together with a validation rule that just delegates to the &lt;em&gt;IsThereAnError&lt;/em&gt; method on each entity. In a bigger application, you could write this code in a much more reusable way.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[ValueConversion(typeof (DateTime), typeof (string))]
public class DateToShortStringConverter : IValueConverter
{
public Object Convert(
        Object value,
        Type targetType,
        Object parameter,
        CultureInfo culture)
{
    var date = (DateTime) value;
    return date.ToShortDateString();
}
public object ConvertBack(
    object value,
    Type targetType,
    object parameter,
    CultureInfo culture)
    {
        string strValue = value as string;
        DateTime resultDateTime;
        if (DateTime.TryParse(strValue, out resultDateTime))
        {
            return resultDateTime;
        }
        return DependencyProperty.UnsetValue;
    }
}
public class ResultValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        var result = (value as BindingGroup).Items[0] as ResultViewModel;
        if(result.IsThereAnError)
            return new ValidationResult(false, &amp;quot;TrailingStop must be between 0 and 100&amp;quot;);
        else
            return ValidationResult.ValidResult;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After all these niceties, this is what you get.&lt;/p&gt;
&lt;p&gt;&lt;a href="/img/spread-trades1.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="/img/spread-trades1.png" width="244" height="219" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Fri, 19 Mar 2010 23:33:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-03-19-tracking-spread-trades-in-f-and-wpf-mvvm-part-ii.html</guid>
        </item>
        
        <item>
            <title>Tracking spread trades in F# (and hooking up XUnit and FsCheck) – Part 1</title>
            <link>https://www.lucabol.com/posts/2010-03-13-tracking-spread-trades-in-f-and-hooking-up-xunit-and-fscheck-part-1.html</link>
            <description>&lt;p&gt;I have a bunch of spread trades open. Spread trades are trades where you buy something and you sell something else generally in the same amount. You hope to profit from the widening of the spread between the price of the two instruments.&lt;/p&gt;
&lt;p&gt;I place stop loss orders or trailing stops for all my trades. I have various tool that automatically notify me when a stop loss or trailing stop is hit. For spread trades I don&amp;rsquo;t have such a tool, hence I decided to build it.&lt;/p&gt;
&lt;p&gt;I defined maximum adverse excursion for a spread trade as the percentage difference between the current value of &amp;lsquo;long price&amp;rsquo; / &amp;lsquo;short price&amp;rsquo; and its maximum value from the point the trade was placed (aka Current(&amp;lsquo;long price&amp;rsquo; / &amp;lsquo;short price&amp;rsquo;) / max (&amp;lsquo;long price&amp;rsquo; / &amp;lsquo;short price&amp;rsquo;) – 1 ). This goes from 0 to 100. If the maximum adverse excursion is larger than the trailing stop (using closing prices only), then I want to be notified by email.&lt;/p&gt;
&lt;p&gt;I decided to create a simple exe and use Task Scheduler to run it at the end of the trading day. The program reads a file with all the open spread trades, downloads their prices, calculates maximum adverse excursion and sends an email if it is larger than the trailing stop. I also built a little WPF veneer to manipulate the configuration file.&lt;/p&gt;
&lt;p&gt;Here is what my &lt;em&gt;common.fs&lt;/em&gt; file looks like.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;namespace Spread
module internal Common =
    open System
    let internal isValidDate s =
        let v, _ = DateTime.TryParse(s)
        v
    let internal isValidTrailingStop s =
        let v1, n = Int32.TryParse(s)
        if not(v1) then
            false
        else
            n &amp;gt;= 0 &amp;amp;&amp;amp; n &amp;lt;= 100
    let internal isValidTicker (t:string) = not(t.Contains(&amp;quot;,&amp;quot;))
    let internal isValidLine (l:string) = l.Split([|','|]).Length = 4
    let internal elseThrow message expression = if not(expression) then raise message
    let internal elseThrowi i message expression = if not(expression) then failwith (sprintf &amp;quot;On line %i : %s&amp;quot; i message)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the &lt;em&gt;isValidTicker&lt;/em&gt; function. Yep, I&amp;rsquo;m using a CSV file to store the list of spread trades. Also I often end up using the little &lt;em&gt;elseThrow&lt;/em&gt; functions that I originally used in the &lt;a href="http://code.msdn.microsoft.com/FinancialFunctions/Wiki/View.aspx?title=Home"&gt;Excel functions library&lt;/a&gt; to check preconditions.&lt;/p&gt;
&lt;p&gt;Here is an example of using them for the &lt;em&gt;parseLine&lt;/em&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;// parse a line in the csv config file, assumes valid csv, dates and trailing stop in [0,100]
let internal parseLine lineNumber line =
    isValidLine line                |&amp;gt; elseThrowi lineNumber &amp;quot;badly formatted line&amp;quot;
    let values = line.Split([|','|])
    isValidDate values.[0]          |&amp;gt; elseThrowi lineNumber &amp;quot;badly formatted date&amp;quot;
    isValidTicker values.[1]        |&amp;gt; elseThrowi lineNumber &amp;quot;long ticker has a comma in it&amp;quot;
    isValidTicker values.[2]        |&amp;gt; elseThrowi lineNumber &amp;quot;short ticker has a comma in it&amp;quot;
    isValidTrailingStop values.[3]  |&amp;gt; elseThrowi lineNumber &amp;quot;trailing stop has to be between 0 and 100 included&amp;quot;
    DateTime.Parse(values.[0]), values.[1].Trim(), values.[2].Trim(), int values.[3]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the csv format is (dateOfTrade, longTicker, shortTicker, trailingStop). Let&amp;rsquo;s now look and the FsCheck testcase for this function.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let writeLine (date:DateTime) (tickerLong:string) (tickerShort:string) (trailingStopValue:int) =
    sprintf &amp;quot;%s,%s,%s,%i&amp;quot; (date.ToShortDateString()) tickerLong tickerShort trailingStopValue
[&amp;lt;Fact;Category(&amp;quot;Fast Tests&amp;quot;)&amp;gt;]
let can_parse_valid_lines () =
    let  prop_parseLine (lineNumber:int) date tickerLong tickerShort trailingStopValue =
        let line = writeLine date tickerLong tickerShort trailingStopValue
        let values = line.Split([|','|])
        (isValidLine(line) &amp;amp;&amp;amp; isValidDate values.[0] &amp;amp;&amp;amp; isValidTicker values.[1] &amp;amp;&amp;amp; isValidTicker values.[2]
                                                                                        &amp;amp;&amp;amp; isValidTrailingStop values.[3])
            ==&amp;gt; lazy
                let actual = parseLine lineNumber line
                (date, tickerLong.Trim(), tickerShort.Trim(), trailingStopValue) = actual
    check config prop_parseLine
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In FsCheck you state properties of your functions and FsCheck generates random values to test them. In this case I&amp;rsquo;m asserting that, given a &lt;em&gt;date, tickerLong, tickerShort, trailingStopValue&lt;/em&gt;, I can write them to a string, read them back and I get the same values. Frankly, I was skeptical on the utility of such exercise, but I was wrong. That&amp;rsquo;s how I discovered that tickers cannot have commas in them (among other things).&lt;/p&gt;
&lt;p&gt;To hook up FsCheck and XUnit (aka to run FsCheck property checking as normal testcases), you need to write the below black magic code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let xUnitRunner =
    { new IRunner with
        member x.OnArguments(_,_,_) = ()
        member x.OnShrink(_,_) = ()
        member x.OnFinished(name, result) =
            match result with
                | True data -&amp;gt; Assert.True(true)
                | _ -&amp;gt; failwith (testFinishedToString name result)
    }
let config = {quick with Runner = xUnitRunner}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, to run XUnit with your brand new .net 4.0 project, you need to add xunit.gui.exe.config to the XUnit directory with the following content:&lt;/p&gt;
&lt;p&gt;&lt;configuration&gt;&lt;/p&gt;
&lt;p&gt;&lt;startup&gt;&lt;/p&gt;
&lt;p&gt;&lt;requiredRuntime version=v4.0.20506&amp;#8243; safemode=true/&gt;&lt;/p&gt;
&lt;p&gt;&lt;/startup&gt;&lt;/p&gt;
&lt;p&gt;&lt;/configuration&gt;&lt;/p&gt;
&lt;p&gt;While we are talking about such trivialities, I compile my testcases as executable, so that I can easily run them under debug. I also add the InternalsVisibleTo attribute, so that I can test internal stuff. Many of my algorithms are in internal functions and I want to test them in isolation.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;[&amp;lt;assembly:InternalsVisibleTo(&amp;quot;SpreadTrackingTests&amp;quot;)&amp;gt;]
    do
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given the previous function, I can then parse text and files with the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let internal parseText (lines:string) = lines.Trim().Split([|'\n'|]) |&amp;gt; Array.mapi parseLine
let public parseFile fileName = File.ReadAllText fileName |&amp;gt; parseText
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I need to load closing prices. I&amp;rsquo;m using &lt;a href="http://code.msdn.microsoft.com/DownloadStockPrices"&gt;my own library&lt;/a&gt; to load prices. That library is pretty badly designed. Also, the function below should be factorized in several sub-functions. It kind of shows how you can write spaghetti code in a beautiful functional language as F# if you really try hard. But let&amp;rsquo;s not worry about such subtleties for now …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let internal loadClosingPrices (endDate:DateTime) tickersStartDate  =
    // format parameters to conform to loadTickersAsync
    let tickersLong, tickersShort =
        tickersStartDate
        |&amp;gt; Array.map (fun (startDate:DateTime, ticker1:string, ticker2:string, _) -&amp;gt;
                (ticker1, {Start = startDate; End = endDate}), (ticker2, {Start = startDate; End = endDate}))
        |&amp;gt; Array.unzip
    let prices = tickersShort
                 |&amp;gt; Array.append tickersLong
                 |&amp;gt; Array.toList
                 |&amp;gt; loadTickersAsync
                 |&amp;gt; Async.RunSynchronously
                 |&amp;gt; Array.map (fun (ticker, span, obs) -&amp;gt; ticker, obs (*|&amp;gt; asHappened 1. |&amp;gt; adjusted adjStart*))
    let len = tickersLong.Length
    let longObs = Array.sub prices 0 len
    let shortObs = Array.sub prices len len
    // removes divs and splits
    let choosePrices observation = match observation.Event with Price(pr) -&amp;gt; Some(observation) | _ -&amp;gt; None
    let combineOverTickerObservations f tickerObservations =
        tickerObservations
        |&amp;gt; Array.map (fun (ticker, observations) -&amp;gt;
                                            ticker,
                                            observations |&amp;gt; List.choose f |&amp;gt; List.rev)
    let longPrices = combineOverTickerObservations choosePrices longObs
    let shortPrices = combineOverTickerObservations choosePrices shortObs
    longPrices, shortPrices
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above, &lt;em&gt;tickerStartDate&lt;/em&gt; is an array of (trade date * long ticker * short ticker * trailingStop) which is what is produced by our &lt;em&gt;parseLine&lt;/em&gt; function. The function first separates out long tickers from short ones.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tickersLong, tickersShort =
    tickersStartDate
    |&amp;gt; Array.map (fun (startDate:DateTime, ticker1:string, ticker2:string, _) -&amp;gt;
            (ticker1, {Start = startDate; End = endDate}), (ticker2, {Start = startDate; End = endDate}))
    |&amp;gt; Array.unzip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It then puts them together again in a single Array, to be able to pass it to the loadTickerAsync functions. It runs the function, waits for the results and then returns an array of (ticker * observations).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let prices = tickersShort
             |&amp;gt; Array.append tickersLong
             |&amp;gt; Array.toList
             |&amp;gt; loadTickersAsync
             |&amp;gt; Async.RunSynchronously
             |&amp;gt; Array.map (fun (ticker, span, obs) -&amp;gt; ticker, obs |&amp;gt; asHappened 1. |&amp;gt; adjusted adjStart)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The data is downloaded as it comes from Yahoo, which is a mix of adjusted and not adjusted data. &lt;em&gt;asHappened&lt;/em&gt; transforms it so that everything is as it really happened, &lt;em&gt;adjusted&lt;/em&gt; then adjusts it for the effect of dividends and splits. Think of this two function as &amp;lsquo;make the data right&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;We then split them again to get the long and short series. The point of merging them and splitting them is to call &lt;em&gt;loadTickersAsync&lt;/em&gt; just once instead of twice. There are better ways to do it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let len = tickersLong.Length
        let longObs = Array.sub prices 0 len
        let shortObs = Array.sub prices len len
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point we remove the observations that represents dividends or splits, as we are interested just in prices and we return the resulting observations.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let choosePrices observation = match observation.Event with Price(pr) -&amp;gt; Some(observation) | _ -&amp;gt; None
let combineOverTickerObservations f tickerObservations =
    tickerObservations
    |&amp;gt; Array.map (fun (ticker, observations) -&amp;gt;
                                        ticker,
                                        observations |&amp;gt; List.choose f |&amp;gt; List.rev)
let longPrices = combineOverTickerObservations choosePrices longObs
let shortPrices = combineOverTickerObservations choosePrices shortObs
longPrices, shortPrices
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The List.rev at the end is interesting. Somewhere in the loadTickerAsync/asHappened/adjusted triad of functions I end up reversing the list. I should fix the bug instead of workaround it, but this is just a blog post, not production code, so I&amp;rsquo;ll let it slip.&lt;/p&gt;
&lt;p&gt;Now that we have our price observations, we need to extract the price values and calculate the sequence of ratios (long price / short price).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let internal calcRatioSeries longPrices shortPrices =
    let extractPrice obs = match obs.Event with Price(pr) -&amp;gt; pr.Close | _ -&amp;gt; failwith &amp;quot;At this point divs and splits should have been removed&amp;quot;
    let longValues = longPrices |&amp;gt;  List.map extractPrice
    let shortValues = shortPrices |&amp;gt; List.map extractPrice
    shortValues |&amp;gt; List.map2 (/) longValues
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Having this ratio series, we can calculate the maximum adverse excursion, incorrectly called trailing stop below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let internal calcTrailingStop ratioSeries = List.head ratioSeries / List.max ratioSeries - 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then create a function that puts it all together.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type public Result = {RatioName:string; CurrentTrailing:int; TrailingStop:int} with
    override x.ToString() = x.RatioName + &amp;quot;\t\t&amp;quot; + x.CurrentTrailing.ToString() + &amp;quot;\t\t&amp;quot; + x.TrailingStop.ToString()
// reads a csv file (startDate, longTicker, shortTicker, trailingStop) and returns an array of results
let public processFile fileName endDate =
    let fileInfo = parseFile fileName
    let longPrices, shortPrices = loadClosingPrices endDate fileInfo
    let ratioSeries = Array.map2 (fun l s -&amp;gt; fst l + &amp;quot;/&amp;quot; + fst s, calcRatioSeries (snd l) (snd s)) longPrices shortPrices
    ratioSeries |&amp;gt; Array.mapi (fun i (name, series) -&amp;gt;
                    let (_,_,_,ts) = fileInfo.[i]
                    {RatioName = name; CurrentTrailing = - int (Math.Round (calcTrailingStop series * 100., 0));
                                                                                                       TrailingStop = ts})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function takes a fileName and an endDate, the latter parameter is for the sake of testcases that has to work in the past, so that the data doesn&amp;rsquo;t change on them.&lt;/p&gt;
&lt;p&gt;Now we need to send an email. The code below works for me:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let sendEmail smtpServer port fromField toField subject body (user:string) (password:string) =
    let client = new SmtpClient(smtpServer, port)
    client.Credentials &amp;lt;- new NetworkCredential(user, password)
    client.EnableSsl &amp;lt;- true
    client.Send(fromField, toField, subject, body)
// gets the password from a file under C: so that when I post it on my blog I don't forget to delete it
let getPassword () =
    File.ReadAllText(@&amp;quot;D:\Documents and Settings\Luca\My Documents\config.txt&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Almost done, in the main part of the program, we gather the data, create the content of the email and send it out:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;do
    let file = &amp;quot;spreads.csv&amp;quot;
    let spreads = processFile file DateTime.Today
    let mutable builder = new System.Text.StringBuilder()
    builder &amp;lt;- builder.AppendLine(&amp;quot;Name\t\tCurrent\t\tStop&amp;quot;)
    for s in spreads do
        builder &amp;lt;- builder.AppendLine(s.ToString())
    let password = getPassword()
    sendEmail &amp;quot;smtp.gmail.com&amp;quot; 587 &amp;quot;***@***.com&amp;quot; &amp;quot;***@***.com&amp;quot; &amp;quot;Alert Trigger Spread&amp;quot; (builder.ToString())
                                                                                           &amp;quot;lucabolg@gmail.com&amp;quot; password;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next stop, the WPF veneer on top of the file.&lt;/p&gt;</description>
            <pubDate>Sat, 13 Mar 2010 01:18:37 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-03-13-tracking-spread-trades-in-f-and-hooking-up-xunit-and-fscheck-part-1.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices, divs and splits in F# updated to Visual Studio 2010</title>
            <link>https://www.lucabol.com/posts/2010-02-26-downloading-stock-prices-divs-and-splits-in-f-updated-to-visual-studio-2010.html</link>
            <description>&lt;p&gt;I’m working on a program to keep track of paired trades with trailing stops. I need to download stock prices, so I thought I might reuse some old code of mine. &lt;a href="http://code.msdn.microsoft.com/DownloadStockPrices"&gt;Here&lt;/a&gt; is the updated framework.&lt;/p&gt;</description>
            <pubDate>Fri, 26 Feb 2010 23:50:44 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-26-downloading-stock-prices-divs-and-splits-in-f-updated-to-visual-studio-2010.html</guid>
        </item>
        
        <item>
            <title>LChart: displaying charts in F# – Part III</title>
            <link>https://www.lucabol.com/posts/2010-02-19-lchart-displaying-charts-in-f-part-iii.html</link>
            <description>&lt;p&gt;The last post is &lt;a href="/2010/02/17/lchart-displaying-charts-in-f-part-ii/"&gt;here&lt;/a&gt;. In this post we&amp;rsquo;ll look at how things work under the cover and to why I came to believe that they shouldn&amp;rsquo;t work this way.&lt;/p&gt;
&lt;p&gt;First of all each one of the functions to create charts looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;static member bar (?y,?x, ?isValueShownAsLabel, ?markerSize, ?markerStyle, ?color, ?xname, ?yname, ?seriesName, ?title, ?drawingStyle) =
    let c = Create (SeriesChartType.Bar, x, y, isValueShownAsLabel, markerSize, markerStyle, color, xname, yname, seriesName, title)
    c.Series.[0].[&amp;quot;DrawingStyle&amp;quot;] &amp;lt;- defaultArg drawingStyle (c.Series.[0].[&amp;quot;DrawingStyle&amp;quot;])
    c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This returns an object of type &lt;em&gt;lc&lt;/em&gt; (this is the type of &amp;lsquo;&lt;em&gt;c&amp;rsquo;&lt;/em&gt;). But &lt;em&gt;lc&lt;/em&gt; inherits from &lt;em&gt;Chart&lt;/em&gt; which is the main class in the Microsoft Chart Controls.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type lc() =
    inherit Chart()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I should have said at the start that you need to reference such controls.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;#r &amp;quot;System.Windows.Forms.DataVisualization.dll&amp;quot;
open System.Collections
open System.Drawing
open System.IO
open System.Windows.Forms
open System.Windows.Forms.DataVisualization.Charting
open System.Windows.Forms.DataVisualization.Charting.Utilities
open System
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is convenient that the return value of each function is a subtype of &lt;em&gt;Chart&lt;/em&gt;. You can then go and customize this object as you like (i.e. changing graphical appearance) before calling &lt;em&gt;display&lt;/em&gt;. Given the &lt;em&gt;Chart&lt;/em&gt; inherits from &lt;em&gt;Control&lt;/em&gt; you can code the display method as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let display (c:lc) =
    let copy () =
        let stream = new MemoryStream()
        c.SaveImage(stream, Imaging.ImageFormat.Bmp)
        let bmp = new Bitmap(stream)
        Clipboard.SetDataObject(bmp)
    c.KeyDown.Add(fun e -&amp;gt; if e.Control = true &amp;amp;&amp;amp; e.KeyCode = Keys.C then copy ())
    let pressToCopy = &amp;quot;(press CTRL+C to copy)&amp;quot;
    let name = if c.Titles.Count = 0 then sprintf &amp;quot;%s %s &amp;quot; &amp;quot;lc&amp;quot; pressToCopy else sprintf &amp;quot;%s %s &amp;quot; c.Titles.[0].Text  pressToCopy
    let f = new Form(Text = name, Size = new Size(800,600), TopMost = true)
    c.Dock &amp;lt;- DockStyle.Fill
    f.Controls.Add(c)
    f.Show()
    c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apart from a bit of convolutions to implement a Copy function, this just put the &lt;em&gt;Chart&lt;/em&gt; control on a newly created &lt;em&gt;Form&lt;/em&gt;. The &lt;em&gt;Create&lt;/em&gt; method called inside &lt;em&gt;bar&lt;/em&gt; looks like the following.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;static let Create (chartType, x, y, isValueShownAsLabel, markerSize, markerStyle, color, xname, yname, seriesName, title) =
    let c = new lc()
    let a = new ChartArea()
    let s = new Series()
    s.ChartType &amp;lt;- chartType
    c.ChartAreas.Add(a)
    c.Series.Add(s)
    match x, y with
        | Some(x), None     -&amp;gt; failwith &amp;quot;You cannot pass only x to a chart drawing function&amp;quot;
        | Some(x), Some(y)  -&amp;gt; s.Points.DataBindXY(x, [|y|])
        | None, Some(y)     -&amp;gt; s.Points.DataBindY([|y|])
        | None, None        -&amp;gt; ()
    s.IsValueShownAsLabel &amp;lt;- defaultArg isValueShownAsLabel s.IsValueShownAsLabel
    s.MarkerSize &amp;lt;- defaultArg markerSize s.MarkerSize
    s.MarkerStyle &amp;lt;- defaultArg markerStyle s.MarkerStyle
    s.Color &amp;lt;- defaultArg color s.Color
    a.AxisX.MajorGrid.Enabled &amp;lt;- false
    a.AxisY.MajorGrid.Enabled &amp;lt;- false
    match xname with
    | Some(xname) -&amp;gt;
        a.AxisX.Title &amp;lt;- xname
        a.AxisX.TitleFont &amp;lt;- axisFont
        a.AxisX.TitleForeColor &amp;lt;- axisColor
    | _ -&amp;gt; ()
    match yname with
    | Some(yname) -&amp;gt;
        a.AxisY.Title &amp;lt;- yname
        a.AxisY.TitleFont &amp;lt;- axisFont
        a.AxisY.TitleForeColor &amp;lt;- axisColor
    | _ -&amp;gt; ()
    match seriesName with
    | Some(seriesName) -&amp;gt; s.Name &amp;lt;- seriesName
    | _ -&amp;gt; ()
    match title with
    | Some(title) -&amp;gt;
        let t = c.Titles.Add(title: string)
        t.Font &amp;lt;- titleFont
        t.ForeColor &amp;lt;- titleColor
    | _ -&amp;gt; ()
    c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pretty standard imperative code here. Creating a chart and assigning its properties. Read the documentation for the Chart Control to understand what I&amp;rsquo;m doing here. I&amp;rsquo;m not even sure I remember what I&amp;rsquo;m doing. Given that we have our own &lt;em&gt;lc&lt;/em&gt; class (which is a type of &lt;em&gt;Chart&lt;/em&gt;) we can then override the &amp;lsquo;+&amp;rsquo; operator and &amp;lsquo;++&amp;rsquo; operator to do what is needed.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;static member (+) (c1:lc, c2:lc) =
    let c = copyChart(c1)
    c1.ChartAreas |&amp;gt; Seq.iter (fun a -&amp;gt; addAreaAndSeries c a c1.Series)
    let lastArea = c.ChartAreas |&amp;gt; Seq.nth ((c.ChartAreas |&amp;gt; Seq.length) - 1)
    c2.Series |&amp;gt; Seq.iter(fun s -&amp;gt; c.Series.Add(copySeries s c lastArea.Name))
    let l = c.Legends.Add(&amp;quot;&amp;quot;)
    l.Font &amp;lt;- legendFont
    c
static member (++) (c1:lc, c2:lc) =
    let c = copyChart(c1)
    c1.ChartAreas |&amp;gt; Seq.iter (fun a -&amp;gt; addAreaAndSeries c a c1.Series)
    let lastArea = c.ChartAreas |&amp;gt; Seq.nth ((c.ChartAreas |&amp;gt; Seq.length) - 1)
    addAreaAndSeries c c2.ChartAreas.[0] c2.Series
    let firstArea = c.ChartAreas |&amp;gt; Seq.nth ((c.ChartAreas |&amp;gt; Seq.length) - 1)
    c2.ChartAreas |&amp;gt; Seq.skip 1 |&amp;gt; Seq.iter (fun a -&amp;gt; addAreaAndSeries c a c2.Series)
    c    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apart from some other utility functions, this is how it all works. Why do I say that it is wrong? It is my opinion that the right way to do it would be to use &lt;em&gt;&amp;rsquo;+&lt;/em&gt;&amp;rsquo;, &amp;lsquo;&lt;em&gt;++&lt;/em&gt;&amp;rsquo; and all the &lt;em&gt;lc.XXX&lt;/em&gt; functions to create an object model that is completely independent from the Microsoft Chart controls. The display method would then translate it to the appropriate displayable Chart. It would work like a compiler translating to IL and then a Jitter producing native code. This would:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make possible to do more interesting compositions of graphs. Now I&amp;rsquo;m very constrained in what I can do by the fact that I&amp;rsquo;m working directly with Chart objects&lt;/li&gt;
&lt;li&gt;Make possible to change the backend. Using something different than Microsoft Chart controls to draw the chart&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why I have not done it? I didn&amp;rsquo;t know that was the right design until I used the wrong one. Now that I know, I have no time to do it.&lt;/p&gt;</description>
            <pubDate>Fri, 19 Feb 2010 18:03:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-19-lchart-displaying-charts-in-f-part-iii.html</guid>
        </item>
        
        <item>
            <title>Luca Bolognese leaves Microsoft</title>
            <link>https://www.lucabol.com/posts/2010-02-19-luca-bolognese-leaves-microsoft.html</link>
            <description>&lt;p&gt;&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;FYI I imported all the posts from the old MSDN blog to this one. Hence this post doesn&amp;rsquo;t make sense anymore. I left it here for memory sake. BTW: I am also back in msft now (30/11/2018).&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is my last post on this blog. My new blog is here: &lt;a href="http://www.lucabol.com" title="http://www.lucabol.com"&gt;http://www.lucabol.com &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I accepted a role as Director for Credit Suisse in London. I’m excited by the opportunity to work in the financial industry, a long-standing desire of mine. I’m also excited to write more F# code and to be closer to Italy, where my extended family is.&lt;/p&gt;
&lt;p&gt;The past ten years in Microsoft have been a wild ride. I’m proud to have been part of ObjectSpaces, Generics, LINQ and F# (and much more …). I’ve been lucky to be able to post on this blog and present at conferences about such innovative technologies. It has all been a lot of fun. I’m sure the next ten years will be as good.&lt;/p&gt;
&lt;p&gt;I’ll see you guys on my new blog.&lt;/p&gt;</description>
            <pubDate>Fri, 19 Feb 2010 08:58:02 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-19-luca-bolognese-leaves-microsoft.html</guid>
        </item>
        
        <item>
            <title>LChart: displaying charts in F# – Part II</title>
            <link>https://www.lucabol.com/posts/2010-02-17-lchart-displaying-charts-in-f-part-ii.html</link>
            <description>&lt;p&gt;In the &lt;a href="/2010/02/17/lchart-displaying-charts-in-f-part-i"&gt;previous post&lt;/a&gt; on my old blog I showed how to display simple charts with LChart. In this one we&amp;rsquo;ll talk about more complex charts. I wanted to define a little language for graphs for the sake of creating a more complex chart in a single line of code. Remember, the scenario here is: I got some data, I want to display it quickly in the fsi. The language has two operators: &amp;lsquo;+&amp;rsquo; and &amp;lsquo;++&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;&amp;rsquo;+&amp;rsquo; allows you to to superimpose things on a chart as in the following example.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.scatter(y) + lc.line(y) |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how I can superimpose two graphs of a different type and display the result.&lt;/p&gt;
&lt;p&gt;&lt;a href="/img/lchart1.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="/img/lchart1.png" width="417" height="303" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice on the upper right corner a bizarre (Series1, Series2) legend. What I wanted to do, but didn&amp;rsquo;t get around to do, was to allow a syntax like&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.scatter(y) + lc.line(y) + lc.legend(&amp;quot;Players&amp;quot;) |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should be relatively trivial to add it to the code. Also notice that the &amp;lsquo;y&amp;rsquo; parameter in the second chart is not needed. Data flows freely from left to right. So you can write the equivalent code below. This is a feature that caused all sort of grief. With hindsight it&amp;rsquo;s not worth the hassle. That&amp;rsquo;s why you always need to write your code at least twice to get it right.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.scatter(y) + lc.line() |&amp;gt; display 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some other, more elaborate charts follows. Notice how data flows from left to right until I introduce a new variable (i.e. the two &lt;em&gt;lc.boxplot&amp;#160;&lt;/em&gt; instructions plot different boxplots)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.scatter(y, markerSize = 10) + lc.column() + lc.boxplot() + lc.line()  + lc.column(x) + lc.boxplot()|&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="/img/lchart2.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="/img/lchart2.png" width="410" height="298" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Things would be better with names for axis, titles and such. I&amp;rsquo;m not including them for the sake of simplicity.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.scatter(y, markerSize = 10) + lc.column() + (lc.line(x)  + lc.column()) + lc.scatter(markerSize = 20) |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="/img/lchart3.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="/img/lchart3.png" width="396" height="288" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you remember the previous post, we talked about boxplots and how you generally want to have more than one on a graph. You can do that with the &amp;lsquo;+&amp;rsquo; operator and get this ugly chart. More work is needed here.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.boxplot(y = y, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;, title = &amp;quot;Players' Ratings&amp;quot;, color = Color.Blue, whiskerPercentile = 5, percentile = 30,
    showAverage = false, showMedian = false, showUnusualValues = true) +  lc.boxplot(y = x) |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="/img/lchart5.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="/img/lchart5.png" width="399" height="290" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;rsquo;++&amp;rsquo; allows you to create new charts below the chart you already have as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let h = [1.;2.5;3.1;4.;4.8;6.0;7.5;8.;9.1;15.]
let w = h |&amp;gt; List.map (fun h -&amp;gt; h * 1.2)
lc.line(h) + lc.column() ++ lc.line(w) ++ lc.bubble() |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="/img/lchart4.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="/img/lchart4.png" width="396" height="288" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice the left to right flowing of information here as well. In the next installment we&amp;rsquo;ll take a look at how things are implemented and why it&amp;rsquo;s all wrong.&lt;/p&gt;</description>
            <pubDate>Wed, 17 Feb 2010 20:24:33 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-17-lchart-displaying-charts-in-f-part-ii.html</guid>
        </item>
        
        <item>
            <title>LChart: displaying charts in F# – Part I</title>
            <link>https://www.lucabol.com/posts/2010-02-17-lchart-displaying-charts-in-f-part-i.html</link>
            <description>&lt;p&gt;I want to use F# as a exploratory data analysis language (like &lt;a href="http://www.r-project.org/"&gt;R&lt;/a&gt;). But I don&amp;rsquo;t know how to get the same nice graphic capabilities. So I decided to create them. Here is a library to draw charts in F#. It steals ideas from &lt;a href="http://www.amazon.com/Grammar-Graphics-Leland-Wilkinson/dp/0387987746"&gt;this book&lt;/a&gt; and &lt;a href="http://had.co.nz/ggplot2/book/"&gt;this R package&lt;/a&gt;. It is nothing more than a wrapper on top of the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=130F7986-BF49-4FE5-9CA8-910AE6EA442C&amp;amp;displaylang=en"&gt;Microsoft Chart Controls&lt;/a&gt; to give it a more &amp;lsquo;exploratory&amp;rsquo; one line calling syntax. It is also rough work in progress: I don&amp;rsquo;t wrap all the chart types and there are bugs in the ones I wrap. Also the architecture is all wrong (more on this in another post). But it&amp;rsquo;s a start and it kind of works. Attached the full code.&lt;/p&gt;
&lt;p&gt;I will continue this series in my new blog at wordpress: &lt;a href="http://lucabolognese.wordpress.com/" title="http://lucabolognese.wordpress.com/"&gt;http://lucabolognese.wordpress.com/&lt;/a&gt;. The reason I need a new blog will be explained in an upcoming post.&lt;/p&gt;
&lt;p&gt;Part II is now &lt;a href="http://lucabolognese.wordpress.com/2010/02/17/lchart-displaying-charts-in-f-part-ii/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ok, let&amp;rsquo;s start. How do I draw a chart?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let x = [1.;2.5;3.1;4.;4.8;6.0;7.5;8.;9.1;15.]
let y = [1.6;2.1;1.4;4.;2.3;1.9;2.4;1.4;5.;2.9]
lc.scatter(x, y) |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;X and Y are just some make up data. &lt;em&gt;lc&lt;/em&gt; is the name of a class (????) and &lt;em&gt;scatter&lt;/em&gt; is a static method on it. &lt;em&gt;scatter&lt;/em&gt; doesn&amp;rsquo;t display the chart, it just produces a an object that represents the chart. &lt;em&gt;Display&lt;/em&gt; displays the chart. The reason for using the bizarre lc static class is that I want it to be short so that it is easy to type in the fsi.exe. At the same time it needs to support optional parameters (which are not supported on top level functions in F#).&lt;/p&gt;
&lt;p&gt;You get a window with this chart on it. You can press CTRL+C to copy it (as I did to post it here).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_2.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb.png" width="382" height="295" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;You might want to customize the chart a bit by passing some of these famous optional parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.scatter(x = x, y = y, markerSize = 10, markerStyle = MarkerStyle.Diamond,
    xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;, title = &amp;quot;Players' Ratings&amp;quot;)  |&amp;gt; display     
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_4.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_1.png" width="382" height="295" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Or you might want to print different types of charts:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.line(y = y, markerSize = 10, markerStyle = MarkerStyle.Diamond, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;, title = &amp;quot;Players' Ratings&amp;quot;, isValueShownAsLabel = true,
    color = Color.Red) |&amp;gt; display       
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_6.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_2.png" width="373" height="289" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.spline(x = x, y = y, markerSize = 10, markerStyle = MarkerStyle.Diamond, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;,
    title = &amp;quot;Players' Ratings&amp;quot;, isValueShownAsLabel = true, color = Color.Red) |&amp;gt; display 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_8.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_3.png" width="371" height="287" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.stepline(x = x, y = y, markerSize = 10, markerStyle = MarkerStyle.Diamond, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;,
    title = &amp;quot;Players' Ratings&amp;quot;, isValueShownAsLabel = true, color = Color.Red) |&amp;gt; display
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_10.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_4.png" width="372" height="288" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.bar(y = y, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;, title = &amp;quot;Players' Ratings&amp;quot;, isValueShownAsLabel = true,
    drawingStyle = &amp;quot;Emboss&amp;quot;) |&amp;gt; display      
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_12.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_5.png" width="351" height="265" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.column(y = y, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;, title = &amp;quot;Players' Ratings&amp;quot;,
    isValueShownAsLabel = true, drawingStyle = &amp;quot;Cylinder&amp;quot;) |&amp;gt; display   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_14.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_6.png" width="375" height="283" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;lc.boxplot(y = y, xname = &amp;quot;Players&amp;quot;, yname = &amp;quot;Ratings&amp;quot;, title = &amp;quot;Players' Ratings&amp;quot;, color = Color.Blue, whiskerPercentile = 5, percentile = 30,
    showAverage = false, showMedian = false, showUnusualValues = true) |&amp;gt; display    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_16.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_7.png" width="408" height="317" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Ok, the last one is weird. You probably want more than one boxplot in a chart. I&amp;rsquo;ll show you how to do that in the next post.&lt;/p&gt;
&lt;p&gt;The next post will be on how to have more than one series on the same chart and more than one chart in the same windows. Something like the below:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_18.png"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LChartdisplayingchartsinFPartI_9F73/image_thumb_8.png" width="445" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/96/52/55/ChartPlotter.fsx"&gt;ChartPlotter.fsx&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Wed, 17 Feb 2010 11:20:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-17-lchart-displaying-charts-in-f-part-i.html</guid>
        </item>
        
        <item>
            <title>Excel Financial Functions upgraded to Visual Studio 2010 RC</title>
            <link>https://www.lucabol.com/posts/2010-02-16-excel-financial-functions-upgraded-to-visual-studio-2010-rc.html</link>
            <description>&lt;p&gt;Here is a link to the home page: &lt;a href="http://code.msdn.microsoft.com/FinancialFunctions/Wiki/View.aspx?title=Home" title="http://code.msdn.microsoft.com/FinancialFunctions/Wiki/View.aspx?title=Home"&gt;http://code.msdn.microsoft.com/FinancialFunctions/Wiki/View.aspx?title=Home&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Tue, 16 Feb 2010 14:55:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-16-excel-financial-functions-upgraded-to-visual-studio-2010-rc.html</guid>
        </item>
        
        <item>
            <title>New version of LAgent compatible with VS 2010 RC online</title>
            <link>https://www.lucabol.com/posts/2010-02-15-new-version-of-lagent-compatible-with-vs-2010-rc-online.html</link>
            <description>&lt;p&gt;My crazy agent framework now works with RC: &lt;a href="http://code.msdn.microsoft.com/LAgent" title="http://code.msdn.microsoft.com/LAgent"&gt;http://code.msdn.microsoft.com/LAgent&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 15 Feb 2010 09:36:54 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-15-new-version-of-lagent-compatible-with-vs-2010-rc-online.html</guid>
        </item>
        
        <item>
            <title>A simpler F# MailboxProcessor</title>
            <link>https://www.lucabol.com/posts/2010-02-12-a-simpler-f-mailboxprocessor.html</link>
            <description>&lt;p&gt;I always forget the pattern to use to create a functioning &lt;em&gt;MailboxProcessor&lt;/em&gt; in F#. I mean, which piece has to be async and how to structure the recursive loop. When I find myself in that kind of a situation situation, my instincts scream at me: &amp;ldquo;Wrap it and make it work how your mind expects it to work&amp;rdquo;. So here is a simplification of the paradigm.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how some standard &lt;em&gt;MailboxProcessor&lt;/em&gt; code looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let counter0 =
    MailboxProcessor.Start(fun inbox -&amp;gt;
        let rec loop n =
            async {
                    let! msg = inbox.Receive()
                    return! loop(n+msg) }
        loop 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This keeps a running sum of the messages it receives. The only part that is really unique to this guy is &amp;ldquo;n + msg&amp;rdquo;. All the rest is infrastructure.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;d probably prefer to write code like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let counter1 = MailboxProcessor.SpawnAgent((fun msg n -&amp;gt; msg + n), 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yep, just one line of code. But, is it possible? Let&amp;rsquo;s look at one way of doing it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type AfterError&amp;lt;'state&amp;gt; =
| ContinueProcessing of 'state
| StopProcessing
| RestartProcessing
type MailboxProcessor&amp;lt;'a&amp;gt; with
    static member public SpawnAgent&amp;lt;'b&amp;gt;(messageHandler :'a-&amp;gt;'b-&amp;gt;'b,
                                        initialState : 'b, ?timeout:'b -&amp;gt; int,
                                        ?timeoutHandler:'b -&amp;gt; AfterError&amp;lt;'b&amp;gt;,
                                        ?errorHandler:
                                            Exception -&amp;gt; 'a option -&amp;gt; 'b -&amp;gt; AfterError&amp;lt;'b&amp;gt;)
                                        : MailboxProcessor&amp;lt;'a&amp;gt; =
        let timeout = defaultArg timeout (fun _ -&amp;gt; -1)
        let timeoutHandler = defaultArg timeoutHandler (fun state -&amp;gt;
                                                                  ContinueProcessing(state))
        let errorHandler = defaultArg errorHandler (fun _ _ state -&amp;gt;
                                                                  ContinueProcessing(state))
        MailboxProcessor.Start(fun inbox -&amp;gt;
            let rec loop(state) = async {
                let! msg = inbox.TryReceive(timeout(state))
                try
                    match msg with
                    | None      -&amp;gt; match timeoutHandler state with
                                    | ContinueProcessing(newState)    -&amp;gt;
                                                                   return! loop(newState)
                                    | StopProcessing        -&amp;gt; return ()
                                    | RestartProcessing     -&amp;gt; return! loop(initialState)
                    | Some(m)   -&amp;gt; return! loop(messageHandler m state)
                with
                | ex -&amp;gt; match errorHandler ex msg state with
                        | ContinueProcessing(newState)    -&amp;gt; return! loop(newState)
                        | StopProcessing        -&amp;gt; return ()
                        | RestartProcessing     -&amp;gt; return! loop(initialState)
                }
            loop(initialState))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The funny formatting is because I have to fit it in the small horizontal space of this blog. In any case, this is just a simple (?) wrapper for the &lt;em&gt;MailboxProcessor&lt;/em&gt; pattern. The function takes two necessary parameters and two optional ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;messageHandler&lt;/strong&gt;: a function to execute when a message comes in, it takes the message and the current state as parameters and returns the new state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;initialState&lt;/strong&gt;: the initial state for the &lt;em&gt;MailboxProcessor&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeoutHandler&lt;/strong&gt;: a function that is executed whenever a timeout occurs. It takes as a parameter the current state and returns one of &lt;em&gt;ContinueProcessing(newState), StopProcessing or RestartProcessing&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;errorHandler&lt;/strong&gt;: a function that gets call if an exception is generated inside the &lt;em&gt;messageHandler&lt;/em&gt; function. It takes the exception, the message, the current state and returns &lt;em&gt;ContinueProcessing(newState), StopProcessing or RestartProcessing&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An example of how to use &lt;em&gt;errorHandler&lt;/em&gt; to implement the CountingAgent in the Expert F# book follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type msg = Increment of int | Fetch of AsyncReplyChannel&amp;lt;int&amp;gt; | Stop
exception StopException
type CountingAgent() =
    let counter = MailboxProcessor.SpawnAgent((fun msg n -&amp;gt;
                    match msg with
                    | Increment m -&amp;gt;  n + m
                    | Stop -&amp;gt; raise(StopException)
                    | Fetch replyChannel -&amp;gt;
                        do replyChannel.Reply(n)
                        n
                  ), 0, errorHandler = (fun _ _ _ -&amp;gt; StopProcessing))
    member a.Increment(n) = counter.Post(Increment(n))
    member a.Stop() = counter.Post(Stop)
    member a.Fetch() = counter.PostAndReply(fun replyChannel -&amp;gt; Fetch(replyChannel))
let counter2 = CountingAgent()
counter2.Increment(1)
counter2.Fetch()
counter2.Increment(2)
counter2.Fetch()
counter2.Stop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes your agent doesn&amp;rsquo;t need a state, it is purely stateless. Something as simple as the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let echo = MailboxProcessor&amp;lt;_&amp;gt;.SpawnWorker(fun msg -&amp;gt; printfn &amp;quot;%s&amp;quot; msg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can easily make that happen by using this toned down version of an agent, called worker:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;static member public SpawnWorker(messageHandler,  ?timeout, ?timeoutHandler,?errorHandler) =
    let timeout = defaultArg timeout (fun () -&amp;gt; -1)
    let timeoutHandler = defaultArg timeoutHandler (fun _ -&amp;gt; ContinueProcessing(()))
    let errorHandler = defaultArg errorHandler (fun _ _ -&amp;gt; ContinueProcessing(()))
    MailboxProcessor.SpawnAgent((fun msg _ -&amp;gt; messageHandler msg; ()),
                                 (), timeout, timeoutHandler,
                                 (fun ex msg _ -&amp;gt; errorHandler ex msg))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given that they are parallel, you might want to run a whole bunch of them at the same time. You might want something that looks like a worker, but that, under the cover, execute each &lt;em&gt;messageHandler&lt;/em&gt; in parallel. Something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type msg1 = Message1 | Message2 of int | Message3 of string
let a = MailboxProcessor.SpawnParallelWorker(function
                | Message1 -&amp;gt; printfn &amp;quot;Message1&amp;quot;;
                | Message2 n -&amp;gt; printfn &amp;quot;Message2 %i&amp;quot; n;
                | Message3 _ -&amp;gt; failwith &amp;quot;I failed&amp;quot;
                , 10
                , errorHandler = (fun ex _ -&amp;gt; printfn &amp;quot;%A&amp;quot; ex; ContinueProcessing()))
a.Post(Message1)
a.Post(Message2(100))
a.Post(Message3(&amp;quot;abc&amp;quot;))
a.Post(Message2(100))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the different messages, are likely to cause things to print out of order. Notice the number 10 above which is how many workers you want to process your messages. This is implemented by round-robin messages to the various workers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;static member public SpawnParallelWorker(messageHandler, howMany, ?timeout,
                                                        ?timeoutHandler,?errorHandler) =
    let timeout = defaultArg timeout (fun () -&amp;gt; -1)
    let timeoutHandler = defaultArg timeoutHandler (fun _ -&amp;gt; ContinueProcessing(()))
    let errorHandler = defaultArg errorHandler (fun _ _ -&amp;gt; ContinueProcessing(()))
    MailboxProcessor&amp;lt;'a&amp;gt;.SpawnAgent((fun msg (workers:MailboxProcessor&amp;lt;'a&amp;gt; array, index) -&amp;gt;
                                        workers.[index].Post msg
                                        (workers, (index + 1) % howMany))
                                    , (Array.init howMany
                                      (fun _ -&amp;gt; MailboxProcessor&amp;lt;'a&amp;gt;.SpawnWorker(
                                                 messageHandler, timeout, timeoutHandler,
                                                 errorHandler)), 0))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One drawback with the current code is that it doesn&amp;rsquo;t supports cancellations. It should be possible to wrap that too, but I haven&amp;rsquo;t done it (yet). If you don&amp;rsquo;t want to cut and paste the code, it is inside the AgentSystem.fs file &lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
            <pubDate>Fri, 12 Feb 2010 15:29:46 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-12-a-simpler-f-mailboxprocessor.html</guid>
        </item>
        
        <item>
            <title>The F#unctional Londoners Meetup Group</title>
            <link>https://www.lucabol.com/posts/2010-02-11-the-functional-londoners-meetup-group.html</link>
            <description>&lt;p&gt;If you live in London and work with F#, you should join &lt;a href="http://www.meetup.com/FSharpLondon/" title="http://www.meetup.com/FSharpLondon/"&gt;http://www.meetup.com/FSharpLondon/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also, if you don’t work with F#, but you’d like too, and you live in London you should join it. Also if you don’t live in London, but you’d like to and you’d like not to work on F# … Ok, you get the point.&lt;/p&gt;</description>
            <pubDate>Thu, 11 Feb 2010 09:24:05 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2010-02-11-the-functional-londoners-meetup-group.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part X – ActiveObject</title>
            <link>https://www.lucabol.com/posts/2009-12-10-lagent-an-agent-framework-in-f-part-x-activeobject.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you stare long enough at agents, you start to realize that they are just &amp;lsquo;glorified locks&amp;rsquo;. They are a convenient programming model to protect a resource from concurrent access. The programming model is convenient because both the client and the server can write their code without worrying about concurrency problems, and yet the program runs in parallel. Protecting a resource sounds a lot like state encapsulation and the concept of state encapsulation is what object orientation is all about.&lt;/p&gt;
&lt;p&gt;So you start thinking if there is a way to enhance vanilla objects to make them agents. You want to reuse all the concepts that you are familiar with (i.e. inheritance, visibility rules, etc…) and you want your clients to call agents as if they were calling normal objects. Obviously, under the cover, the method calls won&amp;rsquo;t execute immediately, but they would be queued. Let&amp;rsquo;s look at an example.&lt;/p&gt;
&lt;p&gt;This is our simple counter agent:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type CounterMessage =
| Add of int
| Print
let counterF = fun msg count -&amp;gt;
    match msg with
    | Add(i)    -&amp;gt; count + i
    | Print     -&amp;gt; printfn &amp;quot;The value is %i&amp;quot; count; count
let c1 = spawnAgent counterF 0
c1 &amp;lt;-- Add(3)
c1 &amp;lt;-- Print
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As nice as this looks, there are unfamiliar things in this model:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The communication is through messages. This requires packing and unpacking which, albeit easy in F#, is unfamiliar and feels like machinery that we&amp;rsquo;d like to get rid off. &lt;/li&gt;
&lt;li&gt;The management of state is bizarre, it gets passed into the lambda and returned from it instead of being represented as fields and properties on the agent &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My best attempt at creating an object-like syntax follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Counter() =
    let w = new WorkQueue()
    let mutable count = 0
    member c.Add x = w.Queue (fun () -&amp;gt;
        count &amp;lt;- count + x
        )
    member c.Print () = w.Queue (fun () -&amp;gt;
        printfn &amp;quot;The value is %i&amp;quot; count
        )
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let c = new Counter()
c.Add 3
c.Print
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this syntax, you write your agents like you write your vanilla classes except:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You need a private field of type &lt;em&gt;WorkQueue&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;You need to write your methods as lambdas passed to the &lt;em&gt;WorkQueue.Queue&lt;/em&gt; function &lt;/li&gt;
&lt;li&gt;Your methods cannot return values &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The most worrisome of these constraints is 2. because you can easily forget about it. If you do forget, then everything compiles just fine, but it doesn&amp;rsquo;t do what you expect. That&amp;rsquo;s pure badness. I haven&amp;rsquo;t found a way to enforce it. This is a place where the language could help me. Other than that, the whole model works rather nicely.&lt;/p&gt;
&lt;p&gt;Regarding the third point, you can concoct a programming model that allows you to return values from your methods. Here it is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;member c.CountTask = w.QueueWithTask(fun () -&amp;gt;
    count
    )
member c.CountAsync = w.QueueWithAsync(fun () -&amp;gt;
    count
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;printfn &amp;quot;The count using Task is %i&amp;quot; (c.CountTask.Result)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first method returns a &lt;em&gt;Task;&lt;/em&gt; the second method returns an &lt;em&gt;AsyncResultCell&lt;/em&gt;. Both are ways to represent a &lt;a href="http://en.wikipedia.org/wiki/Future_(programming)"&gt;promise&lt;/a&gt;. The latter allows a natural integration with the async block in F# as in the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;Async.RunSynchronously (
            async {
                let! count = c.CountAsync
                printfn &amp;quot;The countusing Async is %i&amp;quot; count
            })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As for myself, I don&amp;rsquo;t like methods returning values. Every time I use them, I end up going back and thinking about my problem in a traditional way, aka as method calls that return results, instead of thinking about it in a more actor oriented fashion. I end up waiting for these promises to be materialized and, by doing so, I limit the amount of parallelism that I unleash. As a matter of fact, the whole business of hiding the message passing nature of the programming model is dubious. It makes for a nicer syntax, but you need to make an extra effort in your mind to translate it to what it really is: just message passing with a nice syntactical veneer. I haven&amp;rsquo;t decided yet which model I like the most.&lt;/p&gt;
&lt;p&gt;You should have a sense of what &lt;em&gt;WorkQueue&lt;/em&gt; is. In essence, it is a &lt;em&gt;Mailbox&lt;/em&gt; of lambdas (look at the red bold code below). &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type WorkQueue() =
    let workQueue = spawnWorker (fun f -&amp;gt; f())
    member w.Queue (f) = workQueue &amp;lt;-- f
    member w.QueueWithTask f : Task&amp;lt;'T&amp;gt; =
        let source = new TaskCompletionSource&amp;lt;_&amp;gt;()
        workQueue &amp;lt;-- (fun () -&amp;gt; f() |&amp;gt; source.SetResult)
        source.Task
    member w.QueueWithAsync (f:unit -&amp;gt; 'T) : Async&amp;lt;'T&amp;gt; =
        let result = new AsyncResultCell&amp;lt;'T&amp;gt;()
        workQueue &amp;lt;-- (fun () -&amp;gt; f() |&amp;gt; result.RegisterResult )
        result.AsyncWaitResult
    member w.Restart () = workQueue &amp;lt;-! Restart
    member w.Stop () = workQueue &amp;lt;-! Stop
    member w.SetErrorHandler(h) =
        let managerF = fun (_, name:string, ex:Exception, _, _, _) -&amp;gt; h name ex
        let manager = spawnWorker managerF
        workQueue &amp;lt;-! SetManager manager
    member w.SetName(name) = workQueue &amp;lt;-! SetName(name)
    member w.SetQueueHandler(g) = workQueue &amp;lt;-! SetWorkerHandler(g)
    member w.SetTimeoutHandler(timeout, f) = workQueue &amp;lt;-! SetTimeoutHandler(timeout, f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I implemented all the services that are in the message passing model. The two are equivalent as expressing power goes. In case you wonder how a real piece of code looks like using this model, here is an &lt;em&gt;ActiveObject&lt;/em&gt; version of the map reduce algorithm. One of these days, I will gather the strength to go trough this code and explain what it does, but not today 🙂&lt;/p&gt;
&lt;p&gt;```fsharp&lt;/p&gt;
&lt;h1&gt;load &amp;ldquo;AgentSystem.fs&amp;rdquo;&lt;/h1&gt;
&lt;p&gt;open AgentSystem.LAgent
open System
open System.Collections
open System.Collections.Generic
open System.Threading
type IOutput&amp;lt;&amp;rsquo;out_key, &amp;lsquo;out_value&amp;gt; =
    abstract Reduced: &amp;lsquo;out_key -&amp;gt; seq&amp;lt;&amp;rsquo;out_value&amp;gt; -&amp;gt; unit
    abstract MapReduceDone: unit -&amp;gt; unit
type Mapper&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;my_out_key, &amp;lsquo;out_value when &amp;lsquo;my_out_key : comparison&amp;gt;
                                                      (map:&amp;rsquo;in_key -&amp;gt; &amp;lsquo;in_value -&amp;gt; seq&amp;lt;&amp;rsquo;my_out_key * &amp;lsquo;out_value&amp;gt;, i, partitionF) =
    let w = new WorkQueue()
    let mutable reducerTracker: BitArray = null
    let mutable controller = Unchecked.defaultof&amp;lt;Controller&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;my_out_key, &amp;lsquo;out_value&amp;gt;&amp;gt;
    let mutable reducers = Unchecked.defaultof&amp;lt;Reducer&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;my_out_key, &amp;lsquo;out_value&amp;gt; array&amp;gt;
    member m.Init c reds =
        w.Queue (fun () -&amp;gt;
            controller &amp;lt;- c
            reducers &amp;lt;- reds
            reducerTracker &amp;lt;- new BitArray(reducers.Length, false))
    member m.Process inKey inValue =
        w.Queue (fun () -&amp;gt;
            let outKeyValues = map inKey inValue
            outKeyValues |&amp;gt; Seq.iter (fun (outKey, outValue) -&amp;gt;
                                        let reducerUsed = partitionF outKey (reducers.Length)
                                        reducerTracker.Set(reducerUsed, true)
                                        reducers.[reducerUsed].Add(outKey, outValue)))
    member m.Done () =
        w.Queue (fun () -&amp;gt;
            controller.MapDone i reducerTracker)
    member m.Stop () = w.Stop ()
and Reducer&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value when &amp;lsquo;out_key :
                     comparison&amp;gt;(reduce:&amp;rsquo;out_key -&amp;gt; seq&amp;lt;&amp;rsquo;out_value&amp;gt; -&amp;gt; seq&amp;lt;&amp;rsquo;out_value&amp;gt;, i, output:IOutput&amp;lt;&amp;rsquo;out_key, &amp;lsquo;out_value&amp;gt;) =
    let w = new WorkQueue()
    let mutable workItems = new List&amp;lt;&amp;rsquo;out_key * &amp;lsquo;out_value&amp;gt;()
    let mutable controller = Unchecked.defaultof&amp;lt;Controller&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value&amp;gt;&amp;gt;
    member r.Init c =
        w.Queue (fun () -&amp;gt;
            controller &amp;lt;- c)
    member r.StartReduction () =
        w.Queue (fun () -&amp;gt;
            workItems
            |&amp;gt; Seq.groupBy fst
            |&amp;gt; Seq.sortBy fst
            |&amp;gt; Seq.map (fun (key, values) -&amp;gt; (key, reduce key (values |&amp;gt; Seq.map snd)))
            |&amp;gt; Seq.iter (fun (key, value) -&amp;gt; output.Reduced key value)
            controller.ReductionDone i)
    member r.Add (outKey:&amp;rsquo;out_key, outValue:&amp;rsquo;out_value) : unit =
        w.Queue (fun () -&amp;gt;
            workItems.Add((outKey, outValue)))
    member m.Stop () = w.Stop ()
and Controller&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value when &amp;lsquo;out_key : comparison&amp;gt;(output:IOutput&amp;lt;&amp;rsquo;out_key, &amp;lsquo;out_value&amp;gt;) =
    let w = new WorkQueue()
    let mutable mapperTracker: BitArray = null
    let mutable reducerUsedByMappers: BitArray = null
    let mutable reducerDone: BitArray = null
    let mutable mappers = Unchecked.defaultof&amp;lt;Mapper&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value&amp;gt; array&amp;gt;
    let mutable reducers = Unchecked.defaultof&amp;lt;Reducer&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value&amp;gt; array&amp;gt;
    let BAtoSeq (b:BitArray) = [for x in b do yield x]
    member c.Init maps reds =
        w.Queue (fun () -&amp;gt;
            mappers &amp;lt;- maps
            reducers &amp;lt;- reds
            mapperTracker &amp;lt;- new BitArray(mappers.Length, false)
            reducerUsedByMappers &amp;lt;- new BitArray(reducers.Length, false)
            reducerDone &amp;lt;- new BitArray(reducers.Length, false))
    member c.MapDone (i : int) (reducerTracker : BitArray) : unit =
        w.Queue (fun () -&amp;gt;
            mapperTracker.Set(i, true)
            let reducerUsedByMappers = reducerUsedByMappers.Or(reducerTracker)
            if not( BAtoSeq mapperTracker |&amp;gt; Seq.exists(fun bit -&amp;gt; bit = false)) then
                BAtoSeq reducerUsedByMappers |&amp;gt; Seq.iteri (fun i r -&amp;gt; if r = true then reducers.[i].StartReduction ())
                mappers |&amp;gt; Seq.iter (fun m -&amp;gt; m.Stop ())
              )
    member c.ReductionDone (i: int) : unit =
        w.Queue (fun () -&amp;gt;
            reducerDone.Set(i, true)
            if BAtoSeq reducerDone |&amp;gt; Seq.forall2 (fun x y -&amp;gt; x = y) (BAtoSeq reducerUsedByMappers) then
                output.MapReduceDone ()
                reducers |&amp;gt; Seq.iter (fun r -&amp;gt; r.Stop ())
                c.Stop()
             )
    member m.Stop () = w.Stop ()
let mapReduce   (inputs:seq&amp;lt;&amp;rsquo;in_key * &amp;lsquo;in_value&amp;gt;)
                (map:&amp;rsquo;in_key -&amp;gt; &amp;lsquo;in_value -&amp;gt; seq&amp;lt;&amp;rsquo;out_key * &amp;lsquo;out_value&amp;gt;)
                (reduce:&amp;rsquo;out_key -&amp;gt; seq&amp;lt;&amp;rsquo;out_value&amp;gt; -&amp;gt; seq&amp;lt;&amp;rsquo;out_value&amp;gt;)
                (output:IOutput&amp;lt;&amp;rsquo;out_key, &amp;lsquo;out_value&amp;gt;)
                M R partitionF =
    let len = inputs |&amp;gt; Seq.length
    let M = if len &amp;lt; M then len else M
    let mappers = Array.init M (fun i -&amp;gt; new Mapper&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value&amp;gt;(map, i, partitionF))
    let reducers = Array.init R (fun i -&amp;gt; new Reducer&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value&amp;gt;(reduce, i, output))
    let controller = new Controller&amp;lt;&amp;rsquo;in_key, &amp;lsquo;in_value, &amp;lsquo;out_key, &amp;lsquo;out_value&amp;gt;(output)
    mappers |&amp;gt; Array.iter (fun m -&amp;gt; m.Init controller reducers)
    reducers |&amp;gt; Array.iter (fun r -&amp;gt; r. Init controller )
    controller.Init mappers reducers
    inputs |&amp;gt; Seq.iteri (fun i (inKey, inValue) -&amp;gt; mappers.[i % M].Process inKey inValue)
    mappers |&amp;gt; Seq.iter (fun m -&amp;gt; m.Done ())
let partitionF = fun key M -&amp;gt; abs(key.GetHashCode()) % M
let map = fun (fileName:string) (fileContent:string) -&amp;gt;
            let l = new List&lt;string * int&gt;()
            let wordDelims = [|&amp;rsquo; &amp;lsquo;;&amp;rsquo;,&amp;rsquo;;&amp;rsquo;;&amp;rsquo;;&amp;rsquo;.&amp;rsquo;;&amp;rsquo;:&amp;rsquo;;&amp;rsquo;?&amp;rsquo;;&amp;rsquo;!&amp;rsquo;;&amp;rsquo;(&amp;lsquo;;&amp;rsquo;)&amp;rsquo;;&amp;rsquo;n&amp;rsquo;;&amp;rsquo;t&amp;rsquo;;&amp;rsquo;f&amp;rsquo;;&amp;rsquo;r&amp;rsquo;;&amp;rsquo;b&amp;rsquo;|]
            fileContent.Split(wordDelims) |&amp;gt; Seq.iter (fun word -&amp;gt; l.Add((word, 1)))
            l :&amp;gt; seq&lt;string * int&gt;
let reduce = fun key (values:seq&lt;int&gt;) -&amp;gt; [values |&amp;gt; Seq.sum] |&amp;gt; seq&lt;int&gt;
let printer () =
  { new IOutput&lt;string, int&gt; with
        member o.Reduced key values = printfn &amp;ldquo;%A %A&amp;rdquo; key values
        member o.MapReduceDone () = printfn &amp;ldquo;All done!!&amp;rdquo;}
let testInput =
     [&amp;ldquo;File1&amp;rdquo;, &amp;ldquo;I was going to the airport when I saw someone crossing&amp;rdquo;; &amp;ldquo;File2&amp;rdquo;, &amp;ldquo;I was going home when I saw you coming toward me&amp;rdquo;]
mapReduce testInput map reduce (printer ()) 2 2 partitionF
open System.IO
open System.Text
let gatherer(step) =
  let w = new WorkQueue()
  let data = new List&lt;string * int&gt;()
  let counter = ref 0
  { new IOutput&lt;string, int&gt; with
        member o.Reduced key values =
            w.Queue (fun () -&amp;gt;
                if !counter % step = 0 then
                    printfn &amp;ldquo;Processed %i words. Now processing %s&amp;rdquo; !counter key
                data.Add((key, values |&amp;gt; Seq.hd))
                counter := !counter + 1)
        member o.MapReduceDone () =
            w.Queue (fun () -&amp;gt;
                data
                |&amp;gt; Seq.distinctBy (fun (key, &lt;em&gt;) -&amp;gt; key.ToLower())
                |&amp;gt; Seq.filter (fun (key, &lt;/em&gt;) -&amp;gt; not(key = &amp;ldquo;&amp;rdquo; || key = &amp;ldquo;&amp;rdquo;&amp;rdquo; || (fst (Double.TryParse(key)))))
                |&amp;gt; Seq.to_array
                |&amp;gt; Array.sortBy snd
                |&amp;gt; Array.rev
                |&amp;gt; Seq.take 20
                |&amp;gt; Seq.iter (fun (key, value) -&amp;gt; printfn &amp;ldquo;%A\t%A&amp;rdquo; key value)
                printfn &amp;ldquo;All done!!&amp;rdquo;)
        }
let splitBook howManyBlocks fileName =
    let buffers = Array.init howManyBlocks (fun _ -&amp;gt; new StringBuilder())
    fileName
    |&amp;gt; File.ReadAllLines
    |&amp;gt; Array.iteri (fun i line -&amp;gt; buffers.[i % (howManyBlocks)].Append(line) |&amp;gt; ignore)
    buffers
let blocks1 = &lt;strong&gt;SOURCE_DIRECTORY&lt;/strong&gt; + &amp;ldquo;kjv10.txt&amp;rdquo; |&amp;gt; splitBook 100
let blocks2 = &lt;strong&gt;SOURCE_DIRECTORY&lt;/strong&gt; + &amp;ldquo;warandpeace.txt&amp;rdquo; |&amp;gt; splitBook 100
let input =
    blocks1
    |&amp;gt; Array.append blocks2
    |&amp;gt; Array.mapi (fun i b -&amp;gt; i.ToString(), b.ToString())
//mapReduce input map reduce (gatherer(1000)) 20 20 partitionF
type BookSplitter () =
    let blocks = new List&lt;string * string&gt;()
    member b.Split howManyBlocks fileName =
            let b =
                fileName
                |&amp;gt; splitBook howManyBlocks
                |&amp;gt; Array.mapi (fun i b -&amp;gt; i.ToString(), b.ToString())
            blocks.AddRange(b)
    member b.Blocks () =
            blocks.ToArray() :&amp;gt; seq&lt;string * string&gt;
type WordCounter () =
    let w = new WorkQueue()
    let words = new Dictionary&lt;string,int&gt;()
    let worker(wordCounter:WordCounter, ev:EventWaitHandle) =
          let w1 = new WorkQueue()
          { new IOutput&lt;string, int&gt; with
                member o.Reduced key values =
                    w1.Queue (fun() -&amp;gt;
                        wordCounter.AddWord key (values |&amp;gt; Seq.hd))
                member o.MapReduceDone () =
                    w1.Queue(fun () -&amp;gt;
                        ev.Set() |&amp;gt; ignore)
           }
    member c.AddWord word count =
            let exist, value = words.TryGetValue(word)
            if exist then
                words.[word] &amp;lt;- value + count
            else
                words.Add(word, count)
    member c.Add fileName =
        w.Queue (fun () -&amp;gt;
            let s = new BookSplitter()
            fileName |&amp;gt; s.Split 100
            let ev = new EventWaitHandle(false, EventResetMode.AutoReset)
            let blocks = s.Blocks ()
            mapReduce blocks map reduce (worker(c, ev)) 20 20 partitionF
            ev.WaitOne() |&amp;gt; ignore
            )
    member c.Words =
        w.QueueWithAsync (fun () -&amp;gt;
            words |&amp;gt; Seq.to_array |&amp;gt; Array.map (fun kv -&amp;gt; kv.Key, kv.Value)
        )
let wc = new WordCounter()
wc.Add (&lt;strong&gt;SOURCE_DIRECTORY&lt;/strong&gt; + &amp;ldquo;kjv10.txt&amp;rdquo;)
wc.Add (&lt;strong&gt;SOURCE_DIRECTORY&lt;/strong&gt; + &amp;ldquo;warandpeace.txt&amp;rdquo;)
let wordsToPrint = async {
                    let! words = wc.Words
                    return words
                        |&amp;gt; Seq.distinctBy (fun (key, &lt;em&gt;) -&amp;gt; key.ToLower())
                        |&amp;gt; Seq.filter (fun (key, &lt;/em&gt;) -&amp;gt; not(key = &amp;ldquo;&amp;rdquo; || key = &amp;ldquo;&amp;rdquo;&amp;rdquo; || (fst (Double.TryParse(key)))))
                        |&amp;gt; Seq.to_array
                        |&amp;gt; Array.sortBy snd
                        |&amp;gt; Array.rev
                        |&amp;gt; Seq.take 20
                        |&amp;gt; Seq.iter (fun (key, value) -&amp;gt; printfn &amp;ldquo;%A\t%A&amp;rdquo; key value)}
Async.RunSynchronously wordsToPrint
Thread.Sleep(15000)
printfn &amp;ldquo;Closed session&amp;rdquo;&lt;/p&gt;</description>
            <pubDate>Thu, 10 Dec 2009 10:09:14 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-12-10-lagent-an-agent-framework-in-f-part-x-activeobject.html</guid>
        </item>
        
        <item>
            <title>My PDC session is online - “Future directions for C# and Visual Basic”</title>
            <link>https://www.lucabol.com/posts/2009-11-23-my-pdc-session-is-online-future-directions-for-c-and-visual-basic.html</link>
            <description>&lt;p&gt;In case you are training to play the part of a first generation Italian immigrant in a Broadway show or if you want to understand why I never short msft stock: &lt;a href="http://microsoftpdc.com/Sessions/FT11" title="http://microsoftpdc.com/Sessions/FT11"&gt;http://microsoftpdc.com/Sessions/FT11&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 23 Nov 2009 13:17:44 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-11-23-my-pdc-session-is-online-future-directions-for-c-and-visual-basic.html</guid>
        </item>
        
        <item>
            <title>Luca at PDC 2009 next week</title>
            <link>https://www.lucabol.com/posts/2009-11-13-luca-at-pdc-2009-next-week.html</link>
            <description>&lt;p&gt;I’ll be in Los Angeles next week for PDC 2009. My session is called “&lt;a href="http://microsoftpdc.com/Sessions/FT11"&gt;Future Directions for C# and Visual Basic&lt;/a&gt;” and it comes on Tuesday immediately after the first keynote.&lt;/p&gt;
&lt;p&gt;I’m planning on spending the first half of the session talking about the biggest trends influencing C# and VB. The second part will be about more future looking features we are playing with these days.&lt;/p&gt;
&lt;p&gt;My deck has just two slides, as always. It’s all about watching me typing code on stage, hoping that I make crazy errors …&lt;/p&gt;
&lt;p&gt;There are several other interesting language related sessions at PDC. Here is a list of them (please notice that the times might change). Also feel free to drop by the languages booth and chat. My team and I will be there most of the time.&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="0"&gt;
  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        &lt;b&gt;Day&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        &lt;b&gt;Time&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Title&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        &lt;b&gt;Presenter&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        &lt;b&gt;Room&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        11:00  - 12:00
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Future Directions for C# and Visual Basic&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Luca Bolognese
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Hall F
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        11:00  - 12:00
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Accelerated Windows Application Development with Microsoft Visual C++ 2010&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Boris Jabes
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        408B
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17&lt;b&gt;&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        12:30  - 13:15
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Dynamic Binding in C# 4&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Mads Torgersen
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Hall F
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17&lt;b&gt;&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        12:30  - 13:15
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Using Dynamic Languages to Build Scriptable Applications&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Dino Viehland
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        403AB
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        13:30  - 14:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;C++ Forever: Interactive Applications in the Age of Manycore&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Rick Molloy
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        515B
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        16:30  - 17:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Manycore and the Microsoft .NET Framework 4: A Match Made in Microsoft Visual Studio 2010&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Stephen Toub
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        502A
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Tues 11/17
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        16:30  - 17:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Code Contracts and Pex: Power Charge Your Assertions and Unit Tests&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Mike Barnett, Nikolai Tillmann
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        408A
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Wed 11/18
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        11:30  - 12:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Microsoft Perspectives on the Future of Programming&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Panel
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Petree Hall C
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Wed 11/18
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        12:00  - 13:00
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;F# for Architects – Hitting the Sweet Spot&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Chris Smith
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        VS and .NET Pavillion
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Wed 11/18
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        13:00  - 13:45
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Code Like the Wind with Microsoft Visual Basic 2010&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Lucian Wischik
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Petree Hall D
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Wed 11/18
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        13:00  - 13:45
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Future of Garbage Collection&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Patrick Dussud
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Petree Hall C
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Wed 11/18
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        13:00  - 13:45
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Microsoft Project Code Name “M”: The Data and Modeling Language&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Don Box, Jeff Pinkston
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        408A
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Thu
      &lt;/p&gt;

      &lt;p&gt;
        11/19
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        08:30  - 09:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;PLINQ: LINQ, but Faster!&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Ed Essey, Igor Ostrovsky
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        515A
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Thu
      &lt;/p&gt;

      &lt;p&gt;
        11/19
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        10:00  - 11:00
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;A Lap around Microsoft Visual Studio 2010 for the Visual Basic Developer &lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Lisa Feigenbaum
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        VS and .NET Pavillion
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Thu
      &lt;/p&gt;

      &lt;p&gt;
        11/19
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        10:00  - 11:00
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Axum: A .NET Language for Safe and Scalable Concurrency&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Niklas Gustafsson
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        515A
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Thu
      &lt;/p&gt;

      &lt;p&gt;
        11/1&lt;br /&gt; 9
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        11:30  - 12:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;F# for Parallel and Asynchronous Programming&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Luke Hoban
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        515A
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Thu
      &lt;/p&gt;

      &lt;p&gt;
        11/19
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        12:45  - 13:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Microsoft Visual C# IDE Tips and Tricks&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        DJ Park
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Petree Hall D
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td valign="top" width="62"&gt;
      &lt;p&gt;
        Thu
      &lt;/p&gt;

      &lt;p&gt;
        11/19&lt;b&gt;&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="96"&gt;
      &lt;p&gt;
        12:45  - 13:30
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="502"&gt;
      &lt;p&gt;
        &lt;b&gt;Microsoft Visual Basic IDE Tips and Tricks&lt;/b&gt;
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="147"&gt;
      &lt;p&gt;
        Dustin Campbell
      &lt;/p&gt;
    &lt;/td&gt;

    &lt;td valign="top" width="117"&gt;
      &lt;p&gt;
        Petree Hall C
      &lt;/p&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</description>
            <pubDate>Fri, 13 Nov 2009 10:49:18 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-11-13-luca-at-pdc-2009-next-week.html</guid>
        </item>
        
        <item>
            <title>Becoming really rich with C#</title>
            <link>https://www.lucabol.com/posts/2009-09-22-becoming-really-rich-with-c.html</link>
            <description>&lt;p&gt;Or maybe not, please do not hold me responsible if you lose money following this system. Having said that, it is my opinion that there are very few concepts that are important in investing. Three big ones are value, diversification and momentum. This post is about the latter two and how to use C# to create a simple trading system that uses both.&lt;/p&gt;
&lt;p&gt;Diversification is &amp;lsquo;not put all your eggs in one basket&amp;rsquo; (contrary to &amp;lsquo;put all of them in one basket and watch that basket&amp;rsquo;). I don&amp;rsquo;t believe you can &amp;lsquo;watch&amp;rsquo; very much in financial markets, so I tend to prefer diversification.&lt;/p&gt;
&lt;p&gt;Momentum is a mysterious tendency of financial prices that have risen the most in the recent past, to continue outperforming in the close future. In essence, buying the top stocks/sectors/asset classes tends to outperform buying the bottom ones over horizons from three months to one year.&lt;/p&gt;
&lt;p&gt;The idea then is to rank some assets (i.e. ETFs) by how fast they have risen in the past, go long the top ones and short the bottom ones. There are hundreds of variations of this basic strategy, we&amp;rsquo;ll add the rule that we won&amp;rsquo;t buy assets that are below their 200 days moving average or sell short assets that are above it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m writing this code with VS 2010 Beta 2 (which hasn&amp;rsquo;t shipped yet). It should be trivial to modify it to run on B1 (or maybe it does run on it already). I attach the code and data files to this post.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;struct Event {
    internal Event(DateTime date, double price) { Date = date; Price = price; }
    internal readonly DateTime Date;
    internal readonly double Price;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ll use this simple structure to load the closing price for a particular date. My use of internal is kind of bizarre. Actually the whole code might look strange. It is an interesting (maybe un-elegant) mix of object orientation and functional programming.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;class Summary {
    internal Summary(string ticker, string name, string assetClass,
                    string assetSubClass, double? weekly, double? fourWeeks,
                    double? threeMonths, double? sixMonths, double? oneYear,
                    double? stdDev, double price, double? mav200) {
        Ticker = ticker;
        Name = name;
        AssetClass = assetClass;
        AssetSubClass = assetSubClass;
        // Abracadabra ...
        LRS = (fourWeeks + threeMonths + sixMonths + oneYear) / 4;
        Weekly = weekly;
        FourWeeks = fourWeeks;
        ThreeMonths = threeMonths;
        SixMonths = sixMonths;
        OneYear = oneYear;
        StdDev = stdDev;
        Mav200 = mav200;
        Price = price;
    }
    internal readonly string Ticker;
    internal readonly string Name;
    internal readonly string AssetClass;
    internal readonly string AssetSubClass;
    internal readonly double? LRS;
    internal readonly double? Weekly;
    internal readonly double? FourWeeks;
    internal readonly double? ThreeMonths;
    internal readonly double? SixMonths;
    internal readonly double? OneYear;
    internal readonly double? StdDev;
    internal readonly double? Mav200;
    internal double Price;
    internal static void Banner() {
        Console.Write(&amp;quot;{0,-6}&amp;quot;, &amp;quot;Ticker&amp;quot;);
        Console.Write(&amp;quot;{0,-50}&amp;quot;, &amp;quot;Name&amp;quot;);
        Console.Write(&amp;quot;{0,-12}&amp;quot;, &amp;quot;Asset Class&amp;quot;);
        //Console.Write(&amp;quot;{0,-30}t&amp;quot;, &amp;quot;Asset SubClass&amp;quot;;
        Console.Write(&amp;quot;{0,4}&amp;quot;, &amp;quot;RS&amp;quot;);
        Console.Write(&amp;quot;{0,4}&amp;quot;, &amp;quot;1Wk&amp;quot;);
        Console.Write(&amp;quot;{0,4}&amp;quot;, &amp;quot;4Wk&amp;quot;);
        Console.Write(&amp;quot;{0,4}&amp;quot;, &amp;quot;3Ms&amp;quot;);
        Console.Write(&amp;quot;{0,4}&amp;quot;, &amp;quot;6Ms&amp;quot;);
        Console.Write(&amp;quot;{0,4}&amp;quot;, &amp;quot;1Yr&amp;quot;);
        Console.Write(&amp;quot;{0,6}&amp;quot;, &amp;quot;Vol&amp;quot;);
        Console.WriteLine(&amp;quot;{0,2}&amp;quot;, &amp;quot;Mv&amp;quot;);
        //Console.Write(&amp;quot;{0,6}&amp;quot;, &amp;quot;Pr&amp;quot;);
        //Console.WriteLine(&amp;quot;{0,6}&amp;quot;, &amp;quot;M200&amp;quot;);
    }
    internal void Print() {
        Console.Write(&amp;quot;{0,-6}&amp;quot;, Ticker);
        Console.Write(&amp;quot;{0,-50}&amp;quot;, new String(Name.Take(48).ToArray()));
        Console.Write(&amp;quot;{0,-12}&amp;quot;, new String(AssetClass.Take(10).ToArray()));
        //Console.Write(&amp;quot;{0,-30}t&amp;quot;, new String(AssetSubClass.Take(28).ToArray()));
        Console.Write(&amp;quot;{0,4:N0}&amp;quot;, LRS * 100);
        Console.Write(&amp;quot;{0,4:N0}&amp;quot;, Weekly * 100);
        Console.Write(&amp;quot;{0,4:N0}&amp;quot;, FourWeeks * 100);
        Console.Write(&amp;quot;{0,4:N0}&amp;quot;, ThreeMonths * 100);
        Console.Write(&amp;quot;{0,4:N0}&amp;quot;, SixMonths * 100);
        Console.Write(&amp;quot;{0,4:N0}&amp;quot;, OneYear * 100);
        Console.Write(&amp;quot;{0,6:N0}&amp;quot;, StdDev * 100);
        if (Price &amp;lt;= Mav200)
            Console.WriteLine(&amp;quot;{0,2}&amp;quot;, &amp;quot;X&amp;quot;);
        else
            Console.WriteLine();
        //Console.Write(&amp;quot;{0,6:N2}&amp;quot;, Price);
        //Console.WriteLine(&amp;quot;{0,6:N2}&amp;quot;, Mav200);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The class Summary above is how I want to present my results. A few comments on the code. I use &lt;em&gt;Nullable&lt;T&gt;&lt;/em&gt; because some of this values can be null (i.e. not enough history), but I still don&amp;rsquo;t want to worry about it. It ends up working rather neatly.&lt;/p&gt;
&lt;p&gt;I also print the results out to &lt;em&gt;Console,&lt;/em&gt; which is crazy. I really should be using WPF/Silverlight as the presentation layer. Also the &lt;em&gt;{0,4:N0}&lt;/em&gt; notation might be unfamiliar to some of you, but this is how mad &lt;em&gt;Console&lt;/em&gt; guys like myself avoid using real UI frameworks. Sometimes we print things in color too.&lt;/p&gt;
&lt;p&gt;The real meat is in the following line:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;LRS = (fourWeeks + threeMonths + sixMonths + oneYear) / 4;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is our highway to richness. It&amp;rsquo;s a very elaborated quant formula, never before shown, that calculate a magick relative strength (aka momentum) factor as the average of the performance of four weeks, three months, six months and one year.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;class TimeSeries {
    internal readonly string Ticker;
    readonly DateTime _start;
    readonly Dictionary&amp;lt;DateTime, double&amp;gt; _adjDictionary;
    readonly string _name;
    readonly string _assetClass;
    readonly string _assetSubClass;
    internal TimeSeries(string ticker, string name, string assetClass, string assetSubClass, 
                                                                IEnumerable&amp;lt;Event&amp;gt; events) {
        Ticker = ticker;
        _name = name;
        _assetClass = assetClass;
        _assetSubClass = assetSubClass;
        _start = events.Last().Date;
        _adjDictionary = events.ToDictionary(e =&amp;gt; e.Date, e =&amp;gt; e.Price);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I then built myself a little TimeSeries class that represents a series of (date, price). I choose a dictionary to store it because of my assumption that I will be accessing it by date a lot. In retrospect, I was kind of right and kind of wrong. It doesn&amp;rsquo;t really matter much.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;bool GetPrice(DateTime when, out double price, out double shift) {
    // To nullify the effect of hours/min/sec/millisec being different from 0
    when = new DateTime(when.Year, when.Month, when.Day);
    var found = false;
    shift = 1;
    double aPrice = 0;
    while (when &amp;gt;= _start &amp;amp;&amp;amp; !found) {
        if (_adjDictionary.TryGetValue(when, out aPrice)) {
            found = true;
        }
        when = when.AddDays(-1);
        shift -= 1;
    }
    price = aPrice;
    return found;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A TimeSeries can give you back the price at a particular date. This looks bizarre and complex, but there is a reason for it. I might ask for a date that doesn&amp;rsquo;t have a price associated with it (i.e. holidays, week-ends). In such cases I want to return the previous price which could be N days in the past.&lt;/p&gt;
&lt;p&gt;I also want to return how many days in the past I had to go, so that other calculations (i.e. &lt;em&gt;Return&lt;/em&gt;) can modify their end date by the same amount. Also I might not find such a price at all, in which case I don&amp;rsquo;t want to throw an exception, but instead notify the caller. In retrospect, I should have used &lt;em&gt;double?&lt;/em&gt; to signify &amp;lsquo;price not found&amp;rsquo;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;double? GetReturn(DateTime start, DateTime end) {
    var startPrice = 0.0;
    var endPrice = 0.0;
    var shift = 0.0;
    var foundEnd = GetPrice(end, out endPrice, out shift);
    var foundStart = GetPrice(start.AddDays(shift), out startPrice, out shift);
    if (!foundStart || !foundEnd)
        return null;
    else
        return endPrice / startPrice - 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now go and calculate the return between two dates. Also the &lt;em&gt;TimeSeries&lt;/em&gt; object needs to perform a little more calculations.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;internal double? LastWeekReturn() {
        return GetReturn(DateTime.Now.AddDays(-7), DateTime.Now);
    }
    internal double? Last4WeeksReturn() {
        return GetReturn(DateTime.Now.AddDays(-28), DateTime.Now);
    }
    internal double? Last3MonthsReturn() {
        return GetReturn(DateTime.Now.AddMonths(-3), DateTime.Now);
    }
    internal double? Last6MonthsReturn() {
        return GetReturn(DateTime.Now.AddMonths(-6), DateTime.Now);
    }
    internal double? LastYearReturn() {
        return GetReturn(DateTime.Now.AddYears(-1), DateTime.Now);
    }
    internal double? StdDev() {
        var now = DateTime.Now;
        now = new DateTime(now.Year, now.Month, now.Day);
        var limit = now.AddYears(-3);
        var rets = new List&amp;lt;double&amp;gt;();
        while (now &amp;gt;= _start.AddDays(12) &amp;amp;&amp;amp; now &amp;gt;= limit) {
            var ret = GetReturn(now.AddDays(-7), now);
            rets.Add(ret.Value);
            now = now.AddDays(-7);
        }
        var mean = rets.Average();
        var variance = rets.Select(r =&amp;gt; Math.Pow(r - mean, 2)).Sum();
        var weeklyStdDev = Math.Sqrt(variance / rets.Count);
        return weeklyStdDev * Math.Sqrt(40);
    }
    internal double? MAV200() {
        return _adjDictionary
               .ToList()
               .OrderByDescending(k =&amp;gt; k.Key)
               .Take(200)
               .Average(k =&amp;gt; k.Value);
    }
    internal double TodayPrice() {
        var price = 0.0;
        var shift = 0.0;
        GetPrice(DateTime.Now, out price, out shift);
        return price;
    }
    internal Summary GetSummary() {
        return new Summary(Ticker, _name, _assetClass, _assetSubClass, 
                           LastWeekReturn(), Last4WeeksReturn(), Last3MonthsReturn(),
                           Last6MonthsReturn(), LastYearReturn(), StdDev(), TodayPrice(),
                           MAV200());
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing particularly interesting in this code. Just a bunch of calculations. The &lt;em&gt;MAV200&lt;/em&gt; is the 200 days moving average of closing prices. It shows a more functional way of doing things. The &lt;em&gt;StdDev&lt;/em&gt; function is instead very imperative.&lt;/p&gt;
&lt;p&gt;We now can work on downloading the prices. This is how you construct the right URL:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static string CreateUrl(string ticker, DateTime start, DateTime end) {
    return @&amp;quot;http://ichart.finance.yahoo.com/table.csv?s=&amp;quot; + ticker + &amp;quot;&amp;amp;a=&amp;quot;
            + (start.Month - 1).ToString() + &amp;quot;&amp;amp;b=&amp;quot; + start.Day.ToString() + &amp;quot;&amp;amp;c=&amp;quot;
            + start.Year.ToString() + &amp;quot;&amp;amp;d=&amp;quot; + (end.Month - 1).ToString() + &amp;quot;&amp;amp;e=&amp;quot;
            + end.Day.ToString() + &amp;quot;&amp;amp;f=&amp;quot; + end.Year.ToString() + &amp;quot;&amp;amp;g=d&amp;amp;ignore=.csv&amp;quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&amp;rsquo;s set how many concurrent connections we are going to use …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;ServicePointManager.DefaultConnectionLimit = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On my machine, setting this number too high causes errors to be returned. I&amp;rsquo;m not sure on which side of the connection the problem lies.&lt;/p&gt;
&lt;p&gt;We can then load all the tickers we want to load from a file. One of the files has Leveraged ETFs, which I want to filter out because they tend to pop up always at the top.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var tickers =
    //File.ReadAllLines(&amp;quot;ETFs.csv&amp;quot;)
    //File.ReadAllLines(&amp;quot;ETFTest.csv&amp;quot;)
    File.ReadAllLines(&amp;quot;AssetClasses.csv&amp;quot;)
    .Skip(1)
    .Select(l =&amp;gt; l.Split(new[] { ',' }))
    .Where(v =&amp;gt; v[2] != &amp;quot;Leveraged&amp;quot;)
    .Select(values =&amp;gt; Tuple.Create(values[0], values[1], values[2], values[3]))
    .ToArray();
var len = tickers.Length;
var start = DateTime.Now.AddYears(-2);
var end = DateTime.Now;
var cevent = new CountdownEvent(len);
var summaries = new Summary[len];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then load all of them, making sure to make an asynchronous call so not to keep the thread busy.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;for(var i = 0; i &amp;lt; len; i++)  {
    var t = tickers[i];
    var url = CreateUrl(t.Item1, start, end);
    using (var webClient = new WebClient()) {
        webClient.DownloadStringCompleted +=
                          new DownloadStringCompletedEventHandler(downloadStringCompleted);
        webClient.DownloadStringAsync(new Uri(url), Tuple.Create(t, cevent, summaries, i));
    }
}
cevent.Wait();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the use of a Countdown event to wait for all the thread to complete before printing out the results. Also notice the new &lt;em&gt;Tuple&lt;T&gt;&lt;/em&gt; class used to package things to send around.&lt;/p&gt;
&lt;p&gt;We can then print out the top and bottom 15%:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var top15perc =
        summaries
        .Where(s =&amp;gt; s.LRS.HasValue)
        .OrderByDescending(s =&amp;gt; s.LRS)
        .Take((int)(len * 0.15));
var bottom15perc =
        summaries
        .Where(s =&amp;gt; s.LRS.HasValue)
        .OrderBy(s =&amp;gt; s.LRS)
        .Take((int)(len * 0.15));
Console.WriteLine();
Summary.Banner();
Console.WriteLine(&amp;quot;TOP 15%&amp;quot;);
foreach(var s in top15perc)
    s.Print();
Console.WriteLine();
Console.WriteLine(&amp;quot;Bottom 15%&amp;quot;);
foreach (var s in bottom15perc)
    s.Print();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is what we do when a request comes back with data:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static void downloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) {
    var bigTuple =
             (Tuple&amp;lt;Tuple&amp;lt;string, string, string, string&amp;gt;, CountdownEvent, Summary[], int&amp;gt;)
              e.UserState;
    var tuple = bigTuple.Item1;
    var cevent = bigTuple.Item2;
    var summaries = bigTuple.Item3;
    var i = bigTuple.Item4;
    var ticker = tuple.Item1;
    var name = tuple.Item2;
    var asset = tuple.Item3;
    var subAsset = tuple.Item4;
    if (e.Error == null) {
        var adjustedPrices =
                e.Result
                .Split(new[] { 'n' })
                .Skip(1)
                .Select(l =&amp;gt; l.Split(new[] { ',' }))
                .Where(l =&amp;gt; l.Length == 7)
                .Select(v =&amp;gt; new Event(DateTime.Parse(v[0]), Double.Parse(v[6])));
        var timeSeries = new TimeSeries(ticker, name, asset, subAsset, adjustedPrices);
        summaries[i] = timeSeries.GetSummary();
        cevent.Signal();
        Console.Write(&amp;quot;{0} &amp;quot;, ticker);
    }
    else {
        Console.WriteLine(&amp;quot;[{0} ERROR] &amp;quot;, ticker);
        //Console.WriteLine(e.Error);
        summaries[i] = new Summary(ticker, name, &amp;quot;ERROR&amp;quot;, &amp;quot;ERROR&amp;quot;, 0, 0, 0, 0, 0, 0,0,0);
        cevent.Signal();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We first unpack the &lt;em&gt;Tuple&lt;/em&gt; we sent out originally, we then extract the Date and Price, create a &lt;em&gt;Summary&lt;/em&gt; object and store it in the &lt;em&gt;summaries&lt;/em&gt; array. It&amp;rsquo;s important to remember to &lt;em&gt;Signal&lt;/em&gt; to the &lt;em&gt;cevent&lt;/em&gt; in the error case as well because we want to print out the results even if some downloading failed.&lt;/p&gt;
&lt;p&gt;And here is what you get for your effort:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/BecomingreallyrichwithC_C128/image_2.png"&gt;&lt;img style="display:inline;border-width:0;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/BecomingreallyrichwithC_C128/image_thumb.png" width="743" height="506" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/89/69/82/SystemCodeAndData.zip"&gt;SystemCodeAndData.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Tue, 22 Sep 2009 19:40:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-09-22-becoming-really-rich-with-c.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part IX – Counting words …</title>
            <link>https://www.lucabol.com/posts/2009-09-18-lagent-an-agent-framework-in-f-part-ix-counting-words.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s now use our mapReduce to do something more interesting, for example finding the frequency of words in several books. Now the agent that processes the output needs to be a bit more complex.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let gathererF = fun msg (data:List&amp;lt;string * int&amp;gt;, counter, step) -&amp;gt;
                    match msg with
                    | Reduced(key, value)   -&amp;gt;
                        if counter % step = 0 then
                            printfn &amp;quot;Processed %i words. Now processing %s&amp;quot; counter key
                        data.Add((key, value |&amp;gt; Seq.hd))
                        data, counter + 1, step
                    | MapReduceDone         -&amp;gt;
                        data
                        |&amp;gt; Seq.distinctBy (fun (key, _) -&amp;gt; key.ToLower())
                        |&amp;gt; Seq.filter (fun (key, _) -&amp;gt; not(key = &amp;quot;&amp;quot; || key = &amp;quot;&amp;quot;&amp;quot; ||
                                                             (fst (Double.TryParse(key)))))
                        |&amp;gt; Seq.to_array
                        |&amp;gt; Array.sortBy snd
                        |&amp;gt; Array.rev
                        |&amp;gt; Seq.take 20
                        |&amp;gt; Seq.iter (fun (key, value) -&amp;gt; printfn &amp;quot;%A\t%A&amp;quot; key value)
                        printfn &amp;quot;All done!!&amp;quot;
                        data, counter, step
let gatherer = spawnAgent gathererF (new List&amp;lt;string * int&amp;gt;(), 0, 1000)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every time a new word is reduced, a message is printed out and the result is added to a running list. When everything is done such a list is printed out by first manipulating it to reduce weirdness and limit the number of items. BTW: there are at least two bugs in this code, maybe more (late night quick-and-dirty-see-if-the-algo-works kind of coding).&lt;/p&gt;
&lt;p&gt;We want to maximize the number of processors to use, so let&amp;rsquo;s split the books in chunks so that they can be operated in parallel. The code below roughly does it (I say roughly because it doesn&amp;rsquo;t chunk the lines in the right order, but for this particular case it doesn&amp;rsquo;t matter).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let gatherer = spawnAgent gathererF (new List&amp;lt;string * int&amp;gt;(), 0, 1000)
let splitBook howManyBlocks fileName =
    let buffers = Array.init howManyBlocks (fun _ -&amp;gt; new StringBuilder())
    fileName
    |&amp;gt; File.ReadAllLines
    |&amp;gt; Array.iteri (fun i line -&amp;gt; buffers.[i % (howManyBlocks)].Append(line) |&amp;gt; ignore)
    buffers
let blocks1 = &amp;quot;C:UserslucabolDesktopAgentsAgentskjv10.txt&amp;quot; |&amp;gt; splitBook 100
let blocks2 = &amp;quot;C:UserslucabolDesktopAgentsAgentswarandpeace.txt&amp;quot; |&amp;gt; splitBook 100
let input =
    blocks1
    |&amp;gt; Array.append blocks2
    |&amp;gt; Array.mapi (fun i b -&amp;gt; i.ToString(), b.ToString())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&amp;rsquo;s execute!!&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;mapReduce input map reduce gatherer 20 20 partitionF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On my machine I get the following, which could be the right result.&lt;/p&gt;
&lt;p&gt;```fsharp
&amp;ldquo;a&amp;rdquo;        16147
&amp;ldquo;And&amp;rdquo;        13071
&amp;ldquo;I&amp;rdquo;        11349
&amp;ldquo;unto&amp;rdquo;        8125
&amp;ldquo;as&amp;rdquo;        6400
&amp;ldquo;her&amp;rdquo;        5865
&amp;ldquo;which&amp;rdquo;        5544
&amp;ldquo;from&amp;rdquo;        5378
&amp;ldquo;at&amp;rdquo;        5175
&amp;ldquo;on&amp;rdquo;        5155
&amp;ldquo;have&amp;rdquo;        5135
&amp;ldquo;me&amp;rdquo;        5068
&amp;ldquo;my&amp;rdquo;        4629
&amp;ldquo;this&amp;rdquo;        3782
&amp;ldquo;out&amp;rdquo;        3653
&amp;ldquo;ye&amp;rdquo;        3399
&amp;ldquo;when&amp;rdquo;        3312
&amp;ldquo;an&amp;rdquo;        2841
&amp;ldquo;upon&amp;rdquo;        2558
&amp;ldquo;so&amp;rdquo;        2489
All done!!&lt;/p&gt;</description>
            <pubDate>Fri, 18 Sep 2009 14:43:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-09-18-lagent-an-agent-framework-in-f-part-ix-counting-words.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part VIII  - Implementing MapReduce (user model)</title>
            <link>https://www.lucabol.com/posts/2009-09-04-lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this post I use a newer version of the framework that I just uploaded on CodeGallery. In the process of using LAgent I grew more and more unhappy with the weakly typed way of sending messages. The code that implements that feature is nasty: full of upcasts and downcasts. I was losing faith in it. Bugs were cropping up in all sorts of scenarios (i.e. using generic union types as messages).&lt;/p&gt;
&lt;p&gt;In the end I decided to re-architecture the framework so to make it strongly typed. In essence now each agent can just receive messages of a single type. The limitations that this design choice introduces (i.e. more limited hot swapping) are compensated by the catching of errors at compile time and the streamlining of the code. I left the old framework on the site in case you disagree with me.&lt;/p&gt;
&lt;p&gt;In any case, today&amp;rsquo;s post is about &lt;em&gt;MapReduce&lt;/em&gt;. It assumes that you know what it is (link to the original Google paper that served as inspiration is here: &lt;a href="http://labs.google.com/papers/mapreduce.html" title="Google Research Publication- MapReduce"&gt;Google Research Publication- MapReduce&lt;/a&gt;). What would it take to implement an in-memory &lt;em&gt;MapReduce&lt;/em&gt; using my agent framework?&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the user model.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let mapReduce   (inputs:seq&amp;lt;'in_key * 'in_value&amp;gt;)
                (map:'in_key -&amp;gt; 'in_value -&amp;gt; seq&amp;lt;'out_key * 'out_value&amp;gt;)
                (reduce:'out_key -&amp;gt; seq&amp;lt;'out_value&amp;gt; -&amp;gt; seq&amp;lt;'reducedValues&amp;gt;)
                outputAgent
                M R partitionF =                
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;mapReduce&lt;/em&gt; takes seven parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;u&gt;inputs&lt;/u&gt;: a sequence of input key/value pairs. &lt;/li&gt;
&lt;li&gt;&lt;u&gt;map&lt;/u&gt;: this function operates on each input key/value pair. It&amp;#160; returns a sequence of output key/value pairs. The type of the output sequence can be different from the type of the inputs. &lt;/li&gt;
&lt;li&gt;&lt;u&gt;reduce&lt;/u&gt;: this function operates on an output key and all the values associated with it. It returns a sequence of reduced values (i.e. the average of all the values for this key) &lt;/li&gt;
&lt;li&gt;&lt;u&gt;ouputAgent&lt;/u&gt;: this is the agent that gets notified every time a new output key has been reduced and at the end when all the operation ends. &lt;/li&gt;
&lt;li&gt;&lt;u&gt;M&lt;/u&gt;: how many mapper agents to instantiate &lt;/li&gt;
&lt;li&gt;&lt;u&gt;R&lt;/u&gt;: how many reducer agents to instantiate &lt;/li&gt;
&lt;li&gt;&lt;u&gt;partitionF&lt;/u&gt;: the partition function used to choose which of the reducers is associated with a key &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;rsquo;s look at how to use this function to find how often each word is used in a set of files. First a simple partition function can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let partitionF = fun key M -&amp;gt; abs(key.GetHashCode()) % M 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given a key and some buckets, it picks one of the buckets. Its type is: &amp;lsquo;a –&amp;gt; int –&amp;gt; int, so it&amp;rsquo;s fairly reusable.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s also create a basic agent that just prints out the reduced values:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let printer = spawnWorker (fun msg -&amp;gt;
                            match msg with
                            | Reduced(key, value)   -&amp;gt; printfn &amp;quot;%A %A&amp;quot; key value
                            | MapReduceDone         -&amp;gt; printfn &amp;quot;All done!!&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The agent gets notified whenever a new key is reduced or the algorithm ends. It is useful to be notified immediately instead of waiting for everything to be done. If I hadn&amp;rsquo;t written this code using agents I would have not realized that possibility. I would simply have framed the problem as a function that takes an input and returns an output. Agents force you to think explicitly about the parallelism in your app. That&amp;rsquo;s a good thing.&lt;/p&gt;
&lt;p&gt;The mapping function simply split the content of a file into words and adds a word/1 pair to the list. I know that there are much better ways to do this (i.e. regular expressions for the parsing and summing words counts inside the function), but I wanted to test the basic framework capabilities and doing it this way does it better.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let map = fun (fileName:string) (fileContent:string) -&amp;gt;
            let l = new List&amp;lt;string * int&amp;gt;()
            let wordDelims = [|' ';',';';';'.';':';'?';'!';'(';')';'n';'t';'f';'r';'b'|]
            fileContent.Split(wordDelims) |&amp;gt; Seq.iter (fun word -&amp;gt; l.Add((word, 1)))
            l :&amp;gt; seq&amp;lt;string * int&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reducer function simply sums the various word statistics sent by the mappers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let reduce = fun key (values:seq&amp;lt;int&amp;gt;) -&amp;gt; [values |&amp;gt; Seq.sum] |&amp;gt; seq&amp;lt;int&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can create some fake input to check that it works:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let testInput = [&amp;quot;File1&amp;quot;, &amp;quot;I was going to the airport when I saw someone crossing&amp;quot;;
                               &amp;quot;File2&amp;quot;, &amp;quot;I was going home when I saw you coming toward me&amp;quot;]   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And execute the &lt;em&gt;mapReduce&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;mapReduce testInput map reduce printer 2 2 partitionF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On my machine I get the following. You might get a different order because of the async/parallel processing involved. If I wanted a stable order I would need to change the &lt;em&gt;printer&lt;/em&gt; agent to cache results on &lt;em&gt;Reduced&lt;/em&gt; and process them on &lt;em&gt;MapReduceDone&lt;/em&gt; (see next post).&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I&amp;rdquo; [4]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;crossing&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;going&amp;rdquo; [2]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;home&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;me&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;the&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;toward&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;airport&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;coming&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;saw&amp;rdquo; [2]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;someone&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;to&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;was&amp;rdquo; [2]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;when&amp;rdquo; [2]&lt;/p&gt;
&lt;p&gt;&amp;ldquo;you&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;In the next post we&amp;rsquo;ll process some real books …&lt;/p&gt;</description>
            <pubDate>Fri, 04 Sep 2009 13:57:48 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-09-04-lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – part VII – An auction application</title>
            <link>https://www.lucabol.com/posts/2009-07-10-lagent-an-agent-framework-in-f-part-vii-an-auction-application.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an application that uses the framework we have been creating. It is an auction application and it is described in more detail &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/20/f-actors-revisited.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s go through it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type AuctionMessage =
  | Offer of int * AsyncAgent // Make a bid
  | Inquire of AsyncAgent     // Check the status
and AuctionReply =
  | StartBidding
  | Status of int * DateTime // Asked sum and expiration
  | BestOffer                // Ours is the best offer
  | BeatenOffer of int       // Yours is beaten by another offer
  | AuctionConcluded of      // Auction concluded
      AsyncAgent * AsyncAgent
  | AuctionFailed            // Failed without any bids
  | AuctionOver              // Bidding is closed
let timeToShutdown = 3000
let bidIncrement = 10 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the format of the messages that the clients can send and the action agent can reply to. F# is really good at this sort of thing. First, we need an auction agent:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let auctionAgent seller minBid closing =
    let agent = spawnAgent (fun msg (isConcluded, maxBid, maxBidder) -&amp;gt;
                            match msg with
                            | Offer (_, client) when isConcluded -&amp;gt;
                                client &amp;lt;-- AuctionOver
                                (isConcluded, maxBid, maxBidder)
                            | Offer(bid, client) when not(isConcluded) -&amp;gt;
                                if bid &amp;gt;= maxBid + bidIncrement then
                                    if maxBid &amp;gt;= minBid then maxBidder &amp;lt;-- BeatenOffer bid
                                    client &amp;lt;-- BestOffer
                                    (isConcluded, bid, client)
                                else
                                    client &amp;lt;-- BeatenOffer maxBid
                                    (isConcluded, maxBid, maxBidder)
                            | Inquire client    -&amp;gt;
                                client &amp;lt;-- Status(maxBid, closing)
                                (isConcluded, maxBid, maxBidder))
                            (false, (minBid - bidIncrement), spawnWorker (fun _ -&amp;gt; ()))                             
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that, if the action is concluded, the agent replies to offers by sending an &lt;em&gt;AuctionOver&lt;/em&gt; message. If the auction is still open, then, in case the bid is higher than the max, it sets a new max and notify the two parties involved; otherwise it notifies the bidder that the offer wasn&amp;rsquo;t successful. Also you can ask for the status of the auction.&lt;/p&gt;
&lt;p&gt;This is what the code above says. Maybe the code is simpler than words. Anyhow, we need to treat the case where no message is received for some amount of time.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;agent &amp;lt;-- SetTimeoutHandler
            (closing - DateTime.Now).Milliseconds
            (fun (isConcluded: bool, maxBid, maxBidder) -&amp;gt;
                if maxBid &amp;gt;= minBid then
                  let reply = AuctionConcluded(seller, maxBidder)
                  maxBidder &amp;lt;-- reply
                  seller &amp;lt;-- reply
                else seller &amp;lt;-- AuctionFailed
                agent &amp;lt;-- SetTimeoutHandler
                    timeToShutdown
                    (fun (_:bool, _:int,_:AsyncAgent) -&amp;gt; StopProcessing)
                ContinueProcessing (true, maxBid, maxBidder))
agent            
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We start by waiting for the amount of time to the closing of the auction. If we get no messages, then two things might happen: we have an offer that is more than the minimum or we don&amp;rsquo;t. If we do, we tell everyone that it&amp;rsquo;s finished. Otherwise, we tell the seller that its item wasn&amp;rsquo;t successful.&amp;#160; In any case, we prepare the agent to shutdown by setting its next timeout to be &lt;em&gt;timeoutToShutdown&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It is interesting that we set the timeout handler inside the timeout handler. This is not a problem because of the nature of message processing (aka it processes one message at the time).&lt;/p&gt;
&lt;p&gt;We then need a bunch of of symbols …&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;module Auction =
  let random = new Random()
  let minBid = 100
  let closing = DateTime.Now.AddMilliseconds 10000.
  let seller = spawnWorker (fun (msg:AuctionReply) -&amp;gt; ())
  let auction = auctionAgent seller minBid closing
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not a very smart seller we have here … Next up is our definition of a client.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec c = spawnAgent (
                fun msg (max, current) -&amp;gt;
                    let processBid (aMax, aCurrent) =
                        if aMax &amp;gt;= top then
                            log &amp;quot;too high for me&amp;quot;
                            (aMax, aCurrent)
                        elif aCurrent &amp;lt; aMax then
                              let aCurrent = aMax + increment
                              Thread.Sleep (1 + random.Next 1000)
                              auction &amp;lt;-- Offer(aCurrent, c)
                              (aMax, aCurrent)
                        else (aMax, aCurrent)
                    match msg with
                    | StartBidding      -&amp;gt;
                        auction &amp;lt;-- Inquire c
                        (max, current)
                    | Status(maxBid,_)  -&amp;gt;
                        log &amp;lt;| sprintf &amp;quot;status(%d)&amp;quot; maxBid
                        let s = processBid (maxBid, current)
                        c &amp;lt;-- SetTimeoutHandler timeToShutdown (fun _ -&amp;gt; StopProcessing)
                        s
                    | BestOffer -&amp;gt;
                        log &amp;lt;| sprintf &amp;quot;bestOffer(%d)&amp;quot; current
                        processBid(max, current)
                    | BeatenOffer maxBid -&amp;gt;
                        log &amp;lt;| sprintf &amp;quot;beatenOffer(%d)&amp;quot; maxBid
                        processBid(maxBid, current)
                    | AuctionConcluded(seller, maxBidder) -&amp;gt;
                        log &amp;quot;auctionConcluded&amp;quot;
                        c &amp;lt;-- Stop
                        (max, current)
                    | AuctionOver -&amp;gt;
                        log &amp;quot;auctionOver&amp;quot;
                        c &amp;lt;-- Stop
                        (max, current))
                 (0,0)
c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Something that I like about agents is the fact that you need to understand just small snippets of code at the time. For example, you can read the processing for BestOffer and figure out if it makes sense.&amp;#160; I have an easy time personalizing them as in : &amp;ldquo;Ok, the guy just got a notification that there has been a better offer, what is he going to do next?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The code should be self explanatory for the most part. In essence, if you can offer more, do it otherwise wait for the auction to end. I&amp;rsquo;m not even sure the processing is completely right. I confess I&amp;rsquo;m just trying to do the same as Matthews code from the link above.&lt;/p&gt;
&lt;p&gt;We can then start up the whole thing and enjoy the cool output.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;open Auction
(client 1 20 200) &amp;lt;-- StartBidding
(client 2 10 300) &amp;lt;-- StartBidding
(client 3 30 150) &amp;lt;-- StartBidding
Console.ReadLine() |&amp;gt; ignore  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now for the nasty part. Implementing the framework.&lt;/p&gt;</description>
            <pubDate>Fri, 10 Jul 2009 16:14:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-07-10-lagent-an-agent-framework-in-f-part-vii-an-auction-application.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part VI – Hot swapping of code (and something silly)</title>
            <link>https://www.lucabol.com/posts/2009-07-03-lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt;&amp;#160; &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Hot swapping of code&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s get back a couple of steps and consider what happens when you get an error. Sure, your agent will continue processing messages, but it might be doing the wrong thing. Your message handling code might be buggy.&lt;/p&gt;
&lt;p&gt;Ideally you&amp;rsquo;d want to patch things on the fly. You&amp;rsquo;d want to replace the message processing code for an agent without stopping it.&lt;/p&gt;
&lt;p&gt;Here is how you do it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let counter2 = spawnAgent (fun msg state -&amp;gt; printfn &amp;quot;From %i to %i&amp;quot; state (state + msg);
                                                                              state + msg) 0
counter2 &amp;lt;-- 2
counter2 &amp;lt;-- SetAgentHandler(fun msg state -&amp;gt;
                printfn &amp;quot;From %i to %i via multiplication&amp;quot; state (state * msg); msg * state)
counter2 &amp;lt;-- 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which generates:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**From 0 to 2&lt;/p&gt;
&lt;p&gt;From 2 to 6 via multiplication**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After the agent receives a &lt;em&gt;SetAgentHandler&lt;/em&gt; message, it switch from a &amp;lsquo;+&amp;rsquo; agent to a &amp;lsquo;*&amp;rsquo; agent on the fly!! All the messages that come after that one gets multiplied to the state. Also, the state is preserved between changes in behavior.&lt;/p&gt;
&lt;p&gt;It might not be immediately apparent how to load a function at runtime, but it is really simple. Imagine that I get the data on the function to load from somewhere (i.e. a management console UI).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let assemblyNameFromSomewhere, typeNameFromSomewhere, methodNameFromSomewhere = 
                                                &amp;quot;mscorlib.dll&amp;quot;, &amp;quot;System.Console&amp;quot;, &amp;quot;WriteLine&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can then use it to dynamically load a message handler (in this case &lt;em&gt;Console.Writeline&lt;/em&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let a = Assembly.Load(assemblyNameFromSomewhere)
let c = a.GetType(typeNameFromSomewhere)
let m = c.GetMethod(methodNameFromSomewhere, [|&amp;quot;&amp;quot;.GetType()|])
let newF = fun (msg:string) (state:obj) -&amp;gt; m.Invoke(null, [| (msg:&amp;gt;obj) |])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then it is as simple as posting a &lt;em&gt;SetAgentHandler&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter2 &amp;lt;-- SetAgentHandler(newF)
counter2 &amp;lt;-- &amp;quot;blah&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our &lt;em&gt;counter2&lt;/em&gt; agent has become an echo agent on the fly, having loaded &lt;em&gt;Console.WriteLine&lt;/em&gt; dynamically. Note how the agent moved from being a &amp;lsquo;+&amp;rsquo; agent taking integers to being a &amp;lsquo;*&amp;rsquo; agent taking integers to being an &amp;lsquo;echo&amp;rsquo; agent taking strings. And it didn&amp;rsquo;t stop processing messages for the whole time.&lt;/p&gt;
&lt;p&gt;Obviously, you can do the same thing with workers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;echo &amp;lt;-- SetWorkerHandler(fun msg -&amp;gt; printfn &amp;quot;I'm an echo and I say: %s&amp;quot; msg)
echo &amp;lt;-- &amp;quot;Hello&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And parallelWorkers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;parallelEcho &amp;lt;-- SetWorkerHandler(fun msg -&amp;gt; tprint (&amp;quot;I'm new and &amp;quot; + msg))
messages |&amp;gt; Seq.iter (fun msg -&amp;gt; parallelEcho &amp;lt;-- msg)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;A silly interlude&lt;/h2&gt;
&lt;p&gt;As a way to show some agents talking to each other, here is a simple program that simulates marital interactions (of the worst kind):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec husband = spawnWorker (fun (To, msg) -&amp;gt; printfn &amp;quot;Husband says: %s&amp;quot; msg; To &amp;lt;-- msg)
let rec wife = spawnWorker (fun msg -&amp;gt; printfn &amp;quot;Wife says: screw you and your '%s'&amp;quot; msg)
husband &amp;lt;-- (wife, &amp;quot;Hello&amp;quot;)
husband &amp;lt;-- (wife, &amp;quot;But darling ...&amp;quot;)
husband &amp;lt;-- (wife, &amp;quot;ok&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which produces:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**Husband says: Hello&lt;/p&gt;
&lt;p&gt;Husband says: But darling&lt;/p&gt;
&lt;p&gt;Wife says: screw you and your &amp;lsquo;Hello&amp;rsquo;&lt;/p&gt;
&lt;p&gt;Wife says: screw you and your &amp;lsquo;But darling&amp;rsquo;&lt;/p&gt;
&lt;p&gt;Husband says: ok&lt;/p&gt;
&lt;p&gt;Wife says: screw you and your &amp;lsquo;ok&amp;rsquo;**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And yes, you cannot expect messages to be in the right sequence … Next up is an auction application.&lt;/p&gt;</description>
            <pubDate>Fri, 03 Jul 2009 15:23:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-07-03-lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part V – Timeout management</title>
            <link>https://www.lucabol.com/posts/2009-06-26-lagent-an-agent-framework-in-f-part-v-timeout-management.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Timeout management&lt;/h2&gt;
&lt;p&gt;Timeouts are very important in message based systems. In essence, if you are not getting messages for a certain period of time, that usually means something. It might be that something crashed, that other agents think that you are not online, or any other number of things. Hence the need to set timeouts and react when they are triggered.&lt;/p&gt;
&lt;p&gt;You do that by writing the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;--SetTimeoutHandler 1000 
            (fun state -&amp;gt; printfn &amp;quot;I'm still waiting for a message in state %A, come on ...&amp;quot; 
                                                            state; ContinueProcessing(state))              
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which generates the following message every second:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**I&amp;rsquo;m still waiting for a message in state 2, come on&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still waiting for a message in state 2, come on .…**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first parameter to &lt;em&gt;SetTimeoutHandler&lt;/em&gt; is how long to wait before triggering the handler. The second parameter is the handler that gets called whenever no message is received for that amount of time. Notice that the handler takes the current state of the agent and returns &lt;em&gt;ContinueProcessing(state)&lt;/em&gt;.&amp;#160; This tells the agent to continue processing messages and sets the current state to &lt;em&gt;state&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then generates:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**I&amp;rsquo;m still waiting for a message in state 4, come on&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still waiting for a message in state 4, come on**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;ContinueProcessing&lt;/em&gt; is just one of the three possible values of the (terribly named) &lt;em&gt;AfterError&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type AfterError =
| ContinueProcessing of obj
| StopProcessing
| RestartProcessing
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s see what RestartProcessing does.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- SetTimeoutHandler 1000  (fun state -&amp;gt; printfn &amp;quot;Restart from state %A&amp;quot; state
                                                                        ; RestartProcessing)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which, as expected, generates a nice stream of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**Restart from state 0&lt;/p&gt;
&lt;p&gt;Restart from state 0**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To bring things back to normal (aka no timeout) you can just pass –1 as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- SetTimeoutHandler -1  (fun state -&amp;gt; ContinueProcessing(state))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, you can stop the agent when a timeout occurs by returning the aptly named &lt;em&gt;StopProcessing&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- SetTimeoutHandler 1000  (fun state -&amp;gt; printfn &amp;quot;Restart from state %A&amp;quot; state; 
                                                                             StopProcessing)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another interesting thing you might want to do is hot swapping of code. More on that in the next part …&lt;/p&gt;</description>
            <pubDate>Fri, 26 Jun 2009 14:56:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-06-26-lagent-an-agent-framework-in-f-part-v-timeout-management.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part IV – Custom error management</title>
            <link>https://www.lucabol.com/posts/2009-06-19-lagent-an-agent-framework-in-f-part-iv-custom-error-management.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt;&amp;#160; &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Custom error management&lt;/h2&gt;
&lt;p&gt;In the last part we saw what happens by default in the framework when an error occurs. But that might not be what you want. You might want to have your sophisticated error detection and recovery distributed algorithm.&lt;/p&gt;
&lt;p&gt;To make such a thing possible each agent has a manager. The manager is an agent that gets called whenever an error occurs in the agent it is monitoring.&lt;/p&gt;
&lt;p&gt;In code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let manager = spawnWorker (fun (agent, name:string, ex:Exception, msg:obj,
                 state, initialState) -&amp;gt; printfn &amp;quot;%s restarting ...&amp;quot; name; agent &amp;lt;-- Restart)
counter1 &amp;lt;-- SetManager(manager)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whenever an error is generated the manager receives a tuple of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(agent, name, exception, message, currentState, inititialState)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This manager prints out something and then restarts the agent. Let&amp;rsquo;s trigger an error by posting the wrong message:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- &amp;quot;afdaf&amp;quot;
counter1 &amp;lt;-- 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The expectation is that the counter will restart from 0 whenever an error is triggered. This is what happens:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**Bob restarting&lt;/p&gt;
&lt;p&gt;From 0 to 2**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which is what we expected. Obviously this is not a very sophisticated error recovery algorithm. You might want to do something more meaningful. Hopefully you have enough information to build whatever you need.&lt;/p&gt;
&lt;p&gt;A particularly important class of unexpected event is timeouts. We&amp;rsquo;ll talk about them next.&lt;/p&gt;</description>
            <pubDate>Fri, 19 Jun 2009 14:36:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-06-19-lagent-an-agent-framework-in-f-part-iv-custom-error-management.html</guid>
        </item>
        
        <item>
            <title>LAgent: an agent framework in F# – Part III – Default error management</title>
            <link>https://www.lucabol.com/posts/2009-06-12-lagent-an-agent-framework-in-f-part-iii-default-error-management.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Default error management&lt;/h2&gt;
&lt;p&gt;What happens when an error occurs? Well, ideally you want to notify someone and continue processing messages. By default you want to print the error and as much information as you can about it.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s first see what happens if you pass the wrong message type:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- &amp;quot;fst&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generates:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**&amp;gt; The exception below occurred on agent Undefined at state 3 with message &amp;ldquo;fst&amp;rdquo;. The agent was started with state 0.&lt;/p&gt;
&lt;p&gt;System.InvalidCastException: Specified cast is not valid.&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0003.AgentSystem.f@158.Invoke(Object a, Object b)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0003.AgentSystem.loop@20-3.Invoke(Unit unitVar)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Control.AsyncBuilderImpl.callA@245.Invoke(AsyncParams`1 args)**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You get information about the current state of the agent, the message that generated the error, the initial state of the agent and the exception that was generated. But, in a system with several agents, you&amp;rsquo;d like to know which one agent failed. Then you need to name your agent:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- SetName(&amp;quot;Bob&amp;quot;)
counter1 &amp;lt;-- &amp;quot;fadfad&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you get (important part in blue):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**&amp;gt; The exception below occurred on agent &lt;font color="#0000ff"&gt;Bob&lt;/font&gt; at state 3 with message &amp;ldquo;fadfad&amp;rdquo;. The agent was started with state 0.&lt;/p&gt;
&lt;p&gt;System.InvalidCastException: Specified cast is not valid.&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0003.AgentSystem.f@158.Invoke(Object a, Object b)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0003.AgentSystem.loop@20-3.Invoke(Unit unitVar)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Control.AsyncBuilderImpl.callA@245.Invoke(AsyncParams`1 args)**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The important thing is that the agent continues running. It lives to fight another day. Hence:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Produces:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;From 3 to 6&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which shows that the agent is running and that it has kept its current state. Also errors can occur inside the message handler with a similar result:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;(spawnAgent (fun msg state -&amp;gt; state / msg) 100) &amp;lt;-- 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Produces:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**&amp;gt; The exception below occurred on agent Undefined at state 100 with message 0. The agent was started with state 100.&lt;/p&gt;
&lt;p&gt;System.DivideByZeroException: Attempted to divide by zero.&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0013.it@48-3.Invoke(Int32 msg, Int32 state)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0003.AgentSystem.f@158.Invoke(Object a, Object b)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Core.FastFunc`2.InvokeFast[V](FastFunc`2 func, T arg1, TResult arg2)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at FSI_0003.AgentSystem.loop@20-3.Invoke(Unit unitVar)&lt;/p&gt;
&lt;p&gt;&amp;#160;&amp;#160; at Microsoft.FSharp.Control.AsyncBuilderImpl.callA@245.Invoke(AsyncParams`1 args)**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But this might not be what you want. You might want to customize what happens when an error occurs. We&amp;rsquo;ll talk about that next.&lt;/p&gt;</description>
            <pubDate>Fri, 12 Jun 2009 14:07:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-06-12-lagent-an-agent-framework-in-f-part-iii-default-error-management.html</guid>
        </item>
        
        <item>
            <title>LAgent : an agent framework in F# – Part II – Agents and control messages</title>
            <link>https://www.lucabol.com/posts/2009-06-05-lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Agents&lt;/h2&gt;
&lt;p&gt;Agents are entities that process messages and keep state between one message and the next. As such they need to be initialized with a lambda that takes a message and a state and returns a new state. In F# pseudo code: msg –&amp;gt; state –&amp;gt; newState. For example the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let counter = spawnAgent (fun msg state -&amp;gt; state + msg) 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a counter that starts from 0 and gets incremented by the value of the received message. Let&amp;rsquo;s make it print something when it receives a message:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let counter1 = spawnAgent
                (fun msg state -&amp;gt; printfn &amp;quot;From %i to %i&amp;quot; state (state + msg); state + msg) 0
counter1 &amp;lt;-- 3
counter1 &amp;lt;-- 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which produces:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**From 0 to 3&lt;/p&gt;
&lt;p&gt;From 3 to 7**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is no &lt;em&gt;spawnParallelAgent&lt;/em&gt;, because I couldn&amp;rsquo;t figure out its usage patterns. Maybe I don&amp;rsquo;t have enough creativity. Obviously &lt;em&gt;msg&lt;/em&gt; and &lt;em&gt;state&lt;/em&gt; could be of whatever type (in real application they end up being tuples more often than not).&lt;/p&gt;
&lt;h2&gt;Control messages&lt;/h2&gt;
&lt;p&gt;You can do things to agents. I&amp;rsquo;m always adding to them but at this stage they are:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Command =
| Restart
| Stop
| SetManager of AsyncAgent
| SetName of string
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plus some others. I&amp;rsquo;ll describe most of them later on, right now I want to talk about &lt;em&gt;Restart&lt;/em&gt; and &lt;em&gt;Stop&lt;/em&gt;. You use the former like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;counter1 &amp;lt;-- Restart
counter1 &amp;lt;-- 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which produces:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;From 0 to 3&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This should be somehow surprising to you. You would have thought that you could just post integers to a counter. This is not the case. You can post whatever object. This is useful because it allows to have a common model for passing all sort of messages, it allows for the agent not to be parameterized by the type of the message (and of state) so that you can store them in data structures and allows advanced scenarios (i.e. hot swapping of code).&lt;/p&gt;
&lt;p&gt;This is a debatable decision. I tried to get the best of strongly typing and dynamic typing, while keeping simplicity of usage. The implementation of this is kind of a mess though. We&amp;rsquo;ll get there.&lt;/p&gt;
&lt;p&gt;BTW: you use Stop just by posting Stop, which stops the agent (forever).&lt;/p&gt;</description>
            <pubDate>Fri, 05 Jun 2009 14:03:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-06-05-lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.html</guid>
        </item>
        
        <item>
            <title>LAgent : an agent framework in F# – Part I – Workers and ParallelWorkers</title>
            <link>https://www.lucabol.com/posts/2009-05-29-lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.html</link>
            <description>&lt;p&gt;Download framework &lt;a href="http://code.msdn.microsoft.com/LAgent"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All posts are here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;Part I  - Workers and ParallelWorkers&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Part II  - Agents and control messages&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Part III  - Default error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Part IV  - Custom error management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Part V  - Timeout management&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Part VI  - Hot swapping of code&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx"&gt;Part VII  - An auction framework&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/04/lagent-an-agent-framework-in-f-part-viii-implementing-mapreduce-user-model.aspx"&gt;Part VIII – Implementing MapReduce (user model)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;Part IX – Counting words …&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I like to try out different programming paradigms. I started out as an object oriented programmer. In university, I used Prolog. I then learned functional programming. I also experimented with various shared memory parallel paradigms (i.e. async, tasks and such). I now want to learn more about message based parallel programming (&lt;a href="http://www.amazon.com/Programming-Erlang-Software-Concurrent-World/dp/193435600X"&gt;Erlang&lt;/a&gt; style). I&amp;rsquo;m convinced that doing so makes me a better programmer. Plus, I enjoy it …&lt;/p&gt;
&lt;p&gt;My usual learning style is to build a framework that replicates a particular programming model and then write code using it. In essence, I build a very constrained environment. For example, when learning functional programming, I didn&amp;rsquo;t use any OO construct for a while even if my programming language supports them.&lt;/p&gt;
&lt;p&gt;In this case, I built myself a little agent framework based on F# &lt;em&gt;MailboxProcessors&lt;/em&gt;. I could have used &lt;em&gt;MailboxProcessors&lt;/em&gt; directly, but they are too flexible for my goal. Even to write a simple one of these guys, you need to use async and recursion in a specific pattern, which I always forget. Also, there are multiple ways to to do Post. I wanted things to be as simple as possible. I was willing to sacrifice flexibility for that.&lt;/p&gt;
&lt;p&gt;Notice that there are serious efforts in this space (as &lt;a href="http://blogs.msdn.com/maestroteam/"&gt;Axum&lt;/a&gt;). This is not one of them. It&amp;rsquo;s just a simple thing I enjoy working on between one meeting and the next.&lt;/p&gt;
&lt;h2&gt;Workers and ParallelWorkers&lt;/h2&gt;
&lt;p&gt;The two major primitives are spawning an agent and posting a message.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let echo = spawnWorker (fun msg -&amp;gt; printfn &amp;quot;%s&amp;quot; msg)
echo &amp;lt;-- &amp;quot;Hello guys!&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are two kinds of agents in my system. A &lt;em&gt;worker&lt;/em&gt; is an agent that doesn&amp;rsquo;t keep any state between consecutive messages. It is a stateless guy. Notice that the lambda that you pass to create the agent is strongly typed (aka &lt;em&gt;msg&lt;/em&gt; is of type &lt;em&gt;string&lt;/em&gt;). Also notice that I overloaded the &lt;em&gt;&amp;lt;—&lt;/em&gt; operator to mean &lt;em&gt;Post&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Given that a worker is stateless, you can create a whole bunch of them and, when a message is posted, route it to one of them transparently.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parallelEcho = spawnParallelWorker(fun s -&amp;gt; printfn &amp;quot;%s&amp;quot; s) 10
parallelEcho &amp;lt;-- &amp;quot;Hello guys!&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, in the above code, 10 workers are created and, when a message is posted, it gets routed to one of them (using a super duper innovative dispatching algorithm I&amp;rsquo;ll describe in the implementation part). This &lt;em&gt;parallelWorker&lt;/em&gt; guy is not really needed, you could easily built it out of the other primitives, but it is kind of cute.&lt;/p&gt;
&lt;p&gt;To show the difference between a worker and a &lt;em&gt;parallelWorker&lt;/em&gt;, consider this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let tprint s = printfn &amp;quot;%s running on thread %i&amp;quot; s Thread.CurrentThread.ManagedThreadId
let echo1 = spawnWorker (fun s -&amp;gt; tprint s)
let parallelEcho1 = spawnParallelWorker(fun s -&amp;gt; tprint s) 10
let messages = [&amp;quot;a&amp;quot;;&amp;quot;b&amp;quot;;&amp;quot;c&amp;quot;;&amp;quot;d&amp;quot;;&amp;quot;e&amp;quot;;&amp;quot;f&amp;quot;;&amp;quot;g&amp;quot;;&amp;quot;h&amp;quot;;&amp;quot;i&amp;quot;;&amp;quot;l&amp;quot;;&amp;quot;m&amp;quot;;&amp;quot;n&amp;quot;;&amp;quot;o&amp;quot;;&amp;quot;p&amp;quot;;&amp;quot;q&amp;quot;;&amp;quot;r&amp;quot;;&amp;quot;s&amp;quot;;&amp;quot;t&amp;quot;]
messages |&amp;gt; Seq.iter (fun msg -&amp;gt; echo1 &amp;lt;-- msg)
messages |&amp;gt; Seq.iter (fun msg -&amp;gt; parallelEcho1 &amp;lt;-- msg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result of the &lt;em&gt;echo1&lt;/em&gt; iteration is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**a running on thread 11&lt;/p&gt;
&lt;p&gt;b running on thread 11&lt;/p&gt;
&lt;p&gt;c running on thread 11&lt;/p&gt;
&lt;p&gt;d running on thread 11&lt;/p&gt;
&lt;p&gt;…**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While the result of the &lt;em&gt;parallelEcho1&lt;/em&gt; iteration is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**a running on thread 13&lt;/p&gt;
&lt;p&gt;c running on thread 14&lt;/p&gt;
&lt;p&gt;b running on thread 12&lt;/p&gt;
&lt;p&gt;o running on thread 14&lt;/p&gt;
&lt;p&gt;m running on thread 13&lt;/p&gt;
&lt;p&gt;…**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice how the latter executes on multiple threads (but not in order). Next time I&amp;rsquo;ll talk about agents, control messages and error management.&lt;/p&gt;</description>
            <pubDate>Fri, 29 May 2009 13:26:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-05-29-lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.html</guid>
        </item>
        
        <item>
            <title>Luke talks about F# on Channel9</title>
            <link>https://www.lucabol.com/posts/2009-05-27-luke-talks-about-f-on-channel9.html</link>
            <description>&lt;p&gt;Here you go: &lt;a href="https://channel9.msdn.com/posts/Charles/Luke-Hoban-Latest-version-of-F-Released-Whats-the-story-Whats-next/" title="https://channel9.msdn.com/posts/Charles/Luke-Hoban-Latest-version-of-F-Released-Whats-the-story-Whats-next/"&gt;https://channel9.msdn.com/posts/Charles/Luke-Hoban-Latest-version-of-F-Released-Whats-the-story-Whats-next/&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Wed, 27 May 2009 12:47:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-05-27-luke-talks-about-f-on-channel9.html</guid>
        </item>
        
        <item>
            <title>A version of the AsyncCache found its way into the Parallel Programming samples …</title>
            <link>https://www.lucabol.com/posts/2009-05-21-a-version-of-the-asynccache-found-its-way-into-the-parallel-programming-samples.html</link>
            <description>&lt;p&gt;Go &lt;a href="http://code.msdn.microsoft.com/ParExtSamples"&gt;here&lt;/a&gt; to download them. It is in ParallelExtensionsExtrasCoordinationDataStructures. It has a slightly different design in that it returns Tasks. I’m trying to get &lt;a href="http://blogs.msdn.com/pfxteam"&gt;Stephen&lt;/a&gt; to blog about it so that you can compare them.&lt;/p&gt;</description>
            <pubDate>Thu, 21 May 2009 13:28:13 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-05-21-a-version-of-the-asynccache-found-its-way-into-the-parallel-programming-samples.html</guid>
        </item>
        
        <item>
            <title>I talk about C# and VB Co-Evolution on Channel9 (and some F# …)</title>
            <link>https://www.lucabol.com/posts/2009-05-14-i-talk-about-c-and-vb-co-evolution-on-channel9-and-some-f.html</link>
            <description>&lt;p&gt;The title says it all. If you are interested, go &lt;a href="https://channel9.msdn.com/posts/Charles/Luca-Bolognese-C-and-VBNET-Co-Evolution-The-Twain-Shall-Meet/#Page=2"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
            <pubDate>Thu, 14 May 2009 13:26:18 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-05-14-i-talk-about-c-and-vb-co-evolution-on-channel9-and-some-f.html</guid>
        </item>
        
        <item>
            <title>An Async Html cache – part II – Testing the cache</title>
            <link>https://www.lucabol.com/posts/2009-05-08-an-async-html-cache-part-ii-testing-the-cache.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/04/27/an-async-html-cache-part-i.aspx"&gt;Part I – Writing the cache&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s try out our little cache. First I want to write a synchronous version of it as a baseline.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Private Shared Sub TestSync(ByVal sites() As String, ByVal sitesToDownload As Integer, ByVal howLong As Integer)
    Dim syncCache As New Dictionary(Of String, String)
    Dim count = sites.Count()
    Dim url1 = &amp;quot;http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=&amp;quot;
    For i = 0 To sitesToDownload - 1
        Dim html As String = &amp;quot;&amp;quot;
        Dim url = url1 &amp;amp; sites(i Mod count)
        If Not syncCache.TryGetValue(url, html) Then
            html = LoadWebPage(url)
            syncCache(url) = html
        End If
        DoWork(html, howLong)
    Next
End Sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a loop that loads webpages in the cache if they are not already there. &lt;em&gt;sites&lt;/em&gt; is a list of tickers used to compose the urls; &lt;em&gt;sitesToDownload&lt;/em&gt; is the total number of sites to download, so that a single url can be loaded multiple times; &lt;em&gt;howLong&lt;/em&gt; represents the work to be done on each loaded page.&lt;/p&gt;
&lt;p&gt;In this version the cache is simply a &lt;em&gt;Dictionary&lt;/em&gt; and there is no parallelism. The two bold lines is where the cache is managed.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;DoWork&lt;/em&gt; is this.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Shared Sub DoWork(ByVal html As String, ByVal howLong As Integer)
    Thread.Sleep(howLong)
End Sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at the asynchronous version.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Private Shared Sub TestAsync(ByVal sites() As String, ByVal sitesToDownload As Integer, ByVal howLong As Integer)
    Dim htmlCache As New HtmlCache
    Dim count = sites.Count()
    Dim url = &amp;quot;http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=&amp;quot;
    Using ce = New CountdownEvent(sitesToDownload)
        For i = 1 To sitesToDownload
            htmlCache.GetHtmlAsync(
                url &amp;amp; sites(i Mod count),
                Sub(s)
                    DoWork(s, howLong)
                    ce.Signal()
                End Sub)
        Next
        ce.Wait()
    End Using
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are several points worth making on this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The lambda used as second parameter for &lt;em&gt;GetHtmlAsync&lt;/em&gt; is invoked on a different thread whenever the html has been retrieved (which could be immediately if the cache has downloaded the url before) &lt;/li&gt;
&lt;li&gt;&lt;em&gt;CountDownEvent&lt;/em&gt; allows a thread to wait for a certain number of signals to be sent. The waiting happens on the main thread in the &lt;em&gt;ce.Wait()&lt;/em&gt; instruction. The triggering of the event happens in the lambda described in the point above (the &lt;em&gt;ce.Signal()&lt;/em&gt; instruction) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the driver for the overall testing.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Private Shared Sub TestPerf(ByVal s As String, ByVal a As Action, ByVal iterations As Integer)
    Dim clock As New Stopwatch
    clock.Start()
    For i = 1 To iterations
        a()
    Next
    clock.Stop()
    Dim ts = clock.Elapsed
    Dim elapsedTime = String.Format(s &amp;amp; &amp;quot;: {0:00}:{1:00}:{2:00}.{3:00}&amp;quot;, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10)
    Console.WriteLine(elapsedTime, &amp;quot;RunTime&amp;quot;)
End Sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is not much to say about it. Start the clock, perform a bunch of iterations of the passed lambda, stop the clock, print out performance.&lt;/p&gt;
&lt;p&gt;And finally the main method. Note that all the adjustable parameters are factored out before the calls to &lt;em&gt;TestPerf&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Shared Sub Main()
    Dim tickers = New String() {&amp;quot;mmm&amp;quot;, &amp;quot;aos&amp;quot;, &amp;quot;shlm&amp;quot;, &amp;quot;cas&amp;quot;, &amp;quot;abt&amp;quot;, &amp;quot;anf&amp;quot;, &amp;quot;abm&amp;quot;, &amp;quot;akr&amp;quot;, &amp;quot;acet&amp;quot;, &amp;quot;afl&amp;quot;, &amp;quot;agl&amp;quot;, &amp;quot;adc&amp;quot;, &amp;quot;apd&amp;quot;,
                               &amp;quot;ayr&amp;quot;, &amp;quot;alsk&amp;quot;, &amp;quot;ain&amp;quot;, &amp;quot;axb&amp;quot;, &amp;quot;are&amp;quot;, &amp;quot;ale&amp;quot;, &amp;quot;ab&amp;quot;, &amp;quot;all&amp;quot;}
    Dim sitesToDownload = 50
    Dim workToDoOnEachUrlInMilliSec = 20
    Dim perfIterations = 5
    TestPerf(&amp;quot;Async&amp;quot;, Sub() TestAsync(tickers, sitesToDownload, workToDoOnEachUrlInMilliSec), perfIterations)
    TestPerf(&amp;quot;Sync&amp;quot;, Sub() TestSync(tickers, sitesToDownload, workToDoOnEachUrlInMilliSec), perfIterations)
End Sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Feel free to change (&lt;em&gt;tickers&lt;/em&gt;, &lt;em&gt;sitesToDownload&lt;/em&gt;, &lt;em&gt;workToDoOnEachUrlInMilliSec&lt;/em&gt;, &lt;em&gt;perfIterations&lt;/em&gt;). Depending on the ratios between these parameters and the number of cores on your machine, you&amp;rsquo;re going to see different results. Which highlights the fact that parallelizing your algorithms can yield performance gains or not depending on both software and hardware considerations. I get ~3X improvement on my box. I attached the full source file for your amusement. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/58/90/57/AsyncCache.vb"&gt;AsyncCache.vb&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Fri, 08 May 2009 11:34:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-05-08-an-async-html-cache-part-ii-testing-the-cache.html</guid>
        </item>
        
        <item>
            <title>An Async Html cache – Part I - Writing the cache</title>
            <link>https://www.lucabol.com/posts/2009-04-27-an-async-html-cache-part-i-writing-the-cache.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;font color="#006bad"&gt;&lt;a href="http://blogs.msdn.com/lucabol/"&gt;Part II  - Testing the cache&lt;/a&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the process of converting a financial VBA Excel Addin to .NET (more on that in later posts), I found myself in dire need of a HTML cache that can be called from multiple threads without blocking them. Visualize it as a glorified dictionary where each entry is (url, cachedHtml). The only difference is that when you get the page, you pass a callback to be invoked when the html has been loaded (which could be immediately if the html had already been retrieved by someone else).&lt;/p&gt;
&lt;p&gt;In essence, I want this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Sub GetHtmlAsync(ByVal url As String, ByVal callback As Action(Of String))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;m not a big expert in the &lt;a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"&gt;.Net Parallel Extensions&lt;/a&gt;, but I&amp;rsquo;ve got &lt;a href="http://blogs.msdn.com/pfxteam"&gt;help&lt;/a&gt;. Stephen Toub helped so much with this that he could have blogged about it himself. And, by the way, this code runs on Visual Studio 2010, which we haven&amp;rsquo;t shipped yet. I believe with some modifications, it can be run in 2008 + .Net Parallel Extensions CTP, but you&amp;rsquo;ll have to change a bunch of names.&lt;/p&gt;
&lt;p&gt;In any case, here it comes. First, let&amp;rsquo;s add some imports.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Imports System.Threading
Imports System.Net
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, let&amp;rsquo;s define an asynchronous cache.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Class AsyncCache(Of TKey, TValue)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This thing needs to store the (url, html) pairs somewhere and, luckily enough, there is an handy &lt;em&gt;ConcurrentDictionary&lt;/em&gt; that I can use. Also the cache needs to know how to load a &lt;em&gt;TValue&lt;/em&gt; given a &lt;em&gt;TKey&lt;/em&gt;. In &amp;lsquo;programmingese&amp;rsquo;, that means.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Private _loader As Func(Of TKey, TValue)
Private _map As New ConcurrentDictionary(Of TKey, Task(Of TValue))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;ll need a way to create it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Sub New(ByVal l As Func(Of TKey, TValue))
    _loader = l
End Sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice in the above code the use of the &lt;em&gt;Task&lt;/em&gt; class for my dictionary instead of &lt;em&gt;TValue&lt;/em&gt;. Task is a very good abstraction for &amp;ldquo;do some work asynchronously and call me when you are done&amp;rdquo;. It&amp;rsquo;s easy to initialize and it&amp;rsquo;s easy to attach callbacks to it. Indeed, this is what we&amp;rsquo;ll do next:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Sub GetValueAsync(ByVal key As TKey, ByVal callback As Action(Of TValue))
    Dim task As Task(Of TValue) = Nothing
    If Not _map.TryGetValue(key, task) Then
        task = New Task(Of TValue)(Function() _loader(key), TaskCreationOptions.DetachedFromParent)
        If _map.TryAdd(key, task) Then
            task.Start()
        Else
            task.Cancel()
            _map.TryGetValue(key, task)
        End If
    End If
    task.ContinueWith(Sub(t) callback(t.Result))
End Sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wow. Ok, let me explain. This method is divided in two parts. The first part is just a thread safe way to say &amp;ldquo;give me the task corresponding to this key or, if the task hasn&amp;rsquo;t been inserted in the cache yet, create it and insert it&amp;rdquo;. The second part just says &amp;ldquo;add callback to the list of functions to be called when the task has finished running&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The first part needs some more explanation. What is TaskCreationOptions.DetachedFromParent? It essentially says that the created task is not going to prevent the parent task from terminating. In essence, the task that created the child task won&amp;rsquo;t wait for its conclusion. The rest is better explained in comments.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;If Not _map.TryGetValue(key, task) Then ' Is the task in the cache? (Loc. X)
    task = New Task(Of TValue)(Function() _loader(key), TaskCreationOptions.DetachedFromParent) ' No, create it
    If _map.TryAdd(key, task) Then ' Try to add it
        task.Start() ' I succeeded. I'm the one who added this task. I can safely start it.
    Else
        task.Cancel() ' I failed, someone inserted the task after I checked in (Loc. X). Cancel it.
        _map.TryGetValue(key, task) ' And get the one that someone inserted
    End If
End If
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Got it? Well, I admit I trust Stephen that this is what I should do …&lt;/p&gt;
&lt;p&gt;I can then create my little HTML Cache by using the above class as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Public Class HtmlCache
    Public Sub GetHtmlAsync(ByVal url As String, ByVal callback As Action(Of String))
        _asyncCache.GetValueAsync(url, callback)
    End Sub
    Private Function LoadWebPage(ByVal url As String) As String
        Using client As New WebClient()
            'Test.PrintThread(&amp;quot;Downloading on thread {0} ...&amp;quot;)
            Return client.DownloadString(url)
        End Using
    End Function
    Private _asyncCache As New AsyncCache(Of String, String)(AddressOf LoadWebPage)
End Class
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have no idea why coloring got disabled when I copy/paste. It doesn&amp;rsquo;t matter, this is trivial. I just create an &lt;em&gt;AsyncCache&lt;/em&gt; and initialize it with a method that knows how to load a web page. I then simply implement &lt;em&gt;GetHtmlAsync&lt;/em&gt; by delegating to the underlying &lt;em&gt;GetValueAsync&lt;/em&gt; on &lt;em&gt;AsyncCache&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It is somehow bizarre to call &lt;em&gt;Webclient.DownloadString&lt;/em&gt;, when the design could be revised to take advantage of its asynchronous version. Maybe I&amp;rsquo;ll do it in another post. Next time, I&amp;rsquo;ll write code to use this thing.&lt;/p&gt;</description>
            <pubDate>Mon, 27 Apr 2009 19:57:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-04-27-an-async-html-cache-part-i-writing-the-cache.html</guid>
        </item>
        
        <item>
            <title>Luca at NDC in Oslo 17 – 19 June 2009</title>
            <link>https://www.lucabol.com/posts/2009-03-24-luca-at-ndc-in-oslo-17-19-june-2009.html</link>
            <description>&lt;p&gt;I’ll be speaking about the future of C# and F#. Oslo brings back so many memories …&lt;/p&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LucaatNDCinOslo1719June2009_8952/Logo%20NDC%202009_2.jpg"&gt;&lt;img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Logo NDC 2009" border="0" alt="Logo NDC 2009" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/lucabol/WindowsLiveWriter/LucaatNDCinOslo1719June2009_8952/Logo%20NDC%202009_thumb.jpg" width="244" height="72" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;“one of the world’s most important conferences for IT developers and leaders”&lt;/p&gt;</description>
            <pubDate>Tue, 24 Mar 2009 12:46:27 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-03-24-luca-at-ndc-in-oslo-17-19-june-2009.html</guid>
        </item>
        
        <item>
            <title>Excel Financial functions 2.0 released</title>
            <link>https://www.lucabol.com/posts/2009-02-25-excel-financial-functions-2-0-released.html</link>
            <description>&lt;p&gt;I simply fixed a bug related to the Rate function (wrong name for parameters).&lt;/p&gt;
&lt;p&gt;It is here: &lt;a href="http://code.msdn.microsoft.com/FinancialFunctions"&gt;http://code.msdn.microsoft.com/FinancialFunctions&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Wed, 25 Feb 2009 14:55:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-02-25-excel-financial-functions-2-0-released.html</guid>
        </item>
        
        <item>
            <title>Simulating INumeric with dynamic in C# 4.0</title>
            <link>https://www.lucabol.com/posts/2009-02-05-simulating-inumeric-with-dynamic-in-c-4-0.html</link>
            <description>&lt;p&gt;When I wrote my &lt;a href="http://blogs.msdn.com/lucabol/archive/2008/12/04/financial-functions-for-net-released.aspx"&gt;Excel financial library&lt;/a&gt; I agonized over the decision of which numeric type to use to represent money. Logic would push me toward &lt;em&gt;decimal&lt;/em&gt;, but common usage among financial library writers would push me toward &lt;em&gt;double&lt;/em&gt;. I ended up picking double, but I regret having to make that choice in the first place.&lt;/p&gt;
&lt;p&gt;Conceptually, I&amp;rsquo;d like my numeric functions to work for anything that supports the basic arithmetic operators (i.e. +, -, *). Unfortunately that is not possible in .NET at this point in time. In essence you have to write your code twice as below.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static double SumDouble(double a, double b) { return a + b; }
static decimal SumDecimal(decimal a, decimal b) { return a + b; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Granted, this is not a good state of affairs. We often discussed how to make it work, but we couldn&amp;rsquo;t find a solution that was both fast to run and cheap for us to implement. More often than not we speculated about having the numeric types implement a specific &lt;em&gt;INumeric&lt;/em&gt; interface and add a generic constraint to the C#/VB languages to make it work. Hence the title of this post.&lt;/p&gt;
&lt;p&gt;With we implemented &lt;em&gt;dynamic&lt;/em&gt; in C# 4.0 it occurred to me that you can fake your way into writing your code just once. For sure, this solution doesn&amp;rsquo;t have the same performance characteristics of &amp;lsquo;writing your code twice&amp;rsquo;, but at least it doesn&amp;rsquo;t duplicate your code.&lt;/p&gt;
&lt;p&gt;This is how it looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static dynamic Sum1(dynamic a, dynamic b) { return a + b; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The call to the &amp;lsquo;+&amp;rsquo; operator is resolved at runtime, by the C# binder, hence a performance penalty is incurred. The penalty is less than you might think, given that the &lt;a href="http://www.codeplex.com/dlr"&gt;DLR&lt;/a&gt; caches things under the cover so that no v-table lookup is performed the second time around. The whole thing is explained in more detail &lt;a href="http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx"&gt;here&lt;/a&gt;. But still, it is not as fast as a normal &amp;lsquo;+&amp;rsquo; operator over a primitive type. I&amp;rsquo;ll let you enjoy micro performance testing this one 🙂&lt;/p&gt;
&lt;p&gt;A slight refinement is to make the code generic so that a caller doesn&amp;rsquo;t see a signature with dynamic types as arguments.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;static dynamic Sum2&amp;lt;T1, T2&amp;gt;(T1 a, T2 b)
{
    dynamic ad = a;
    dynamic bd = b;
    return ad + bd;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I could make the return type generic as well, but that would force the caller to be explicit about the types, making the calling code much less readable. The other good thing about this signature is that you get a different call site with each combination of type arguments and, since they are separate, the binding caches should stay small. With the former signature there is only one call site and the cache could pile up to the point where the DLR decides to discard it.&lt;/p&gt;
&lt;p&gt;Here is how the calling code looks like right now:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Console.WriteLine(Sum2(2m, 4m));
Console.WriteLine(Sum2(2.0, 4.0));
Console.WriteLine(Sum2(new DateTime(2000,12,1), new TimeSpan(24,0,0)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yet another way to write this code is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static T Sum3&amp;lt;T&amp;gt;(T a, T b)
{
    dynamic ad = a;
    dynamic bd = b;
    return ad + bd;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gets around the problem of showing a dynamic return value and give you some more compile time type checking. But it prevents summing not coercible types. The compiler doesn&amp;rsquo;t let you get there. The last line below wont&amp;rsquo; compile:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Console.WriteLine(Sum3(2m, 4m));
Console.WriteLine(Sum3(2.0, 4.0));
//Console.WriteLine(Sum3(new DateTime(2000,12,1), new TimeSpan(24,0,0)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also notice that in VB you could have done this a long time ago 🙂&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vbnet"&gt;Function Sum(Of T1, T2)(ByVal a As T1, ByVal b As T2)
    Dim aa As Object = a
    Dim bb As Object = b
    Return aa + bb
End Function
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In summary, by using dynamic you can write your numeric code just once, but you pay a performance price. You are the only one who can decide if the price is worth paying in your particular application. As often, the profiler is your friend.&lt;/p&gt;</description>
            <pubDate>Thu, 05 Feb 2009 11:47:26 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-02-05-simulating-inumeric-with-dynamic-in-c-4-0.html</guid>
        </item>
        
        <item>
            <title>New release of Financial Functions .NET uploaded on MSDN Code Gallery</title>
            <link>https://www.lucabol.com/posts/2009-01-27-new-release-of-financial-functions-net-uploaded-on-msdn-code-gallery.html</link>
            <description>&lt;p&gt;I fixed the bug described in &lt;a href="https://code.msdn.microsoft.com/Thread/View.aspx?ProjectName=FinancialFunctions&amp;amp;ThreadId=1060"&gt;this&lt;/a&gt; thread and cleaned up the root finding algorithm. I’m still unhappy about it, but I have no time to code a better one right now (i.e. Ridder, Brent). I also added changes.txt and todo.txt to keep track of things.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;u&gt;Changes.txt&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;V1 &lt;br /&gt;
1. Fixed call to throw in bisection &lt;br /&gt;
2. Changed findBounds algo &lt;br /&gt;
3. Added TestXirrBugs function &lt;br /&gt;
4. Removed the NewValue functions everywhere&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;u&gt;ToDo.txt&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The interaction of Bisection and Newton algo in findRoot needs review. It seems like it is working now, but it could use some love. Maybe I should switch to a better root finding algo (i.e. Rudder or Brent)&lt;/li&gt;
&lt;/ol&gt;</description>
            <pubDate>Tue, 27 Jan 2009 14:18:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-01-27-new-release-of-financial-functions-net-uploaded-on-msdn-code-gallery.html</guid>
        </item>
        
        <item>
            <title>Bayesian inference in F# – Part IIb – Finding Maia underlying attitude</title>
            <link>https://www.lucabol.com/posts/2009-01-19-bayesian-inference-in-f-part-iib-finding-maia-underlying-attitude.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/11/07/bayesian-inference-in-f-part-i-background.aspx"&gt;Part I – Background&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/11/26/bayesian-inference-in-f-part-iia-a-simple-example-modeling-maia.aspx"&gt;Part II – A simple example – modeling Maia&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The previous post ended on this note.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let MaiaJointProb attitude action =
    match attitude with
    | Happy     -&amp;gt; happyActions |&amp;gt; List.assoc action
    | UnHappy   -&amp;gt; unHappyActions |&amp;gt; List.assoc action
    | Quiet     -&amp;gt; quietActions |&amp;gt; List.assoc action
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is just a two by two matrix. It simply represents which probability is associated to an (attitude, action) tuple. It is useful to think about it in these terms, because it makes easier to grasp the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Conditional probability of a mental state, given a particular observed action
let MaiaLikelihood action = fun attitude -&amp;gt; MaiaJointProb attitude action
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is simply a row in the matrix. It answers the question: given that I observe a particular action, what is the probability that Maia has a certain attitude?. This is called &amp;ldquo;likelihood function&amp;rdquo; in statistics. Its general form is: given that a I observe an outcome, what is the probability that it is generated by a process with a particular parameter?&lt;/p&gt;
&lt;p&gt;A related question is then: what if I observe a sequence of independent actions? What is the probability that the baby has a certain attitude then? This is answered by the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Multiple applications of the previous conditional probabilities for a series of actions (multiplied)
let MaiaLikelihoods actions =
    let composeLikelihoods previousLikelihood action  = fun attitude -&amp;gt; previousLikelihood attitude * MaiaLikelihood action attitude
    actions |&amp;gt; Seq.fold composeLikelihoods (fun attitude -&amp;gt; 1.)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a trivial extension of the previous function (really), once you know that to combine likelihoods you multiply them.&lt;/p&gt;
&lt;p&gt;We now need to describe what our prior is. A prior is our preconceived notion about a particular parameter (in this case the baby&amp;rsquo;s attitude). You might be tempted to express that notion with a single value, but that would be inaccurate. You need to indicate how confident you are about it. In statistics you do that by choosing a distribution for your belief. This is one of the beauties of Bayesian statistics, everything is a probability distribution. In this case, we really don&amp;rsquo;t have any previous belief, so we pick the uniform distribution.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let MaiaUniformPrior attitude = 1. / 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Think of this as: you haven&amp;rsquo;t read any baby-attitude-specific study or received any external information about the likely attitude of Maia, so you cannot prefer one attitude over another.&lt;/p&gt;
&lt;p&gt;We are almost done. Now we have to apply the Bayesian theorem and get the un-normalized posterior distribution. Forget about the un-normalized word. What is a posterior distribution? This is your output, your return value. It says: given my prior belief on the value of a parameter and given the outcomes that I observed, this is what I now believe the parameter to be. In this case it goes like: I had no opinion on Maia&amp;rsquo;s attitude to start with, but after I observed her behavior for a while, I now think she is Happy with probability X, UnHappy with probability Y and Quiet with probability Z.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Calculates the unNormalized posterior given prior and likelihood
let unNormalizedPosterior (prior:'a -&amp;gt; float) likelihood =
    fun theta -&amp;gt; prior theta * likelihood theta
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then need to normalize this thing (it doesn&amp;rsquo;t sum to one). The way to do it is to divide each probability by the sum of the probabilities for all the possible outcomes.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// All possible values for the unobservable parameter (mental state)
let support = [Happy; UnHappy; Quiet]
/// Normalize the posterior (it integrates to 1.)
let posterior prior likelihood =
    let post = unNormalizedPosterior prior likelihood
    let sum = support |&amp;gt; List.sum_by (fun attitude -&amp;gt; post attitude)
    fun attitude -&amp;gt; post attitude / sum
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are done. Now we can now start modeling scenarios. Let&amp;rsquo;s say that you observe [Smile;Smile;Cry;Smile;LookSilly]. What could the underlying attitude of Maia be?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let maiaIsANormalBaby = posterior MaiaUniformPrior (MaiaLikelihoods [Smile;Smile;Cry;Smile;LookSilly])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can then execute our little model:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;maiaIsANormalBaby Happy
maiaIsANormalBaby UnHappy
maiaIsANormalBaby Quiet
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we get (0.5625, 0.0625, 0.375). So Maia is likely to be happy and unlikely to be unhappy. Let&amp;rsquo;s now model one extreme case:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Extreme cases
let maiaIsLikelyHappyDist = posterior MaiaUniformPrior (MaiaLikelihoods [Smile;Smile;Smile;Smile;Smile;Smile;Smile])
maiaIsLikelyHappyDist Happy
maiaIsLikelyHappyDist UnHappy
maiaIsLikelyHappyDist Quiet
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we get (0.944, 0.000431, 0.05). Now Maia is almost certainly Happy. Notice that I can confidently make this affirmation because my end result is exactly what I was looking for when I started my quest. Using classical statistics, that wouldn&amp;rsquo;t be the case.&lt;/p&gt;
&lt;p&gt;A related question I might want to ask is: given the posterior distribution for attitude that I just found, what is the probability of observing a particular action? In other words, given the model that I built, what does it predict?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let posteriorPredictive jointProb posterior =
    let composeProbs previousProbs attitude = fun action -&amp;gt; previousProbs action + jointProb attitude action * posterior attitude
    support |&amp;gt; Seq.fold composeProbs (fun action -&amp;gt; 0.)
let nextLikelyUnknownActionDist = posteriorPredictive MaiaJointProb maiaIsLikelyHappyDist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don&amp;rsquo;t have the strength right now to explain the mathematical underpinning of this. In words, this says: considering that Maia can have one of the possible three Attitudes with the probability calculated above, what is the probability that I observe a particular action? Notice that the signature for it is: (Action -&amp;gt; float), which is the compiler way to say it.&lt;/p&gt;
&lt;p&gt;Now we can run the thing.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;nextLikelyUnknownActionDist Smile
nextLikelyUnknownActionDist Cry
nextLikelyUnknownActionDist LookSilly
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we get (0.588, 0.2056, 0.2055). Why is that? We&amp;rsquo;ll talk about it in the next post.&lt;/p&gt;</description>
            <pubDate>Mon, 19 Jan 2009 11:48:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2009-01-19-bayesian-inference-in-f-part-iib-finding-maia-underlying-attitude.html</guid>
        </item>
        
        <item>
            <title>Financial Functions for .NET released !</title>
            <link>https://www.lucabol.com/posts/2008-12-04-financial-functions-for-net-released.html</link>
            <description>&lt;p&gt;Today I released the following library on CodeGallery. It is the result of three months of coding during my paternity leave in Italy. You can get it from &lt;a href="http://code.msdn.microsoft.com/FinancialFunctions"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt; &lt;br /&gt;
This is a .NET library that provides the full set of financial functions from Excel. The main goal for the library is compatibility with Excel, by providing the same functions, with the same behaviour. Note though that this is not a wrapper over the Excel library; the functions have been re-implemented in managed code so that you do not need to have Excel installed to use this library.&amp;nbsp;&lt;br /&gt;
&lt;strong&gt;&amp;nbsp;&lt;br /&gt;
&lt;/strong&gt; &lt;strong&gt;Where I can find documentation on these functions?&lt;/strong&gt; &lt;br /&gt;
Just open Excel and click on Formulas/Financial or go to &lt;a href="http://office.microsoft.com/client/helppreview.aspx?AssetID=HP100791841033&amp;amp;ns=EXCEL&amp;amp;lcid=1033&amp;amp;CTT=3&amp;amp;Origin=HP100623561033"&gt;this&lt;/a&gt; &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
I don&amp;rsquo;t think one of the function is right. Excel produces the wrong results! Why don&amp;rsquo;t you do it right?&lt;/strong&gt; &lt;br /&gt;
My goal is to replicate Excel results (right and wrong). Feel free to contribute to the effort by coding what you think is the right solution and I&amp;rsquo;ll add an ExcelCompliant flag to the function to conditionally invoke your code. &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
How do I use the library?&lt;/strong&gt; &lt;br /&gt;
Just add Financial.dll to the references in your project. The functions are provided as static methods on a Financial class in the System.Numeric namespace &lt;br /&gt;
&lt;strong&gt;I see the library was implemented with F#. But I don’t want to redistribute F# along with my application. What should I do?&lt;/strong&gt; &lt;br /&gt;
There are two versions of the library. One of them statically links the F# libraries so that there is no dependency on F#. However, this assembly larger, so if you have F# installed, you can use the FinancialNotStandalone.dll instead. &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
How do I run the tests?&lt;/strong&gt; &lt;br /&gt;
Run FinancialTests.exe. You need Excel 12 for the tests to work because they use Excel to test that the results are correct. You don&amp;rsquo;t need Excel 12 to use the library in your own application. &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
How do I compile the library?&lt;/strong&gt; &lt;br /&gt;
You need to have F# September CTP installed (you can get it from &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c"&gt;here&lt;/a&gt;). There are two batch files (CreateLibraryStandalone.bat and CreateLibraryNotStandalon.bat). Run them to compile the dll. You might have to change the path to the F# compiler inside these files &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
How do I compile the tests?&lt;/strong&gt; &lt;br /&gt;
Run CreateTests.bat &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
Have you tested this thing?&lt;/strong&gt; &lt;br /&gt;
Yes, I do have 201,349 testcases running against it. You can easily raise that number significantly by adding new values to test in testdef.fs. If you have a multiproc machine the testcases will run faster as I parallelize their execution. &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
Have you run performance tests on it?&lt;/strong&gt; &lt;br /&gt;
Not at all. The only thing I checked is that all the recursive functions are tail recursive. Feel free to let me know if they are slow. &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
Are there any functions that behave different from Excel?&lt;/strong&gt; &lt;br /&gt;
Yes, there are two of them. &lt;br /&gt;
&lt;em&gt;CoupDays&lt;/em&gt; &lt;br /&gt;
The Excel algorithm seems wrong in that it doesn&amp;rsquo;t respect the following: &lt;br /&gt;
coupDays = coupDaysBS + coupDaysNC. &lt;br /&gt;
This equality should stand. By manually counting the days, I&amp;rsquo;m pretty confident that my algorithm is correct.My result differs from Excel by +/- one or two days when the date spans a leap year. &lt;br /&gt;
&lt;em&gt;VDB&lt;/em&gt; &lt;br /&gt;
In the excel version of this algorithm the depreciation in the period (0,1) is not the same as the sum of the depreciations in periods (0,0.5) (0.5,1). &lt;br /&gt;
VDB(100,10,13,0,0.5,1,0) + VDB(100,10,13,0.5,1,1,0) &amp;lt;&amp;gt; VDB(100,10,13,0,1,1,0) &lt;br /&gt;
Notice that in Excel by using &amp;#8216;1&amp;rsquo; (no_switch) instead of &amp;#8216;0&amp;rsquo; as the last parameter everything works as expected. The last parameter should have no influence in the calculation given that in the first period there is no switch to sln depreciation. &lt;br /&gt;
Overall, I think my algorithm is correct, even if it disagrees with Excel when startperiod is fractional. &lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
Can you list the functions with their testcases results?&lt;/strong&gt; &lt;br /&gt;
Succeeded 1840/1840 for PV &lt;br /&gt;
Succeeded 2024/2024 for FV &lt;br /&gt;
Succeeded 2240/2240 for PMT &lt;br /&gt;
Succeeded 853/853 for NPER &lt;br /&gt;
Succeeded 5355/5355 for IPMT &lt;br /&gt;
Succeeded 5355/5355 for PPMT &lt;br /&gt;
Succeeded 208/208 for CUMIPMT &lt;br /&gt;
Succeeded 208/208 for CUMPRINC &lt;br /&gt;
Succeeded 624/624 for ISPMT &lt;br /&gt;
Succeeded 12/12 for FVSCHEDULE &lt;br /&gt;
Succeeded 9/9 for IRR &lt;br /&gt;
Succeeded 21/21 for NPV &lt;br /&gt;
Succeeded 147/147 for MIRR &lt;br /&gt;
Succeeded 18/18 for XIRR &lt;br /&gt;
Succeeded 396/396 for DB &lt;br /&gt;
Succeeded 24/24 for SLN &lt;br /&gt;
Succeeded 132/132 for SYD &lt;br /&gt;
Succeeded 456/456 for DDB &lt;br /&gt;
Succeeded 2544/2544 for VDB excluding fractional startdates &lt;br /&gt;
Succeeded 11520/11520 for AMORLINC &lt;br /&gt;
Succeeded 23040/23040 for AMORDEGRC &lt;br /&gt;
Succeeded 15/15 for COUPDAYS excluding leap years &lt;br /&gt;
Succeeded 915/915 for COUPDAYSBS &lt;br /&gt;
Succeeded 915/915 for COUPDAYSNC &lt;br /&gt;
Succeeded 915/915 for COUPNUM &lt;br /&gt;
Succeeded 915/915 for COUPPCD &lt;br /&gt;
Succeeded 915/915 for COUPNCD &lt;br /&gt;
Succeeded 360/360 for ACCRINTM &lt;br /&gt;
Succeeded 1920/1920 for ACCRINT &lt;br /&gt;
Succeeded 10980/10980 for PRICE &lt;br /&gt;
Succeeded 1940/1940 for PRICEMAT &lt;br /&gt;
Succeeded 2910/2910 for YIELDMAT &lt;br /&gt;
Succeeded 1395/1395 for YEARFRAC &lt;br /&gt;
Succeeded 2745/2745 for INTRATE &lt;br /&gt;
Succeeded 1290/1290 for RECEIVED &lt;br /&gt;
Succeeded 2745/2745 for DISC &lt;br /&gt;
Succeeded 3660/3660 for PRICEDISC &lt;br /&gt;
Succeeded 2745/2745 for YIELDDISC &lt;br /&gt;
Succeeded 48/48 for TBILLEQ &lt;br /&gt;
Succeeded 69/69 for TBILLYIELD &lt;br /&gt;
Succeeded 81/81 for TBILLPrice &lt;br /&gt;
Succeeded 12/12 for DOLLARDE &lt;br /&gt;
Succeeded 12/12 for DOLLARFR &lt;br /&gt;
Succeeded 12/12 for EFFECT &lt;br /&gt;
Succeeded 12/12 for NOMINAL &lt;br /&gt;
Succeeded 5490/5490 for DURATION &lt;br /&gt;
Succeeded 5490/5490 for MDURATION &lt;br /&gt;
Succeeded 19320/19320 for ODDFPRICE &lt;br /&gt;
Succeeded 30600/30600 for ODDLPRICE &lt;br /&gt;
Succeeded 45900/45900 for ODDLYIELD &lt;br /&gt;
Test Cases Succeeded 201349/201349&lt;/p&gt;</description>
            <pubDate>Thu, 04 Dec 2008 16:40:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-12-04-financial-functions-for-net-released.html</guid>
        </item>
        
        <item>
            <title>Bayesian inference in F# - Part IIa - A simple example - modeling Maia</title>
            <link>https://www.lucabol.com/posts/2008-11-26-bayesian-inference-in-f-part-iia-a-simple-example-modeling-maia.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/11/07/bayesian-inference-in-f-part-i-background.aspx"&gt;Part I  - Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2009/01/19/bayesian-inference-in-f-part-iib-finding-maia-underlying-attitude.aspx"&gt;Part IIb  - Finding Maia underlying attitude&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s start with a simple example: inferring the underlying attitude of a small baby by observing her actions. Let&amp;rsquo;s call this particular small baby Maia. People always asks her father if she is a &amp;lsquo;good&amp;rsquo; baby or not. Her father started to wonder how he can possibly know that. Being &amp;lsquo;good&amp;rsquo; is not very clear, so he chooses to answer the related question if her attitude is generally happy, unhappy or simply quiet (a kind of middle ground).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Underlying unobservable, but assumed stationary, state of the process (baby). Theta.
type Attitude =
    | Happy
    | UnHappy
    | Quiet
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Her poor father doesn&amp;rsquo;t have much to go with. He can just observe what she does. He decides, for the sake of simplifying things, to categorize her state at each particular moment as smiling, crying or looking silly (a kind of middle ground).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Observable data. y.
type Action =
    | Smile
    | Cry
    | LookSilly
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The father now has to decide what does it mean for Maia to be of an happy attitude. Lacking an universal definition of happiness in terms of these actions, he makes one up. Maia would be considered happy if she smiles 60% of the times, she cries 20% of the times and looks silly the remaining 20% of the times. He might as well have experimented with clearly happy/unhappy babies to come up with those numbers.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Data to model the underlying process (baby)
let happyActions = [ Smile, 0.6; Cry, 0.2; LookSilly, 0.2]
let unHappyActions = [Smile, 0.2; Cry, 0.6; LookSilly, 0.2]
let quietActions = [Smile, 0.4; Cry, 0.3; LookSilly, 0.3]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What does it mean exactly? Well, this father would call his wife at random times during the day and ask her if Maia is smiling, crying or looking silly. He would then keep track of the numbers and then somehow decide what her attitude is. The general idea is simple, the somehow part is not.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Generates a new uniformly distributed number between 0 and 1
let random =
    let rnd = new System.Random()
    rnd.NextDouble
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now model Maia. We want our model to return a particular action depending on which attitude we assume Maia is in mostly. For example, if we assume she is an happy baby, we want our model to return Smile about 60% of the times. In essence, we want to model what happens when the (poor) father calls his (even poorer) wife. What would his wife tell him (assuming a particular attitude)? The general idea is expressed by the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Process (baby) modeling. How she acts if she is fundamentally happy, unhappy or quiet
let MaiaSampleDistribution attitude =
    match attitude with
    | Happy     -&amp;gt; pickOne happyActions
    | UnHappy   -&amp;gt; pickOne unHappyActions
    | Quiet     -&amp;gt; pickOne quietActions
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &amp;lsquo;pickOne&amp;rsquo; function simply picks an action depending on the probability of it being picked. The name sample distribution is statistic-lingo to mean &amp;lsquo;what you observe&amp;rsquo; and indeed you just can observe Maia&amp;rsquo;s actions, not her underlying attitude.&lt;/p&gt;
&lt;p&gt;The implementation of pickOne gets technical. You don&amp;rsquo;t need to understand it to understand the rest of this post. This is the beauty of encapsulation. You can start reading from after the next code snippet if you want to.&lt;/p&gt;
&lt;p&gt;&amp;lsquo;pickOne&amp;rsquo; works by constructing the inverse cumulative distribution function for the probability distribution described by the Happy/UnHappy/Quiet/Actions lists. There is an &lt;a href="http://en.wikipedia.org/wiki/Inverse_transform_sampling"&gt;entry on wikipedia&lt;/a&gt; that describes how this works and I don&amp;rsquo;t wish to say more here except presenting the code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Find the first value more or equal to a key in a seq&amp;lt;'a * 'b&amp;gt;.
/// The seq is assumed to be sorted
let findByKey key aSeq =
    aSeq |&amp;gt; Seq.find (fun (k, _) -&amp;gt; k &amp;gt;= key) |&amp;gt; snd
/// Simulate an inverse CDF given values and probabilities
let buildInvCdf valueProbs =
    let cdfValues =
        valueProbs
        |&amp;gt; Seq.scan (fun cd (_, p) -&amp;gt; cd + p) 0.
        |&amp;gt; Seq.skip 1
    let cdf =
        valueProbs
        |&amp;gt; Seq.map fst
        |&amp;gt; Seq.zip cdfValues
        |&amp;gt; Seq.cache
    fun x -&amp;gt; cdf |&amp;gt; findByKey x
/// Picks an 'a in a seq&amp;lt;'a * float&amp;gt; using float as the probability to pick a particular 'a
let pickOne probs =
    let rnd = random ()
    let picker = buildInvCdf probs
    picker rnd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another way to describe Maia is more mathematically convenient and will be used in the rest of the post. This second model answers the question: what is the probability of observing an action assuming a particular attitude? The distribution of both actions and attitudes (observable variable and parameter) is called joint probability.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;/// Another, mathematically more convenient, way to model the process (baby)
let MaiaJointProb attitude action =
    match attitude with
    | Happy     -&amp;gt; happyActions |&amp;gt; List.assoc action
    | UnHappy   -&amp;gt; unHappyActions |&amp;gt; List.assoc action
    | Quiet     -&amp;gt; quietActions |&amp;gt; List.assoc action
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;List.assoc returns the value associated with a key in a list containing (key, value) pairs. Notice that in general, if you are observing a process, you don&amp;rsquo;t know what its joint distribution is. But you can approximate it by running the MaiaSampleDistribution function on known babies many times and keeping track of the result. So, in theory, if you have a way to experiment with many babies with known attitudes, you can create such a joint distribution.&lt;/p&gt;
&lt;p&gt;We now have modeled our problem, this is the creative part. From now on, it is just execution. We&amp;rsquo;ll get to that.&lt;/p&gt;</description>
            <pubDate>Wed, 26 Nov 2008 15:41:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-11-26-bayesian-inference-in-f-part-iia-a-simple-example-modeling-maia.html</guid>
        </item>
        
        <item>
            <title>Expression tree serialization code posted on Code Gallery</title>
            <link>https://www.lucabol.com/posts/2008-11-20-expression-tree-serialization-code-posted-on-code-gallery.html</link>
            <description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/lukeh/default.aspx"&gt;Luke&lt;/a&gt; and I worked on this last year for one week doing pair programming. It is a good sample of how you can serialize LINQ expression trees to xml. &lt;/p&gt;
&lt;p&gt;The sample includes these components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;An Expression Tree serialization API&lt;/strong&gt;: A general purpose XML serialization of Expression Trees. This should work over any expression tree  - though there are inevitably bugs. The serialization format is fairly crude, but has been expressive enough to support the variety of expression trees I&amp;rsquo;ve tried throwing at it. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A wrapper for serializing/deserializing LINQ to SQL queries&lt;/strong&gt;: A wrapper around the expression serializer allows serializing LINQ to SQL queries and de-serializing into a query against a given DataContext. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A WCF service which accepts serialized query expression trees and executes against a back-end LINQ to SQL&lt;/strong&gt;: To enable querying across tiers, a WCF service exposes service methods which execute serialized queries. The service implementation deserializes the queries against its LINQ to SQL connection. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An IQueryable implementation wrapping the client side of the WCF service&lt;/strong&gt;: The client-side calling syntax is simplified by providing an IQueryable implementation. This implementation, RemoteTable, executes queries by serializing the query expression tree and calling the appropriate service. The object model that the service user is able to query against is imported by the WCF service reference per the DataContracts on the LINQ to SQL mapping on the server side&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href="http://code.msdn.microsoft.com/exprserialization"&gt;sample&lt;/a&gt; is here. Enjoy!&lt;/p&gt;</description>
            <pubDate>Thu, 20 Nov 2008 15:39:20 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-11-20-expression-tree-serialization-code-posted-on-code-gallery.html</guid>
        </item>
        
        <item>
            <title>Bayesian inference in F#  - Part I - Background</title>
            <link>https://www.lucabol.com/posts/2008-11-07-bayesian-inference-in-f-part-i-background.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;div&gt;
      &lt;a href="http://blogs.msdn.com/lucabol/archive/2008/11/26/bayesian-inference-in-f-part-iia-a-simple-example-modeling-maia.aspx"&gt;Part IIa  - A simple example  - modeling Maia&lt;/a&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div&gt;
      &lt;a href="http://blogs.msdn.com/lucabol/archive/2009/01/19/bayesian-inference-in-f-part-iib-finding-maia-underlying-attitude.aspx"&gt;Part IIb  - Finding Maia underlying attitude&lt;/a&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My interest in Bayesian inference comes from my dissatisfaction with &amp;#8216;classical&amp;rsquo; statistics. Whenever I want to know something, for example the probability that an unknown parameter is between two values, &amp;#8216;classical&amp;rsquo; statistics seems to answer a different and more convoluted question.&lt;/p&gt;
&lt;p&gt;Try asking someone what the 95% confidence interval for X is (x1, x2) means. Very likely he will tell you that it means that there is a 95% probability that X lies between x1 and x2. That is not the case in classical statistics. It is the case in Bayesian statistics. Also all the funny business of defining a Null hypothesis for the sake of proving its falseness always made my head spin. You don&amp;rsquo;t need any of that in Bayesian statistics. More recently, my discovery that statistical significance is an harmful concept, instead of the bedrock of knowledge I always thought it to be, shook my confidence in &amp;#8216;classical&amp;rsquo; statistics even more.&lt;/p&gt;
&lt;p&gt;Admittedly, I&amp;rsquo;m not that smart. If I have an hard time getting an intuitive understanding of something, it tends to go away from my mind after a couple of days I&amp;rsquo;ve learned it. This happens all the time with &amp;#8216;classical&amp;rsquo; statistics. I feel like I have learned the thing ten times, because I continuously forget it. This doesn&amp;rsquo;t happen with Bayesian statistics. It just makes intuitive sense.&lt;/p&gt;
&lt;p&gt;At this point you might be wandering what &amp;#8216;classical&amp;rsquo; statistics is. I use the term classical, but I really shouldn&amp;rsquo;t. Classical statistics is normally just called &amp;#8216;statistics&amp;rsquo; and it is all you learn if you pick up whatever book on the topic (for example the otherwise excellent &lt;a href="http://www.amazon.com/Introduction-Practice-Statistics-w-CD-ROM/dp/0716764008/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1225747881&amp;amp;sr=1-1"&gt;Introduction to the Practice of Statistics&lt;/a&gt;). Bayesian statistics is just a footnote in such books. This is a shame.&lt;/p&gt;
&lt;p&gt;Bayesian statistics provides a much clearer and elegant framework for understanding the process of inferring knowledge from data. The underlying question that it answers is: If I hold an opinion about something and I receive additional data on it, how should I rationally change my opinion?. This question of how to update your knowledge is at the very foundation of human learning and progress in general (for example the scientific method is based on it). We better be sure that the way we answer it is sound.&lt;/p&gt;
&lt;p&gt;You might wander how it is possible to go against something that is so widely accepted and taught everywhere as &amp;#8216;classical&amp;rsquo; statistics is. Well, very many things that most people believe are wrong. I always like to cite &lt;a href="http://en.wikipedia.org/wiki/Benjamin_Graham"&gt;old Ben&lt;/a&gt; on this: The fact that other people agree or disagree with you makes you neither right nor wrong. You will be right if your facts and your reasoning are correct.. This little rule always served me well.&lt;/p&gt;
&lt;p&gt;In this series of posts I will give examples of Bayesian statistics in F#. I am not a statistician, which makes me part of the very dangerous category of &amp;#8216;people who are not statisticians but talk about statistics. To try to mitigate the problem I enlisted the help of &lt;a href="http://research.microsoft.com/~rherb/"&gt;Ralf Herbrich&lt;/a&gt;, who is a statistician and can catch my most blatant errors. Obviously I&amp;rsquo;ll manage to hide my errors so cleverly that not even Ralf would spot them. In which case the fault is just mine.&lt;/p&gt;
&lt;p&gt;In the next post we&amp;rsquo;ll look at some F# code to model the Bayesian inference process.&lt;/p&gt;</description>
            <pubDate>Fri, 07 Nov 2008 11:48:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-11-07-bayesian-inference-in-f-part-i-background.html</guid>
        </item>
        
        <item>
            <title>My F# PDC presentation is online (+ ppt and demo application)</title>
            <link>https://www.lucabol.com/posts/2008-11-03-my-f-pdc-presentation-is-online-ppt-and-demo-application.html</link>
            <description>&lt;p&gt;You can watch it &lt;a href="https://channel9.msdn.com/pdc2008/TL11/"&gt;here&lt;/a&gt;. Also I attached the demo application I built on stage.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/03/37/46/fsharpdemoPDCPrez.zip"&gt;fsharpdemoPDCPrez.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 03 Nov 2008 11:33:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-11-03-my-f-pdc-presentation-is-online-ppt-and-demo-application.html</guid>
        </item>
        
        <item>
            <title>Luca presenting F# at PDC 2008</title>
            <link>https://www.lucabol.com/posts/2008-10-24-luca-presenting-f-at-pdc-2008.html</link>
            <description>&lt;p&gt;Next Thursday at 1.45pm I will present &lt;a href="https://channel9.msdn.com/pdc2008/TL11/"&gt;&amp;ldquo;An introduction to Microsoft F#&amp;rdquo;&lt;/a&gt; at PDC 2008. If you are there, please stop by or drop by the lounge area to chat.&lt;/p&gt;
&lt;p&gt;There are a bunch of other great sessions from my team. They are all good (I swear I tried to format John&amp;rsquo;s session correctly, but failed).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:.5in;text-indent:-.25in;"&gt;
      &lt;strong&gt;TL16: The Future of C#&lt;/strong&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Speaker: Anders Hejlsberg
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Mon 10/27 | 1:45 PM-3:00 PM | Petree Hall CD
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Repeated: Wed 10/29 | 3:00 PM-4:15 PM | 502A
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:.5in;text-indent:-.25in;"&gt;
      &lt;strong&gt;TL10: Deep Dive: Dynamic Languages in .NET&lt;/strong&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Speaker: Jim Hugunin
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Mon 10/27 | 3:30PM | 502A
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:.5in;text-indent:-.25in;"&gt;
      &lt;strong&gt;TL11: An Introduction to Microsoft F#&lt;/strong&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Speaker: Luca Bolognese
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Thu 10/30 | 1:45 PM-3:00 PM | 502A
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:.5in;text-indent:-.25in;"&gt;
      &lt;strong&gt;TL12: Future Directions for Microsoft Visual Basic&lt;/strong&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Speaker: Paul Vick
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Tue 10/28 | 5:15 PM-6:30 PM | 406A
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:.5in;text-indent:-.25in;"&gt;
      &lt;strong&gt;TL54: Natural Interop with Silverlight and Office&lt;/strong&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Alex Turner
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      Tue 10/28 | 12:45 PM-1:30 PM | 404A
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:.5in;text-indent:-.25in;"&gt;
      &lt;strong&gt;TL57: A Panel on the Future of Programming Languages&lt;/strong&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      G. Bracha, D.Crockford, A. Hejlsberg, E. Meijer, W.Schulte, J. Siek
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;div class="MsoNormal" style="margin-left:1in;text-indent:-.25in;"&gt;
      &lt;span lang="DE"&gt;Wed 10/29 | 10:30 AM-11:45 AM | 403AB&lt;/span&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TL44 IronRuby: The Right Language for the Right Job&lt;/strong&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;l Speaker: John Lam&lt;/li&gt;
&lt;li&gt;l Mon 10/27, 5:15PM, 515B&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Fri, 24 Oct 2008 12:21:14 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-10-24-luca-presenting-f-at-pdc-2008.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices in F# - Part VI - Code posted</title>
            <link>https://www.lucabol.com/posts/2008-10-20-downloading-stock-prices-in-f-part-vi-code-posted.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I  - Data modeling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II  - Html scraping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;Part III  - Async loader for prices and divs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx"&gt;Part IV  - Async loader for splits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V  - Adjusting historical data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/lukeh/default.aspx"&gt;An unnamed friend&lt;/a&gt; told me that I should stop posting small snippets of code and instead post entire solutions on &lt;a href="http://code.msdn.microsoft.com/"&gt;CodeGallery&lt;/a&gt;. I did it for this one and &lt;a href="http://code.msdn.microsoft.com/DownloadStockPrices"&gt;here&lt;/a&gt; is the link.&lt;/p&gt;
&lt;p&gt;Here is what&amp;rsquo;s in the zip file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;BackTestF&lt;/strong&gt;  - main library to download stock prices&lt;/li&gt;
&lt;li&gt;Common.fs  - common things used in the rest of the project (i.e. data modeling and common funcs)&lt;/li&gt;
&lt;li&gt;html.fs  - functions to scrap html tables, rows and cells&lt;/li&gt;
&lt;li&gt;loader.fs  - this is where the main async downloading algorithms are implemented&lt;/li&gt;
&lt;li&gt;persistence.fs  - async saving and loading of stock prices to files&lt;/li&gt;
&lt;li&gt;algorithms.fs  - async calculations of compound yearly returns given tickers and dates&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dotNetWrapper.fs  - gives a .NET friendly interface to the whole library so that you can use it from C#/VB.NET&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tests&lt;/strong&gt;  - too few testcases running on xUnit (you need to download xUnit separately to run them&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ReturnCalculator&lt;/strong&gt;  - simple console application to show usage of the library&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bob&lt;/strong&gt;  - rough winforms UI application that uses the library. An unnamed friend (&lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb735849.aspx"&gt;Jonathan&lt;/a&gt;) promised me that he was going to create a UI for my little library. My requirements were very simple: I want the best UI app of this century, one that fully takes advantage of the async nature of my code. Bob doesn&amp;rsquo;t fully satisfy my requirements yet 🙂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code in persistence.fs, algorithms.fs and especially dotnetwrapper.fs is pretty rough and uninteresting. This is why I don&amp;rsquo;t blog about it. I reserve the right to do it if I get around to clean it up.&lt;/p&gt;</description>
            <pubDate>Mon, 20 Oct 2008 18:45:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-10-20-downloading-stock-prices-in-f-part-vi-code-posted.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices in F# - Part V - Adjusting historical data</title>
            <link>https://www.lucabol.com/posts/2008-09-26-downloading-stock-prices-in-f-part-v-adjusting-historical-data.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I  - Data modeling&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II  - Html scraping&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;Part III  - Async loader for prices and divs&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx"&gt;Part IV  - Async loader for splits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx"&gt;Part VI  - Code posted&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the problem. When you download prices/divs/splits from Yahoo you get a strange mix of historical numbers and adjusted numbers. To be more precise, the dividends are historically adjusted. The prices are not adjusted, but there is one last column in the data for Adjusted close. If you don&amp;rsquo;t know what &amp;lsquo;adjusted&amp;rsquo; means in this context read &lt;a href="http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-12.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The problem with using the &amp;lsquo;adjusted close&amp;rsquo; column is that, for a particular date in the past, &amp;lsquo;adjusted close&amp;rsquo; changes whenever the company pays a dividend or splits its stock. So if I retrieve the value on two different days I might get different numbers because, in the meantime, the company paid a dividend. This prevents me from storing a subset of the data locally and then retrieving other subsets later on. It also has the limitation that just the closing price is present while I might need adjusted opening price, adjusted high price or even adjusted volume depending on the operations I want to perform on the data (i.e. calculating oscillators or volume-adjusted moving averages).&lt;/p&gt;
&lt;p&gt;The solution I came up with is to download the data and transform it to an &amp;lsquo;asHappened&amp;rsquo; state. This state is simply an unadjusted version of what happened in the past. Data in this state is not going to change in the future, which means that I can safely store it locally. I can then on demand produce &amp;lsquo;historically adjusted&amp;rsquo; data whenever I need to.&lt;/p&gt;
&lt;p&gt;Ok, to the code. As it often happens, I need some auxiliary functions before I get to the core of the algorithms. The first one is a way to compare two observations, I will use it later on to sort a list of observations.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let compareObservations obs1 obs2 =
    if obs1.Date &amp;lt;&amp;gt; obs2.Date then obs2.Date.CompareTo(obs1.Date)
    else
        match obs1.Event, obs2.Event with
            | Price _, Price _ | Div _, Div _ | Split _, Split _
                -&amp;gt; failwith &amp;quot;Two same date/ same kind observations&amp;quot;
            | Price _, _  -&amp;gt; -1
            | _, Price _  -&amp;gt; 1
            | _           -&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is rather simple. If the dates of these observations are different, just compare them. If they are the same then the two observations cannot be of the same type (i.e. I cannot have two prices for a particular date). Given that they are not of the same, then &amp;amp;(&amp;amp;^%!#$!4. Crap, that teaches me to put comments in my code! I think I&amp;rsquo;m putting the price information first, but I&amp;rsquo;m not sure. Anyhow my universal excuse not to figuring it out is that the testcases succeed so I must be doing it right (how lame, testcase-addiction I guess).&lt;/p&gt;
&lt;p&gt;The next auxiliary function is just a wrapper over fold. I always tend to wrap fold calls in a method with a better name because I remember the old times when I didn&amp;rsquo;t know what fold was. I want a reader of my code to be able to understand it even if they are not familiar with fold (the &amp;lsquo;universal functional Swiss-Army-Knife). This function is a map that needs to know the value of an accumulator to correctly perform its mapping over each element.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let mapAcc acc newAccF newItemF inl =
    let foldF (acc, l) x = newAccF acc x, (newItemF acc x)::l
    let _, out = inl |&amp;gt; List.fold_left foldF (acc, [])
    out
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apart from the implementation details, this function takes an accumulator, an accumulator function, an item function and an input list. For each element in the list it calculates two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a new value for the accumulator: newAccumulatorValue = &lt;u&gt;newAccF&lt;/u&gt; oldAccValue itemValue &lt;/li&gt;
&lt;li&gt;a new value for the item: new ItemValue = &lt;u&gt;newItemF&lt;/u&gt; accValue oldItemValue &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Maybe there is a standard functional way to do such a thing with a specific name that I&amp;rsquo;m not aware of. &lt;a href="http://blogs.msdn.com/lukeh/default.aspx"&gt;Luke&lt;/a&gt; might know. He is my resident &lt;u&gt;fold&lt;/u&gt; expert.&lt;/p&gt;
&lt;p&gt;All right, now to he main algorithm.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let asHappened splitFactor observations =
    let newSplitFactor splitFactor obs =
        match obs.Event with
            | Split(factor) -&amp;gt; splitFactor * factor
            | _             -&amp;gt; splitFactor
    let newObs splitFactor obs =
        let date = obs.Date
        let event = match obs.Event with
                        | Price(p)                  -&amp;gt; Price(p)
                        | Div(amount)               -&amp;gt; Div(amount * splitFactor)
                        | Split(factor)             -&amp;gt; Split(factor)
        {Date = date; Event = event}
    observations
    |&amp;gt; List.sort compareObservations
    |&amp;gt; mapAcc splitFactor newSplitFactor newObs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To understand what&amp;rsquo;s going on start from the bottom. I&amp;rsquo;m taking the observation list downloaded from Yahoo and sorting it using my &lt;u&gt;compareObservations&lt;/u&gt; function. I then take the resulting list and apply the previously described &lt;u&gt;mapAcc&lt;/u&gt; to it. For this function splitFactor is the accumulator, newSplitFactor is the accumulator function and newObs is the function that generate a new value for each item in the list.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;NewSplitFactor&lt;/u&gt; is trivial: every time it sees a Split observation it updates the value of the split factor. That&amp;rsquo;s it. &lt;u&gt;NewObs&lt;/u&gt; is rather simple as well. Every time it sees a dividend, it &amp;lsquo;unadjust&amp;rsquo; it by multiplying its amount by the split factor. The end result is to transform the dividends downloaded from Yahoo (which are adjusted) to an unadjusted state. I could have filtered out the price observations before doing all of this and add them back afterward, but didn&amp;rsquo;t. It&amp;rsquo;d probably be slower&lt;/p&gt;
&lt;p&gt;Now that I can recreate the state of the world as it was at a particular point in time, what if I want to adjust the data? I can call &lt;u&gt;adjusted&lt;/u&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let adjusted (splitFactor, lastDiv, oFact, hFact, lFact, cFact, vFact)
                                                                   asHappenedObs =
    let newFactor (splitFactor, lastDiv, oFact, hFact, lFact, cFact, vFact) obs =
        match obs.Event with
            | Split(split)  -&amp;gt;
                 splitFactor * split, lastDiv, oFact, hFact, lFact, cFact, vFact
            | Div(div)      -&amp;gt; splitFactor, div, oFact, hFact, lFact, cFact, vFact
            | Price(p)      -&amp;gt;
                 splitFactor, 0.&amp;lt;money&amp;gt;, oFact / (1. - lastDiv / p.Open),
                 hFact / (1. - lastDiv / p.High), lFact / (1. - lastDiv / p.Low),
                 cFact / (1. - lastDiv / p.Close), vFact / (1. - lastDiv / p.Close)
    let newObs (splitFactor, lastDiv, oFact, hFact, lFact, cFact, vFact) obs =
        let date = obs.Date
        let event = match obs.Event with
                        | Price(p)          -&amp;gt;
                            Price({Open = p.Open / splitFactor / oFact;
                            High = p.High / splitFactor / hFact;
                            Low = p.Low / splitFactor / lFact;
                            Close = p.Close / splitFactor / cFact;
                            Volume = p.Volume / splitFactor / vFact })
                        | Div(amount)       -&amp;gt; Div (amount / splitFactor)
                        | Split(split)      -&amp;gt; Split(split)
        {Date = date; Event = event}
    asHappenedObs
        |&amp;gt; List.sort compareObservations
        |&amp;gt; mapAcc (splitFactor, lastDiv, oFact, hFact, lFact, cFact, vFact)
                                                                  newFactor newObs
        |&amp;gt; List.filter (fun x -&amp;gt; match x.Event with Split(_) -&amp;gt; false | _ -&amp;gt; true)        
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wow, ok, this looks messy. Let&amp;rsquo;s go through it. Starting from the bottom: sort the observations, perform the right algorithm and filter away all the splits. It doesn&amp;rsquo;t make sense to have splits in adjusted data.&lt;/p&gt;
&lt;p&gt;The interesting piece is the &lt;u&gt;mappAcc&lt;/u&gt; function. It take a tuple of factors as accumulator and the usual two functions to update such tuple and create new observations. The &lt;u&gt;newObs&lt;/u&gt; function creates a new Observation using the factors in the accumulator tuple. Notice how the dividends are divided by the &lt;u&gt;splitFactor&lt;/u&gt; (which is the opposite of our &lt;u&gt;asHappened&lt;/u&gt; algorithm where we were multiplying them). Also notice how the prices are divided by both the &lt;u&gt;splitFactor&lt;/u&gt; and the pertinent price factor. This is needed because the prices need to be adjusted by the dividends paid out and the adjustment factor is different for each kind of price (i.e. open, close, etc). The &lt;u&gt;newFactor&lt;/u&gt; function simply updates all the factors depending on the current observation.&lt;/p&gt;
&lt;p&gt;Notice how &lt;u&gt;asHappened&lt;/u&gt; and &lt;u&gt;adjusted&lt;/u&gt; are structurally similar. This is an artifact of having a functional approach to writing code: it kind of forces you to identify these commonality in the way an algorithm behave and abstract them out (in this case in the &lt;u&gt;mapAcc&lt;/u&gt; function). You often discover that such abstracted-out pieces are more generally useful than the case at hand.&lt;/p&gt;</description>
            <pubDate>Fri, 26 Sep 2008 16:04:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-09-26-downloading-stock-prices-in-f-part-v-adjusting-historical-data.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices in F# - Part IV - Async loader for splits</title>
            <link>https://www.lucabol.com/posts/2008-09-19-downloading-stock-prices-in-f-part-iv-async-loader-for-splits.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I  - Data modeling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II  - Html scraping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;Part III  - Async loader for prices and divs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V  - Adjusting historical data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx"&gt;Part VI  - Code posted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Downloading splits is a messy affair. The problem is that Yahoo doesn&amp;rsquo;t give you&amp;nbsp; a nice comma-delimitated stream to work with. You have to parse the Html yourself (and it can be on multiple pages). At the end of the post, the overall result is kind of neat, but to get there we need a lot of busywork.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s define a function that constructs the correct URL to download splits from. Notice that you need to pass a page number to it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let splitUrl ticker span page =
    &amp;quot;http://finance.yahoo.com/q/hp?s=&amp;quot; + ticker + &amp;quot;&amp;amp;a=&amp;quot;
    + (span.Start.Month - 1).ToString() + &amp;quot;&amp;amp;b=&amp;quot; + span.Start.Day.ToString() + &amp;quot;&amp;amp;c=&amp;quot; 
    + span.Start.Year.ToString() + &amp;quot;&amp;amp;d=&amp;quot; + (span.End.Month - 1).ToString() + &amp;quot;&amp;amp;e=&amp;quot;
    + span.End.Day.ToString() + &amp;quot;&amp;amp;f=&amp;quot; + span.End.Year.ToString() + &amp;quot;&amp;amp;g=v&amp;amp;z=66&amp;amp;y=&amp;quot;
    + (66 * page).ToString();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason for this particular url format (i.e. 66 * page) is completely unknown to me. I also have the feeling that it might change in the future. Or maybe not given how many people rely on it.&lt;/p&gt;
&lt;p&gt;I then describe the driver function for loading splits:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec loadWebSplitAsync ticker span page splits =
    let parseSplit text splits =
        List.append splits (parseSplits (scrapHtmlRows text)),
                                           not(containsDivsOrSplits (scrapHtmlCells text))
    async {
        let url = splitUrl ticker span page
        let! text = loadWebStringAsync url
        let splits, beyondLastPage = parseSplit text splits
        if beyondLastPage then return splits else
                                 return! loadWebSplitAsync ticker span (page + 1) splits }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a bit convoluted (it is an Async recursive function). Let&amp;rsquo;s go through it in some detail. First there is a nested function &lt;u&gt;parseSplit&lt;/u&gt;. It takes an html string and a list of observations and returns a tuple of two elements. The first element is the same list of observations augmented with the splits found in the text. The second element is a boolean that is true if we have navigated beyond the last page for the splits.&lt;/p&gt;
&lt;p&gt;The function to test that we are beyond the last page is the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let containsDivsOrSplits cells =
    cells |&amp;gt; Seq.exists
        (fun (x:string) -&amp;gt; Regex.IsMatch(x, @&amp;quot;$.+Dividend&amp;quot;, RegexOptions.Multiline)
                           || Regex.IsMatch(x, &amp;quot;Stock Split&amp;quot;))  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function just checks if the words Stock Split or Dividend are anywhere in the table. If they aren&amp;rsquo;t, then we have finished processing the pages for this particular ticker and date span.&lt;/p&gt;
&lt;p&gt;The function to extract the splits observations from the web page takes some cells (a &lt;u&gt;seq&lt;seq\&lt;string&gt;&gt;)&lt;/u&gt; as input and returns an observation list. It is reproduced below:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parseSplits rows =
    let parseRow row =
        if row |&amp;gt; Seq.exists (fun (x:string) -&amp;gt; x.Contains(&amp;quot;Stock Split&amp;quot;))
        then
            let dateS = Seq.hd row
            let splitS = Seq.nth 1 row
            let date = DateTime.Parse(dateS)
            let regex = Regex.Match(splitS,@&amp;quot;(d+)s+:s+(d+)s+Stock Split&amp;quot;,
                                                                   RegexOptions.Multiline)
            let newShares = shares (float (regex.Groups.Item(1).Value))
            let oldShares = shares (float (regex.Groups.Item(2).Value))
            Some({Date = date; Event = Split(newShares / oldShares)})
        else None
    rows |&amp;gt; Seq.choose parseRow |&amp;gt; Seq.to_list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It just take a bunch of rows and choose the ones that contain stock split information. For these, it parses the information out of the text and creates a Split Observation out of it. I think it is intuitive what the various Seq functions do in this case. Also note my overall addiction to the pipe operator ( |&amp;gt; ). In my opinion this is the third most important keyword in F# (after &amp;lsquo;let&amp;rsquo; and &amp;lsquo;match&amp;rsquo;).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s now go back to the loadWebSplitAsync function and discuss the rest of it. In particular this part:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;async {
    let url = splitUrl ticker span page
    let! text = loadWebStringAsync url
    let splits, beyondLastPage = parseSplit text splits
    if beyondLastPage then return splits else
        return! loadWebSplitAsync ticker span (page + 1) splits }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First of all it is an Async function. You should expect some Async stuff to go on inside it. And indeed, after forming the URL in the first line, the very next line is a call to &lt;u&gt;loadWebStringAsync&lt;/u&gt;. We discussed this one in the previous installment. It just asynchronously loads a string from an URL. Notice the bang after &amp;lsquo;let&amp;rsquo;. This is your giveaway that async stuff is being performed.&lt;/p&gt;
&lt;p&gt;The result of the async request is parsed to extract splits. Also, the &lt;u&gt;beyondLastPage&lt;/u&gt; flag is set if we have finished our work. If we have, we return the split observation list; if we haven&amp;rsquo;t, we do it again incrementing the page number to load the html text from.&lt;/p&gt;
&lt;p&gt;Now that we have all the pieces in places, we can wrap up the split loading stuff inside this facade function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadSplitsAsync ticker span = loadWebSplitAsync ticker span 0 []
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally put together the results of this post and the previous one with the overall function-to-rule-them-all:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadTickerAsync ticker span =
    async {
        let prices = loadPricesAsync ticker span
        let divs =  loadDivsAsync ticker span
        let splits = loadSplitsAsync ticker span
        let! prices, divs, splits = Async.Parallel3 (prices, divs, splits)
        return prices |&amp;gt; List.append divs |&amp;gt; List.append splits
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All right, that was a lot of work to get to this simple thing. This is a good entry point to our price/divs/split loading framework. It has the right inputs and outputs: it takes a ticker and a date span and returns an Async of a list of observations. Our caller can decide when he wants to execute the returned Async object.&lt;/p&gt;
&lt;p&gt;Notice that in the body of the function I call &lt;u&gt;Async.Parallel&lt;/u&gt;. This is debatable. A more flexible solution is to return a tuple containing three Asyncs (prices, divs, splits) and let the caller decide how to put them together. I decided against this for simplicity reasons. This kind of trade-off is very common in Async programming: giving maximum flexibility to your caller against exposing something more understandable.&lt;/p&gt;
&lt;p&gt;I have to admit I didn&amp;rsquo;t enjoy much writing (and describing) all this boilerplate code. I&amp;rsquo;m sure it can be written in a better way. I might rewrite plenty of it if I discover bugs. I kind of like the end result though. &lt;u&gt;loadTickerAsync&lt;/u&gt; has an overall structure I&amp;rsquo;m pretty happy with.&lt;/p&gt;
&lt;p&gt;Next post,&amp;nbsp; some algorithms with our observations&lt;/p&gt;</description>
            <pubDate>Fri, 19 Sep 2008 17:59:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-09-19-downloading-stock-prices-in-f-part-iv-async-loader-for-splits.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices in F# - Part III - Async loader for prices and divs</title>
            <link>https://www.lucabol.com/posts/2008-09-12-downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I  - Data modeling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II  - Html scraping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx"&gt;Part IV  - Async loader for splits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V  - Adjusting historical data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx"&gt;Part VI  - Code posted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is now time to load our data. There is a bit of uninteresting code to start with, but things get interesting afterward. Let&amp;rsquo;s start with functions that create the right URLs to download prices and dividends. We&amp;rsquo;ll talk about splits in the next installment.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let commonUrl ticker span =
    @&amp;quot;http://ichart.finance.yahoo.com/table.csv?s=&amp;quot; + ticker + &amp;quot;&amp;amp;a=&amp;quot;
    + (span.Start.Month - 1).ToString() + &amp;quot;&amp;amp;b=&amp;quot; + span.Start.Day.ToString() + &amp;quot;&amp;amp;c=&amp;quot;
    + span.Start.Year.ToString() + &amp;quot;&amp;amp;d=&amp;quot; + (span.End.Month - 1).ToString() + &amp;quot;&amp;amp;e=&amp;quot; 
    + span.End.Day.ToString() + &amp;quot;&amp;amp;f=&amp;quot; + span.End.Year.ToString()
let priceUrl ticker span = commonUrl ticker span + &amp;quot;&amp;amp;g=d&amp;amp;ignore=.csv&amp;quot;
let divUrl ticker span = commonUrl ticker span + &amp;quot;&amp;amp;g=v&amp;amp;ignore=.csv&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will also need to construct an observation given a comma delimitated line of text. Again, for spits things will be harder.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let parsePrice (line: string) =
    let tokens = line.Split([|','|])
    { Date = DateTime.Parse(tokens.[0]);
      Event = Price ({Open = money (Double.Parse(tokens.[1])) ;
      High = money (Double.Parse(tokens.[2]));
      Low = money (Double.Parse(tokens.[3])); Close = money (Double.Parse(tokens.[4]));
      Volume = volume (Double.Parse(tokens.[5]))})}
let parseDiv (line: string) =
    let tokens = line.Split([|','|])
    let date = DateTime.Parse(tokens.[0])
    let amount = money (Double.Parse(tokens.[1]))
    {Date = date; Event = Div amount}        
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing noteworthy about this code. We have a couple of other &amp;lsquo;infrastructure pieces before we get to the Async pieces. The next function is recursive. It takes a StringReader and reads lines out of it. For each line it calls a parsing function that takes the line as input and returns an object as output. The function gathers all such objects in the &lt;u&gt;listOfThings&lt;/u&gt; list. If you are new to F# the following construct (parseLineFunc line:: listOfThings) means: execute the parseLineFunc with argument line, take the result and create a list that has the result as head and listOfThings as tail).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let rec loadFromLineReader (reader:StringReader) listOfThings parseLineFunc =
    match  reader.ReadLine () with
    | null  -&amp;gt; listOfThings
    | line  -&amp;gt; loadFromLineReader reader (parseLineFunc line::listOfThings) parseLineFunc        
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next function is rather uninteresting. It just converts a string to a &lt;u&gt;StringReader&lt;/u&gt;, cut out the first line (header) and calls &lt;u&gt;loadFromLineReader&lt;/u&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadFromLineString text listOfThings parseLineFunc =
    let reader = new StringReader(text)
    reader.ReadLine ()|&amp;gt; ignore // skip header
    loadFromLineReader reader listOfThings parseLineFunc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now come to the first Async function. But what is an Async function? There are several possible technically correct definition as: it is an instance of the monad pattern or it is a function that returns an Async object or it is a way to release your thread to the thread pool. These definition don&amp;rsquo;t help me much. I need something intuitive to latch one.&lt;/p&gt;
&lt;p&gt;The way that I personally visualize it is: there are things in the world that are very good at executing certain tasks and like to be hit by multiple parallel requests for these tasks. They&amp;rsquo;d like me to give them their workload and get out of their way. They&amp;rsquo;ll call me when they are done with it. These &amp;lsquo;things&amp;rsquo; are disk drives, web servers, processors, etc Async is a way to say: hey, go and do this, call me when you are done.&lt;/p&gt;
&lt;p&gt;Now, you can &lt;a href="http://msdn.microsoft.com/en-us/library/aa719595(VS.71).aspx"&gt;call the asynchronous APIs directly&lt;/a&gt;, or you can use the nice F# language structures to do it. Let&amp;rsquo;s do the latter.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadWebStringAsync url =
    async {
        let req = WebRequest.Create(url: string)
        use! response = req.AsyncGetResponse()
        use reader = new StreamReader(response.GetResponseStream())
        return! reader.AsyncReadToEnd()}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function retrieves a web page as a string asynchronously. Notice that even if the code looks rather normal, this function will likely be executed on three different thread. The first thread is the one the caller of the function lives on. The function &lt;u&gt;AsyncGetResponse&lt;/u&gt; causes the thread to be returned to the thread pool waiting for a response back from the web server. Once such a response arrives, the execution resumes on a different thread until &lt;u&gt;AsyncReadToEnd&lt;/u&gt;. That instruction returns the execution thread to the thread pool. A new thread is then instantiated when the string has been completely read. The good thing is that all of this is not explicitly managed by the programmer. The compiler &amp;lsquo;writes the code&amp;rsquo; to make it all happen. You just have to follow a set of simple conventions (i.e. putting exclamation marks in the right place).&lt;/p&gt;
&lt;p&gt;The return result of this function is an &lt;u&gt;Async&lt;string&gt;&lt;/u&gt;, which is something that, when executed, returns a string. I cannot emphasize this enough: always look at the signature of your F# functions. Type inference can be tricky&lt;/p&gt;
&lt;p&gt;Async is somehow contagious. If you are calling an Async function you have to decide if propagate the Asyncness to your callers or remove it by executing the function. Often propagating it is the right thing to do as your callers might want to batch your function with other aync ones to be executed together in parallel. Your callers have more information than you do and you don&amp;rsquo;t want to short-circuit them. The following function propagates ayncness.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadFromUrlAsync url parseFunc =
    async {
        let! text = loadWebStringAsync url
        return loadFromLineString text [] parseFunc}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s see how the functions presented to this point compose to provide a way to load prices and dividends (splits will be shown afterward).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let loadPricesAsync ticker span = loadFromUrlAsync (priceUrl ticker span) parsePrice
let loadDivsAsync ticker span = loadFromUrlAsync (divUrl ticker span) parseDiv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This composition of functions is very common in functional code. You construct your building blocks and assemble them to achieve your final goal. Functional programming is good at almost forcing you to identify the primitive blocks in your code. All right, next in line is how to load splits.&lt;/p&gt;</description>
            <pubDate>Fri, 12 Sep 2008 16:18:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-09-12-downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices in F# - Part II - Html scraping</title>
            <link>https://www.lucabol.com/posts/2008-09-05-downloading-stock-prices-in-f-part-ii-html-scraping.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I  - Data modeling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;Part III  - Async loader for prices and divs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx"&gt;Part IV  - Async loader for splits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V  - Adjusting historical data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx"&gt;Part VI  - Code posted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Getting stock prices and dividends is relatively easy given that, on &lt;a href="http://finance.yahoo.com/q/hp?s=GE"&gt;Yahoo&lt;/a&gt;, you can get the info &lt;a href="http://ichart.finance.yahoo.com/table.csv?s=GE&amp;amp;a=00&amp;amp;b=2&amp;amp;c=1962&amp;amp;d=08&amp;amp;e=5&amp;amp;f=2008&amp;amp;g=d&amp;amp;ignore=.csv"&gt;as a CVS file&lt;/a&gt;. Getting the splits info is harder. You would think that Yahoo would put that info in the dividends CVS as it does when it displays it on screen, but it doesn&amp;rsquo;t. So I had to write code to scrap it from the multiple web pages where it might reside. In essence, I&amp;rsquo;m scraping &lt;a href="http://finance.yahoo.com/q/hp?s=GE&amp;amp;a=00&amp;amp;b=2&amp;amp;c=1962&amp;amp;d=08&amp;amp;e=5&amp;amp;f=2008&amp;amp;g=v"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;html.fs&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this file there are utility functions that I will use later on to retrieve split info. &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;#light
open System
open System.IO
open System.Text.RegularExpressions

// It assumes no table inside table ...
let tableExpr = &amp;quot;&amp;lt;table[^&amp;gt;]*&amp;gt;(.*?)&amp;lt;/table&amp;gt;&amp;quot;
let headerExpr = &amp;quot;&amp;lt;th[^&amp;gt;]*&amp;gt;(.*?)&amp;lt;/th&amp;gt;&amp;quot;
let rowExpr = &amp;quot;&amp;lt;tr[^&amp;gt;]*&amp;gt;(.*?)&amp;lt;/tr&amp;gt;&amp;quot;
let colExpr = &amp;quot;&amp;lt;td[^&amp;gt;]*&amp;gt;(.*?)&amp;lt;/td&amp;gt;&amp;quot;
let regexOptions = RegexOptions.Multiline ||| RegexOptions.Singleline 
                                          ||| RegexOptions.IgnoreCase
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code is straightforward enough (if you know what Regex does). I&amp;rsquo;m sure that there are better expression to scrap tables and rows on the web, but these work in my case. I really don&amp;rsquo;t need to scrape tables. I put the table expression there in case you need it.&lt;/p&gt;
&lt;p&gt;I then write code to scrape all the cells in a piece of html:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let scrapHtmlCells html =
  seq { for x in Regex.Matches(html, colExpr, regexOptions) -&amp;gt; x.Groups.Item(1).ToString()}            
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a sequence expression. Sequence expressions are used to generate sequences starting from some expression (as the name hints to). In this case &lt;u&gt;Regex.Matches&lt;/u&gt; returns a &lt;u&gt;MatchClollection&lt;/u&gt;, which is a non-generic &lt;u&gt;IEnumerable&lt;/u&gt;. For each element in it, we return the value of the first match. We could as easily have constructed a list or an array, given that there is not much deferred computation going on. But oh well&lt;/p&gt;
&lt;p&gt;Always check the type of your functions in F#! With type inference it is easy to get it wrong. Hovering your mouse on top of it in VS shows it. This one is typed: &lt;u&gt;string -&amp;gt; seq&lt;string&gt;&lt;/u&gt;. It takes a string (html) and return a sequence of strings (the cells in html).&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll need rows as well.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let scrapHtmlRows html =
    seq { for x in Regex.Matches(html, rowExpr, regexOptions) -&amp;gt; scrapHtmlCells x.Value }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works about the same. I&amp;rsquo;m matching all the rows and retrieving the cells for each one of them. I&amp;rsquo;m getting back a matrix-like structure, that is to say that this function as type: &lt;u&gt;string -&amp;gt; seq&lt;seq\&lt;string&gt;&gt;&lt;/u&gt;.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all for today. In the next installment we&amp;rsquo;ll make it happen.&lt;/p&gt;</description>
            <pubDate>Fri, 05 Sep 2008 14:41:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-09-05-downloading-stock-prices-in-f-part-ii-html-scraping.html</guid>
        </item>
        
        <item>
            <title>Downloading stock prices in F# - Part I - Data modeling</title>
            <link>https://www.lucabol.com/posts/2008-08-29-downloading-stock-prices-in-f-part-i-data-modeling.html</link>
            <description>&lt;p&gt;Other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II  - Html scraping&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;&lt;strong&gt;&lt;font color="#006bad"&gt;Part III  - Async loader for prices and divs&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx"&gt;Part IV  - Async loader for splits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V  - Adjusting historical data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx"&gt;Part VI  - Code posted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Today we shipped the September CTP of F# !!!! Evviva !! Read &lt;a href="http://blogs.msdn.com/dsyme/archive/2008/08/29/the-f-september-2008-ctp-is-now-available.aspx"&gt;this&lt;/a&gt; blog post about it. To celebrate I decided to share one of my several F# project. It might make for a good sample; sort of a crash course on F#.&lt;/p&gt;
&lt;p&gt;This application downloads stock prices, dividends and splits from &lt;a href="http://finance.yahoo.com/q/hp?s=MSFT"&gt;Yahoo Historical Prices&lt;/a&gt; and performs computations on them. I will describe it file by file.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;common.fs&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;I always have such a file in my projects. It is a repository for the types that I&amp;rsquo;m going to use in my program and the functions that are common across multiple modules. If I have a large program I also have a types.fs just for the types.&lt;/p&gt;
&lt;p&gt;This one starts like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;#light
open System
[&amp;lt;Measure&amp;gt;] type money
let money (f:float) = f * 1.&amp;lt;money&amp;gt;
[&amp;lt;Measure&amp;gt;] type shares
let shares (f:float) = f * 1.&amp;lt;shares&amp;gt;
[&amp;lt;Measure&amp;gt;] type volume
let volume (f:float) = f * 1.&amp;lt;volume&amp;gt;
[&amp;lt;Measure&amp;gt;] type rateOfReturn
let rateOfReturn (f:float) = f * 1.&amp;lt;rateOfReturn&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first line instructs the compiler to use the lightweight syntax. You don&amp;rsquo;t want to know what the heavyweight syntax is. Just always put such a line at the start of your files. The next line opens up the System namespace. Then the good stuff starts.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m defining some units of measures. The simplest way to think about units of measures is: they are a type system for floats. You can do much more than that, but it is a good first approximation. For example, you cannot now sum a &lt;u&gt;money&lt;/u&gt; type and a &lt;u&gt;volume&lt;/u&gt; type. Also for each one I define a function that converts from a normal &lt;u&gt;float&lt;/u&gt; type to it (if you come from a C# background, floats are doubles).&lt;/p&gt;
&lt;p&gt;Then I define the data model for my application:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;type Span = { Start: DateTime; End: DateTime }
type Price = { Open: float&amp;lt;money&amp;gt;; High: float&amp;lt;money&amp;gt;; Low:float&amp;lt;money&amp;gt;; 
                                                Close:float&amp;lt;money&amp;gt;; Volume: float&amp;lt;volume&amp;gt;}
type Event =
    | Price of Price
    | Split of float
    | Div of float&amp;lt;money&amp;gt;
type Observation = { Date: DateTime; Event: Event}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first record that I define, &lt;u&gt;Span&lt;/u&gt;,&amp;nbsp; represents the difference between two dates. It is just a little useful thing. A more fundamental record is &lt;u&gt;Observation&lt;/u&gt;. An &lt;u&gt;Observation&lt;/u&gt; is defined as something that happens on a particular &lt;u&gt;Date&lt;/u&gt;. That something, an &lt;u&gt;Event&lt;/u&gt;, can be one of three things: a &lt;u&gt;Price&lt;/u&gt;, a &lt;u&gt;Split&lt;/u&gt; or a &lt;u&gt;Div&lt;/u&gt;. A &lt;u&gt;Price&lt;/u&gt; is another record with a bunch of &lt;u&gt;float&lt;money&gt;&lt;/u&gt; fields and on &lt;u&gt;float&lt;volume&gt;&lt;/u&gt; field. If you go to the Yahoo site, you&amp;rsquo;ll see what it represents.&lt;/p&gt;
&lt;p&gt;A &lt;u&gt;Split&lt;/u&gt; is simply a &lt;u&gt;float&lt;/u&gt;. Why not a &lt;u&gt;float&amp;lt;&amp;gt;&lt;/u&gt;? Because it is just a number, a factor to be precise. It represents the number of new shares divided by the number of old shares. &lt;u&gt;float&lt;shares&gt; / float&lt;shares&gt; = float&lt;/u&gt;. A &lt;u&gt;Div&lt;/u&gt; is a &lt;u&gt;float&lt;money&gt;&lt;/u&gt;.&lt;/p&gt;
&lt;p&gt;This is one way to model the problem. Infinite other ways are possible (and I tried many of them in a C# version of this code that ended up using polymorphism). Note that all of the types are records except &lt;u&gt;Event&lt;/u&gt; that is a discriminated union.&lt;/p&gt;
&lt;p&gt;Records are read only containers of data. Discriminated unions are what the name says: things that can be one of multiple things (even recursively). They are rather handy to represent the structure of the data. We will see how you use them using the &lt;u&gt;match&lt;/u&gt; operator in upcoming posts.&lt;/p&gt;
&lt;p&gt;Also notice the following common pattern in F# (and functional programming in general). You define your data and then you define transformations over it. F# has a third optional step, that is to expose these transformations as methods of a .NET objects.&lt;/p&gt;
&lt;p&gt;We are almost done here. A handful of other functions are in my file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-fsharp"&gt;let span sy sm sd ey em ed =
                   {Start = new DateTime(sy, sm, sd); End = new DateTime(ey, em, ed)}
let date y m d = new DateTime(y, m, d)
let now () = DateTime.Now
let idem x = x
let someIdem x = Some(x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;u&gt;Span&lt;/u&gt; is a function that creates a span given the relevant info. &lt;u&gt;date&lt;/u&gt; creates a date given year, month and day. &lt;u&gt;now&lt;/u&gt; is a value that corresponds to the current date. &lt;u&gt;idem&lt;/u&gt; is a function that returns its parameter (you&amp;rsquo;ll see how that can possibly be useful). &lt;u&gt;someIdem&lt;/u&gt; is a function that unpack an Option type and gives his value. I could write all my code without these things, but it looks better (to me) with them.&lt;/p&gt;
&lt;p&gt;Notice that in the F# code you have access to all the functions and type in the .NET framework. It is just another .NET language: it can create or consume .NET types.&lt;/p&gt;
&lt;p&gt;All right, we are done for part one. In part II there will be some real code.&lt;/p&gt;</description>
            <pubDate>Fri, 29 Aug 2008 19:13:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-08-29-downloading-stock-prices-in-f-part-i-data-modeling.html</guid>
        </item>
        
        <item>
            <title>A C# library to write functional code - Part V - The Match operator</title>
            <link>https://www.lucabol.com/posts/2008-07-15-a-c-library-to-write-functional-code-part-v-the-match-operator.html</link>
            <description>&lt;p&gt;Other posts in the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;Part I  - Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;Part II  - Tuples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;Part III  - Records&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV  - Type Unions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V  - The Match operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is my last post of this series. It is about the &lt;em&gt;match&lt;/em&gt; operator. To the untrained eyes this operator might look like a case statement. But they are different.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;match&lt;/em&gt; operator combines control flow and decomposition in a single construct. As it often happens, even if these two things are well known concepts, putting them together gives you a different perspective on your code.&lt;/p&gt;
&lt;p&gt;I have to admit that the similarity with a case statement triggered all sorts of bad reactions in my OO trained mind. Phrases from wise gurus on the tone of never use an &amp;lsquo;if&amp;rsquo; statement was echoing in my mind. After a while I got over it and enjoyed the power that this operator gives.&lt;/p&gt;
&lt;p&gt;In this library we won&amp;rsquo;t get close to the beauty of the &lt;em&gt;match&lt;/em&gt; operator in functional languages (i.e. F#), especially the decomposition piece. There might be a way to do better than this in C#, but this was enough for my purpose of learning about functional programming, so I didn&amp;rsquo;t investigate further. Learning was my real goal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to use it&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are two versions of this operator. Let&amp;rsquo;s start from the more eye pleasing one.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s assume a discriminated union like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Node : TypeUnion&amp;lt;int, string&amp;gt; {
    public Node(int i) : base(i) { }
    public Node(string s) : base(s) { }
    public int IntNode { get { return Type1; } }
    public string StringNode { get { return Type2; } }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can then match against this union with the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var no = new Node(35);
r = F.Match(no,
                (int i)    =&amp;gt; (i + 3).ToString(),
                (string s) =&amp;gt; s
            );
Assert.AreEqual(&amp;quot;38&amp;quot;, r);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the &lt;em&gt;match&lt;/em&gt; operator behaves a bit like a case statement, but it also gives you the &amp;lsquo;right&amp;rsquo; type on the right of the &amp;lsquo;=&amp;gt;&amp;rsquo; for you to write code against.&lt;/p&gt;
&lt;p&gt;I have to admit I&amp;rsquo;m rather happy of this syntax, but it has one severe limitation. You need to specify all the types of the type union and they have to be in the same order. For example, in the previous code I cannot match against &lt;em&gt;string&lt;/em&gt; first and &lt;em&gt;int&lt;/em&gt; second. I consider this to be a big deal.&lt;/p&gt;
&lt;p&gt;A different implementation of match that doesn&amp;rsquo;t have that limitation is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;no = new Node(&amp;quot;35&amp;quot;);
r = F.Match(no,
    n =&amp;gt; n.Is&amp;lt;int&amp;gt;(),   n =&amp;gt; (n.As&amp;lt;int&amp;gt;() + 3).ToString(),
    n =&amp;gt; n.Is&amp;lt;string&amp;gt;(),n =&amp;gt; n.As&amp;lt;string&amp;gt;());
Assert.AreEqual(&amp;quot;35&amp;quot;, r);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rather less pleasing to the eyes, but more robust to use.&lt;/p&gt;
&lt;p&gt;By using this more generic version, you can obviously match against all the constructs we described in this series. I.E. against &lt;em&gt;Tuples&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var t = F.Tuple(&amp;quot;msft&amp;quot;, 10, &amp;quot;Nasdaq&amp;quot;);
var r = F.Match(t,
    i =&amp;gt; i.Item2 &amp;lt; 5 &amp;amp;&amp;amp; i.Item3 == &amp;quot;OTC&amp;quot;,          i =&amp;gt; i.Item1 + &amp;quot; is low price OTC stock&amp;quot;,
    i =&amp;gt; i.Item3 == &amp;quot;OTC&amp;quot;,                         i =&amp;gt; i.Item1 + &amp;quot;is a normal OTC stock&amp;quot;,
    i =&amp;gt; i.Item3 == &amp;quot;Nasdaq&amp;quot;,                      i =&amp;gt; i.Item1 + &amp;quot; is a Nasdaq stock&amp;quot;);
Assert.AreEqual(&amp;quot;msft is a Nasdaq stock&amp;quot;, r);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or against sequences:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var i1 = new int[] { 1, 2, 3, 4, 5, 6, 7 };
var r1 = F.Match(i1,
                s =&amp;gt; s.SequenceEqual(new int[] { 1, 2}),    s =&amp;gt; s.Where(i =&amp;gt; i &amp;lt; 4),
                s =&amp;gt; s.First() == 2,                        s =&amp;gt; s.Where(i =&amp;gt; i == 1),
                s =&amp;gt; s.Last() == 6,                         s =&amp;gt; s.Select(i =&amp;gt; i * i),
                s =&amp;gt; true,                                  s =&amp;gt; s.Where(i =&amp;gt; i &amp;lt; 7));
Assert.IsTrue(i1.Take(6).SequenceEqual(r1));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The match operator, as I defined it, is very flexible (probably too flexible as it doesn&amp;rsquo;t use the type system to enforce much).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How it is implemented&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start from the special &lt;em&gt;match&lt;/em&gt; against union types: the one that is beautiful but flawed. Its implementation looks just like this (I just show the two parameters version):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static R Match&amp;lt;T1, T2, R&amp;gt;(
                           this TypeUnion&amp;lt;T1, T2&amp;gt; u,
                           Func&amp;lt;T1, R&amp;gt; f1, Func&amp;lt;T2, R&amp;gt; f2) {
    if (u.Is&amp;lt;T1&amp;gt;()) return f1(u.As&amp;lt;T1&amp;gt;());
    if (u.Is&amp;lt;T2&amp;gt;()) return f2(u.As&amp;lt;T2&amp;gt;());
    throw new Exception(&amp;quot;No Match for this Union Type&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is easy to see the reason for the limitations of this function. The same thing that gives you type inference (nice to look at) also gives you the problem with the ordering of lambdas. Also note the I originally intended to have these as extension methods. In practice I ended up liking more the F.Match syntax. De gustibus I assume&lt;/p&gt;
&lt;p&gt;The more general version looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static R Match&amp;lt;T, R&amp;gt;(this T t,
    Func&amp;lt;T, bool&amp;gt; match1, Func&amp;lt;T, R&amp;gt; func1,
    Func&amp;lt;T, bool&amp;gt; match2, Func&amp;lt;T, R&amp;gt; func2) {
    if (match1(t))
        return func1(t);
    if (match2(t))
        return func2(t);
    throw new Exception(&amp;quot;Nothing matches&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, it is easy to see in the implementation that this is an extremely general thing: a glorified case statement really. This is the beauty of it (you can match against anything) and the ugliness of it (you can write anything as &lt;em&gt;match1&lt;/em&gt; of &lt;em&gt;func1&lt;/em&gt;, even code that doesn&amp;rsquo;t reference &lt;em&gt;t&lt;/em&gt; at all).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to use this series to learn functional programming&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here is how I did it (it worked for me). Take this library and force yourself to write a medium size program using &lt;u&gt;just&lt;/u&gt; these constructs.&lt;/p&gt;
&lt;p&gt;I mean it. No objects, just records. No inheritance, just discriminated unions. Tuples to return values. Match operators everywhere. No iteration statements (for, while, etc), just recursion. Extensive use of sequence operators. After a while I noticed that all my functions had the same pattern: they just match against the input and produce an output, usually by calling other functions or recursively calling themselves.&lt;/p&gt;
&lt;p&gt;Obviously, this is overcompensating. After a while you will realize the different trade offs that come with a functional vs OO style of programming. At that point you&amp;rsquo;ll be able to get the best of the two. Or maybe you&amp;rsquo;ll be royally confused&lt;/p&gt;
&lt;p&gt;At that point I picked up F# and I&amp;rsquo;m now enjoying the fact that all these constructs are directly embedded in the language (and yes, you can use while statements too).&lt;/p&gt;</description>
            <pubDate>Tue, 15 Jul 2008 05:46:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-07-15-a-c-library-to-write-functional-code-part-v-the-match-operator.html</guid>
        </item>
        
        <item>
            <title>A C# library to write functional code - Part IV - Type Unions</title>
            <link>https://www.lucabol.com/posts/2008-06-06-a-c-library-to-write-functional-code-part-iv-type-unions.html</link>
            <description>&lt;p&gt;Other posts in the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;Part I  - Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;Part II  - Tuples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;Part III  - Records&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV  - Type Unions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V  - The Match operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;m sorry for my prolonged absence in the middle of this series of posts. I&amp;rsquo;m on a long paternity leave in Italy (playing beach volley every day). It&amp;rsquo;s hard to have the discipline&lt;/p&gt;
&lt;p&gt;A bunch of you wrote telling me to finish this. So here I go: let&amp;rsquo;s talk about type unions. First of all: they are not called like that. The correct name is discriminated unions. I have no idea why I call them differently, but I want to be consistent with my previous mistake.&lt;/p&gt;
&lt;p&gt;For those of you with a C++ background (like myself) they are like unions, just better (or worse depending on your convictions). They let you define a type that can represent one of several different types. You can then use the &amp;lsquo;match&amp;rsquo; operator (discussed in the next post) to pattern match against it.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t elaborate on the pros and cons of this style of programming versus using polymorphism. I just want to show you how I implemented this construct in C#. As always, my usual caveat: this is just &amp;lsquo;educational code&amp;rsquo;, use it at your own risk, no extensive or perf related test has been done on it. You can download the zip file and check my unit tests for yourself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How type unions are used&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In my world, you declare a type union like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Person { }
public class Dog { }
public class Friend : TypeUnion&amp;lt;Person, Dog&amp;gt; {
    public Friend(Person p) : base(p) { }
    public Friend(Dog d) : base(d) { }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You inherit a type union from the TypeUnion class and use generic parameters that correspond to the types that the union can represent.&lt;/p&gt;
&lt;p&gt;You can then create a type union as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var fr = new Friend(new Dog());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Test its type by:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Assert.IsTrue(fr.Is&amp;lt;Dog&amp;gt;());
Assert.IsFalse(fr.Is&amp;lt;Person&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cast it to one of the types they represent:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var d = fr.As&amp;lt;Dog&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or use it with the &amp;lsquo;match&amp;rsquo; operator (fully explained in an upcoming post):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var r = F.Match(fr,
    f =&amp;gt; f.Is&amp;lt;Dog&amp;gt;(), f =&amp;gt; f.As&amp;lt;Dog&amp;gt;().ToString(),
    f =&amp;gt; f.Is&amp;lt;Person&amp;gt;(), f =&amp;gt; f.As&amp;lt;Person&amp;gt;().ToString());
Assert.AreEqual(r, new Dog().ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or the slightly more pleasing:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;r = F.Match(fr,
        (Person p) =&amp;gt; p.ToString(),
        (Dog d) =&amp;gt; d.ToString());
Assert.AreEqual(r, new Dog().ToString());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You get the idea.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How they are implemented&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nothing really sophisticated going on here. Let&amp;rsquo;s take as an example a type union that can represent two types. I have versions that go to 5 types in the zip file.&lt;/p&gt;
&lt;p&gt;First of all a TypeUnion is a Record:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class TypeUnion&amp;lt;T1, T2&amp;gt; : Record&amp;lt;T1, T2&amp;gt; {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has overloaded constructors to create a type union of a particular type:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public TypeUnion(T1 t1)
    : base(t1, default(T2)) {
    UnionType = t1.GetType();
}
public TypeUnion(T2 t2)
    : base(default(T1), t2) {
    UnionType = t2.GetType();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UnionType is used to &amp;lsquo;remember&amp;rsquo; which type it is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;protected Type UnionType;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also has properties to return the objects of all the types that can be stored:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;protected T1 Type1 { get { return state.Item1; } }
protected T2 Type2 { get { return state.Item2; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &amp;lsquo;Is&amp;rsquo; operator is simply implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public bool Is&amp;lt;K&amp;gt;() {
    return typeof(K).IsAssignableFrom(UnionType);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the &amp;lsquo;As&amp;rsquo; operator looks like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public K As&amp;lt;K&amp;gt;() {
    if (!Is&amp;lt;K&amp;gt;())
        throw new Exception(string.Format(
          &amp;quot;In a TypeUnion cannot cast from {0} to {1}&amp;quot;,
          UnionType.Name, typeof(K).Name));
    if (typeof(T1) == UnionType)
        return (K)(object) Type1;
    if (typeof(T2) == UnionType)
        return (K)(object) Type2;
    throw new Exception(&amp;quot;Shouldn't get here&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I leave as an exercise to the reader to understand what happens if T1 and T2 are the same type or inherit from the same type. I could have written code to handle this case in a more explicit manner, but didn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Also, by reviewing my code I found an obvious bug in my Is&lt;K&gt;/As&lt;K&gt; code. I fixed it and re-posted the zip file in the second post of this series.&lt;/p&gt;
&lt;p&gt;Now back to the beach. Next post is on the &amp;lsquo;match&amp;rsquo; operator.&lt;/p&gt;</description>
            <pubDate>Fri, 06 Jun 2008 04:45:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-06-06-a-c-library-to-write-functional-code-part-iv-type-unions.html</guid>
        </item>
        
        <item>
            <title>A C# library to write functional code - Part III - Records</title>
            <link>https://www.lucabol.com/posts/2008-04-21-a-c-library-to-write-functional-code-part-iii-records.html</link>
            <description>&lt;p&gt;Other posts in the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;Part I  - Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;Part II  - Tuples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;Part III  - Records&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV  - Type Unions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V  - The Match operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that we know what Tuples are, we can start talking about Record, as they use a derivative of Tuples under the cover. But first, what is a record?&lt;/p&gt;
&lt;p&gt;Well, in C# parlance a Record is a sort of immutable value object. I talked at length about these fellows in &lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;this series of blog posts&lt;/a&gt;. In functional parlance, a Record is a Tuple that lets you access its items by name.&lt;/p&gt;
&lt;p&gt;You code Records like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Order: Record&amp;lt;string, int&amp;gt; {
    public Order(string item, int qty): base(item,qty) {}
    public string Item { get { return state.Item1;}}
    public int Quantity { get { return state.Item2; } }
}
public class Customer: Record&amp;lt;string, IEnumerable&amp;lt;Order&amp;gt;&amp;gt; {
    public Customer(string name, IEnumerable&amp;lt;Order&amp;gt; orders) : base(name, orders) { }
    public string Name { get { return state.Item1; } }
    public IEnumerable&amp;lt;Order&amp;gt; Orders { get { return state.Item2; } }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You need to do three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Inherit from a generic Record class specifying the types of the properties as parameters&lt;/li&gt;
&lt;li&gt;Add a constructor that calls back to the Record constructor&lt;/li&gt;
&lt;li&gt;Add getters to retrieve the values of the properties (no setters as it is immutable)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This may seem like plenty of work, but in return you get structural equality. Coding that by hand every time you use a record would be a royal pain. You lose control of the base class, but that is often not a problem as in functional-land you more often use type unions than inheritance.&lt;/p&gt;
&lt;p&gt;How is it implemented?&lt;/p&gt;
&lt;p&gt;First of all it is an abstract class with as many generic parameters as properties that you need in your Record. Let&amp;rsquo;s use two as an example.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public abstract class Record&amp;lt;T1, T2&amp;gt; {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This abstract class has a field of type STuple:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;protected readonly STuple&amp;lt;T1, T2&amp;gt; state;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is a STuple? Well it is exactly the same as the Tuple described in Part II, but coded as a struct instead of a class. The reason to use a struct is to not allocate an additional object on the stack. This allows this solution to be as &amp;lsquo;performant&amp;rsquo; as simply having coded the fields on the class itself. Or at least I think so&lt;/p&gt;
&lt;p&gt;The Record class also has a constructor that simply initialize the STuple:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public Record(T1 t1, T2 t2) { state = F.STuple(t1, t2); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;internal static STuple&amp;lt;T1, T2&amp;gt; STuple&amp;lt;T1, T2&amp;gt;(T1 t1, T2 t2) {
    return new STuple&amp;lt;T1, T2&amp;gt;(t1, t2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Equals method is very much the same as the Tuple&amp;rsquo;s one, just delegating to the same DSEqual function that checks equality for Tuples.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public override bool Equals(object right) {
    Utils.CheckNull(right);
    if (object.ReferenceEquals(this, right))
        return true;
    if (this.GetType() != right.GetType())
        return false;
    var rightT = right as Record&amp;lt;T1, T2&amp;gt;;
    return F.DSEquals(this.state, rightT.state);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s it. Not too difficult as most of the implementation is based on the Tuple&amp;rsquo;s code. Next post will hopefully be more interesting. It is about Type Unions.&lt;/p&gt;</description>
            <pubDate>Mon, 21 Apr 2008 13:34:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-04-21-a-c-library-to-write-functional-code-part-iii-records.html</guid>
        </item>
        
        <item>
            <title>A C# library to write functional code - Part II - Tuples</title>
            <link>https://www.lucabol.com/posts/2008-04-08-a-c-library-to-write-functional-code-part-ii-tuples.html</link>
            <description>&lt;p&gt;Other posts in the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;Part I  - Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;Part II  - Tuples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;Part III  - Records&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV  - Type Unions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V  - The Match operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Tuple"&gt;Tuples&lt;/a&gt; are a way for you not to name things. In Object Oriented languages you got to name everything. If you need to represent a bunch of data, you create a class for it.&lt;/p&gt;
&lt;p&gt;There is a strange asymmetry in mainstream OO languages in that you can pass multiple parameters to a function, but you can return just one value. Granted, there are ways around it: you can use &amp;lsquo;ref&amp;rsquo; in C# or return some sort of collection where things are stored. But by and large the model is: you pass many, you get one; if you need to return more than one, create a class to represent this &amp;lsquo;bunch of data&amp;rsquo;. Tuples are a way for you not to create such a class.&lt;/p&gt;
&lt;p&gt;Tuples are also much more than that. Once you have the language concept of &amp;lsquo;a bunch of data without a name&amp;rsquo;, you can create arrays of them, you can pass them as parameters, use them as local variables. Wherever you&amp;rsquo;d use a type, you can use a Tuple instead.&lt;/p&gt;
&lt;p&gt;This is particularly appealing to me as I like to use classes almost exclusively to represent things that have a counterpart in the domain I&amp;rsquo;m modeling (i.e. Customer, Account). I don&amp;rsquo;t like to create classes/structs just for the sake of temporarily put some data together.&lt;/p&gt;
&lt;p&gt;You can create your own Tuple class in C#, but the syntax gets ugly. Syntax matter. Syntax helps you to think differently about your program. We have syntax for anonymous types, but given that they cannot escape the scope of a method, they cannot be used as full replacement for Tuples.&lt;/p&gt;
&lt;p&gt;In any case, to my implementation. Here is how you create a Tuple:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var t1 = F.Tuple(34, &amp;quot;bo&amp;quot;, 2.3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;not too bad. In F# it is better: (34, bo, 2.3). And you often don&amp;rsquo;t need the parenthesis. But still, my C# version is ok.&lt;/p&gt;
&lt;p&gt;You then need to access its elements:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var n = t1.Item1;
var s = t1.Item2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In F# you usually access them by doing pattern matching, which gives a more intuitive syntax. But again, my C# syntax is not terrible.&lt;/p&gt;
&lt;p&gt;Tuples need to have structural equality, which means that the following has to work:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;ArrayList mad1 = new ArrayList { new List&amp;lt;IEnumerable&amp;lt;string&amp;gt;&amp;gt; { new string[] { &amp;quot;bo&amp;quot; }, new string[] { &amp;quot;bo&amp;quot; } },
                               32, &amp;quot;bo&amp;quot;, new int[] { 4, 5, 6 } };
ArrayList mad2 = new ArrayList { new List&amp;lt;IEnumerable&amp;lt;string&amp;gt;&amp;gt; { new string[] { &amp;quot;bo&amp;quot; }, new string[] { &amp;quot;bo&amp;quot; } },
                               32, &amp;quot;bo&amp;quot;, new int[] { 4, 5, 6 } };
ArrayList mad3 = new ArrayList { new List&amp;lt;IEnumerable&amp;lt;string&amp;gt;&amp;gt; { new string[] { &amp;quot;bo&amp;quot; }, new string[] { &amp;quot;bo&amp;quot; } },
                               32, &amp;quot;bo&amp;quot;, new int[] { 4, 5, 5 } };

Assert.AreEqual(F.Tuple(mad1, mad2, mad1), F.Tuple(mad2, mad1, mad2));
Assert.AreNotEqual(F.Tuple(mad1, mad2, mad1), F.Tuple(mad1, mad3, mad1));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use Tuples as return values, parameters, locals etc. Unfortunately, the syntax is ugly when Tuples are part of the signature of a function:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public Tuple&amp;lt;string, IEnumerable&amp;lt;Tuple&amp;lt;string, ObservationHistory&amp;gt;&amp;gt;&amp;gt; Execute() {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the above information, you can be a user of Tuples. From this point on, I&amp;rsquo;ll talk about some details of the implementation (I also attach the full code to this post as a zip file).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Tuple&amp;lt;T1&amp;gt; {
    public Tuple(T1 t1) {
        Item1 = t1;
    }
    public readonly T1 Item1;
    #region Equals, GetHashCode, ==, !=
}
public class Tuple&amp;lt;T1, T2&amp;gt; : Tuple&amp;lt;T1&amp;gt; {
    public Tuple(T1 t1, T2 t2) : base(t1) { Item2 = t2; }
    public readonly T2 Item2;
    #region Equals, GetHashCode, ==, !=
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, Tuples are classes, not structs. The reason for it is fully described in &lt;a href="http://blogs.msdn.com/lucabol/archive/2008/01/11/creating-an-immutable-value-object-in-c-part-v-using-a-library.aspx"&gt;this series of posts&lt;/a&gt;. They also inherit from one another. There are pros and cons to that. The main pros are that I had to write less code and that you can pass a Tuple&lt;int, string&gt; when a function expects a Tuple&lt;int, string, int&gt;. The main drawback is that you can pass a Tuple&lt;int, string&gt; when a function expects a Tuple&lt;int, string, int&gt;. Also notice the use of public fields. These is a problem with frameworks that insist on properties (i.e. Data Binding). Also, I just got to 5 as arity goes. The day I need 6 items, I&amp;rsquo;ll add another one. It is boilerplate code (that I&amp;rsquo;d still like not to write).&lt;/p&gt;
&lt;p&gt;The Equals method is a bit convoluted:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;internal static class Utils {
    public static void CheckNull&amp;lt;T&amp;gt;(T t) {
        if (t == null)
            throw new ArgumentNullException();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public override bool Equals(object right) {
    Utils.CheckNull(right);
    if (object.ReferenceEquals(this, right))
        return true;
    if (this.GetType() != right.GetType())
        return false;
    var rightT = right as Tuple&amp;lt;T1, T2, T3&amp;gt;;
    return base.Equals(rightT) &amp;amp;&amp;amp; F.DSEquals(this.Item3, rightT.Item3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I always get complaints when I show Equals methods that throw if null is passed in, but I stand by my logic, that the presence of null for these categories of &amp;lsquo;structurally equal&amp;rsquo; classes is symptom of an error and I want to be notified. Returning false doesn&amp;rsquo;t do that.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;internal static bool DSEquals&amp;lt;T&amp;gt;(T left, T right) {
    if (left == null &amp;amp;&amp;amp; right == null)
        return true;
    if (left == null &amp;amp;&amp;amp; right != null)
        return false;
    var len = left as IEnumerable;
    var ren = right as IEnumerable;
    if (len == null &amp;amp;&amp;amp; ren == null)
        return left.Equals(right);
    if (len == null &amp;amp;&amp;amp; ren != null)
        return false;
    if (len != null &amp;amp;&amp;amp; ren == null)
        return false;
    return SequenceEqual(len, ren);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DSEquals check the content of the Tuple and forward to SequenceEqual in case one slot of the Tuple contains an IEnumerable.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;internal static bool SequenceEqual(IEnumerable en1, IEnumerable en2) {
    var enumerator = en2.GetEnumerator();
    foreach (var o in en1) {
        if (!enumerator.MoveNext())
            return false;
        if (!DSEquals(o, enumerator.Current))
            return false;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SequenceEqual checks that the number of items in the enumerator is the same and recursively calls DSEqual to check structural equality for items at the same index in the two enumerators.&lt;/p&gt;
&lt;p&gt;GetHashCode is trivial (and maybe trivially wrong, one of these days I&amp;rsquo;ll learn everything about GetHashCode() ).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public override int GetHashCode() {
    return base.GetHashCode() | Item3.GetHashCode();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The equality operators are equally simple.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static bool operator ==(Tuple&amp;lt;T1, T2, T3&amp;gt; t1, Tuple&amp;lt;T1, T2, T3&amp;gt; t2) {
    Utils.CheckNull(t1);
    Utils.CheckNull(t2);
    return t1.Equals(t2);
}
public static bool operator !=(Tuple&amp;lt;T1, T2, T3&amp;gt; t1, Tuple&amp;lt;T1, T2, T3&amp;gt; t2) {
    return !(t1 == t2);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And ToString() prints my favorite Tuple format.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public override string ToString() {
    return string.Format(&amp;quot;{0},{1}&amp;quot;, base.ToString(), Item3.ToString());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;m sure you can find plenty of issues in this code. As always, it is not &amp;lsquo;production ready&amp;rsquo;, it is more &amp;lsquo;Luca having fun doing it&amp;rsquo;. In any case, there are some testcases in the solution to check the extent of my testing.&lt;/p&gt;
&lt;p&gt;In the next post we&amp;rsquo;ll look at Records.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/08/36/99/78/Functional.zip"&gt;Functional.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Tue, 08 Apr 2008 16:51:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-04-08-a-c-library-to-write-functional-code-part-ii-tuples.html</guid>
        </item>
        
        <item>
            <title>A C# library to write functional code - Part I - Background</title>
            <link>https://www.lucabol.com/posts/2008-04-01-a-c-library-to-write-functional-code-part-i-background.html</link>
            <description>&lt;p&gt;Other posts in the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;&lt;strong&gt;&lt;font color="#006bad"&gt;Part I  - Background&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt; &lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;&lt;strong&gt;&lt;font color="#006bad"&gt;Part II  - Tuples&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;&lt;font color="#006bad"&gt;Part III  - Records&lt;/font&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a class="" href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV  - Type Unions&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a class="" href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V  - The Match operator&lt;/a&gt;&lt;/strong&gt;
In December (slow time in msft) I decided to understand what functional programming is all about. When I say &amp;#8216;understanding&amp;rsquo; I don&amp;rsquo;t mean just paying lip service to the main concepts by knowingly mentioning them in casual conversations (i.e. look at this memoization, man! or this lambda function is so hot!. I can already do that. I intellectually know what the thing is.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wanted to *really* understand it. For me that means writing plenty of code. I had a medium size application in my mind that I&amp;rsquo;ve been wanting to write for quite some time (stock price, dividends, splits downloading and various return calculations), so I went ahead and wrote it. I also wanted to use C#. It would have been easier in F#, but I work on the C# team and love using our own product.&lt;/p&gt;
&lt;p&gt;My early attempts were unpleasing. I would fall back to my OO background and my functional code slowly reverted to OO code. My way of thinking about it, even if starting with the best intentions, would go back to: what are the objects, what are their responsibilities and such.&lt;/p&gt;
&lt;p&gt;I needed to force myself somehow; kind of overcompensate on the other side. I hit on the idea of pragmatically defining functional programming and try to limit myself to the subset of language constructs inside my definition. As a way to define it, I used Chapter 3 of &lt;a href="http://www.amazon.com/Expert-F-Experts-Voice-Net/dp/1590598504/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1207069956&amp;sr=8-1" target="_blank"&gt;&lt;strong&gt;&lt;font color="#006bad"&gt;Expert F#&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;. I know, I know, I could have read 1,000s of academic papers and come up with a meta-analysis of all of them that formally defines what &amp;#8216;functional programming&amp;rsquo; really is. But life is too short. I trusted Don.&lt;/p&gt;
&lt;p&gt;The problem is, several of the language constructs in my small definition of functional programming don&amp;rsquo;t exist in C#. So I went ahead and created them. I built a little library to represent them and forced myself to write code using just this library. It worked.&lt;/p&gt;
&lt;p&gt;In this series of posts I will describe what&amp;rsquo;s inside this library. I want to emphasize that I built it for educational purpose only, not for performance or production code. Caveat emptor.&lt;/p&gt;
&lt;p&gt;My plan is to cover the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Tuples &lt;ul&gt;
&lt;li&gt;Records &lt;ul&gt;
&lt;li&gt;Type Unions &lt;ul&gt;
&lt;li&gt;Match&lt;/ol&gt; 
Let&amp;rsquo;s see if I can find the time to actually write these posts 🙂&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
            <pubDate>Tue, 01 Apr 2008 13:36:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-04-01-a-c-library-to-write-functional-code-part-i-background.html</guid>
        </item>
        
        <item>
            <title>LINQ to SQL Overview - video</title>
            <link>https://www.lucabol.com/posts/2008-03-03-linq-to-sql-overview-video.html</link>
            <description>&lt;p&gt;This is my presentation from TechEd Barcelona: &lt;strong&gt;The link has been fixed. It should work now. Let me know if it doesn&amp;rsquo;t.&lt;/strong&gt;&amp;nbsp;&lt;a href="http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=716"&gt;http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=716&lt;/a&gt;. The European locale brings out my Italian accent&lt;/p&gt;
&lt;p&gt;&amp;nbsp;On this page there are a bunch of interesting presentations (i.e. Anders on LINQ): &lt;a href="http://www.microsoft.com/emea/msdn/spotlight/default.aspx"&gt;http://www.microsoft.com/emea/msdn/spotlight/default.aspx&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 03 Mar 2008 16:51:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-03-03-linq-to-sql-overview-video.html</guid>
        </item>
        
        <item>
            <title>Creating an immutable value object in C# - Part V - Using a library</title>
            <link>https://www.lucabol.com/posts/2008-01-11-creating-an-immutable-value-object-in-c-part-v-using-a-library.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;Part I  - Using a class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx"&gt;Part II  - Making the class better&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;Part III  - Using a struct&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/"&gt;Part IV  - A class with a special value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the last post we presented a variation of implementing a value object using a class. Everything works (obviously), but the amount of code to write is unpleasing. In this post we examine a library based solution. I just describe how to use the Record class, not how it is implemented. You can read the attached implementation code (it is in functional.cs). There is much more in there than Record&amp;lt;&amp;gt;. I&amp;rsquo;ll talk about the rest in a (hopefully) upcoming series.&lt;/p&gt;
&lt;p&gt;To use the record class you need to inherit from it, as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class DateSpan: Record&amp;lt;DateTime, DateTime, bool&amp;gt; {...}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generic argument types represent the types that comprise the (immutable) state of the object. You then need a friendly way for folks to access this state:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public DateTime Start { get { return state.Item1; } }
    public DateTime End { get { return state.Item2; } }
    public bool HasValue { get { return state.Item3; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is all you have to do. You don&amp;rsquo;t need to implement Equals, ==, != and GetHashCode. Structural equivalence is given to you by the Record class. Such a property is recursive, in the sense that you can embed value objects inside other value objects and the implementation would walk your object graph as necessary.&lt;/p&gt;
&lt;p&gt;For example, given the following class hierarchy:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Order: Record&amp;lt;string, int&amp;gt; {
        public Order(string item, int qty): base(item,qty) {}
        public string Item { get { return state.Item1;}}
        public int Quantity { get { return state.Item2; } }
    }
    public class Customer: Record&amp;lt;string, IEnumerable&amp;lt;Order&amp;gt;&amp;gt; {
        public Customer(string name, IEnumerable&amp;lt;Order&amp;gt; orders) : base(name, orders) { }
        public string Name { get { return state.Item1; } }
        public IEnumerable&amp;lt;Order&amp;gt; Orders { get { return state.Item2; } }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following test case succeed:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[TestMethod]
        public void Record2Test() {
            var c1 = new Customer(&amp;quot;Luca&amp;quot;, new Order[] { new Order(&amp;quot;car&amp;quot;,1), new Order(&amp;quot;stereo&amp;quot;, 3)});
            var c11 = new Customer(&amp;quot;Luca&amp;quot;, new Order[] { new Order(&amp;quot;car&amp;quot;, 1), new Order(&amp;quot;stereo&amp;quot;, 3) });
            var c2 = new Customer(&amp;quot;Bob&amp;quot;, new Order[] { new Order(&amp;quot;car&amp;quot;, 1), new Order(&amp;quot;stereo&amp;quot;, 3) });
            var c3 = new Customer(&amp;quot;Bob&amp;quot;, new Order[] { new Order(&amp;quot;car&amp;quot;, 1), new Order(&amp;quot;stereo&amp;quot;, 2) });
            Assert.AreEqual(c1, c11);
            Assert.AreNotEqual(c1, c2);
            Assert.AreNotEqual(c1, c3);
            Assert.AreNotEqual(c2, c3);
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please don&amp;rsquo;t take my library as production ready code. The amount of test I put into it is limited. You can probably find obvious bugs with it. &lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at other drawbacks. The biggest one is that I&amp;rsquo;m stealing your base class. If you want your value object to inherit from something else, you cannot. You cannot even have value objects inherit from each other. In that case you are back to implementing your own Equals, == and so on. The only tools at your disposal are interfaces and composition.&lt;/p&gt;
&lt;p&gt;Another drawback is that writing classes in this way is slightly unnatural. You have to think about the &amp;lsquo;type&amp;rsquo; of your state in the declaration of the class itself instead of more naturally writing it closer to where you assign names to it (property/field declaration).&lt;/p&gt;
&lt;p&gt;Having considered these drawbacks, I&amp;rsquo;m using this library in all my code wherever I need value objects (which is almost everywhere these days). Writing all the Equals explicitly is too error prone for my taste. I will also be creating IDE snippets for myself that make writing these classes easier.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think I have anything else to say on this topic, so this will be my last post on it. If something else comes up, I&amp;rsquo;ll let you know.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/07/07/77/13/TimeLineUsingRecord.zip"&gt;TimeLineUsingRecord.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Fri, 11 Jan 2008 13:36:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-01-11-creating-an-immutable-value-object-in-c-part-v-using-a-library.html</guid>
        </item>
        
        <item>
            <title>Book review: The Halo Effect</title>
            <link>https://www.lucabol.com/posts/2008-01-07-book-review-the-halo-effect.html</link>
            <description>&lt;p&gt;When I read &lt;a href="http://www.amazon.com/Built-Last-Successful-Visionary-Companies/dp/0060566108/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1199729020&amp;sr=1-1" target="_blank"&gt;Built to Last&lt;/a&gt;, &lt;a href="http://www.amazon.com/Search-Excellence-Americas-Best-Run-Companies/dp/B0007M2K8Q/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1199729066&amp;sr=1-1" target="_blank"&gt;In search of excellent&lt;/a&gt; and &lt;a href="http://www.amazon.com/Good-Great-Companies-Leap-Others/dp/0066620996/ref=pd_bbs_2?ie=UTF8&amp;s=books&amp;qid=1199729020&amp;sr=1-2" target="_blank"&gt;Good to great&lt;/a&gt; I immediately thought: What a bunch of BS!!. But again, I think that about most business books.&lt;/p&gt;
&lt;p&gt;The content of these books seemed particularly ludicrous to me. I found both logical inconsistencies and methodological flaws in their process. For example, picking successful companies &lt;em&gt;after the fact&lt;/em&gt; is analogous to picking the winners of a lottery and claim that they have exceptional skills. Betting the farm on a single concept (i.e. &lt;em&gt;Big Hairy Goal&lt;/em&gt;) is clearly the right thing when you are right, but most often than not you are wrong. What about all the companies that did that and failed? Also, &lt;em&gt;Keeping to the Core&lt;/em&gt; worked really well for Coca Cola, but really badly for Kodak.&lt;/p&gt;
&lt;p&gt;These are just examples. These books are packed full of such reasonably sounding absurdities. I thought that everybody would immediately spot this. I thought that the mediocre subsequent performance of the companies originally selected as excellent would obviously demonstrate the unsoundness of such conclusion. I was very wrong. These tomes are hugely successful. People seemed to disagree with me. They really like this stuff. Given that my work and my life were not overly impacted one way or the other, I left the matter to rest.&lt;/p&gt;
&lt;p&gt;And then came &lt;a href="http://www.amazon.com/Halo-Effect-Business-Delusions-Managers/dp/0743291255/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1199729844&amp;sr=1-1" target="_blank"&gt;The Halo Effect&lt;/a&gt;. It was a pleasure for me to read, as it confirmed my own ideas (confirmation bias anyone?) and added many more.&lt;/p&gt;
&lt;p&gt;The title is slightly misleading. A better title would have been: Why the idea of finding common traits among successful companies is baloney. I know, not as catchy. The catchy halo effect, mentioned in the title, is just the biggest delusion that people have about the topic.&lt;/p&gt;
&lt;p&gt;I found an experiment recounted in the book to be very illuminating. They divided a set of people in multiple groups and gave each group a problem to solve. They then told half of the groups that they did a very good job and the other half that they did a very poor job. The thing is, they did so at random. They then asked people to rate the dynamics of their group on several factors. People that were told that they did a good job reported to have had wonderful dynamics: open discussions, inspired leaders, high caliber people and such. The opposite was true for the other groups.&lt;/p&gt;
&lt;p&gt;It didn&amp;rsquo;t matter what the actual dynamics had really been: some groups were very confrontational, others were very amicable; some were very vocal, others were very quiet. In the end, people who were told that they did good recalled the experience in positive terms. People who were told that they did poorly, recalled the experience in negative terms. Remember, good and bad outcomes were assigned randomly. Also, the results have been confirmed in several similar studies.&lt;/p&gt;
&lt;p&gt;It is not a good strategy that drives performance. It is perceived performance that makes people think that they had a good strategy. This is: The halo effect. This simple concept has dramatic repercussions.&lt;/p&gt;
&lt;p&gt;First of all, it invalidates the main process used in these studies: if you use newspapers articles and managers recollection to draw conclusions, you are just piling halos over halos. People would certainly give all sort of positive attributes to companies that succeeded. They do it exactly &lt;em&gt;because&lt;/em&gt; they succeeded. And when these companies fail, they suddenly give all sort of negative attributes to them. The book is full of examples of companies that were rated as excellent when their stock price went up and terrible when their stock price went down. Nothing changed in these companies, they were still doing the same exact thing.&lt;/p&gt;
&lt;p&gt;The book contains many other insights of why these &amp;#8216;studies&amp;rsquo; are deeply flawed. It calls them delusions. You are probably familiar with some of them if you have a scientific background: for example, Delusion of Correlation and Causality, Delusion of Single Explanation (factors are not independent), Delusion of Connecting the Winning Dots (ad hoc after the fact selection). Other delusions are specific to the analyzed domain: Delusion of Lasting Success, Delusion of Absolute Performance, Delusion of Organizational Physics.&lt;/p&gt;
&lt;p&gt;In the end what should managers do? Instead of following these books&amp;rsquo;s precepts, they should focus on two things: strategy and execution. Both of these things are probabilistic endeavors where the absolutely wrong measuring stick is the result that you obtain. I always found this to be a very common error people fall into at whatever level in an organization. The error is judging the soundness of a decision by its result. A decision should be judged by the soundness of the process to get to the decision and the information available &lt;em&gt;at the time the decision was taken&lt;/em&gt;. This is the only thing that is consistent with the probabilistic nature of the world we live in. The book profiles three leaders who embody this probabilistic view.&lt;/p&gt;
&lt;p&gt;In summary, please go and read this book. There are many more things in it than I described in this (albeit long and boring) post.&lt;/p&gt;</description>
            <pubDate>Mon, 07 Jan 2008 14:04:22 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2008-01-07-book-review-the-halo-effect.html</guid>
        </item>
        
        <item>
            <title>Creating an immutable value object in C# - Part IV - A class with a special value</title>
            <link>https://www.lucabol.com/posts/2007-12-28-creating-an-immutable-value-object-in-c-part-iv-a-class-with-a-special-value.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;Part I  - Using a class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx"&gt;Part II  - Making the class better&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;Part III  - Using a struct&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the last post we looked at structs as ways to implement immutable value objects and we discovered that they have several issues. &lt;/p&gt;
&lt;p&gt;A good thing about the struct implementation was the introduction of an explicit &amp;lsquo;special value&amp;rsquo; instead of &amp;lsquo;null&amp;rsquo;. I personally like doing that because it forces me to think about what are the special values in my domain instead of blindly rely on null and its semantics. Plus, it also works where null breaks down, when there are multiple special values.&lt;/p&gt;
&lt;p&gt;Having explicit special values is obviously not related to structs in any way. You can use the same pattern with classes as well, but you have to manage &amp;lsquo;null&amp;rsquo; values that can enter your API. Here is how I did it for the DateSpan class.&lt;/p&gt;
&lt;p&gt;First I defined an utility function to manage null values:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static void CheckNull&amp;lt;T&amp;gt;(T t) {
    if (t == null)
        throw new ArgumentNullException();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I had to check my null precondition for each parameter of my API. I.E.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public DateSpan Intersect(DateSpan other) {
    Utils.CheckNull(other);
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most importantly I now have to check for null in &amp;lsquo;Equals&amp;rsquo; and &amp;lsquo;==&amp;rsquo;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public override bool Equals(object obj) {
    // Interesting choice, null is not valid in this domain
    Utils.CheckNull(obj);
    if (this.GetType() != obj.GetType()) return false;
    DateSpan other = obj as DateSpan;
    return other.End == End &amp;amp;&amp;amp; other.Start == Start;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static Boolean operator ==(DateSpan v1, DateSpan v2) {
    Utils.CheckNull(v1);
    Utils.CheckNull(v2);
    return (v1.Equals(v2));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So now we have an immutable value object, represented as a class, with checks for nulls and a special value (not shown above because it is essentially the same as for structs). So, does this work?&lt;/p&gt;
&lt;p&gt;It does, but it is cumbersome to write. And if it is too cumbersome, I already know that I&amp;rsquo;m not going to use it. I might start doing it, but I would soon give up. Are there ways to ease the pain?&lt;/p&gt;
&lt;p&gt;One way would be to use snippets to help in writing the code. Snippets in this case have a couple of problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is not easy to &amp;lsquo;snippify&amp;rsquo; the logic inside &amp;lsquo;Equals&amp;rsquo;, &amp;lsquo;GetHashcode&amp;rsquo; and such&lt;/li&gt;
&lt;li&gt;It makes easy to write the code, but still it is hard to read it and maintain it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the next post we&amp;rsquo;ll look at a better solution.&lt;/p&gt;</description>
            <pubDate>Fri, 28 Dec 2007 18:45:32 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-12-28-creating-an-immutable-value-object-in-c-part-iv-a-class-with-a-special-value.html</guid>
        </item>
        
        <item>
            <title>Creating an immutable value object in C#  - Part III  - Using a struct</title>
            <link>https://www.lucabol.com/posts/2007-12-24-creating-an-immutable-value-object-in-c-part-iii-using-a-struct.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;Part I  - Using a class&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx"&gt;Part II  - Making the class better&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/"&gt;Part IV  - A class with a special value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Part II I talked about the asymmetry created by using &amp;lsquo;null&amp;rsquo; as the special value for our little DateSpan domain. We also noticed the boredom of having to implement Equals, GetHashCode, &amp;lsquo;==&amp;rsquo; and &amp;lsquo;!=&amp;rsquo; for our value objects. Let&amp;rsquo;s see if structs solve our problem.&lt;/p&gt;
&lt;p&gt;Well, to the untrained eye they do. Structs cannot be null and they implement Equals and GetHashCode by checking the state of the object, not its pointer in memory.&lt;/p&gt;
&lt;p&gt;So, have we found the perfect tool to implement our value object?&lt;/p&gt;
&lt;p&gt;Unfortunately, no. Here is why a struct is a less than optimal way to implement a value object:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;u&gt;Convenience issues&lt;/u&gt;  - it is not as convenient as it looks&lt;/li&gt;
&lt;li&gt;You still have to implement &amp;lsquo;==&amp;rsquo; and &amp;lsquo;!=&amp;rsquo;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You still want to implement Equals() and GetHashCode(), if you want to avoid boxing/unboxing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;u&gt;Performance issues&lt;/u&gt;  - it is not as fast as it looks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Structs are allocated on the stack. Every time you pass them as arguments, the state is copied. If your struct has more than a few fields, performance might suffer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;u&gt;Usability issues&lt;/u&gt;  - it is not as useful as it looks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Structs always have a public default constructor that &amp;lsquo;zeros&amp;rsquo; all the fields&lt;/li&gt;
&lt;li&gt;Structs cannot be abstract&lt;/li&gt;
&lt;li&gt;Structs cannot extend another structs&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Don&amp;rsquo;t get me wrong, structs are extremely useful as a way to represent small bundles of data. But if you use value objects extensively, their limitations start to show.&lt;/p&gt;
&lt;p&gt;A case could be made that you should use struct to implement value objects if the issues exposed above don&amp;rsquo;t apply to your case. When they do apply, you should use classes. I&amp;rsquo;m a forgetful and lazy programmer, I don&amp;rsquo;t want to remember all these cases. I just want a pattern that I can use whenever I need a value object. It seems to me that structs don&amp;rsquo;t fit the bill.&lt;/p&gt;
&lt;p&gt;For the sake of completeness, here is the code for DateSpan using a struct. Note that I explicitly introduced a &amp;lsquo;special value&amp;rsquo; instead of using null (which is not available for structs).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public struct DateSpan {
    public static DateSpan NoValueDateSpan { get { return noValueDateSpan; } }
    public DateSpan(DateTime pstart, DateTime pend) {
        if (pend &amp;lt; pstart)
            throw new ArgumentException(pstart.ToString() + &amp;quot; doesn't come before &amp;quot; + pend.ToString());
        start = pstart;
        end = pend;
        hasValue = true;
    }
    public DateSpan Union(DateSpan other) {
        if (!HasValue)
            return other;
        if (!other.HasValue)
            return this;
        if (IsOutside(other))
            return DateSpan.NoValueDateSpan;
        DateTime newStart = other.Start &amp;lt; Start ? other.Start : Start;
        DateTime newEnd = other.End &amp;gt; End ? other.End : End;
        return new DateSpan(newStart, newEnd);
    }
    public DateSpan Intersect(DateSpan other) {
        if (!HasValue)
            return DateSpan.NoValueDateSpan;
        if (!other.HasValue)
            return DateSpan.NoValueDateSpan;
        if (IsOutside(other))
            return DateSpan.NoValueDateSpan;
        DateTime newStart = other.Start &amp;gt; Start ? other.Start : Start;
        DateTime newEnd = other.End &amp;lt; End ? other.End : End;
        return new DateSpan(newStart, newEnd);
    }
    public DateTime Start { get { return start; } }
    public DateTime End { get { return end; } }
    public bool HasValue { get { return hasValue; } }
    // Making field explicitely readonly (but cannot use autoproperties)
    // BTW: If you want to use autoproperties, given that it is a struct,
    // you need to add :this() to the constructor
    private readonly DateTime start;
    private readonly DateTime end;
    private readonly bool hasValue;
    private bool IsOutside(DateSpan other) {
        return other.start &amp;gt; end || other.end &amp;lt; start;
    }
    // Changing the internal machinery so that hasValue default is false
    // This way the automatically generated empty constructor returns the right thing
    private static DateSpan noValueDateSpan = new DateSpan();
    #region Boilerplate Equals, ToString Implementation
    public override string ToString() {
        return string.Format(&amp;quot;Start:{0} End:{1}&amp;quot;, start, end);
    }
    public static Boolean operator ==(DateSpan v1, DateSpan v2) {
        return (v1.Equals(v2));
    }
    public static Boolean operator !=(DateSpan v1, DateSpan v2) {
        return !(v1 == v2);
    }
    //public override bool Equals(object obj) {
    //    if (this.GetType() != obj.GetType()) return false;
    //    DateSpan other = (DateSpan) obj;
    //    return other.end == end &amp;amp;&amp;amp; other.start == start;
    //}
    //public override int GetHashCode() {
    //    return start.GetHashCode() | end.GetHashCode();
    //}
    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/06/85/58/26/TimeLineAsStruct.zip"&gt;TimeLineAsStruct.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 24 Dec 2007 17:39:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-12-24-creating-an-immutable-value-object-in-c-part-iii-using-a-struct.html</guid>
        </item>
        
        <item>
            <title>Bisection-based XIRR implementation in C#</title>
            <link>https://www.lucabol.com/posts/2007-12-17-bisection-based-xirr-implementation-in-c.html</link>
            <description>&lt;p&gt;Here is a quick implementation of XIRR (using Excel nomenclature) written in C#.&lt;/p&gt;
&lt;p&gt;Disclaimer: this is a super simple Bisection-based implementation. People tend to prefer the Newton method, but this is simpler and works for the app I&amp;rsquo;m writing. I decided to post it because I couldn&amp;rsquo;t find one on the net when I looked for it. I attached testcases to show the extent of my testing.&lt;/p&gt;
&lt;p&gt;It is called CalculateXIRR and it is invoked by passing a list of cash flows, a tolerance and a max number of iterations.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;

using System.Linq;

using Money = System.Decimal;

using Rate = System.Double;

using System.Collections.Generic;
public

 struct Pair&amp;lt;T, Z&amp;gt; {
public Pair(T first, Z second) { First = first; Second = second; }

public readonly T First;

public readonly Z Second;

}


public class CashFlow {

public CashFlow(Money amount, DateTime date) { Amount = amount; Date = date; }

public readonly Money Amount;
public readonly DateTime Date;
}

public struct AlgorithmResult&amp;lt;TKindOfResult, TValue&amp;gt; {

public AlgorithmResult(TKindOfResult kind, TValue value) {

Kind = kind;
Value = value;
}

public readonly TKindOfResult Kind;
public readonly TValue Value;
}

public enum ApproximateResultKind {
ApproximateSolution,
ExactSolution,
NoSolutionWithinTolerance
}

public static class Algorithms {

internal static Money CalculateXNPV(IEnumerable&amp;lt;CashFlow&amp;gt; cfs, Rate r) {

if (r &amp;lt;= -1)
r= -0.99999999; // Very funky ... Better check what an IRR &amp;lt;= -100% means

return (from cf in cfs
let startDate = cfs.OrderBy(cf1 =&amp;gt; cf1.Date).First().Date
select cf.Amount / (decimal) Math.Pow(1 + r, (cf.Date - startDate).Days / 365.0)).Sum();
}

internal static Pair&amp;lt;Rate, Rate&amp;gt; FindBrackets(Func&amp;lt;IEnumerable&amp;lt;CashFlow&amp;gt;, Rate, Money&amp;gt; func, IEnumerable&amp;lt;CashFlow&amp;gt; cfs) {

// Abracadabra magic numbers ...
const int maxIter = 100;
const Rate bracketStep = 0.5;
const Rate guess = 0.1;

Rate leftBracket = guess - bracketStep;
Rate rightBracket = guess + bracketStep;
var iter = 0;

while (func(cfs, leftBracket) * func(cfs, rightBracket) &amp;gt; 0 &amp;amp;&amp;amp; iter++ &amp;lt; maxIter) {

leftBracket -= bracketStep;
rightBracket += bracketStep;
}

if (iter &amp;gt;= maxIter)
return new Pair&amp;lt;double, double&amp;gt;(0, 0);

return new Pair&amp;lt;Rate, Rate&amp;gt;(leftBracket, rightBracket);
}

// From &amp;quot;Applied Numerical Analyis&amp;quot; by Gerald
internal static AlgorithmResult&amp;lt;ApproximateResultKind, Rate&amp;gt; Bisection(Func&amp;lt;Rate, Money&amp;gt; func, Pair&amp;lt;Rate, Rate&amp;gt; brackets, Rate tol, int maxIters) {

int iter = 1;

Money f3 = 0;
Rate x3 = 0;
Rate x1 = brackets.First;
Rate x2 = brackets.Second;

do {
var f1 = func(x1);
var f2 = func(x2);

if (f1 == 0 &amp;amp;&amp;amp; f2 == 0)
return new AlgorithmResult&amp;lt;ApproximateResultKind, Rate&amp;gt;(ApproximateResultKind.NoSolutionWithinTolerance, x1);

if (f1 * f2 &amp;gt; 0)
throw new ArgumentException(&amp;quot;x1 x2 values don't bracket a root&amp;quot;);

x3 = (x1 + x2) / 2;
f3 = func(x3);

if (f3 * f1 &amp;lt; 0)
x2 = x3;
else
x1 = x3;

iter++;

} while (Math.Abs(x1 - x2)/2 &amp;gt; tol &amp;amp;&amp;amp; f3 != 0 &amp;amp;&amp;amp; iter &amp;lt; maxIters);

if (f3 == 0)
return new AlgorithmResult&amp;lt;ApproximateResultKind, Rate&amp;gt;(ApproximateResultKind.ExactSolution, x3);

if (Math.Abs(x1 - x2) / 2 &amp;lt; tol)
return new AlgorithmResult&amp;lt;ApproximateResultKind, Rate&amp;gt;(ApproximateResultKind.ApproximateSolution, x3);

if (iter &amp;gt; maxIters)
return new AlgorithmResult&amp;lt;ApproximateResultKind, Rate&amp;gt;(ApproximateResultKind.NoSolutionWithinTolerance, x3);

throw new Exception(&amp;quot;It should never get here&amp;quot;);
}

public static AlgorithmResult&amp;lt;ApproximateResultKind, Rate&amp;gt; CalculateXIRR(IEnumerable&amp;lt;CashFlow&amp;gt; cfs, Rate tolerance, int maxIters) {

var brackets = FindBrackets(CalculateXNPV, cfs);

if (brackets.First == brackets.Second)
return new AlgorithmResult&amp;lt;ApproximateResultKind, double&amp;gt;(ApproximateResultKind.NoSolutionWithinTolerance, brackets.First);

return Bisection(r =&amp;gt; CalculateXNPV(cfs,r), brackets, tolerance, maxIters);
}
}

// TESTS
using Microsoft.VisualStudio.TestTools.UnitTesting;

using System.Collections.Generic;

using System;

using Rate = System.Double;
namespace TimeLineTest
{
[TestClass()]
public class AlgorithmsTest {

IEnumerable&amp;lt;CashFlow&amp;gt; cfs = new CashFlow[] {
new CashFlow(-10000, new DateTime(2008,1,1)),
new CashFlow(2750, new DateTime(2008,3,1)),
new CashFlow(4250, new DateTime(2008,10,30)),
new CashFlow(3250, new DateTime(2009,2,15)),
new CashFlow(2750, new DateTime(2009,4,1))
};

IEnumerable&amp;lt;CashFlow&amp;gt; bigcfs = new CashFlow[] {
new CashFlow(-10, new DateTime(2000,1,1)),
new CashFlow(10, new DateTime(2002,1,2)),
new CashFlow(20, new DateTime(2003,1,3))
};

IEnumerable&amp;lt;CashFlow&amp;gt; negcfs = new CashFlow[] {
new CashFlow(-10, new DateTime(2000,1,1)),
new CashFlow(-1, new DateTime(2002,1,2)),
new CashFlow(1, new DateTime(2003,1,3))
};

IEnumerable&amp;lt;CashFlow&amp;gt; samedaysamecfs = new CashFlow[] {
new CashFlow(-10, new DateTime(2000,1,1)),
new CashFlow(10, new DateTime(2000,1,1)),
};

IEnumerable&amp;lt;CashFlow&amp;gt; samedaydifferentcfs = new CashFlow[] {
new CashFlow(-10, new DateTime(2000,1,1)),
new CashFlow(100, new DateTime(2000,1,1)),
};

IEnumerable&amp;lt;CashFlow&amp;gt; bigratecfs = new CashFlow[] {
new CashFlow(-10, new DateTime(2000,1,1)),
new CashFlow(20, new DateTime(2000,5,30)),
};

IEnumerable&amp;lt;CashFlow&amp;gt; zeroRate = new CashFlow[] {
new CashFlow(-10, new DateTime(2000,1,1)),
new CashFlow(10, new DateTime(2003,1,1)),
};

IEnumerable&amp;lt;CashFlow&amp;gt; doubleNegative = new CashFlow[] {
new CashFlow(-10000, new DateTime(2008,1,1)),
new CashFlow(2750, new DateTime(2008,3,1)),
new CashFlow(-4250, new DateTime(2008,10,30)),
new CashFlow(3250, new DateTime(2009,2,15)),
new CashFlow(2750, new DateTime(2009,4,1))
};

IEnumerable&amp;lt;CashFlow&amp;gt; badDoubleNegative = new CashFlow[] {
new CashFlow(-10000, new DateTime(2008,1,1)),
new CashFlow(2750, new DateTime(2008,3,1)),
new CashFlow(-4250, new DateTime(2008,10,30)),
new CashFlow(3250, new DateTime(2009,2,15)),
new CashFlow(-2750, new DateTime(2009,4,1))
};

double r = 0.09;
double tolerance = 0.0001;
int maxIters = 100;

private TestContext testContextInstance;

public TestContext TestContext {
get {
return testContextInstance;
}
set {
testContextInstance = value;
}
}

[TestMethod()]
public void CalculateXNPV() {

Assert.AreEqual(2086.6476020315416570634272814M, Algorithms.CalculateXNPV(cfs, r));
Assert.AreEqual(-10.148147600710372651326920258M, Algorithms.CalculateXNPV(negcfs, 0.5));
Assert.AreEqual(4.9923725815954514810351876895M, Algorithms.CalculateXNPV(bigcfs, 0.3));
}

[TestMethod]
public void FindBrackets() {

var brackets = Algorithms.FindBrackets(Algorithms.CalculateXNPV, cfs);
Assert.IsTrue(brackets.First &amp;lt; 0.3733 &amp;amp;&amp;amp; brackets.Second &amp;gt; 0.3733);

brackets = Algorithms.FindBrackets(Algorithms.CalculateXNPV, bigcfs);
Assert.IsTrue(brackets.First &amp;lt; 0.5196 &amp;amp;&amp;amp; brackets.Second &amp;gt; 0.5196);

brackets = Algorithms.FindBrackets(Algorithms.CalculateXNPV, negcfs);
Assert.IsTrue(brackets.First &amp;lt; -0.6059 &amp;amp;&amp;amp; brackets.Second &amp;gt; -0.6059);
}

[TestMethod]
public void XIRRTest() {

var irr = Algorithms.CalculateXIRR(cfs, tolerance, maxIters);
Assert.AreEqual(0.3733, irr.Value, 0.001);
Assert.AreEqual(ApproximateResultKind.ApproximateSolution, irr.Kind);

irr = Algorithms.CalculateXIRR(bigcfs, tolerance, maxIters);
Assert.AreEqual(0.5196, irr.Value, 0.001);
Assert.AreEqual(ApproximateResultKind.ApproximateSolution, irr.Kind);

irr = Algorithms.CalculateXIRR(negcfs, tolerance, maxIters);
Assert.AreEqual(-0.6059, irr.Value, 0.001);
Assert.AreEqual(ApproximateResultKind.ApproximateSolution, irr.Kind);

irr = Algorithms.CalculateXIRR(samedaysamecfs, tolerance, maxIters);
Assert.AreEqual(ApproximateResultKind.NoSolutionWithinTolerance, irr.Kind);

irr = Algorithms.CalculateXIRR(samedaydifferentcfs, tolerance, maxIters);
Assert.AreEqual(ApproximateResultKind.NoSolutionWithinTolerance, irr.Kind);

irr = Algorithms.CalculateXIRR(bigratecfs, tolerance, maxIters);
Assert.AreEqual(4.40140, irr.Value, 0.001);
Assert.AreEqual(ApproximateResultKind.ApproximateSolution, irr.Kind);

irr = Algorithms.CalculateXIRR(zeroRate, tolerance, maxIters);
Assert.AreEqual(0, irr.Value, 0.001);
Assert.AreEqual(ApproximateResultKind.ApproximateSolution, irr.Kind);

irr = Algorithms.CalculateXIRR(doubleNegative, tolerance, maxIters);
Assert.AreEqual(-0.537055, irr.Value, 0.001);
Assert.AreEqual(ApproximateResultKind.ApproximateSolution, irr.Kind);

irr = Algorithms.CalculateXIRR(badDoubleNegative, tolerance, maxIters);
Assert.AreEqual(ApproximateResultKind.NoSolutionWithinTolerance, irr.Kind);
}
}
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Mon, 17 Dec 2007 18:17:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-12-17-bisection-based-xirr-implementation-in-c.html</guid>
        </item>
        
        <item>
            <title>Creating an immutable value object in C#  - Part II  - Making the class better</title>
            <link>https://www.lucabol.com/posts/2007-12-06-creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;Part I  - Using a class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;Part III  - Using a struct&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/"&gt;Part IV  - A class with a special value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the previous post I showed how to trivially implement a value object. The code works but it has several issues. Some are very simple, others are more interesting.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;State not explicitly read-only&lt;/li&gt;
&lt;li&gt;Asymmetry in the usage of Union and Intersection&lt;/li&gt;
&lt;li&gt;Small perf issue in the Union method&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first problem is that my use of automatic properties doesn&amp;rsquo;t assure that the status of the object is immutable; I can still modify it from inside the class. The simple solution is to make the fields &lt;em&gt;readonly&lt;/em&gt; and write the getters as in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;private readonly DateTime start;
    private readonly DateTime end;
    public DateTime Start { get { return start; } }
    public DateTime End { get { return end; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second issue is more subtle. Consider this code&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;DateSpan d1 = new DateSpan(new DateTime(1, 1, 2000), new DateTime(1, 1, 2002));
        DateSpan d2 = null;
        DateSpan r1 = d1.Intersect(d2);
        DateSpan r2 = d2.Intersect(d1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I would like things in my little &amp;lsquo;algebra&amp;rsquo; to be symmetric. In this case I&amp;rsquo;d like: &lt;em&gt;r1 == r2 == null&lt;/em&gt;. But this code throws in the last line as I&amp;rsquo;m trying to invoke a method on a null object.&lt;/p&gt;
&lt;p&gt;The traditional solution to this problem is to make Union and Intersect to be static methods, but then you loose the magic of calling them as instance methods (i.e. it becomes hard to chain them together as in &lt;em&gt;d1.Intersect(d2).Union(d3).Intersect(d4)&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Extension methods come to the rescue here as they allow you to create static methods, but to call them as if the were instance methods. The new code for &lt;em&gt;Intersect&lt;/em&gt; looks like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static DateSpan Intersect(this DateSpan one, DateSpan other) {
        if (one == null)
            return null;
        if (other == null)
            return null;
        if (one.IsOutside(other))
            return null;
        DateTime start = other.Start &amp;gt; one.Start ? other.Start : one.Start;
        DateTime end = other.End &amp;lt; one.End ? other.End : one.End;
        return new DateSpan(start, end);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This workaround would not work if the extension method needs to access private state of the class. In that case you would need to create a static method on the &lt;em&gt;DataSpan&lt;/em&gt; class and invoke it from the extension method. Slightly more convoluted, but still doable.&lt;/p&gt;
&lt;p&gt;At a more philosophical level, the asymmetry issue happens here because I&amp;rsquo;m using something outside my domain of interest (the &lt;em&gt;null&lt;/em&gt; value) to represent a special value inside my domain of interest. More on this as we talk about structs in upcoming posts.&lt;/p&gt;
&lt;p&gt;The last point is a very small one. In the &lt;em&gt;Union&lt;/em&gt; method I am creating a new object unnecessarily in the following line:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;if (other == null)
            return new DateSpan(Start, End);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can obviously avoid it by just returning &lt;em&gt;this&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This post hints to several possible issues. Is it a good idea to use null to represent special values in my domain? What if I have more than one of them (i.e. positive/negative infinite)? Would using structs solve these problems?&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll take a look at these options in upcoming posts. Attached is the modified code.&lt;/p&gt;</description>
            <pubDate>Thu, 06 Dec 2007 12:34:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-12-06-creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.html</guid>
        </item>
        
        <item>
            <title>Creating an immutable value object in C#  - Part I  - Using a class</title>
            <link>https://www.lucabol.com/posts/2007-12-03-creating-an-immutable-value-object-in-c-part-i-using-a-class.html</link>
            <description>&lt;p&gt;Other posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx"&gt;Part II  - Making the class better&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;Part III  - Using a struct&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/"&gt;Part IV  - A class with a special value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Value objects are objects for which the identity is based on their state instead of their pointer in memory. For example, a numeric Complex class is, most of the time, a value object because you can treat two instances as the same if their state (real and img fields in this case) is the same. An immutable value object is a value object that cannot be changed. You cannot modify its state, you have to create new ones.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m using these guys more and more in my code for a number of reasons, both practical and philosophical. The practical ones revolve around the greater robustness of programming without side effects and the greater simplicity of parallelizing your code. The philosophical ones are more interesting (and subjective). When in my design process I spend the time to aggressively looking for these kinds of objects, the resulting design ends up cleaner. I especially like when I can define some sort of close algebra for these guys (i.e. a set of functions that operate over them and produces new ones, not unlike &amp;lsquo;+&amp;rsquo; and &amp;lsquo;-&amp;rsquo; for numbers).&lt;/p&gt;
&lt;p&gt;This series describes how to create immutable value objects in C# and the design decisions involved. This is a summary of an email thread I had with &lt;a href="http://blogs.msdn.com/madst/default.aspx"&gt;Mads&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/lukeh/default.aspx"&gt;Luke&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The concept I will use for this series is a &lt;strong&gt;DateSpan&lt;/strong&gt;. As I define it, a DateSpan has a &lt;strong&gt;Start&lt;/strong&gt; and an &lt;strong&gt;End&lt;/strong&gt; date. You can ask for the DateSpan that represents the &lt;strong&gt;Union&lt;/strong&gt; and &lt;strong&gt;Intersection&lt;/strong&gt; of two DateSpans. The tests in the attached code better define the behavior of these operations.&lt;/p&gt;
&lt;p&gt;Given that I never use structs in my code (I&amp;rsquo;m a minimalist language user), I&amp;rsquo;ll start by using a class to represent it. We&amp;rsquo;ll make this class better in part II and use a struct in part III. A first stab at it is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class DateSpan {
    public DateSpan(DateTime start, DateTime end) {
        if (end &amp;lt; start)
            throw new ArgumentException(start.ToString() + &amp;quot; doesn't come before &amp;quot; + end.ToString());
        Start = start;
        End = end;
    }
    public DateSpan Union(DateSpan other) {
        if (other == null)
            return new DateSpan(Start, End);
        if (IsOutside(other))
            return null;
        DateTime start = other.Start &amp;lt; Start ? other.Start : Start;
        DateTime end = other.End &amp;gt; End ? other.End : End;
        return new DateSpan(start, end);
    }
    public DateSpan Intersect(DateSpan other) {
        if (other == null)
            return null;
        if (IsOutside(other))
            return null;
        DateTime start = other.Start &amp;gt; Start ? other.Start : Start;
        DateTime end = other.End &amp;lt; End ? other.End : End;
        return new DateSpan(start, end);
    }
    private bool IsOutside(DateSpan other) {
        return other.Start &amp;gt; End || other.End &amp;lt; Start;
    }
    public DateTime Start { get; private set; }
    public DateTime End { get; private set; }
    #region Boilerplate Equals, ToString Implementation
    public override string ToString() {
        return string.Format(&amp;quot;Start:{0} End:{1}&amp;quot;, Start, End);
    }
    public override bool Equals(object obj) {
        if (obj == null) return false;
        if (this.GetType() != obj.GetType()) return false;
        DateSpan other = obj as DateSpan;
        return other.End == End &amp;amp;&amp;amp; other.Start == Start;
    }
    public override int GetHashCode() {
        return Start.GetHashCode() | End.GetHashCode();
    }
    public static Boolean operator ==(DateSpan v1, DateSpan v2) {
        if ((object)v1 == null)
            if ((object)v2 == null)
                return true;
            else
                return false;
        return (v1.Equals(v2));
    }
    public static Boolean operator !=(DateSpan v1, DateSpan v2) {
        return !(v1 == v2);
    }
    #endregion
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class TimeLineExtensions {
    public static bool IsSuperSet(this DateSpan span, DateSpan other) {
        if (span.Intersect(other) == other)
            return true;
        return false;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some things to notice in this code:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Defining a value object with a C# class involves overriding Equals, Hashcode, == and !=. It is tricky, but usually boilerplate stuff, well described in &lt;a href="http://www.amazon.com/Effective-Specific-Improve-Software-Development/dp/0321245660"&gt;Wagner (2004)&lt;/a&gt;. I don&amp;rsquo;t have Bill&amp;rsquo;s book in my office, so I kind of made it up on the fly. It could be very wrong (the &amp;lsquo;==&amp;rsquo; one looks very suspicious). Don&amp;rsquo;t copy it, read Bill&amp;rsquo;s book instead&lt;/li&gt;
&lt;li&gt;Defining an immutable object with a C# class involves discipline in not changing the private state (we&amp;rsquo;ll see in Part II that we can do better than &amp;lsquo;discipline&amp;rsquo;)&lt;/li&gt;
&lt;li&gt;Notice the extension method IsSuperSet. This is something I picked up from an old Coplien book, &lt;a href="http://www.amazon.com/Multi-Paradigm-Design-James-O-Coplien/dp/0201824671"&gt;probably this one&lt;/a&gt;. The concept is to keep methods that don&amp;rsquo;t use internal state of an object external to the object itself for the sake of future maintainability. The syntax for doing that was awkward before, but extension methods make it easier&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This works (it passes all the tests), but it has a number of problems. We&amp;rsquo;ll talk about these in Part II.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/06/64/68/07/TimeLineAsClass%20-%201.zip"&gt;TimeLineAsClass  - 1.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 03 Dec 2007 13:22:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-12-03-creating-an-immutable-value-object-in-c-part-i-using-a-class.html</guid>
        </item>
        
        <item>
            <title>Brief review of Total Workday Control</title>
            <link>https://www.lucabol.com/posts/2007-11-20-brief-review-of-quottotal-workday-controlquot.html</link>
            <description>&lt;p&gt;We get plenty of emails in Microsoft. Without a system to manage them you are dead. Or better, your mind plays strange tricks on you making you think that you still have work to do. You need to convince your mind that you are done for the day and to stop bugging you, please.&lt;/p&gt;
&lt;p&gt;Almost everyone has a system. Some are better than others. My current system is &lt;a href="http://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280"&gt;Getting things done&lt;/a&gt; and it does achieve its goal of freeing my mind (mostly) without imposing too much overhead. But I&amp;rsquo;m always looking for something better. That&amp;rsquo;s why I checked out &lt;a href="http://www.amazon.com/Total-Workday-Control-Microsoft-Outlook/dp/0974930415"&gt;Total Workday Control&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The title conjures in my mind all sort of scary images of control freaks going through their days trying to achieve&amp;nbsp;optimization of every single action. In reality the book is just a light update of David Allen methodology. The most interesting thing I picked out is the differentiation between a Master Task List and a Daily List. The former contains projects or delayed tasks while the latter contains tasks (typically taken from the Master List) that you want to perform today. It also has a system of prioritizing such tasks and give good rules of thumbs on how many you&amp;nbsp;should have on each list and so on.&lt;/p&gt;
&lt;p&gt;My rule of thumb is that if I learn one useful thing by reading a book, then it is a fantastic book. This book qualifies. If you are currently using Getting things done, this book constitutes a nice upgrade. If you aren&amp;rsquo;t, I suggest you read David Allen first, as it gives you the reasons for the system, before you move to the more technical Total Workday Control.&lt;/p&gt;</description>
            <pubDate>Tue, 20 Nov 2007 11:56:46 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-11-20-brief-review-of-quottotal-workday-controlquot.html</guid>
        </item>
        
        <item>
            <title>Instead of a simple switch statement</title>
            <link>https://www.lucabol.com/posts/2007-08-31-instead-of-a-simple-switch-statement.html</link>
            <description>&lt;p&gt;This&amp;nbsp;is &lt;a href="http://blogs.msdn.com/lukeh/default.aspx"&gt;Luke&lt;/a&gt;&amp;#8216;s kind of code. I might be catching the virus&lt;/p&gt;
&lt;p&gt;```csharp
abstract class QIFParserBase {
    public enum LoadOptions {
        All,
        Prices,
        Securities,
        Transactions
    }
    static readonly Dictionary&lt;LoadOptions, Action\&lt;QIFParserBase, string[]&gt;&gt; parseFuncs =
                                        new Dictionary&lt;LoadOptions, Action\&lt;QIFParserBase, string[]&gt;&gt; {
        {LoadOptions.All, (q,c) =&amp;gt; q.ParseAll(c)},
        {LoadOptions.Prices, (q,c) =&amp;gt; q.ParsePricesBlocks(c)},
        {LoadOptions.Securities, (q,c) =&amp;gt; q.ParseSecurityBlocks(c)},
        {LoadOptions.Transactions, (q,c) =&amp;gt; q.ParseTransactionBlocks(c)}
    };
    public QIFParserBase(string fileName, LoadOptions opt) {
        string content = File.ReadAllText(fileName);
        string[] blocks = content.Split(new string[] { &amp;ldquo;!Type:&amp;rdquo;, &amp;ldquo;!Option:&amp;rdquo; },
                                                        StringSplitOptions.RemoveEmptyEntries);
        parseFuncs&lt;a href="this,blocks"&gt;opt&lt;/a&gt;;
    }&lt;/p&gt;</description>
            <pubDate>Fri, 31 Aug 2007 16:54:15 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-08-31-instead-of-a-simple-switch-statement.html</guid>
        </item>
        
        <item>
            <title>Parsing QIF Quicken files in C#</title>
            <link>https://www.lucabol.com/posts/2007-08-31-parsing-qif-quicken-files-in-c.html</link>
            <description>&lt;p&gt;I&amp;rsquo;m slightly prouder of the structure of this code than&amp;nbsp;the&amp;nbsp;one in &lt;a href="http://blogs.msdn.com/lucabol/archive/2007/08/30/retrieve-prices-dividends-and-splits-for-a-stock-in-c.aspx"&gt;the previous blog post&lt;/a&gt;. You can simply inherit from QIFParserBase and override a couple of abstract methods to customize the behavior. Still, I just tested it on a couple of test QIF files. It is not production quality at all.&lt;/p&gt;
&lt;p&gt;Notice that I don&amp;rsquo;t even have Quicken. I&amp;rsquo;m producing these test file with &lt;a href="http://www.fundmanagersoftware.com/"&gt;FundManager&lt;/a&gt;, which I use for my investments. If your software generates QIF files differently, than you have to modify the code. It shouldn&amp;rsquo;t be too hard.&lt;/p&gt;
&lt;p&gt;It works with &lt;a href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;VS 2008 beta 2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/04/67/54/58/ParseQIF.zip"&gt;ParseQIF.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Fri, 31 Aug 2007 16:43:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-08-31-parsing-qif-quicken-files-in-c.html</guid>
        </item>
        
        <item>
            <title>Retrieve prices, dividends and splits for a stock in C#</title>
            <link>https://www.lucabol.com/posts/2007-08-30-retrieve-prices-dividends-and-splits-for-a-stock-in-c.html</link>
            <description>&lt;p&gt;I wrote this code very quickly and I&amp;rsquo;m kind of ashamed of it, but it gets the job done (I think). You need the HTML Agility Pack for the stock splits retrieving code. You can download it from &lt;a class="" href="http://www.codeplex.com/htmlagilitypack/Release/ProjectReleases.aspx?ReleaseId=272"&gt;here&lt;/a&gt;&amp;nbsp;or you can simply comment out the code. I wrote it against &lt;a class="" href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;Visual Studio 2008 beta 2&lt;/a&gt;, but it should be trivial to port it to previous versions.&lt;/p&gt;
&lt;p&gt;You run it from a command window like this: priceretriever msft 1/1/1990 2/3/2003. The last two parameters are optional and default to 1/1/1980 and today.&lt;/p&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/04/65/40/00/PriceRetriever.zip"&gt;PriceRetriever.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Thu, 30 Aug 2007 16:25:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-08-30-retrieve-prices-dividends-and-splits-for-a-stock-in-c.html</guid>
        </item>
        
        <item>
            <title>Lucabol and Kiraly</title>
            <link>https://www.lucabol.com/posts/2007-08-13-lucabol-and-kiraly.html</link>
            <description>&lt;p&gt;My wife took this&amp;nbsp;in Manhattan Beach this week end. Karch is the one on the right.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/04/37/45/40/BeachVolley%20123.JPG"&gt;BeachVolley 123.JPG&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 13 Aug 2007 20:42:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-08-13-lucabol-and-kiraly.html</guid>
        </item>
        
        <item>
            <title>Video of Matt and I talking about the LINQ to SQL query/update pipeline</title>
            <link>https://www.lucabol.com/posts/2007-08-13-here-is-a-seminot-funny-video-of-matt-and-i-talking-about-the-linq-to-sql-queryupdate-pipeline.html</link>
            <description>&lt;p&gt;And a bit of history of O/R in Microsoft at the end: &lt;a href="http://blogs.msdn.com/charlie/archive/2007/08/06/linq-to-sql-pipeline-video-with-luca-bolognese-and-matt-warren.aspx"&gt;http://blogs.msdn.com/charlie/archive/2007/08/06/linq-to-sql-pipeline-video-with-luca-bolognese-and-matt-warren.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
            <pubDate>Mon, 13 Aug 2007 12:56:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-08-13-here-is-a-seminot-funny-video-of-matt-and-i-talking-about-the-linq-to-sql-queryupdate-pipeline.html</guid>
        </item>
        
        <item>
            <title>Interesting 10 years retrospective on The cathedral and the Bazaar</title>
            <link>https://www.lucabol.com/posts/2007-07-05-interesting-10-years-retrospective-on-the-cathedral-and-the-bazaar.html</link>
            <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Interesting &lt;a href="http://www.strategy-business.com/press/enewsarticle/enews053107?pg=all"&gt;read&lt;/a&gt; on what open source has been good for, on the difference between Linux and Wikipedia and on how to best harness the power of crowds.&lt;/p&gt;
&lt;p&gt;Also a highly positively reviewed &lt;a href="http://www.amazon.com/Difference-Diversity-Creates-Schools-Societies/dp/0691128383/ref=sr_1_1/104-4425703-5061533?ie=UTF8&amp;amp;s=books&amp;amp;qid=1183651116&amp;amp;sr=8-1"&gt;new book&lt;/a&gt; that formalizes in almost mathematical fashion what diversity is good for (I haven’t read it yet). The classical work on the matter is “&lt;a href="http://www.amazon.com/gp/product/0385721706/sr=8-1/qid=1183651116/ref=cm_cr_asin_lnk/104-4425703-5061533?ie=UTF8&amp;amp;qid=1183651116&amp;amp;sr=8-1"&gt;The Wisdom of crowds&lt;/a&gt;”.&lt;/p&gt;
&lt;p&gt;Excerpt from the initial article: “Raymond was clear on that point when, toward the end of his paper, he examined some of the “necessary preconditions” for the bazaar model of production. “It’s fairly clear,” he wrote, “that one cannot code from the ground up in bazaar style. One can test, debug and improve in bazaar style, but it would be very hard to &lt;em&gt;originate&lt;/em&gt; a project in bazaar mode.” In a recent e-mail to me, he was even blunter. “The individual wizard,” he wrote, “is where successful bazaar projects generally start.” “&lt;/p&gt;</description>
            <pubDate>Thu, 05 Jul 2007 12:12:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-07-05-interesting-10-years-retrospective-on-the-cathedral-and-the-bazaar.html</guid>
        </item>
        
        <item>
            <title>My TechEd webcast is here</title>
            <link>https://www.lucabol.com/posts/2007-06-19-my-teched-webcast-is-here.html</link>
            <description>&lt;p&gt;In case you want to know more about LINQ: &lt;a href="http://www.virtualteched.com/Pages/OnlineSessions/OnlineWebcastsDevTools.aspx" title="http://www.virtualteched.com/Pages/OnlineSessions/OnlineWebcastsDevTools.aspx"&gt;http://www.virtualteched.com/Pages/OnlineSessions/OnlineWebcastsDevTools.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;CTRL+F for &amp;#8216;(LINQ)&amp;rsquo;&lt;/p&gt;
&lt;p&gt;An introduction to the talk is here: &lt;a href="http://www.virtualteched.com/videos/luca%20bolognese%20sml.asx"&gt;http://www.virtualteched.com/videos/luca%20bolognese%20sml.asx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
            <pubDate>Tue, 19 Jun 2007 10:32:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-06-19-my-teched-webcast-is-here.html</guid>
        </item>
        
        <item>
            <title>ObjectSpaces early days</title>
            <link>https://www.lucabol.com/posts/2007-06-07-objectspaces-early-days.html</link>
            <description>&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;Matt has &lt;/font&gt;&lt;a href="http://blogs.msdn.com/mattwar/archive/2007/05/31/the-origin-of-linq-to-sql.aspx"&gt;&lt;font face="Tahoma" color="#0000ff"&gt;a very good post&lt;/font&gt;&lt;/a&gt;&lt;font face="Tahoma"&gt; on the history of object relational framework inside Microsoft. He and I started the whole ObjectSpaces thing together very many years ago (about six and a half). I thought I should add my two cents. &lt;s&gt;&lt;/s&gt;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;You might be wondering how a project starts inside Microsoft (or you might not). In this case, I was hired in the ADO.NET team to build an object relational framework. That was my assignment. The problem was that I had no dev or tester to work with. I also had just arrived in the US from Italy and my English was terrible (that hasn’t changed much). My only qualifications for the job were that I was incredibly passionate about the topic; I had built a couple of small ones in my spare time and have used many more in various projects. But still I had no idea on how to make things happen in this big company. Hell, I could barely understand what people were talking about at lunch.&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;Anyhow, my boss told me that there was a guy who was relatively free, but I had to come up with an idea, convince him that the idea was a good one and that he should go ahead and prototype it. That guy was Matt Warren, already one of the best developers in the SQL team and the dev lead of plenty of our .NET stack.&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;The first time I entered his office and started talking, he immediately told me: “Not now, I’m debugging”. A good start … But after that, we hit it off immediately. We talked about what an OR framework is, what it should be, how we could innovate in the space and so on. After a while, Matt started working on the very first ObjectSpaces prototype. Our modus operandi was peculiar. I would go to Matt’s office and we would discuss a particular feature or scenario. He would tell me: “Ok, we are on the same page, I’ll see you tomorrow”. The next day the feature would be implemented. If he told me: “It is going to take me 5 days to code it” I knew he didn’t like the feature and I had some more convincing to do. Sometime we would agree, sometime we wouldn’t. Sometime I came up with staff to implement, sometimes Matt did. We figured out a lot of stuff in those days.&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;Also I learned how to work with different categories of programmers. If you work with a bad programmer you have to tell him how to implement something. If you work with a good programmer you have to tell him what you want the feature to look like. If you work with an excellent programmer, you just have to tell him what your final goal is. I quickly realized that the latter was the most productive strategy with Matt. I had just to convince him of the business need for something. Implementing it ended up to be a detail.&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;That initial prototype grew to become ObjectSpaces (it was called Cheops initially). The team grew to be about 25 people, growing and stretching me personally. We went through two painful rounds of unifications with bigger products. In the end ObjectSpaces was cut. Matt moved to the C# team to work on LINQ. Dinesh and I followed after a short while. The whole ObjectSpaces team scattered in various places around the company. The object relational thing started again in the C# team as part of the LINQ project. This time around we also had a compiler to play with. Plus Anders was on board to sprinkle his design magic over the whole thing.&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;As &lt;/font&gt;&lt;a href="http://en.wikipedia.org/wiki/The_Dark_Tower_(series)"&gt;&lt;font face="Tahoma" color="#0000ff"&gt;Roland&lt;/font&gt;&lt;/a&gt;&lt;font face="Tahoma"&gt; would say, the world has moved on. Matt is now a big shot architect and I lead a team of amazingly smart individuals (they are forced to act as if my words make sense, imagine that …). We are shipping a game changing product in LINQ and a wonderful object relational framework in LINQ to SQL. Things turned out for the best (even if five years too late).&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;&amp;nbsp;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;font face="Tahoma"&gt;Still it is a pleasure to think back at those early days (and nights) of ‘figuring out stuff’ six years ago. A lot of that ‘stuff’ is inside our products today, and that is something to be proud of.&lt;/font&gt;
&lt;/p&gt;</description>
            <pubDate>Thu, 07 Jun 2007 10:40:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-06-07-objectspaces-early-days.html</guid>
        </item>
        
        <item>
            <title>My LINQ Overview session at TechEd will be live on the Internet</title>
            <link>https://www.lucabol.com/posts/2007-06-04-my-linq-overview-session-at-teched-will-be-live-on-the-internet.html</link>
            <description>&lt;p&gt;at least they told me so. It is at 8.30am Eastern time. I don&amp;rsquo;t know the exact link, but it will be somewhere here: &lt;a href="http://www.microsoft.com/events/teched2007/default.mspx"&gt;http://www.microsoft.com/events/teched2007/default.mspx&lt;/a&gt;.&lt;/p&gt;</description>
            <pubDate>Mon, 04 Jun 2007 12:45:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-06-04-my-linq-overview-session-at-teched-will-be-live-on-the-internet.html</guid>
        </item>
        
        <item>
            <title>Y combinators anyone?</title>
            <link>https://www.lucabol.com/posts/2007-05-11-y-combinators-anyone.html</link>
            <description>&lt;p&gt;From Mads, our proud C# language PM: &lt;a href="http://blogs.msdn.com/madst/archive/2007/05/11/recursive-lambda-expressions.aspx"&gt;http://blogs.msdn.com/madst/archive/2007/05/11/recursive-lambda-expressions.aspx&lt;/a&gt;.&lt;/p&gt;</description>
            <pubDate>Fri, 11 May 2007 19:16:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-05-11-y-combinators-anyone.html</guid>
        </item>
        
        <item>
            <title>Huntington Beach and Kiraly</title>
            <link>https://www.lucabol.com/posts/2007-05-05-huntington-beach-and-kiraly.html</link>
            <description>&lt;p&gt;Today I&amp;rsquo;m watching the AVP tour, especially (as always)&amp;nbsp;&lt;a class="" href="http://www.avp.com/players/profile.jsp?id=69"&gt;Karch&lt;/a&gt;. This year is his last and I&amp;rsquo;m trying to go and see him as much as I can. Karch is an idol for my generation of beach volley players. Well, it is an idol for all generations really&lt;/p&gt;
&lt;p&gt;He loses one, he wins one. The day is about to end but he still has to play against &lt;a class="" href="http://www.avp.com/players/profile.jsp?id=72" target="_blank"&gt;Lambo&lt;/a&gt;. The sun is going down, it is the last match of the day. The crowd gathers around the court. As always it is not easy to put him down. He plays with &lt;a class="" href="http://www.avp.com/players/profile.jsp?id=141" target="_blank"&gt;Wong&lt;/a&gt;, another veteran of the AVP tour. The other team serves him short to force him to move forward and then backward again to prepare his attack. It is a smart strategy, Karch&amp;rsquo;s legs and not what they used to be 20 years ago&lt;/p&gt;
&lt;p&gt;But he goes on, finds new and interesting ways to overcome a block that is way higher than his maximum one hand reach. Sometimes it feels as if the block is his friend and Lambo starts to lower his hands not to give him that tool to play with. But the short serves are wearing him down and the match is going in the wrong direction.&lt;/p&gt;
&lt;p&gt;Suddenly, out of nowhere, he produces an amazing strong hit. Something &lt;a class="" href="http://www.avp.com/players/profile.jsp?id=1163" target="_blank"&gt;Rosy&lt;/a&gt; could have done. The crowd goes ballistic. Everybody laughs and cheers. Even the other team is laughing. Karch raises his hands smiling as to say: I have no idea where that one came from. But maybe he does, because it happens again the very next side out. It looks like something good might still happen. But then he misses the last shot. He tries to hit the line, but the ball is far from the net and his jump is what it is.&lt;/p&gt;
&lt;p&gt;We give him&amp;nbsp;a two minutes standing ovation. This is the last time Huntington beach has seen him play. He waives his proverbial pink hat to salute the crowd. He sits down&lt;/p&gt;
&lt;p&gt;and he takes the head in his hands. After three Olympic medals, uncounted championships, thousand of beach volley wins and a two minutes standing ovation he is not happy. He missed the last ball.&lt;/p&gt;</description>
            <pubDate>Sat, 05 May 2007 22:24:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-05-05-huntington-beach-and-kiraly.html</guid>
        </item>
        
        <item>
            <title>Luke started to blog again</title>
            <link>https://www.lucabol.com/posts/2007-04-27-luke-started-to-blog-again.html</link>
            <description>&lt;p&gt;After a long hiatus, Luke goes at it again. Luke is our compiler PM and one of the most original coders I&amp;rsquo;ve seen.&lt;/p&gt;
&lt;p&gt;It always makes for a great read: &lt;a href="http://blogs.msdn.com/lukeh/default.aspx" title="http://blogs.msdn.com/lukeh/default.aspx"&gt;http://blogs.msdn.com/lukeh/default.aspx&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Fri, 27 Apr 2007 12:39:37 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-04-27-luke-started-to-blog-again.html</guid>
        </item>
        
        <item>
            <title>A financial education (my ideas)</title>
            <link>https://www.lucabol.com/posts/2007-04-20-a-financial-education-my-ideas.html</link>
            <description>&lt;p&gt;&lt;/p&gt; &lt;/p&gt;
&lt;p&gt;When I came to US, I wanted to get an introduction on personal finance. I needed to know what to insure, when, how to buy an house and all this sort of basic things. At the time I read &lt;a href="http://www.amazon.com/Personal-Finance-Dummies-Eric-Tyson/dp/0764552317"&gt;Personal Finance for Dummies&lt;/a&gt;. I then discovered that very many US folks don’t know about these things either and I found myself recommending this simple book to plenty of people. You can find it for a few bucks in used book-stores. It might be too basic for you, but again, it might not. &lt;/p&gt;
&lt;p&gt;Investment is a subset of personal finance and by far not the most important one (the most important probably being how to save the most – which means paying you first). Nevertheless, understanding how to invest the money that you do save is important. The following represents a very condensed summary of my views on the topic. There are dozens of others very good books that I could have suggested instead. &lt;/p&gt;
&lt;p&gt;The first thing I would do is to get a decent understanding of the relationship between risk and reward that is so pervasive in financial markets. Good books on the topic are &lt;a href="http://www.amazon.com/Four-Pillars-Investing-Building-Portfolio/dp/0071385290/ref=pd_bbs_sr_2/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177084673&amp;amp;sr=1-2"&gt;The Four Pillars of Investing&lt;/a&gt; or &lt;a href="http://www.amazon.com/Random-Walk-Down-Wall-Street/dp/0393062457/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177084725&amp;amp;sr=1-1"&gt;A Random Walk Down Wall Street&lt;/a&gt;. A new book that I haven’t read, but suspect quite good (and short) is &lt;a href="http://www.amazon.com/Little-Book-Common-Sense-Investing/dp/0470102101/ref=pd_bbs_3/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177084725&amp;amp;sr=1-3"&gt;The Little Book of Common Sense Investing&lt;/a&gt;. This books try to convince you that it is not possible to ‘beat the market’ and the best you can do is to decide on an asset allocation that represents your risk/reward profile. If you believe that, then it is worth getting to the next step by understanding the concept of mean variance optimization. Good medium level books on that are &lt;a href="http://www.amazon.com/About-Asset-Allocation-Richard-Ferri/dp/0071429581/ref=sr_1_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177085023&amp;amp;sr=1-1"&gt;All About Asset Allocation&lt;/a&gt; and the &lt;a href="http://www.amazon.com/Intelligent-Asset-Allocator-Portfolio-Maximize/dp/0071362363/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177085117&amp;amp;sr=1-1"&gt;Intelligent Asset Allocator&lt;/a&gt;. There are advanced books on the topic as well, but I won’t mention them here. An advanced service in this area is &lt;a href="http://www.indexinvestor.com/"&gt;IndexInvestor&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;With time, analyzing the amount of evidence, I came to believe that it is indeed possible to beat the market. But it is not easy and 99% of the methods out there are bunk. Moreover it does require a lot of work and a certain passion for the investment field. So, if you don’t have time or passion you are probably better off sticking to the strategies described in the aforementioned books. If you have a small amount of time, but you still want to try and beat the market, an avenue open to you is the selection of mutual funds. Even then, you need to have some strong held view of which kind of investment strategy and character traits are more likely to bring about superior investment results so that you can pick the right manager (or most likely set of managers) for your money. I describe below what are my personal views on the matter. They are all very debatable. A good service that gives sane information about mutual funds, how to select them and assemble them in your portfolio is &lt;a href="http://www.morningstar.com/"&gt;Morningstar&lt;/a&gt;. I certainly suggest you subscribe to it, if you invest in mutual funds. &lt;/p&gt;
&lt;p&gt;A time honored and generally successful stock picking method is value investing. The father of value investing is Benjamin Graham and two books written by him are everlasting classics of investment. They are &lt;a href="http://www.amazon.com/Intelligent-Investor-Collins-Business-Essentials/dp/0060555661/ref=pd_bbs_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177086377&amp;amp;sr=1-1"&gt;The Intelligent Investor&lt;/a&gt; and &lt;a href="http://www.amazon.com/Security-Analysis-Benjamin-Graham/dp/0071448209/ref=sr_1_3/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177086459&amp;amp;sr=1-3"&gt;Security Analysis&lt;/a&gt;. Aficionados disagree on which releases are the best, the links provided represent my opinion. Please start with the former, as the latter is long and complex. They are both quite dated, but plenty of folks believe that not much has been discovered after their publication. I disagree. Another, maybe better, introductory book is &lt;a href="http://www.amazon.com/Little-Book-Value-Investing/dp/0470055898/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177087947&amp;amp;sr=1-1"&gt;The Little Book of Value Investing&lt;/a&gt;. There are wonderful mutual funds out there that invest in the spirit of value investing. Among others, I like &lt;a href="http://www.thirdavenuefunds.com/taf/"&gt;Third Avenue&lt;/a&gt;, &lt;a href="http://www.pinnaclevaluefund.com/"&gt;Pinnacle&lt;/a&gt; and &lt;a href="http://www.roycefunds.com/"&gt;Royce&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Warren Buffett expanded on Graham by putting more emphasis on the quality of the companies he invests in instead of mostly the price. A good book describing his approach is &lt;a href="http://www.amazon.com/Warren-Buffett-Way-Second/dp/0471743674/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177086947&amp;amp;sr=1-1"&gt;The Warren Buffett Way&lt;/a&gt;. You can obviously go and read Buffett’s letters directly &lt;a href="http://www.berkshirehathaway.com/"&gt;here&lt;/a&gt;, but that is better suited as a second step after reading Graham or the aforementioned book. There are plenty of disciples of this method of investing. If you want to have some of them managing your money, my preferred are &lt;a href="http://www.longleafpartners.com/"&gt;Longleaf&lt;/a&gt;, &lt;a href="http://www.fairholmefunds.com/"&gt;Fairholme&lt;/a&gt;, &amp;nbsp;&lt;a href="http://www.weitzfunds.com/"&gt;Weitz&lt;/a&gt; and &lt;a href="http://www.clipperfund.com/"&gt;Clipper&lt;/a&gt; among others. A good service that suggest stocks based on this style of investing is the stock section of &lt;a href="http://www.morningstar.com/"&gt;Morningstar&lt;/a&gt;. You also can invest in brk.b directly to buy the services of Buffett himself. I personally believe it is quite undervalued at the current juncture. &lt;/p&gt;
&lt;p&gt;In the past 15 years or so, there has been a lot of interesting work done on purely quantitative investing systems. They have several advantages over judgment based ones (essentially the human brain is not wired correctly to fight a complex adaptive system as the stock market). There are two categories of systems I feel I can recommend in this area: fundamental based and momentum based. This is a very complex mathematical topic at the high end, but it is possible to get a profitable understanding of it by reading &lt;a href="http://www.amazon.com/What-Works-Street-James-OShaughnessy/dp/0071452257/ref=pd_bbs_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177087865&amp;amp;sr=1-1"&gt;WWOWS&lt;/a&gt; and &lt;a href="http://www.amazon.com/Little-Book-That-Beats-Market/dp/0471733067/ref=pd_bbs_3/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177087865&amp;amp;sr=1-3"&gt;The Little Book That Beats The Market&lt;/a&gt;. These books describe fundamental based systems, for a purely momentum based one the best bet is &lt;a href="http://www.fundx.com/"&gt;FundX&lt;/a&gt;. The web site is not too informative, but if you go to the library and ask the librarian they have a little book written by the FundX guys that describe their system in a great level of detail. The best quantitative mutual funds I can think of are from &lt;a href="http://www.bridgewayfunds.com/"&gt;Bridgeway&lt;/a&gt; (there are also others). Like all the other funds I suggested, they are managed by wonderful people that takes the shareholders interests very seriously. &lt;/p&gt;
&lt;p&gt;You can also try to tactically switch between different asset classes (i.e. stocks and cash) based&lt;/p&gt;
&lt;p&gt;on some indicators. I have mixed feelings about this. It might work, but it is debatable how much do you really gain by doing it, after considering taxes and commissions. It is something I could investigate more. Two good books on the matter are &lt;a href="http://www.amazon.com/Only-Three-Questions-That-Count/dp/047007499X/ref=sr_1_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177088936&amp;amp;sr=1-1"&gt;The Only Three Questions That Count&lt;/a&gt; and &lt;a href="http://www.amazon.com/Research-Driven-Investor-Information-Investment/dp/007135462X/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177088971&amp;amp;sr=1-1"&gt;The Research Driven Investor&lt;/a&gt;. Good mutual funds that do this (with very different risk profiles) are &lt;a href="http://www.hussmanfunds.com/"&gt;Hussman&lt;/a&gt; and &lt;a href="http://www.cgmfunds.com/"&gt;CGM&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;A couple of notes to close. Reading these books is an exercise in critical thinking. There are huge amount of contradictory statements on very basic and important concepts. The only way around it is to do your own research and make up your own mind. Even then, you won’t be in a situation of perfect information/clear decision. This cannot be so because the market changes constantly. As soon as something is discovered it gets priced in. This is why it is such an exciting field of study (for some people at least). Also I have my own key rule about investing: I never invest in anything that I don’t understand completely. Every time I’ve done that, I&amp;rsquo;ve regretted it. If this is the only thing that you remember after reading this, I’ll be very happy.&lt;/p&gt;</description>
            <pubDate>Fri, 20 Apr 2007 14:55:39 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-04-20-a-financial-education-my-ideas.html</guid>
        </item>
        
        <item>
            <title>Which type should I use in C# to represent numbers?</title>
            <link>https://www.lucabol.com/posts/2007-02-27-which-type-should-i-use-in-c-to-represent-numbers.html</link>
            <description>&lt;p&gt;Yesterday I found an old email in my mail box that I thought might be generally interesting.&lt;/p&gt;
&lt;p&gt;I was asking&amp;nbsp;the&amp;nbsp;technical lead&amp;nbsp;on the C# compiler which algorithm/shortcut people should use to choose their &amp;#8216;number types&amp;rsquo; among the many available in the language. I was asking for something that works the majority of times, even if not always. I&amp;rsquo;m sure there are other scenarios we haven&amp;rsquo;t consider. Anyhow, here is his algorithm.&lt;/p&gt;
&lt;p&gt;If you need fractions: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use decimal when intermediate results need to be rounded to fixed precision  - this is almost always limited to calculations involving money.&lt;/li&gt;
&lt;li&gt;Otherwise use double  - you will get the rounding of your calculations wrong, but the extra precision of double will ensure that your results will be good enough.&lt;/li&gt;
&lt;li&gt;Only use float if you know you have a space issue, and you know the precision implications. If you don&amp;rsquo;t have a PhD in numeric computation you don&amp;rsquo;t qualify.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Otherwise: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use int whenever your values can fit in an int, even for values which can never be negative. This is so that subtraction operations don&amp;rsquo;t get you confused.&lt;/li&gt;
&lt;li&gt;Use long when your values can&amp;rsquo;t fit in an int.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Byte, sbyte, short, ushort, uint, and ulong should only ever be used for interop with C code. Otherwise they&amp;rsquo;re not worth the hassle.&lt;/p&gt;</description>
            <pubDate>Tue, 27 Feb 2007 18:09:57 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-02-27-which-type-should-i-use-in-c-to-represent-numbers.html</guid>
        </item>
        
        <item>
            <title>A good Emerging Market fund</title>
            <link>https://www.lucabol.com/posts/2007-02-02-a-good-emerging-market-fund.html</link>
            <description>&lt;p&gt;If you are looking for a good fund for this corner of your portfolio, you might want to consider Eaton Vance Structured Emerging Mkt (EAEMX). There is also a much cheaper version (EITEX), but it is open just to folks with a financial advisor.&lt;/p&gt;
&lt;p&gt;It is a&amp;nbsp;mechanical fund. Here is how their strategy works (as far as I understand it):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They divide EM market countries&amp;nbsp;in 4 categories, they assign a weight&amp;nbsp;to each category (I.E. 20% to tier1, 30% to tier2 etc)&lt;/li&gt;
&lt;li&gt;For each category they equal weight each country in the category (I.E. in tier1 equal weight Russia, Mexico, etc)&lt;/li&gt;
&lt;li&gt;For each country they equal weight each sector&lt;/li&gt;
&lt;li&gt;They actively harvest tax losses&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The end result is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Smaller country have more weight than in a normal Em.Mkt. fund. This is good because:&lt;/li&gt;
&lt;li&gt;Smaller markets have had higher returns in the past&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Smaller markets&amp;nbsp;are less correlated than large markets both among themselves and against the SP500&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Equal weighting the sectors has the following positive effects:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;You get more exposure to sectors, like Services, that are going to benefit from economic growth&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You avoid the &amp;#8216;commodity effect&amp;rsquo;: the tendency of Em.Markets to fall when commodities prices fall because such a large slice of their economy is based on it&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It is extremely tax efficient because:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;The mechanical strategy lends itself to low turnover&lt;/li&gt;
&lt;li&gt;They actively harvest tax losses&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In essence they maximize the positive effects of diversification and tax efficiency, which are very stable effects. They are mathematically provable 🙂 The real time results confirm the theory as this has been one of the best performing Em. Markets funds with the lowest standard deviation and best tax efficiency. No-one knows what the future holds, but there is a good chance that this will continue to be the case.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t own it currently because I don&amp;rsquo;t like the high fees, but the strategy makes so much sense that I might end up buying into it.&lt;/p&gt;</description>
            <pubDate>Fri, 02 Feb 2007 13:26:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-02-02-a-good-emerging-market-fund.html</guid>
        </item>
        
        <item>
            <title>Apparently simple code</title>
            <link>https://www.lucabol.com/posts/2007-02-01-apparently-simple-code.html</link>
            <description>&lt;p&gt;Sometimes what looks simple is complex and what looks complex is simple. See if you can understand how this one calculates all the possible ways to give change for a certain amount of money given some kinds of coins. You MIT guys out there don&amp;rsquo;t count, you probably have read the solution in the same book I have.&lt;/p&gt;
&lt;p&gt;BTW: the code works with the LINQ May CTP &amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;

using System.Collections.Generic;

using System.Text;

using System.Query;

using System.Xml.XLinq;
class Program
{
static void Main(string[] args)
{
var coins = new int[] { 1, 5, 10, 25, 50 };

var i = ChangeComb(100, coins);
Console.WriteLine(i);
}

static int ChangeComb(int amount, IEnumerable&amp;lt;int&amp;gt; coins)
{
if (amount == 0) return 1;
if (amount &amp;lt; 0) return 0;
if (coins.Count() == 0) return 0;

return ChangeComb(amount, coins.Skip(1)) +
ChangeComb(amount - coins.First(), coins);
}
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Thu, 01 Feb 2007 14:54:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-02-01-apparently-simple-code.html</guid>
        </item>
        
        <item>
            <title>Is this functional code? Dr.T. Reply.</title>
            <link>https://www.lucabol.com/posts/2007-01-31-is-this-functional-code-dr-t-reply.html</link>
            <description>&lt;p&gt;This would be a functional approach:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;CountWithPrevious : [‘a] =&amp;gt; (a =&amp;gt; a =&amp;gt; bool) =&amp;gt; int // type of the function
CountWithPrevious [] _                    = 0
CountWithPrevious [_]  _                  = 0
CountWithPrevious [prev, val | tail] pred = CountWithPrevious [val | tail] + (pred val prev ? 1 : 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some observations:&lt;/p&gt;
&lt;p&gt;_” is used as wildcard argument – matches any value that you don’t need a name for.
[ x,y,z | t ] are pattern matching over lists – here x,y and z get bound to the first elements and t is the rest of the list.
Both CountWithPrevious and the passed-in pred are curried – they take two arguments but one at a time.
The CountWithPrevious function is defined with pattern matching – at runtime it searches through the definitions until one matches.
The type declaration is optional – the compiler can figure out the type from the last case of the function.
In C# we don’t have pattern matching and currying, and so would probably need a helper function.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static int CountWithPrevious&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; en, PredWithPrevious pred) {
IEnumerator&amp;lt;T&amp;gt; rest = en.GetEnumerator();

if (rest.MoveNext()) return Helper(rest.Current,rest,pred);

else return 0;

}

private static int Helper&amp;lt;T&amp;gt;(T prev, IEnumerator&amp;lt;T&amp;gt; rest, PredWithPrevious pred) {

if (rest.MoveNext()) {

T val = rest.Current;

return Helper(val,rest,pred) + (pred(val,prev) ? 1 : 0);

} else return 0;

}

We could simulate local functions with lambdas so that we don’t need to pass pred, prev and T along:

public static int CountWithPrevious&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; en, PredWithPrevious pred) {
IEnumerator&amp;lt;T&amp;gt; rest = en.GetEnumerator();

Func&amp;lt;T,int&amp;gt; helper = prev =&amp;gt; {

if (rest.MoveNext()) {

T val = rest.Current;

return Helper(val) + (pred(val,prev) ? 1 : 0);

} else return 0;

};

if (rest.MoveNext()) return Helper(rest.Current);

else return 0;

}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Wed, 31 Jan 2007 12:34:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-01-31-is-this-functional-code-dr-t-reply.html</guid>
        </item>
        
        <item>
            <title>Is this functional code?</title>
            <link>https://www.lucabol.com/posts/2007-01-26-is-this-functional-code.html</link>
            <description>&lt;p&gt;I&amp;rsquo;m an Object Oriented (OO) kind of guy, maybe a bigot. I have read a very large number of OO books and I&amp;rsquo;ve written a fair amount of OO code in my 10+ years in this industry. I&amp;rsquo;m afraid my mind is wired for OO at this point, for good or bad.&lt;/p&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been getting interested in functional languages. The most functional guys around here are Wes and Luke, while Dr. T has somehow transcended the whole thing.&lt;/p&gt;
&lt;p&gt;Here is the text of one of my newbie emails to Dr.T. I&amp;rsquo;ll let you think about it for a bit before posting his reply. The phrase: &amp;ldquo;Is this it?&amp;rdquo; has to be read as &amp;ldquo;Is this what functional programming is all about?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;/// EMAIL TEXT BELOW&lt;/p&gt;
&lt;p&gt;Is this it? I have about four of these ‘delegate taking’ functions in my excel addin ….&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    delegate bool PredWithPrevious&amp;lt;T&amp;gt;(T value, T previous);
static int CountWithPrevious&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; en, PredWithPrevious&amp;lt;T&amp;gt; pred) {

int count = 0;
T previous = default(T);
bool isPrevious = false;

foreach (T val in en) {

if (isPrevious)
if (pred(val, previous))
count++;
previous = val;
isPrevious = true;
}
return count;
}
&lt;/code&gt;&lt;/pre&gt;</description>
            <pubDate>Fri, 26 Jan 2007 12:54:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-01-26-is-this-functional-code.html</guid>
        </item>
        
        <item>
            <title>A trading/portfolio management Excel Add-in based on the books by Ralph Vince</title>
            <link>https://www.lucabol.com/posts/2007-01-04-a-tradingportfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.html</link>
            <description>&lt;p&gt;I like to write code and I still manage to do it even now that it is not my primary job. I never post the things that I write because I don&amp;rsquo;t want to maintain them.&amp;nbsp;Lately &lt;a class="" href="http://blogs.msdn.com/charlie/" target="_blank"&gt;Charlie&lt;/a&gt;&amp;nbsp;convinced me that I don&amp;rsquo;t have to do that. I can just throw the code out, without much preparation or implicit contract of perpetual maintenance.&lt;/p&gt;
&lt;p&gt;This one is an Excel add-in that adds functions to Excel to analyze your trading and manage your portfolio. Notice that I&amp;rsquo;m not a professional trader or statistician, so the whole thing could be wrong, buggy or conceptually absurd. Probably it is all of the above.&lt;/p&gt;
&lt;p&gt;I used the extremely good&amp;nbsp;&lt;a class="" href="http://exceldna.typepad.com/" target="_blank"&gt;ExcelDna&lt;/a&gt; to write the add-in. You need to download it and follow the instructions in &lt;em&gt;HowToInstall.txt&lt;/em&gt; on the attached zip file to use it. I based the formulas mainly on the work of &lt;a class="" href="http://www.amazon.com/s/103-4348138-5739032?ie=UTF8&amp;index=books&amp;rank=-relevance%2C%2Bavailability%2C-daterank&amp;field-author-exact=Vince%2C%20Ralph" target="_blank"&gt;Ralph Vince&lt;/a&gt;. Please buy and read his books on money management as they are wonderful.&lt;/p&gt;
&lt;p&gt;On the statistics side: I made up the Downside correlation coefficient, I have no idea if it is statistically sound.&lt;br /&gt;
On the technical side:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I haven&amp;rsquo;t optimized the algos at all. I.E. I&amp;rsquo;m sure there is a way to calculate the standard deviation without navigating the array twice, but I didn&amp;rsquo;t bother to look. They end up being fast enough anyhow (apart from the Monte Carlo related functions that I should investigate).&lt;/li&gt;
&lt;li&gt;I haven&amp;rsquo;t organized the code correctly. It needs to be rewritten now that I partially know what I&amp;rsquo;m doing.&lt;/li&gt;
&lt;li&gt;I haven&amp;rsquo;t used LINQ. It will be a lot of fun for me to rewrite the code to be more OO and to use LINQ in the process.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I plan to implement OptimalF for a normal distribution and Efficient Frontier calculations in the future. I have no idea when.&lt;/p&gt;
&lt;p&gt;I also have some other projects that might be interesting to share (I.E. a blackjack simulator that you can use to try the result of different strategies inspired by &lt;a class="" href="http://www.amazon.com/Blackjack-Attack-Playing-Pros-Way/dp/0910575207/sr=8-1/qid=1167952522/ref=pd_bbs_sr_1/103-4348138-5739032?ie=UTF8&amp;s=books" target="_blank"&gt;Blackjack Attack&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This is the list of Excel functions that you get with this add-in. They ends up in a Trading category in the list of functions on the Insert Function Excel dialog:&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:.5in;"&gt;
  &lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;AnnualizeRet(double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;AnnualizeStdevp(double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;AnnualStdevpParam(double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;ArithMean(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;AutoCorrel(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;AvgLoss(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;AvgWin(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;Chebyshev(double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;Correlat(object[,], object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;Describe(object)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;DownCorrelat(object[,], object[,], double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;DownStdevp(object[,], double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;EGM(double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;EGM2(double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;GM(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;Kelly(double, double) TradingLibrary.Losses(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;MaxDD(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;MaxDDFromEq(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;MaxLoss(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;MaxNegRun(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;MaxWin(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;MCMaxDD(object[,], double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;MCOptimalF(object[,], double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;OptimalF(object[,], double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;OptimalFArray(object[,], double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;OptimalPos(double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;PortAnnualGM(double, double, double, double, double, double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;PortAnnualTaxGM(double, double, double, double, double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;PortAnnualTaxGMGivenTrades(object[,], double, double, double, double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;PortStdevp(double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;PRR(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;PRRParam(double, double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;RealReturn(double, double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;RunTest(object[,])&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;SharpeRatio(double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;SortinoRatio(double, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;Stdevp2(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span lang="FR" style="font-size:10pt;font-family:Tahoma;"&gt;TWR(object[,], double, double, object, double, double)&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;Wins(object[,])&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-left:.5in;"&gt;
  &lt;font face="Tahoma" size="2"&gt;&lt;span style="font-size:10pt;font-family:Tahoma;"&gt;&lt;/span&gt;&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.dotnetkicks.com/kick/?url=http://blogs.msdn.com/lucabol/archive/2007/01/04/a-trading-portfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="https://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://blogs.msdn.com/lucabol/archive/2007/01/04/a-trading-portfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/01/41/29/46/TradingLibrary.zip"&gt;TradingLibrary.zip&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Thu, 04 Jan 2007 17:53:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2007-01-04-a-tradingportfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.html</guid>
        </item>
        
        <item>
            <title>Our sessions at the PDC</title>
            <link>https://www.lucabol.com/posts/2005-07-14-our-sessions-at-the-pdc.html</link>
            <description>&lt;p&gt;Now we can finally blog about our PDC sessions. We have been working for more then a year on this data language integration stuff and it is quite exciting to be able to talk about it publicly. Here are the sessions involved. They are all tied together by a common theme. They are all part of the same big project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The .NET Language Integrated Query Framework: An Overview&amp;rsquo;&lt;br /&gt;
&lt;/strong&gt; This is an overview of the overall project. Anders is an excellent speaker and this is a prerequisite for the other sessions. Don&amp;rsquo;t miss it&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
C#: Future Directions in Language Innovation from Anders Hejlsberg&lt;br /&gt;
&lt;/strong&gt; Mr. Anders again. If you are a C# programmer, this is one you really want to see&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using the .NET Language Integrated Query Framework with Relational Data&lt;br /&gt;
&lt;/strong&gt; Despite the speaker (probably yours truly) this is a great talk, databases and objects, hmmm sounds interesting&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using the .NET Language Integrated Query Framework with XML Data&lt;br /&gt;
&lt;/strong&gt; Do you want to see how to query XML in a rather innovative way? Here you have it&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;strong&gt;: Future Directions in Language Innovation&lt;br /&gt;
&lt;/strong&gt; This is the equivalent of Anders&amp;rsquo; C# talk. Come and see where VB is going&lt;/p&gt;</description>
            <pubDate>Thu, 14 Jul 2005 12:03:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-07-14-our-sessions-at-the-pdc.html</guid>
        </item>
        
        <item>
            <title>There is a C# Language chat coming</title>
            <link>https://www.lucabol.com/posts/2005-04-14-there-is-a-c-language-chat-coming.html</link>
            <description>&lt;p&gt;Here it is: &lt;a href="http://blogs.msdn.com/scottno/archive/2005/04/14/408212.aspx"&gt;&lt;u&gt;&lt;font color="#0000ff" size="2"&gt;http://blogs.msdn.com/scottno/archive/2005/04/14/408212.aspx&lt;/u&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Thu, 14 Apr 2005 18:40:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-04-14-there-is-a-c-language-chat-coming.html</guid>
        </item>
        
        <item>
            <title>Here is a message board about the C# language</title>
            <link>https://www.lucabol.com/posts/2005-03-28-here-is-a-message-board-about-the-c-language.html</link>
            <description>&lt;p&gt;Here is the link: &lt;a href="http://www.gotdotnet.com/Community/MessageBoard/MessageBoard.aspx?ID=5627"&gt;http://www.gotdotnet.com/Community/MessageBoard/MessageBoard.aspx?ID=5627&lt;/a&gt;. Check it out.&lt;/p&gt;</description>
            <pubDate>Mon, 28 Mar 2005 11:06:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-03-28-here-is-a-message-board-about-the-c-language.html</guid>
        </item>
        
        <item>
            <title>To rent or to buy a house, some more evidence of my unpopular thesis</title>
            <link>https://www.lucabol.com/posts/2005-03-09-to-rent-or-to-buy-a-house-some-more-evidence-of-my-unpopular-thesis.html</link>
            <description>&lt;p&gt;I discussed this topic in a previous post &lt;a href="http://blogs.msdn.com/lucabol/archive/2004/07/30/202394.aspx"&gt;http://blogs.msdn.com/lucabol/archive/2004/07/30/202394.aspx&lt;/a&gt;&amp;nbsp;and I received a number of emails telling me how crazy I was even speculating that, at the current juncture, it may be more convinient to rent than to buy a house.&lt;/p&gt;
&lt;p&gt;This week The Economist runs a piece where they make the same exact claim. House prices are so high and rents are so low all over the world that renting might, indeed, be&amp;nbsp;better. Even considering the low interest rate environment, it would seem that the&amp;nbsp;house prices are out of&amp;nbsp;step with&amp;nbsp;reality, very much as equities where in the 90&amp;rsquo;s.&lt;/p&gt;
&lt;p&gt;It is all a game of expectations. The harder things to estimate are the future house price gain and the interest rate/gain you can get by investing the difference between rent and mortgage payments. By using difference estimates, you get difference answers. My own opinion is that the probabilities weight against buying an house at this time. Here is a spreadsheet to help you out: &lt;a href="http://blogs.msdn.com/lucabol/archive/2004/08/18/216662.aspx"&gt;http://blogs.msdn.com/lucabol/archive/2004/08/18/216662.aspx&lt;/a&gt;&amp;nbsp;.&lt;/p&gt;
&lt;p&gt;There are other considerations: I bought a house not to get killed by my wife 🙂 But I&amp;rsquo;ve been able to limit the expense and I avoided investing more money in real estate.&lt;/p&gt;</description>
            <pubDate>Wed, 09 Mar 2005 12:01:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-03-09-to-rent-or-to-buy-a-house-some-more-evidence-of-my-unpopular-thesis.html</guid>
        </item>
        
        <item>
            <title>Compiler trivia: const, operators and being nice to the compiler</title>
            <link>https://www.lucabol.com/posts/2005-02-10-compiler-trivia-const-operators-and-being-nice-to-the-compiler.html</link>
            <description>&lt;p&gt;This is a question that came up on our internal alias. I thought it might be generally interesting to illustrate how the compiler picks operators.&lt;/p&gt;
&lt;p&gt;Here is the original issue. This code compiles fine:&lt;/p&gt;
&lt;p&gt;UInt64 vUInt641 = UInt64.MaxValue;&lt;br /&gt;
&lt;strong&gt;const&lt;/strong&gt; int&amp;nbsp; vInt2 = 1432765098;&lt;br /&gt;
int res = (int)(vUInt641  - vInt2);&lt;/p&gt;
&lt;p&gt;But this code generates a compile error:&lt;/p&gt;
&lt;p&gt;UInt64 vUInt641 = UInt64.MaxValue;&lt;br /&gt;
int&amp;nbsp; vInt2 = 1432765098;&lt;br /&gt;
int res = (int)(vUInt641  - vInt2);&lt;/p&gt;
&lt;p&gt;(line 3): error CS0019: Operator &amp;#8216;-&amp;#8216; cannot be applied to operands of type &amp;#8216;ulong&amp;rsquo; and &amp;#8216;int&amp;rsquo;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;The only difference between the two pieces of code is the presence of the &lt;strong&gt;const&lt;/strong&gt; keyword in the first one. Let&amp;rsquo;s first analyze the second case. The reason an error is generated is that there is no &amp;#8216;-&amp;#8216; operator&amp;nbsp;defined between an ulong and an int. There is also no implicit conversion between int and and ulong or the other way around. The compiler has to give up and to produce an error.&lt;/p&gt;
&lt;p&gt;In the first case the variable is marked as const, which&amp;nbsp;means that the compiler knows its value at compile time. It realizes that the value is positive and can safely been converted to an ulong.&amp;nbsp;The compiler&amp;nbsp;converts it and then invokes the -(ulong, ulong) operator.&lt;/p&gt;
&lt;p&gt;A bizarre way to think of it is this.&amp;nbsp;As you have been nice to the compiler by telling him that you are not going to modify this value, the compiler then is nice to you by making use of the info to help you out in this case&lt;/p&gt;
&lt;p&gt;Remember, always be nice to the compiler, the more you tell him, the more he tells you&lt;/p&gt;</description>
            <pubDate>Thu, 10 Feb 2005 10:32:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-02-10-compiler-trivia-const-operators-and-being-nice-to-the-compiler.html</guid>
        </item>
        
        <item>
            <title>Nullable trilogy part III: Nullable as type parameter in a generic class</title>
            <link>https://www.lucabol.com/posts/2005-02-03-nullable-trilogy-part-iii-nullablet-as-type-parameter-in-a-generic-class.html</link>
            <description>&lt;p&gt;Another commonly asked question relates to the behavior of Nullable&lt;T&gt; when used as type parameter to instantiate a generic class. It might be surprising that comparing such a parameter to null gives always false as a result. As it turns out, this is not related to Nullable&lt;T&gt;, but it is a result of how generics are implemented. There is a tendency to think about generics in a manner very similar to C++ templates, this view is unfortunately not correct.&lt;/p&gt;
&lt;p&gt;Generics have a runtime representation and, as such, the compiler needs to generate IL that works whatever type is used at runtime to instantiate the generic class. This means that the compiler cannot call user defined operators, because at compile time it has no knowledge about them. The compiler doesn’t know at that point which type will be used to instantiate the generic class in the future. It cannot know that it has to generate code to call these user-defined operators.&lt;/p&gt;
&lt;p&gt;In the same vein the compiler doesn’t know that a generic class will be instantiated with a Nullable&lt;T&gt; parameter and so it cannot produce IL to lift operators (i.e. the equality operator ‘==’ ). The result is that when the programmer writes code like ‘t==null’, the compiler generates IL to call the ‘standard’ ‘==’ operator, which in the case of Nullable&lt;T&gt; returns false because t has the runtime type of struct.&lt;/p&gt;
&lt;p&gt;A similar behavior is observable with the following code using strings:&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial" size="2"&gt;&lt;/font&gt; &lt;font face="Courier New"&gt;&lt;/p&gt; &lt;/p&gt;
&lt;p&gt;
  string s1 = Bob John;
&lt;/p&gt;

&lt;p&gt;
  string s2 = Bob;
&lt;/p&gt;

&lt;p&gt;
  Console.WriteLine(Equals(s1, s2 +  John));
&lt;/p&gt;

&lt;p&gt;
  static bool Equals&lt;T&gt;(T a, T b) where T:class {
&lt;/p&gt;

&lt;p&gt;
  return a == b;
&lt;/p&gt;

&lt;p&gt;
  }
&lt;/p&gt;

&lt;p&gt;
  &lt;/font&gt;
&lt;/p&gt;

&lt;p&gt;
  This code would return false, because the ‘==’ operator for reference types gets invoked.
&lt;/p&gt;

&lt;p&gt;
  &lt;font face="Arial" size="2"&gt;&lt;/font&gt;
&lt;/p&gt;

&lt;p&gt;
  A case could be made that the compiler should generate IL to check the runtime type of the generic parameter and call the correct operator for at least some well-known types. This solution wouldn’t work for user defined operators as the compiler doesn’t know at compile time the set of types that could be used to instantiate a generic class. In general we don’t like to keep this sort of ‘lists of special things’ in the codebase, More importantly the solution would impose a somehow significant performance penalty at each use of the operator. This feeling of ‘hacking’ things and the significant performance problem convinced us not to implement this solution.
&lt;/p&gt;

&lt;p&gt;
  &lt;font face="Arial" size="2"&gt; &lt;/p&gt;

&lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;

&lt;p&gt;
    &lt;/font&gt;
  &lt;/p&gt;</description>
            <pubDate>Thu, 03 Feb 2005 15:42:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-02-03-nullable-trilogy-part-iii-nullablet-as-type-parameter-in-a-generic-class.html</guid>
        </item>
        
        <item>
            <title> Nullable trilogy part II: a == b -&gt; a&gt;=b &amp;&amp; a</title>
            <link>https://www.lucabol.com/posts/2005-01-27-nullable-trilogy-part-ii-a-b-ab-a.html</link>
            <description>&lt;p&gt;A&amp;nbsp;question that often comes up when we discuss Nullable&lt;T&gt;&amp;nbsp;&amp;nbsp;is about&amp;nbsp;the anti-symmetric property. This property states that if a==b then a&amp;gt;=b and a&amp;lt;=b. If a and b are null then this property is not satisfied in the current design as the result of &amp;gt;= and &amp;lt;= is always false when one of the parameters is null. This may seems surprising, but it can be easily understood when considering if null can be ordered.&lt;/p&gt;
&lt;p&gt;We decided that null being less of (or more of) all the other elements in the domain would be an arbitrary decision and as such null cannot be ordered. If it cannot be ordered then the result of the relational operators for null is false as these operators can be defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;  a&amp;lt;b -&amp;gt; ordered(a,b) &amp;amp;&amp;amp; a&amp;lt;b

  a&amp;lt;=b -&amp;gt; ordered(a,b) &amp;amp;&amp;amp; (a&amp;lt;b || a==b)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It might be argued that for practical reasons it is convenient to have the &amp;lt;= and &amp;gt;= operators return true in case null is on both sides, but this choice has some practical drawbacks. Consider the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;    void ProcessTransactions(int?[] transactions, int? maxValue) {
    foreach(int? t in transactions)
      if(t &amp;lt; maxValue) ProcessTransaction(t);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code does what the programmer expects, even when maxValue is null (in which case it won’t process any element). Now let’s suppose that the programmer changes his mind and wants to include maxValue in the processing. He will then change the ‘&amp;lt;’ operator to be ‘&amp;lt;=’.&lt;/p&gt;
&lt;p&gt;Under the current design he will obtain what he expects, even in the case maxValue is null. By considering null &amp;gt;= null as true, this function would suddenly start processing all the null transactions, which is not what the programmer intended. The problem here is that people tend to think about the ‘&amp;gt;=’ and ‘&amp;lt;=’ operators as a way to include the limit value in the set of things to be processed. Very rarely, they intend to process the null value as well. Another way to think about it is that: deciding that null cannot be ordered implies that &amp;gt;= has to return false to be conceptually consistent and to prevent these quite subtle bugs to occur.&lt;/p&gt;</description>
            <pubDate>Thu, 27 Jan 2005 07:54:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-01-27-nullable-trilogy-part-ii-a-b-ab-a.html</guid>
        </item>
        
        <item>
            <title>New C# things happening</title>
            <link>https://www.lucabol.com/posts/2005-01-24-new-c-things-happening.html</link>
            <description>&lt;p align="left"&gt;
  Express yourself about this DCR: &lt;a href="http://blogs.msdn.com/scottno/archive/2005/01/19/356347.aspx"&gt;http://blogs.msdn.com/scottno/archive/2005/01/19/356347.aspx&lt;/a&gt;
&lt;/p&gt;

&lt;p align="left"&gt;
  Partecipate to the C# language chat: &lt;a href="http://blogs.msdn.com/scottno/archive/2005/01/19/356358.aspx"&gt;http://blogs.msdn.com/scottno/archive/2005/01/19/356358.aspx&lt;/a&gt;
&lt;/p&gt;

&lt;p align="left"&gt;
  That's it.
&lt;/p&gt;</description>
            <pubDate>Mon, 24 Jan 2005 09:49:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-01-24-new-c-things-happening.html</guid>
        </item>
        
        <item>
            <title>Nullable trilogy Part I: why not just SQL?</title>
            <link>https://www.lucabol.com/posts/2005-01-20-nullable-trilogy-part-i-why-not-just-sql.html</link>
            <description>&lt;p&gt;This is the first of a weekly three part serie of posts about Nullable&lt;T&gt;. In these posts I want to describe the reasons behind three design choices:&lt;br /&gt;
1. Why not just use SQL semantics for null?&lt;br /&gt;
2. Why null == null doesn&amp;rsquo;t imply null &amp;gt;= null and null &amp;lt;= null?&lt;br /&gt;
3. Why inside a generic class with a type parameter t the expression t == null will return false, when t is a nullable type and the value of it is null.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start from the first question as the answer is shorter. We&amp;rsquo;ll get to the other two in the coming weeks.&lt;/p&gt;
&lt;p&gt;The first question relates to the reason not to have the same semantics as SQL for relational operators. The SQL semantics have been commonly referred to as three-value logic where null == null returns null. Introducing such logic in the C# language would be problematic. The main reason is that the language already contains the concept of null for reference types and it does have the programming languages traditional two-value logic where null == null returns true.&lt;/p&gt;
&lt;p&gt;Granted that we cannot change this definition, then the addition of three-value logic just for some types would be confusing. We would need, for example, to create a new NullableString class to be able to apply three-value logic operators to it. More generally, the presence in the same code of two value logic and three value logic operators would make the code quite difficult to write, read and maintain.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
            <pubDate>Thu, 20 Jan 2005 09:41:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2005-01-20-nullable-trilogy-part-i-why-not-just-sql.html</guid>
        </item>
        
        <item>
            <title>x+=x++;</title>
            <link>https://www.lucabol.com/posts/2004-08-31-xx.html</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;&lt;/p&gt; &lt;/p&gt;
&lt;p&gt;
  Today I was looking through an internal C# user group list. One of the messages was about x+=x++; and what should be the right behavior. I thought this is more generally interesting, so I decided to blog it. But first, DO NOT WRITE THAT CODE!!!
&lt;/p&gt;

&lt;p&gt;
  Ok, with that out of the way, we can start…
&lt;/p&gt;

&lt;p&gt;
  Let’s take this code as an example:
&lt;/p&gt;

&lt;p&gt;
  int x = 3;
&lt;/p&gt;

&lt;p&gt;
  x += x++;
&lt;/p&gt;

&lt;p&gt;
  The first thing the compiler does whenever it sees something like z += y is to convert it to z = z + y. This is obviously true for +=, -=, *=, and /=. Ok, this was easy. Now we have just to consider:
&lt;/p&gt;

&lt;p&gt;
  x= x + x++;
&lt;/p&gt;

&lt;p&gt;
  This, by the way, gives the same result as:
&lt;/p&gt;

&lt;p&gt;
  x = x + x;
&lt;/p&gt;

&lt;p&gt;
  This, by the way, gives a different result from:
&lt;/p&gt;

&lt;p&gt;
  x = x++ + x;
&lt;/p&gt;

&lt;p&gt;
  This, by the way gives the same result as:
&lt;/p&gt;

&lt;p&gt;
  x = x + ++x;
&lt;/p&gt;

&lt;p&gt;
  As maddening as this may seem, it actually makes sense (once you understand how it works). But first, what is the difference between x++ and ++x? x++ returns the value of x to the current expression and then increments x. ++x increments x and then return its value to the current expression. Given this factoid (and knowing that c# evaluates expressions left to right), we can then consider what happens in the following case:
&lt;/p&gt;

&lt;p&gt;
  int x = 3;
&lt;/p&gt;

&lt;p&gt;
  x = x + x++;
&lt;/p&gt;

&lt;p&gt;
  Here is how the compiler conceptually evaluates it:
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    x = (x) + x++ -&gt; the first x gets evaluated and returns 3, x = 3
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + (x)++ -&gt; x gets evaluated and returns 3, x = 3
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + (x++) -&gt; x++ gets evaluated and x is incremented (to 4), x = 4
  &lt;/li&gt;
  &lt;li&gt;
    x = (3 + 3) -&gt; 3 + 3 gets evaluated and returns 6, x = 4
  &lt;/li&gt;
  &lt;li&gt;
    (x = 6) -&gt; x is assigned to 6 (overriding the previous value of 4)
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
  Now let’s see how this one works:
&lt;/p&gt;

&lt;p&gt;
  int x = 3;
&lt;/p&gt;

&lt;p&gt;
  x = x++ + x;
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    x = (x)++ + x -&gt; x gets evaluated and returns 3, x =3
  &lt;/li&gt;
  &lt;li&gt;
    x = (x++) + x -&gt; x++ gets evaluated and x is incremented, x=4
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + (x) -&gt; x gets evaluated and returns 4, x = 4
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + 4 -&gt; 3+4 gets evaluated and returns 7, x = 4
  &lt;/li&gt;
  &lt;li&gt;
    (x=7) -&gt; x is assigned to 7 (overriding the previous value of 4)
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
  Now let’s get to this one:
&lt;/p&gt;

&lt;p&gt;
  int x = 3;
&lt;/p&gt;

&lt;p&gt;
  x = x + ++x;
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    x = (x) + ++x -&gt; x gets evaluated and returns 3, x=3
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + (++x) -&gt; ++x gets evaluated and x is incremented, x=4
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + (x) -&gt; x gets evaluated and returns 4, x=4
  &lt;/li&gt;
  &lt;li&gt;
    x = 3 + 4 -&gt; 3+4 gets evaluated and returns 7, x = 4
  &lt;/li&gt;
  &lt;li&gt;
    (x=7) -&gt; x is assigned to 7 (overriding the previous value of 4)
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
  I hope this is clear. By the way, in c++ the behavior for this expression is undefined…
&lt;/p&gt;

&lt;p&gt;
  But now… why did we make this legal? Why not err or warn at compilation time? Well…
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    We were wrong, we should have erred or warned, but now it is too late because if we change this we break code OR
  &lt;/li&gt;
  &lt;li&gt;
    It is quite complex to form a set of guidelines that the compiler can evaluate to be able to err just in the bizarre cases OR
  &lt;/li&gt;
  &lt;li&gt;
    We prefer to spend our time working on things people really care about instead of these corner-corner-corner cases
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
  Does it matter which of the previous options is the correct one? Not really because…
&lt;/p&gt;

&lt;p&gt;
  YOU ARE NOT GOING TO WRITE THAT CODE &lt;/font&gt;&lt;font face="Wingdings" size="2"&gt;J&lt;/p&gt;

&lt;p&gt;
    &lt;/font&gt;
  &lt;/p&gt;</description>
            <pubDate>Tue, 31 Aug 2004 15:00:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-31-xx.html</guid>
        </item>
        
        <item>
            <title>Homeowner association transcripts</title>
            <link>https://www.lucabol.com/posts/2004-08-18-homeowner-association-transcripts.html</link>
            <description>&lt;p&gt;Does anyone know if the homeowner association president for a condominium complex is legally forced to give the transcripts of their meetings to prospective buyers?&lt;/p&gt;
&lt;p&gt;It is quite funny, the lady in charge just doesn&amp;rsquo;t want to talk to me. I know, I know, I shouldn&amp;rsquo;t buy that condo then love over reason&lt;/p&gt;</description>
            <pubDate>Wed, 18 Aug 2004 12:19:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-18-homeowner-association-transcripts.html</guid>
        </item>
        
        <item>
            <title>Rent or buy spreadsheet</title>
            <link>https://www.lucabol.com/posts/2004-08-18-rent-or-buy-spreadsheet.html</link>
            <description>&lt;p&gt;Someone&amp;nbsp;asked me for the spreadsheet I used for the&amp;nbsp;calculations in my previous posts.&amp;nbsp; &lt;a href="http://www.duncanmackenzie.net/rentorbuy.zip"&gt;Here&lt;/a&gt; you have it. The data doesn&amp;rsquo;t reflect my current situation.&lt;/p&gt;
&lt;p&gt;Feel free to use it with your own numbers (and tell me of any bug).&lt;/p&gt;</description>
            <pubDate>Wed, 18 Aug 2004 12:13:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-18-rent-or-buy-spreadsheet.html</guid>
        </item>
        
        <item>
            <title>How much object relational framework do you really need?</title>
            <link>https://www.lucabol.com/posts/2004-08-06-how-much-object-relational-framework-do-you-really-need.html</link>
            <description>&lt;p&gt;It is always interesting for me to look at debates about object relational layers. I propose we define different levels of object relational support:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;No support: all the objects are persisted and queried by writing ADO.NET code by hand&lt;/li&gt;
&lt;li&gt;Code generation: you run a tool on your database (or on an abstract description of your schema)&amp;nbsp;and the tool generates a bunch of objects for your tables and some ADO.NET code to retrieve/persist their state&lt;/li&gt;
&lt;li&gt;Total code gen: the tool generates all the ADO.NET code&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Partial code gen: the tool generates just code to intercept property accessors and provide delay loading, but all the data access code is in a separate compiled component&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Metadata based: no code generation phase. The access to fields and property goes through reflection and the data access code is not exposed in the user code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Semi transparent: the persistent classes or properties need to be marked in some special way to be persisted (attributes, inherit from a special class or such)&lt;/li&gt;
&lt;li&gt;Transparent: the classes don&amp;rsquo;t need to be modified at all to be persisted&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Things get fuzzy, though. It is sometime unclear the difference between 2.2 and 3.1 and&amp;nbsp;various creative solutions can be hard to classify. But in a general sense,&amp;nbsp;this classification is probably about right.&amp;nbsp;In a generic sense EJB1.1-2.0 is a 2.2, EJB3.0 is a 3.1, JDO is 3.2 (if you don&amp;rsquo;t consider post-compilation) and ObjectSpaces is a 3.2. Hibernate and Toplink are squarely 3.2.&lt;/p&gt;
&lt;p&gt;But do you really need to go all the way to 3.2? All the times? I&amp;rsquo;ll try to post more about trade-offs in all these solutions, but if you have an idea of a better categorization, please let me know. The one I propose is right out of my head and I&amp;rsquo;m not to happy about it either.&lt;/p&gt;</description>
            <pubDate>Fri, 06 Aug 2004 09:05:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-06-how-much-object-relational-framework-do-you-really-need.html</guid>
        </item>
        
        <item>
            <title>I am really an old, almost fat, beach volley player</title>
            <link>https://www.lucabol.com/posts/2004-08-05-im-really-an-old-almost-fat-beach-volley-player.html</link>
            <description>&lt;p&gt;I used to play a lot, back in Italy. We would come out from work, go to the beach, play two or three hours, swim a bit and then go out for the night. This would happen about every day. We took it awfully seriously. We would go to the Italian national championships and all. It was quite a big deal.&lt;/p&gt;
&lt;p&gt;Seattle, on the other hand,&amp;nbsp;is not too conductive to beach volley. Not too many real beaches and all of them quite far (commute wise) from where I live. So I don&amp;rsquo;t play anymore, but I still like the game. One weekend or two each year,&amp;nbsp;my wife and I&amp;nbsp;go down to Los Angeles to watch AVP tournaments. And man, it is a lot of fun!!&lt;/p&gt;
&lt;p&gt;And, by the way, beach volley&amp;nbsp;has a lot going for it.&amp;nbsp;For the players it is a low impact sport (the sand is soft). Plus you&amp;nbsp;play the ball a lot, much more than in normal volleyball (or even soccer). Your are always in to the game, no place for hiding.&amp;nbsp;It happens&amp;nbsp;under the sun, so you don&amp;rsquo;t get all the nasty problem of not warming up correctly. And the environment oh man!! You are on the beach, not in&amp;nbsp;some crazy smelling gym somewhere. All in all, you got to love it.&lt;/p&gt;
&lt;p&gt;Anyway, down memory lane&lt;/p&gt;</description>
            <pubDate>Thu, 05 Aug 2004 08:37:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-05-im-really-an-old-almost-fat-beach-volley-player.html</guid>
        </item>
        
        <item>
            <title>Book: Objects, Components, and Frameworks with UML, Fedmond F. D`Souza</title>
            <link>https://www.lucabol.com/posts/2004-08-03-book-objects-components-and-frameworks-with-uml-fedmond-f-dsouza.html</link>
            <description>&lt;p&gt;This is a &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0201310120/qid=1091563751/sr=8-2/ref=sr_8_xs_ap_i2_xgl14/002-4177789-5140026?v=glance&amp;amp;s=books&amp;amp;n=507846"&gt;book&lt;/a&gt; about Catalysis, an OO methodology. I read this book some time ago (like years). It is a quite complex book. If you don&amp;rsquo;t like methodologists, it will easily put you to sleep. But if you stay awake, it is worth it.&lt;/p&gt;
&lt;p&gt;It is strange how this book crystallized one concept for me:&amp;nbsp;the definition of an interface. An interface is not just the sum of the signatures of the methods. It is a conceptual framework. The only way to fully describe it is to describe in a formal way this conceptual framework. For example without further specification it is impossible to know how to use this interface:&lt;/p&gt;
&lt;p&gt;interface IBook() {&lt;/p&gt;
&lt;p&gt;&amp;nbsp; void AddPage(IPage p);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;What happens when you add a page? Will it add it at the end of the book? At the start? What happens if you call the method twice? Will the pages be in order? Will they be in the same section? Is there a concept of a section?&lt;/p&gt;
&lt;p&gt;There are ways to&amp;nbsp;make explicit&amp;nbsp;the implicit model beyond an interface: the one that&amp;nbsp;I&amp;rsquo;ve commonly seen being used is documentation.&amp;nbsp;The book argues for&amp;nbsp;formal contracts (preconditions, postconditions, invariants). The latter is certainly more formal, but to use it you need to describe formally what is the state beyond the interface and how the different methods affect this state. It is a lot of work.&lt;/p&gt;
&lt;p&gt;Is it worth the effort? I guess it depends on a zillion things like: the type of project, the people involved,&amp;nbsp;I don&amp;rsquo;t think anybody is actually doing it, but it is still a good conceptual framework to keep in mind when you define your interfaces: it is not enough to write down the signature methods, you have somehow to expose the conceptual framework (where somehow means more or less formally).&lt;/p&gt;</description>
            <pubDate>Tue, 03 Aug 2004 13:13:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-03-book-objects-components-and-frameworks-with-uml-fedmond-f-dsouza.html</guid>
        </item>
        
        <item>
            <title>I am buying a house</title>
            <link>https://www.lucabol.com/posts/2004-08-02-im-buying-a-house.html</link>
            <description>&lt;p&gt;I think I&amp;rsquo;ve been misinterpreted in my previous posts. I&amp;rsquo;m not suggesting that renting is better than owning.&amp;nbsp;You have&amp;nbsp;to run your numbers and make your own choice. There are many assumptions to consider (financial and not). The not financial ones often are more important. You have to run your numbers, but&amp;nbsp;in general renting looks better if:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You cannot buy ( 🙂 ) and/or&lt;/li&gt;
&lt;li&gt;You plan to stay in a place for a short time and/or&lt;/li&gt;
&lt;li&gt;You believe houses are vastly overpriced in your area and they&amp;rsquo;ll return will be negative for a while and/or&lt;/li&gt;
&lt;li&gt;You don&amp;rsquo;t want the psychological part of having a house (maintenance, tax payments,)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In my case the most worrisome&amp;nbsp;scenario is&amp;nbsp;3.&lt;/p&gt;
&lt;p&gt;Back to our situation, we are buying a house for the pleasure of living in a particular location. Financially it is an OK transaction (fair price, I think). &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll probably post a little rent-buy spreadsheet as soon as I have time to refine it.&lt;/p&gt;
&lt;p&gt;Thanks for all the good comments.&lt;/p&gt;</description>
            <pubDate>Mon, 02 Aug 2004 12:57:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-08-02-im-buying-a-house.html</guid>
        </item>
        
        <item>
            <title>To rent or to buy a house??</title>
            <link>https://www.lucabol.com/posts/2004-07-30-to-rent-or-to-buy-a-house.html</link>
            <description>&lt;p class="MsoNormal" style="margin:0;"&gt;
  Spurred by some comments to a previous post I quickly run these numbers. They analyze the case of house price not rising in the next five years. I'll take more time to check them if I really get to a point of deciding, but they should be correct.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  This data (fairly typical in my area):
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Home price: $200,000
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Down payment: $0
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Interest rate: 6%
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Monthly mortgage: 1210
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Rent: 750
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Annual gains on investments: 6%
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  If I run this for 5 years and house appreciation 0% I get:
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  $33,043 on investing the rent-mortgage difference
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  $30,609 on paying the mortgage (equity accumulation + tax savings at 28%)
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  If we assume to put down 20% to buy the house then the numbers are even worse:
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  $83,542 on investing the down payment and the rent-mortgage difference
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  $67,548 on paying the mortgage (equity accumulation + tax savings at 28%)
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  There are other things to consider: house repairs for houses, annual raises in rent, etc etc
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Are those assumptions reasonable? So it is better to rent than to buy? Well, over the long term houses do tend to appreciate and the more leverage you have, the more you reap the benefits. Over the short term, run your numbers. There are so many assumptions you can make, that it become almost a personal opinion what is best.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p&gt;&lt;span style="font-size:12pt;font-family:'Times New Roman';"&gt;&lt;em&gt;Running the numbers help you in making sure than it is at least an informed opinion. It makes your assumptions explicit&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;</description>
            <pubDate>Fri, 30 Jul 2004 11:06:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-07-30-to-rent-or-to-buy-a-house.html</guid>
        </item>
        
        <item>
            <title>My quest for a new home</title>
            <link>https://www.lucabol.com/posts/2004-07-29-my-quest-for-a-new-home.html</link>
            <description>&lt;p class="MsoNormal" style="margin:0;"&gt;
  I'm refining my understanding of how to value residential properties. There is this rule of thumb: buy when you can get a rent for the property which is at least 1.2% of the property price (or in another form, when the home price is 7x the annual rent). This is an approx for a more formal spreadsheet (which I have).
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  This is fine and dandy, but in the area I'm interested in a typical one bedroom condo sells for around 200,000-300,000 and you can get a monthly rent of $1,000-1,300. This doesn't work by a very large factor. Hmmm
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Let's change the target to a cheaper area. Now I can probably get around 800 monthly. To make things work I need to find a condo for $67,200. Not an easy task, almost impossible.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  It looks like for me it is hard to find a house in an area I like and at the same time make a good investment (unless the market bails me out by raising home prices at a high rate). There is quite a large disconnect between house prices and rents now. Maybe the residential market is really on the brink of a fall Time to rent again?
&lt;/p&gt;</description>
            <pubDate>Thu, 29 Jul 2004 09:10:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-07-29-my-quest-for-a-new-home.html</guid>
        </item>
        
        <item>
            <title>Book: The coming crash in the housing market, John R. Talbott</title>
            <link>https://www.lucabol.com/posts/2004-07-28-book-the-coming-crash-in-the-housing-market-john-r-talbott.html</link>
            <description>&lt;p class="MsoNormal" style="margin:0;"&gt;
  My wife and I are planning to move somewhere where you can walk to shops and restaurants. We were thinking about selling or renting our current suburbia home. So, as usual, I picked up a bunch of books from the local library. This is one of them. Amazon reviews are&amp;nbsp;&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/007142220X/qid=1091030040/sr=8-1/ref=sr_8_xs_ap_i1_xgl14/104-6539857-7887162?v=glance&amp;s=books&amp;n=507846"&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;b&gt;My opinion on the book&lt;/b&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  The author did a good job of providing numeric evidence of the possibility of a real estate bubble. What I didn't like is that he didn't provide a logical framework to evaluate residential real estate. I was expecting some sort of DCF model that uses rent as the free cash flow. Instead he cites Median house/Median Income and some other contingent evidence to prove his point. It is like a book on stock evaluation that just uses historical P/E as a measure. He also fail to present similar situations that resulted&amp;nbsp;in a crisis. Quite disappointing in that regard
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;b&gt;How it relates to my choice of sell or rent&lt;/b&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  I created my own excel spreadsheet to look at the two different scenarios (if you are interested I can share). It looks like renting is the loosing one. We gain more by selling and investing the equity in a conservative way. The book made me take a hard look at our local real estate market: the ratio Median House/Median Income is about 4.3 (above 3 is bad). Rents are low and house prices have been growing like crazy. This makes me think to buy a small condo, or even to rent for a while. We haven't really decided yet.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &lt;b&gt;Book summary&lt;/b&gt;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;1.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;House prices are high while everything else is low: rents, economy, stocks Yes, there are bigger houses now and rates are low (but won't stay low forever)
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;2.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Mortgage takes more and more of the average salary, foreclosures and personal bankruptcies are at record high. People is more and more leveraged
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;3.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;The house market is far away from an ideal market. A bunch of lenders really make the prices. Bubble can easily create in inefficient markets
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;4.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;People think houses can just go up: same mindset as the internet bubble
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;5.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;House prices have been growing like crazy. The fast growers of the past are the fastest growers now: it is like momentum in stocks
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;6.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Many of the previous crashes were based on leverage and some kind of Ponzi scheme
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;7.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;It will start if rates goes up (people can afford less), if they go down (the economy will be very weak), banks become less aggressive in lending, congress reduces tax benefits
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;8.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Under a worst case scenario Fannie Mae and Freddie Mac ($3 trillion of very leveraged and derivative invested money) stumble and then it may be a worldwide depression as banks credibility goes down
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0 0 0 21pt;text-indent:-.25in;"&gt;
  &lt;span&gt;9.&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;What you can do: decrease your exposure to real estate (rent, downsize or move to cheaper area), be less leveraged, hedge your real estate exposure by not buying real estate cyclical stocks
&lt;/p&gt;</description>
            <pubDate>Wed, 28 Jul 2004 08:56:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-07-28-book-the-coming-crash-in-the-housing-market-john-r-talbott.html</guid>
        </item>
        
        <item>
            <title>Please the perfect object stand up!!</title>
            <link>https://www.lucabol.com/posts/2004-07-27-please-the-perfect-object-stand-up.html</link>
            <description>&lt;p class="MsoNormal" style="margin:0;"&gt;
  I always thought: why people write this very long posts? Here you have it.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  How do I design my objects? What is the set of constraints that dictate my design decisions? People talk about objects in very different contexts. A certain amount of confusion derives from not identifying the contexts for our objects.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  First, kings of them all, there are business objects. My library is full of OO books that describe how to design these guys. We have patterns and anti-patterns. Everybody is out there promoting their own methodology. But if we go deep enough, the most important design task in creating them is assigning responsibilities. This concept is as old as OO itself; it finds its roots in CRC cards. But I digress. Once again, when you design your business objects you have to be very careful to assign responsibilities to the objects that have the right information to perform them.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  It would be nice if this was all you have to code. A crazy bigot (like me) would think that all the rest is infrastructure (ala &lt;a href="http://www.nakedobjects.org/"&gt;naked objects&lt;/a&gt;). But we live in the real world, so let's get down to it.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  A second category of objects I often encounter are network objects. These are the guys you use to communicate data across tiers (logical, physical, webservices). They are usually quite dumb objects, not too much logic in them (if any), and your application creates them by filling their properties from the more noble business objects. Something along the line of the &lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html"&gt;value object pattern&lt;/a&gt;. Is assigning responsibilities a very important task here? Heck no!! They don't even have methods!! The most important characteristic they have is bandwidth optimization; you want to retrieve a whole bunch of stuff in one single round trip. More often than not you sacrifice everything else (manageability, good design) to achieve that.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  This is why I don't believe the quite common ideal of remoting your business objects. The set of constraints you use to design them is completely different (often opposite) to the constraints needed to go over the wire. When anything goes over the wire it becomes just data. Moreover not all of your business state needs to go on the network, but this is another story
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  Another common object category is database objects. There is a big debate if they are the same as business objects or not. I dont' want to go there, but If you want them to be the same you usually pragmatically sacrifice a bit of OO purity to make them more similar to the database tables (you don't want to fight your object relational mapping layer, you want to help it out). To say this in a more positive way, you design your domain model with an eye on how you are going to persist it. If, on the other end, you are willing to create a separate set of objects to represent data coming from the database, then the main constraint for these guys is the same as your database tables: normalization. This is not surprising as they are mirrors of your database. Again assigning responsibilities and being network friendly take the back seat in this case.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  There are many other object categories I often found useful (i.e. fa&amp;#231;ade objects). I don't want to discuss all of them here. Things are already boring as they are. The central point is that it is very hard to&amp;nbsp;define generic guidelines that work well in all the different contexts. You got to think about your context first.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  The funny thing is that I work in a place where we are supposed to design features that are generically interesting in all these scenarios. You use C# to code all of them. Oh well, design is the art of choosing trade offs
&lt;/p&gt;</description>
            <pubDate>Tue, 27 Jul 2004 15:21:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-07-27-please-the-perfect-object-stand-up.html</guid>
        </item>
        
        <item>
            <title>My first (and last?) post</title>
            <link>https://www.lucabol.com/posts/2004-07-27-my-first-and-last-post.html</link>
            <description>&lt;p class="MsoNormal" style="margin:0;"&gt;
  Hello folks,
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  My crazy coworkers finally convinced me to get my own blog. They think I'll say something funny, but I won't  - so don't link to me  - it's probably not worth it. For the few perseverant ones, here is what I plan to talk about: object orientation, c#, sports, financial stuff and books (not in that order). See you later.
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p class="MsoNormal" style="margin:0;"&gt;
  BTW: strange how this blog thing reduces the complexity of one's personality to a bunch of categories on the left of the screen
&lt;/p&gt;</description>
            <pubDate>Tue, 27 Jul 2004 14:18:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-07-27-my-first-and-last-post.html</guid>
        </item>
        
        <item>
            <title>Here I am.</title>
            <link>https://www.lucabol.com/posts/2004-07-27-here-i-am.html</link>
            <description>&lt;p&gt;I&amp;rsquo;m Luca Bolognese. &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m&amp;nbsp;the Principal Group Program Manager&amp;nbsp;for the C#, VB and F# languages, compilers and IDEs. Before that, I was the LINQ guy.&amp;nbsp;&amp;nbsp;Before that, I was the ObjectSpaces guy.&lt;/p&gt;
&lt;p&gt;In my spare time, I read a lot of books. I mean: a lot. I&amp;rsquo;m not sure how much I retain. I also try to keep some form of physical shape by playing sports and walking.&lt;/p&gt;
&lt;p&gt;All in all, I try to recreate my own Italian lifestyle in the&amp;nbsp;Kirkland area.&lt;/p&gt;</description>
            <pubDate>Tue, 27 Jul 2004 13:59:00 GMT</pubDate>
            <guid>https://www.lucabol.com/posts/2004-07-27-here-i-am.html</guid>
        </item>
        
    </channel>
</rss>